From 27ddd1695541ff333104d5a3e441a0c37308750e Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 9 Feb 2015 14:23:12 +0100 Subject: Work on man pages. 009_nxproxy_add-man-page.full+lite.patch 009_nxagent_add-man-page.full.patch 010_nxauth_fix-binary-name-in-man-page.full.patch --- nxproxy/man/nxproxy.1 | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 nxproxy/man/nxproxy.1 (limited to 'nxproxy') diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 new file mode 100644 index 000000000..0432380f8 --- /dev/null +++ b/nxproxy/man/nxproxy.1 @@ -0,0 +1,27 @@ +'\" -*- coding: utf-8 -*- +.if \n(.g .ds T< \\FC +.if \n(.g .ds T> \\F[\n[.fam]] +.de URL +\\$2 \(la\\$1\(ra\\$3 +.. +.if \n(.g .mso www.tmac +.TH nxproxy 1 "Nov 2011" "Version 3.5.0" "NX Proxy" +.SH NAME +nxproxy \- NX Proxy Tool +.SH SYNOPSIS +'nh +.fi +.ad l +\fBnxproxy\fR + +.SH DESCRIPTION +\fBnxproxy\fR is a tool that allows one to tunnel X sessions through +the NX compression libraries. \fBnxproxy\fR is a backend application +utilized by the X2GoClient GUI and some other NX/X2Go clients. +.PP +.SH OPTIONS +For an insight in \fBnxproxy\fR options use \fBnxproxy \-\-help\fR on the command line. +.PP +.SH AUTHOR +This manual has been written by Mike Gabriel for the X2Go project +(http://www.x2go.org). -- cgit v1.2.3 From 4bc550e867f6168c1090aa4e1959a22238be84f1 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 9 Feb 2015 14:26:02 +0100 Subject: nxcomp*,nxproxy: Add clean rules to Makefile.in templates. --- ...omp_makefile-uninstall+autoconf.full+lite.patch | 74 ---------------------- ...xcompext_makefile-uninstall+autoconf.full.patch | 66 ------------------- ...compshad_makefile-uninstall+autoconf.full.patch | 70 -------------------- .../015_nxproxy_makefile-uninstall.full+lite.patch | 40 ------------ debian/patches/series | 4 -- nxcomp/Makefile.in | 39 +++++++++++- nxcompext/Makefile.in | 31 ++++++++- nxcompshad/Makefile.in | 35 +++++++++- nxproxy/Makefile.in | 17 ++++- 9 files changed, 115 insertions(+), 261 deletions(-) delete mode 100644 debian/patches/012_nxcomp_makefile-uninstall+autoconf.full+lite.patch delete mode 100644 debian/patches/013_nxcompext_makefile-uninstall+autoconf.full.patch delete mode 100644 debian/patches/014_nxcompshad_makefile-uninstall+autoconf.full.patch delete mode 100644 debian/patches/015_nxproxy_makefile-uninstall.full+lite.patch (limited to 'nxproxy') diff --git a/debian/patches/012_nxcomp_makefile-uninstall+autoconf.full+lite.patch b/debian/patches/012_nxcomp_makefile-uninstall+autoconf.full+lite.patch deleted file mode 100644 index af778fefc..000000000 --- a/debian/patches/012_nxcomp_makefile-uninstall+autoconf.full+lite.patch +++ /dev/null @@ -1,74 +0,0 @@ -Description: Add install and uninstall stanzas to nxcomp/Makefile, honor ac dirs - Provide install and uninstall functionality in nxcomp/Makefile. - . - Honor autoconf's libdir (and includedir, while at it). This is a - must-have for multiarch platforms like x86_64 et al where multiple - forms of libraries can be installed at the same time. -Forwarded: pending... -Author: Mike Gabriel -Author: Jan Engelhardt -Last-Update: 2012-02-14 ---- a/nxcomp/Makefile.in -+++ b/nxcomp/Makefile.in -@@ -64,10 +64,15 @@ - bindir = @bindir@ - man1dir = @mandir@/man1 - VPATH = @srcdir@ -+libdir = @libdir@ -+includedir = @includedir@ - - INSTALL = @INSTALL@ - INSTALL_PROGRAM = @INSTALL_PROGRAM@ - INSTALL_DATA = @INSTALL_DATA@ -+INSTALL_LINK = cp -av -+DESTDIR = -+RM_FILE = rm -f - - # - # This should be autodetected. -@@ -264,12 +269,44 @@ - fi - touch depend.status - --install: install.bin install.man -+install: install.bin install.lib install.man - - install.bin: - -+install.lib: all -+ ./mkinstalldirs $(DESTDIR)${libdir} -+ ./mkinstalldirs $(DESTDIR)${includedir}/nx -+ $(INSTALL_DATA) $(LIBFULL) $(DESTDIR)${libdir} -+ $(INSTALL_LINK) libXcomp.so.3 $(DESTDIR)${libdir} -+ $(INSTALL_LINK) libXcomp.so $(DESTDIR)${libdir} -+ $(INSTALL_DATA) libXcomp.a $(DESTDIR)${libdir} -+ $(INSTALL_DATA) NX*.h $(DESTDIR)${includedir}/nx -+ $(INSTALL_DATA) MD5.h $(DESTDIR)${includedir}/nx -+ echo "Running ldconfig tool, this may take a while..." && ldconfig || true -+ - install.man: - -+uninstall: uninstall.bin uninstall.lib uninstall.man -+ -+uninstall.bin: -+ -+uninstall.lib: -+ $(RM_FILE) $(DESTDIR)${libdir}/$(LIBFULL) -+ $(RM_FILE) $(DESTDIR)${libdir}/libXcomp.so.3 -+ $(RM_FILE) $(DESTDIR)${libdir}/libXcomp.so -+ $(RM_FILE) $(DESTDIR)${libdir}/libXcomp.a -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NXalert.h -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NX.h -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NXmitshm.h -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NXpack.h -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NXproto.h -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NXrender.h -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NXvars.h -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/MD5.h -+ echo "Running ldconfig tool, this may take a while..." && ldconfig || true -+ -+uninstall.man: -+ - clean: - -rm -f *~ *.o *.bak *.orig *.rej st?????? core core.* *.out.* \ - @ALL@ diff --git a/debian/patches/013_nxcompext_makefile-uninstall+autoconf.full.patch b/debian/patches/013_nxcompext_makefile-uninstall+autoconf.full.patch deleted file mode 100644 index 300c0a39e..000000000 --- a/debian/patches/013_nxcompext_makefile-uninstall+autoconf.full.patch +++ /dev/null @@ -1,66 +0,0 @@ -Description: Add install and uninstall stanzas to nxcompext/Makefile, honor autoconf dirs. - Provide install and uninstall functionality in nxcompext/Makefile. - . - Honor autoconf's libdir (and includedir, while at it). This is a - must-have for multiarch platforms like x86_64 et al where multiple - forms of libraries can be installed at the same time. -Forwarded: pending... -Author: Mike Gabriel -Author: Jan Engelhardt -Last-Update: 2012-02-14 ---- a/nxcompext/Makefile.in -+++ b/nxcompext/Makefile.in -@@ -56,11 +56,15 @@ - bindir = @bindir@ - man1dir = @mandir@/man1 - VPATH = @srcdir@ -+libdir = @libdir@ -+includedir = @includedir@ - - INSTALL = @INSTALL@ - INSTALL_PROGRAM = @INSTALL_PROGRAM@ - INSTALL_DATA = @INSTALL_DATA@ -- -+INSTALL_LINK = cp -av -+DESTDIR = -+RM_FILE = rm -f - # - # This should be autodetected. - # -@@ -147,12 +151,35 @@ - fi - touch depend.status - --install: install.bin install.man -+install: install.bin install.lib install.man - - install.bin: - -+install.lib: all -+ ./mkinstalldirs $(DESTDIR)${libdir} -+ ./mkinstalldirs $(DESTDIR)${includedir}/nx -+ $(INSTALL_DATA) $(LIBFULL) $(DESTDIR)${libdir} -+ $(INSTALL_LINK) libXcompext.so.3 $(DESTDIR)${libdir} -+ $(INSTALL_LINK) libXcompext.so $(DESTDIR)${libdir} -+ $(INSTALL_DATA) NX*.h $(DESTDIR)${includedir}/nx -+ echo "Running ldconfig tool, this may take a while..." && ldconfig || true -+ - install.man: - -+uninstall: uninstall.bin uninstall.lib uninstall.man -+ -+uninstall.bin: -+ -+uninstall.lib: -+ $(RM_FILE) $(DESTDIR)${libdir}/$(LIBFULL) -+ $(RM_FILE) $(DESTDIR)${libdir}/libXcompext.so.3 -+ $(RM_FILE) $(DESTDIR)${libdir}/libXcompext.so -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NXlib.h -+ $(RM_FILE) $(DESTDIR)${includedir}/nx/NXlibint.h -+ echo "Running ldconfig tool, this may take a while..." && ldconfig || true -+ -+uninstall.man: -+ - clean: - -rm -f *~ *.o *.bak *.orig *.rej st?????? core core.* *.out.* \ - @ALL@ diff --git a/debian/patches/014_nxcompshad_makefile-uninstall+autoconf.full.patch b/debian/patches/014_nxcompshad_makefile-uninstall+autoconf.full.patch deleted file mode 100644 index 921eccc4f..000000000 --- a/debian/patches/014_nxcompshad_makefile-uninstall+autoconf.full.patch +++ /dev/null @@ -1,70 +0,0 @@ -Description: Add install and uninstall stanzas to nxcompshad/Makefile, honor autoconf dirs - Provide install and uninstall functionality in nxcompshad/Makefile. - . - Honor autoconf's libdir (and includedir, while at it). This is a - must-have for multiarch platforms like x86_64 et al where multiple - forms of libraries can be installed at the same time. -Forwarded: pending... -Author: Mike Gabriel -Author: Jan Engelhardt -Last-Update: 2012-02-14 ---- a/nxcompshad/Makefile.in -+++ b/nxcompshad/Makefile.in -@@ -74,10 +74,17 @@ - bindir = @bindir@ - man1dir = @mandir@/man1 - VPATH = @srcdir@ -+libdir = @libdir@ -+includedir = @includedir@ - - INSTALL = @INSTALL@ -+INSTALL_DIR = $(INSTALL) -d -o root -g root -m 0755 - INSTALL_PROGRAM = @INSTALL_PROGRAM@ - INSTALL_DATA = @INSTALL_DATA@ -+INSTALL_LINK = cp -av -+DESTDIR = -+RM_FILE = rm -f -+RM_DIR = rmdir -p --ignore-fail-on-non-empty - - # - # This should be autodetected. -@@ -178,12 +185,38 @@ - fi - touch depend.status - --install: install.bin install.man -+install: install.bin install.lib install.man - - install.bin: - -+install.lib: all -+ $(INSTALL_DIR) $(DESTDIR)${libdir} -+ $(INSTALL_DIR) $(DESTDIR)${includedir}/nx -+ $(INSTALL_DATA) $(LIBFULL) $(DESTDIR)${libdir} -+ $(INSTALL_LINK) libXcompshad.so.3 $(DESTDIR)${libdir} -+ $(INSTALL_LINK) libXcompshad.so $(DESTDIR)${libdir} -+ $(INSTALL_DATA) *.a $(DESTDIR)${libdir} -+ $(INSTALL_DATA) *.h $(DESTDIR)${includedir}/nx -+ echo "Running ldconfig tool, this may take a while..." && ldconfig || true -+ - install.man: - -+uninstall: uninstall.bin uninstall.lib uninstall.man -+ -+uninstall.bin: -+ -+uninstall.lib: -+ $(RM_FILE) $(DESTDIR)${libdir}/$(LIBFULL) -+ $(RM_FILE) $(DESTDIR)${libdir}/libXcompshad.so.3 -+ $(RM_FILE) $(DESTDIR)${libdir}/libXcompshad.so -+ $(RM_FILE) $(DESTDIR)${libdir}/libXcompshad.a -+ for header in *.h; do $(RM_FILE) $(DESTDIR)${includedir}/nx/$$header; done -+ $(RM_DIR) $(DESTDIR)${libdir}/nx/ -+ $(RM_DIR) $(DESTDIR)${includedir}/nx/ -+ echo "Running ldconfig tool, this may take a while..." && ldconfig || true -+ -+uninstall.man: -+ - clean: - -rm -f *~ *.o *.gch *.bak st?????? core core.* *.out.* *.exe.stackdump \ - $(LIBFULL) $(LIBLOAD) $(LIBSHARED) $(LIBARCHIVE) $(LIBDLL) $(LIBDLLSTATIC) $(PROGRAM) $(PROGRAM).exe diff --git a/debian/patches/015_nxproxy_makefile-uninstall.full+lite.patch b/debian/patches/015_nxproxy_makefile-uninstall.full+lite.patch deleted file mode 100644 index 554c86aa4..000000000 --- a/debian/patches/015_nxproxy_makefile-uninstall.full+lite.patch +++ /dev/null @@ -1,40 +0,0 @@ -Description: Add install and uninstall stanzas to nxcomp/Makefile - Provide install and uninstall functionality in nxcomp/Makefile. -Forwarded: pending... -Author: Mike Gabriel -Last-Update: 2011-12-31 ---- a/nxproxy/Makefile.in -+++ b/nxproxy/Makefile.in -@@ -41,6 +41,8 @@ - INSTALL = @INSTALL@ - INSTALL_PROGRAM = @INSTALL_PROGRAM@ - INSTALL_DATA = @INSTALL_DATA@ -+DESTDIR = -+RM_FILE = rm -f - - # - # This should be autodetected. -@@ -87,11 +89,20 @@ - install: install.bin install.man - - install.bin: $(PROGRAM) -- $(srcdir)/mkinstalldirs $(bindir) -- $(INSTALL) $(PROGRAM) $(bindir)/$(PROGRAM) -+ $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) -+ $(INSTALL_PROGRAM) $(PROGRAM) $(DESTDIR)$(bindir)/$(PROGRAM) - - install.man: -- $(srcdir)/mkinstalldirs $(man1dir) -+ $(srcdir)/mkinstalldirs $(DESTDIR)$(man1dir) -+ $(INSTALL_DATA) man/$(PROGRAM).1 $(DESTDIR)$(man1dir)/$(PROGRAM).1 -+ -+uninstall: uninstall.bin uninstall.man -+ -+uninstall.bin: -+ $(RM_FILE) $(DESTDIR)$(bindir)/$(PROGRAM) -+ -+uninstall.man: -+ $(RM_FILE) $(DESTDIR)$(man1dir)/nxproxy.1 - - clean: - -rm -f *~ *.o *.bak st?????? core core.* *.out.* \ diff --git a/debian/patches/series b/debian/patches/series index 8bbb69182..f3678f428 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,7 +1,3 @@ -012_nxcomp_makefile-uninstall+autoconf.full+lite.patch -013_nxcompext_makefile-uninstall+autoconf.full.patch -014_nxcompshad_makefile-uninstall+autoconf.full.patch -015_nxproxy_makefile-uninstall.full+lite.patch 016_nx-X11_install-location.full.patch 024_fix-make-clean.full.patch 024_fix-make-clean.full+lite.patch diff --git a/nxcomp/Makefile.in b/nxcomp/Makefile.in index 434118b4e..d291c3967 100644 --- a/nxcomp/Makefile.in +++ b/nxcomp/Makefile.in @@ -64,10 +64,15 @@ exec_prefix = @exec_prefix@ bindir = @bindir@ man1dir = @mandir@/man1 VPATH = @srcdir@ +libdir = @libdir@ +includedir = @includedir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ +INSTALL_LINK = cp -av +DESTDIR = +RM_FILE = rm -f # # This should be autodetected. @@ -264,12 +269,44 @@ depend.status: fi touch depend.status -install: install.bin install.man +install: install.bin install.lib install.man install.bin: +install.lib: all + ./mkinstalldirs $(DESTDIR)${libdir} + ./mkinstalldirs $(DESTDIR)${includedir}/nx + $(INSTALL_DATA) $(LIBFULL) $(DESTDIR)${libdir} + $(INSTALL_LINK) libXcomp.so.3 $(DESTDIR)${libdir} + $(INSTALL_LINK) libXcomp.so $(DESTDIR)${libdir} + $(INSTALL_DATA) libXcomp.a $(DESTDIR)${libdir} + $(INSTALL_DATA) NX*.h $(DESTDIR)${includedir}/nx + $(INSTALL_DATA) MD5.h $(DESTDIR)${includedir}/nx + echo "Running ldconfig tool, this may take a while..." && ldconfig || true + install.man: +uninstall: uninstall.bin uninstall.lib uninstall.man + +uninstall.bin: + +uninstall.lib: + $(RM_FILE) $(DESTDIR)${libdir}/$(LIBFULL) + $(RM_FILE) $(DESTDIR)${libdir}/libXcomp.so.3 + $(RM_FILE) $(DESTDIR)${libdir}/libXcomp.so + $(RM_FILE) $(DESTDIR)${libdir}/libXcomp.a + $(RM_FILE) $(DESTDIR)${includedir}/nx/NXalert.h + $(RM_FILE) $(DESTDIR)${includedir}/nx/NX.h + $(RM_FILE) $(DESTDIR)${includedir}/nx/NXmitshm.h + $(RM_FILE) $(DESTDIR)${includedir}/nx/NXpack.h + $(RM_FILE) $(DESTDIR)${includedir}/nx/NXproto.h + $(RM_FILE) $(DESTDIR)${includedir}/nx/NXrender.h + $(RM_FILE) $(DESTDIR)${includedir}/nx/NXvars.h + $(RM_FILE) $(DESTDIR)${includedir}/nx/MD5.h + echo "Running ldconfig tool, this may take a while..." && ldconfig || true + +uninstall.man: + clean: -rm -f *~ *.o *.bak *.orig *.rej st?????? core core.* *.out.* \ @ALL@ diff --git a/nxcompext/Makefile.in b/nxcompext/Makefile.in index cdf0b1cd9..51bc06ed2 100644 --- a/nxcompext/Makefile.in +++ b/nxcompext/Makefile.in @@ -56,11 +56,15 @@ exec_prefix = @exec_prefix@ bindir = @bindir@ man1dir = @mandir@/man1 VPATH = @srcdir@ +libdir = @libdir@ +includedir = @includedir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ - +INSTALL_LINK = cp -av +DESTDIR = +RM_FILE = rm -f # # This should be autodetected. # @@ -147,12 +151,35 @@ depend.status: fi touch depend.status -install: install.bin install.man +install: install.bin install.lib install.man install.bin: +install.lib: all + ./mkinstalldirs $(DESTDIR)${libdir} + ./mkinstalldirs $(DESTDIR)${includedir}/nx + $(INSTALL_DATA) $(LIBFULL) $(DESTDIR)${libdir} + $(INSTALL_LINK) libXcompext.so.3 $(DESTDIR)${libdir} + $(INSTALL_LINK) libXcompext.so $(DESTDIR)${libdir} + $(INSTALL_DATA) NX*.h $(DESTDIR)${includedir}/nx + echo "Running ldconfig tool, this may take a while..." && ldconfig || true + install.man: +uninstall: uninstall.bin uninstall.lib uninstall.man + +uninstall.bin: + +uninstall.lib: + $(RM_FILE) $(DESTDIR)${libdir}/$(LIBFULL) + $(RM_FILE) $(DESTDIR)${libdir}/libXcompext.so.3 + $(RM_FILE) $(DESTDIR)${libdir}/libXcompext.so + $(RM_FILE) $(DESTDIR)${includedir}/nx/NXlib.h + $(RM_FILE) $(DESTDIR)${includedir}/nx/NXlibint.h + echo "Running ldconfig tool, this may take a while..." && ldconfig || true + +uninstall.man: + clean: -rm -f *~ *.o *.bak *.orig *.rej st?????? core core.* *.out.* \ @ALL@ diff --git a/nxcompshad/Makefile.in b/nxcompshad/Makefile.in index caf9eb14c..26a92bdce 100644 --- a/nxcompshad/Makefile.in +++ b/nxcompshad/Makefile.in @@ -74,10 +74,17 @@ exec_prefix = @exec_prefix@ bindir = @bindir@ man1dir = @mandir@/man1 VPATH = @srcdir@ +libdir = @libdir@ +includedir = @includedir@ INSTALL = @INSTALL@ +INSTALL_DIR = $(INSTALL) -d -o root -g root -m 0755 INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ +INSTALL_LINK = cp -av +DESTDIR = +RM_FILE = rm -f +RM_DIR = rmdir -p --ignore-fail-on-non-empty # # This should be autodetected. @@ -178,12 +185,38 @@ depend.status: fi touch depend.status -install: install.bin install.man +install: install.bin install.lib install.man install.bin: +install.lib: all + $(INSTALL_DIR) $(DESTDIR)${libdir} + $(INSTALL_DIR) $(DESTDIR)${includedir}/nx + $(INSTALL_DATA) $(LIBFULL) $(DESTDIR)${libdir} + $(INSTALL_LINK) libXcompshad.so.3 $(DESTDIR)${libdir} + $(INSTALL_LINK) libXcompshad.so $(DESTDIR)${libdir} + $(INSTALL_DATA) *.a $(DESTDIR)${libdir} + $(INSTALL_DATA) *.h $(DESTDIR)${includedir}/nx + echo "Running ldconfig tool, this may take a while..." && ldconfig || true + install.man: +uninstall: uninstall.bin uninstall.lib uninstall.man + +uninstall.bin: + +uninstall.lib: + $(RM_FILE) $(DESTDIR)${libdir}/$(LIBFULL) + $(RM_FILE) $(DESTDIR)${libdir}/libXcompshad.so.3 + $(RM_FILE) $(DESTDIR)${libdir}/libXcompshad.so + $(RM_FILE) $(DESTDIR)${libdir}/libXcompshad.a + for header in *.h; do $(RM_FILE) $(DESTDIR)${includedir}/nx/$$header; done + $(RM_DIR) $(DESTDIR)${libdir}/nx/ + $(RM_DIR) $(DESTDIR)${includedir}/nx/ + echo "Running ldconfig tool, this may take a while..." && ldconfig || true + +uninstall.man: + clean: -rm -f *~ *.o *.gch *.bak st?????? core core.* *.out.* *.exe.stackdump \ $(LIBFULL) $(LIBLOAD) $(LIBSHARED) $(LIBARCHIVE) $(LIBDLL) $(LIBDLLSTATIC) $(PROGRAM) $(PROGRAM).exe diff --git a/nxproxy/Makefile.in b/nxproxy/Makefile.in index 928e0d34e..5d78972b9 100644 --- a/nxproxy/Makefile.in +++ b/nxproxy/Makefile.in @@ -41,6 +41,8 @@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ +DESTDIR = +RM_FILE = rm -f # # This should be autodetected. @@ -87,11 +89,20 @@ depend.status: install: install.bin install.man install.bin: $(PROGRAM) - $(srcdir)/mkinstalldirs $(bindir) - $(INSTALL) $(PROGRAM) $(bindir)/$(PROGRAM) + $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) $(PROGRAM) $(DESTDIR)$(bindir)/$(PROGRAM) install.man: - $(srcdir)/mkinstalldirs $(man1dir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(man1dir) + $(INSTALL_DATA) man/$(PROGRAM).1 $(DESTDIR)$(man1dir)/$(PROGRAM).1 + +uninstall: uninstall.bin uninstall.man + +uninstall.bin: + $(RM_FILE) $(DESTDIR)$(bindir)/$(PROGRAM) + +uninstall.man: + $(RM_FILE) $(DESTDIR)$(man1dir)/nxproxy.1 clean: -rm -f *~ *.o *.bak st?????? core core.* *.out.* \ -- cgit v1.2.3 From 236ee4ffa8e4fa92bb748301986307841ef060ab Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 9 Feb 2015 15:16:30 +0100 Subject: nxcomp*, nxproxy: Fix clean-up of source tree via Makefile.in templates. 024_fix-make-clean.full.patch 024_fix-make-clean.full+lite.patch --- debian/patches/024_fix-make-clean.full+lite.patch | 19 --------- debian/patches/024_fix-make-clean.full.patch | 51 ----------------------- debian/patches/series | 2 - nx-X11/Makefile | 10 ++++- nxcomp/Makefile.in | 2 +- nxcompext/Makefile.in | 2 +- nxcompshad/Makefile.in | 2 +- nxproxy/Makefile.in | 2 +- 8 files changed, 12 insertions(+), 78 deletions(-) delete mode 100644 debian/patches/024_fix-make-clean.full+lite.patch delete mode 100644 debian/patches/024_fix-make-clean.full.patch (limited to 'nxproxy') diff --git a/debian/patches/024_fix-make-clean.full+lite.patch b/debian/patches/024_fix-make-clean.full+lite.patch deleted file mode 100644 index 7f0b327cf..000000000 --- a/debian/patches/024_fix-make-clean.full+lite.patch +++ /dev/null @@ -1,19 +0,0 @@ -Description: fix clean rule in nxcomp's Makefile.in -Author: Mike Gabriel - ---- a/nxcomp/Makefile.in -+++ b/nxcomp/Makefile.in -@@ -313,4 +313,4 @@ - - distclean: clean - -rm -rf autom4te.cache config.status config.log \ -- config.cache depend.status Makefile tags -+ config.cache depend.status Makefile tags configure ---- a/nxproxy/Makefile.in -+++ b/nxproxy/Makefile.in -@@ -109,4 +109,4 @@ - $(PROGRAM) $(PROGRAM).exe $(LIBFULL) $(LIBLOAD) $(LIBSHARED) $(LIBARCHIVE) - - distclean: clean -- -rm -f config.status config.log config.cache depend.status Makefile tags -+ -rm -rf autom4te.cache config.status config.log config.cache depend.status Makefile tags configure diff --git a/debian/patches/024_fix-make-clean.full.patch b/debian/patches/024_fix-make-clean.full.patch deleted file mode 100644 index 356ce47d8..000000000 --- a/debian/patches/024_fix-make-clean.full.patch +++ /dev/null @@ -1,51 +0,0 @@ -Description: Provide main Makefile for whole source tree - By design this patch is not needed to be sent upstream. -Forwarded: not-needed -Author: Mike Gabriel -Last-Update: 2012-10-19 ---- a/nx-X11/Makefile -+++ b/nx-X11/Makefile -@@ -138,6 +138,7 @@ - - xmakefile: Imakefile - $(RM) xmakefile -+ @rm -f $(IRULESRC)/date.def; echo "" > $(IRULESRC)/date.def; - $(IMAKE_CMD) -s xmakefile -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) - - World.Win32: -@@ -197,11 +198,16 @@ - # a copy of every rule that might be invoked at top level - - clean: -- $(MAKE_CMD) $@ -+ -$(MAKE_CMD) $@ -+ find config -type f | egrep '.*/Makefile$$' | while read makefile; do rm -f $$makefile; done -+ find lib -type f | egrep '.*/Makefile$$' | while read makefile; do rm -f $$makefile; done -+ find programs -type f | egrep '.*/Makefile$$' | while read makefile; do rm -f $$makefile; done -+ find include -type f | egrep '.*/Makefile$$' | while read makefile; do rm -f $$makefile; done -+ rm -f config/cf/{version.def,date.def} - dangerous_strip_clean: - $(MAKE_CMD) $@ - distclean: -- $(MAKE_CMD) $@ -+ -$(MAKE_CMD) $@ - $(RM) xmakefile $(IRULESRC)/version.def $(IRULESRC)/date.def - depend: - $(MAKE_CMD) $@ ---- a/nxcompext/Makefile.in -+++ b/nxcompext/Makefile.in -@@ -185,5 +185,5 @@ - @ALL@ - - distclean: clean -- -rm -rf autom4te.cache config.status config.log \ -+ -rm -rf autom4te.cache config.status config.log configure \ - config.cache depend.status Makefile tags ---- a/nxcompshad/Makefile.in -+++ b/nxcompshad/Makefile.in -@@ -222,4 +222,4 @@ - $(LIBFULL) $(LIBLOAD) $(LIBSHARED) $(LIBARCHIVE) $(LIBDLL) $(LIBDLLSTATIC) $(PROGRAM) $(PROGRAM).exe - - distclean: clean -- -rm -rf config.status config.log config.cache depend.status Makefile tags autom4te.cache -+ -rm -rf config.status config.log config.cache depend.status Makefile tags autom4te.cache configure diff --git a/debian/patches/series b/debian/patches/series index 70c573c38..63bc3dc43 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,5 +1,3 @@ -024_fix-make-clean.full.patch -024_fix-make-clean.full+lite.patch 025_nxcomp-fix-ftbfs-against-jpeg9a.full+lite.patch 026_nxcompext_honour-optflags.full.patch 026_nxcomp_honour-optflags.full+lite.patch diff --git a/nx-X11/Makefile b/nx-X11/Makefile index 3aefb7974..7c4090a95 100644 --- a/nx-X11/Makefile +++ b/nx-X11/Makefile @@ -138,6 +138,7 @@ Makefile:: xmakefile: Imakefile $(RM) xmakefile + @rm -f $(IRULESRC)/date.def; echo "" > $(IRULESRC)/date.def; $(IMAKE_CMD) -s xmakefile -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) World.Win32: @@ -197,11 +198,16 @@ World.OS2: # a copy of every rule that might be invoked at top level clean: - $(MAKE_CMD) $@ + -$(MAKE_CMD) $@ + find config -type f | egrep '.*/Makefile$$' | while read makefile; do rm -f $$makefile; done + find lib -type f | egrep '.*/Makefile$$' | while read makefile; do rm -f $$makefile; done + find programs -type f | egrep '.*/Makefile$$' | while read makefile; do rm -f $$makefile; done + find include -type f | egrep '.*/Makefile$$' | while read makefile; do rm -f $$makefile; done + rm -f config/cf/{version.def,date.def} dangerous_strip_clean: $(MAKE_CMD) $@ distclean: - $(MAKE_CMD) $@ + -$(MAKE_CMD) $@ $(RM) xmakefile $(IRULESRC)/version.def $(IRULESRC)/date.def depend: $(MAKE_CMD) $@ diff --git a/nxcomp/Makefile.in b/nxcomp/Makefile.in index d291c3967..1be928167 100644 --- a/nxcomp/Makefile.in +++ b/nxcomp/Makefile.in @@ -313,4 +313,4 @@ clean: distclean: clean -rm -rf autom4te.cache config.status config.log \ - config.cache depend.status Makefile tags + config.cache depend.status Makefile tags configure diff --git a/nxcompext/Makefile.in b/nxcompext/Makefile.in index 51bc06ed2..9fd2c7d7d 100644 --- a/nxcompext/Makefile.in +++ b/nxcompext/Makefile.in @@ -185,5 +185,5 @@ clean: @ALL@ distclean: clean - -rm -rf autom4te.cache config.status config.log \ + -rm -rf autom4te.cache config.status config.log configure \ config.cache depend.status Makefile tags diff --git a/nxcompshad/Makefile.in b/nxcompshad/Makefile.in index 26a92bdce..00bca25c9 100644 --- a/nxcompshad/Makefile.in +++ b/nxcompshad/Makefile.in @@ -222,4 +222,4 @@ clean: $(LIBFULL) $(LIBLOAD) $(LIBSHARED) $(LIBARCHIVE) $(LIBDLL) $(LIBDLLSTATIC) $(PROGRAM) $(PROGRAM).exe distclean: clean - -rm -rf config.status config.log config.cache depend.status Makefile tags autom4te.cache + -rm -rf config.status config.log config.cache depend.status Makefile tags autom4te.cache configure diff --git a/nxproxy/Makefile.in b/nxproxy/Makefile.in index 5d78972b9..c00df91dc 100644 --- a/nxproxy/Makefile.in +++ b/nxproxy/Makefile.in @@ -109,4 +109,4 @@ clean: $(PROGRAM) $(PROGRAM).exe $(LIBFULL) $(LIBLOAD) $(LIBSHARED) $(LIBARCHIVE) distclean: clean - -rm -f config.status config.log config.cache depend.status Makefile tags + -rm -rf autom4te.cache config.status config.log config.cache depend.status Makefile tags configure -- cgit v1.2.3 From 3384aba386c44ec26d3f131b897f77da440324d7 Mon Sep 17 00:00:00 2001 From: Orion Poplawski Date: Mon, 9 Feb 2015 15:22:07 +0100 Subject: Honour compiler/linker option flags. 026_nxcompext_honour-optflags.full.patch 026_nxcomp_honour-optflags.full+lite.patch 026_nxcompshad_honour-optflags.full.patch --- .../026_nxcomp_honour-optflags.full+lite.patch | 31 ---------------------- .../026_nxcompext_honour-optflags.full.patch | 17 ------------ .../026_nxcompshad_honour-optflags.full.patch | 17 ------------ debian/patches/series | 3 --- nxcomp/configure.in | 4 +-- nxcompext/configure.in | 4 +-- nxcompshad/configure.in | 4 +-- nxproxy/configure.in | 4 +-- 8 files changed, 8 insertions(+), 76 deletions(-) delete mode 100644 debian/patches/026_nxcomp_honour-optflags.full+lite.patch delete mode 100644 debian/patches/026_nxcompext_honour-optflags.full.patch delete mode 100644 debian/patches/026_nxcompshad_honour-optflags.full.patch (limited to 'nxproxy') diff --git a/debian/patches/026_nxcomp_honour-optflags.full+lite.patch b/debian/patches/026_nxcomp_honour-optflags.full+lite.patch deleted file mode 100644 index a2713a1bc..000000000 --- a/debian/patches/026_nxcomp_honour-optflags.full+lite.patch +++ /dev/null @@ -1,31 +0,0 @@ -Description: Honour compiler/linker option flags -Forwarded: pending -Author: Orion Poplawski -diff -up a/nxcomp/configure.in b/nxcomp/configure.in ---- a/nxcomp/configure.in 2012-11-10 06:40:55.000000000 -0700 -+++ b/nxcomp/configure.in 2012-12-11 13:13:19.390229196 -0700 -@@ -7,8 +7,8 @@ AC_PREREQ(2.13) - - dnl Set our default compilation flags. - --CXXFLAGS="-O3 -fno-rtti -fno-exceptions" --CFLAGS="-O3" -+CXXFLAGS="$CXXFLAGS -O3 -fno-rtti -fno-exceptions" -+CFLAGS="$CFLAGS -O3" - - dnl Reset default linking directives. - -diff -up a/nxproxy/configure.in b/nxproxy/configure.in ---- a/nxproxy/configure.in 2012-11-10 06:40:55.000000000 -0700 -+++ b/nxproxy/configure.in 2012-12-11 13:16:19.955301045 -0700 -@@ -7,8 +7,8 @@ AC_PREREQ(2.13) - - dnl Reset default compilation flags. - --CXXFLAGS="-O3" --CPPFLAGS="-O3" -+CXXFLAGS="$CXXFLAGS -O3" -+CPPFLAGS="$CPPFLAGS -O3" - - dnl Prefer headers and libraries from nx-X11 if present. - diff --git a/debian/patches/026_nxcompext_honour-optflags.full.patch b/debian/patches/026_nxcompext_honour-optflags.full.patch deleted file mode 100644 index 4d5df3e6b..000000000 --- a/debian/patches/026_nxcompext_honour-optflags.full.patch +++ /dev/null @@ -1,17 +0,0 @@ -Description: Honour compiler/linker option flags -Forwarded: pending -Author: Orion Poplawski -diff -up a/nxcompext/configure.in b/nxcompext/configure.in ---- a/nxcompext/configure.in 2012-11-10 06:40:55.000000000 -0700 -+++ b/nxcompext/configure.in 2012-12-11 13:15:26.712576302 -0700 -@@ -7,8 +7,8 @@ AC_PREREQ(2.13) - - dnl Reset default compilation flags. - --CXXFLAGS="-O3" --CFLAGS="-O3" -+CXXFLAGS="$CXXFLAGS -O3" -+CFLAGS="$CFLAGS -O3" - - dnl Reset default linking directives. - diff --git a/debian/patches/026_nxcompshad_honour-optflags.full.patch b/debian/patches/026_nxcompshad_honour-optflags.full.patch deleted file mode 100644 index ea1d2ad80..000000000 --- a/debian/patches/026_nxcompshad_honour-optflags.full.patch +++ /dev/null @@ -1,17 +0,0 @@ -Description: Honour compiler/linker option flags -Forwarded: pending -Author: Orion Poplawski -diff -up a/nxcompshad/configure.in b/nxcompshad/configure.in ---- a/nxcompshad/configure.in 2012-11-10 06:40:56.000000000 -0700 -+++ b/nxcompshad/configure.in 2012-12-11 13:13:25.915196300 -0700 -@@ -7,8 +7,8 @@ AC_PREREQ(2.13) - - dnl Reset default compilation flags. - --CXXFLAGS="-O3" --CPPFLAGS="-O3" -+CXXFLAGS="$CXXFLAGS -O3" -+CPPFLAGS="$CPPFLAGS -O3" - - dnl Reset default linking directives. - diff --git a/debian/patches/series b/debian/patches/series index 6eadd7bd9..ca6b6dcdc 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,6 +1,3 @@ -026_nxcompext_honour-optflags.full.patch -026_nxcomp_honour-optflags.full+lite.patch -026_nxcompshad_honour-optflags.full.patch 027_nxcomp_abstract-X11-socket.full+lite.patch 028_nx-X11_abstract-kernel-sockets.full.patch 029_nxcomp_ppc64.full+lite.patch diff --git a/nxcomp/configure.in b/nxcomp/configure.in index e9ab81da8..6fa9757a7 100644 --- a/nxcomp/configure.in +++ b/nxcomp/configure.in @@ -7,8 +7,8 @@ AC_PREREQ(2.13) dnl Set our default compilation flags. -CXXFLAGS="-O3 -fno-rtti -fno-exceptions" -CFLAGS="-O3" +CXXFLAGS="$CXXFLAGS -O3 -fno-rtti -fno-exceptions" +CFLAGS="$CFLAGS -O3" dnl Reset default linking directives. diff --git a/nxcompext/configure.in b/nxcompext/configure.in index fe5abf7cb..08c48a751 100644 --- a/nxcompext/configure.in +++ b/nxcompext/configure.in @@ -7,8 +7,8 @@ AC_PREREQ(2.13) dnl Reset default compilation flags. -CXXFLAGS="-O3" -CFLAGS="-O3" +CXXFLAGS="$CXXFLAGS -O3" +CFLAGS="$CFLAGS -O3" dnl Reset default linking directives. diff --git a/nxcompshad/configure.in b/nxcompshad/configure.in index f0bdecd12..13149b3a0 100644 --- a/nxcompshad/configure.in +++ b/nxcompshad/configure.in @@ -7,8 +7,8 @@ AC_PREREQ(2.13) dnl Reset default compilation flags. -CXXFLAGS="-O3" -CPPFLAGS="-O3" +CXXFLAGS="$CXXFLAGS -O3" +CPPFLAGS="$CPPFLAGS -O3" dnl Reset default linking directives. diff --git a/nxproxy/configure.in b/nxproxy/configure.in index bd930f166..b86828d02 100644 --- a/nxproxy/configure.in +++ b/nxproxy/configure.in @@ -7,8 +7,8 @@ AC_PREREQ(2.13) dnl Reset default compilation flags. -CXXFLAGS="-O3" -CPPFLAGS="-O3" +CXXFLAGS="$CXXFLAGS -O3" +CPPFLAGS="$CPPFLAGS -O3" dnl Prefer headers and libraries from nx-X11 if present. -- cgit v1.2.3 From ce531230f148a8c586a6e29c340e2db03d7bd3bb Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Sat, 14 Feb 2015 15:14:23 +0100 Subject: VERSION file: master VERSION file is in base folder, symlinked from nx*/VERSION and hw/nxagent/VERSION. This commit removes the debian/VERSION file at makes it now unnecessary to copy/symlink the VERSION file at build time. These build scripts got adapted: debian/roll-tarballs.sh debian/rules nx-libs.spec Furthermore, all NX component now use the main VERSION file as reference. typechange: nxcomp/VERSION typechange: nxcompext/VERSION typechange: nxcompshad/VERSION typechange: nxproxy/VERSION --- VERSION | 1 + VERSION.x2goagent | 1 + debian/VERSION | 1 - debian/roll-tarballs.sh | 2 -- debian/rules | 6 +----- nx-X11/programs/Xserver/hw/nxagent/VERSION | 1 + nx-libs.spec | 2 -- nxcomp/VERSION | 2 +- nxcompext/VERSION | 2 +- nxcompshad/VERSION | 2 +- nxproxy/VERSION | 2 +- 11 files changed, 8 insertions(+), 14 deletions(-) create mode 100644 VERSION create mode 120000 VERSION.x2goagent delete mode 100644 debian/VERSION create mode 120000 nx-X11/programs/Xserver/hw/nxagent/VERSION mode change 100644 => 120000 nxcomp/VERSION mode change 100644 => 120000 nxcompext/VERSION mode change 100644 => 120000 nxcompshad/VERSION mode change 100644 => 120000 nxproxy/VERSION (limited to 'nxproxy') diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..9af1780f9 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +3.5.99.0 diff --git a/VERSION.x2goagent b/VERSION.x2goagent new file mode 120000 index 000000000..974cf28e0 --- /dev/null +++ b/VERSION.x2goagent @@ -0,0 +1 @@ +VERSION \ No newline at end of file diff --git a/debian/VERSION b/debian/VERSION deleted file mode 100644 index 9af1780f9..000000000 --- a/debian/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.5.99.0 diff --git a/debian/roll-tarballs.sh b/debian/roll-tarballs.sh index 02a25dff5..03ab6778b 100755 --- a/debian/roll-tarballs.sh +++ b/debian/roll-tarballs.sh @@ -90,7 +90,6 @@ if [ "x$MODE" = "xfull" ]; then cp -v debian/rgb ./etc/ cp -v debian/nxagent.keyboard ./etc/ cp -v debian/x2goagent.keyboard ./etc/ - cp -v debian/VERSION ./VERSION.x2goagent else rm -Rf "nxcompshad"* rm -Rf "nxcompext"* @@ -101,7 +100,6 @@ else echo ${file##*/} >> doc/applied-patches/series done fi -cp -v debian/VERSION ./nxcomp/VERSION cp -v debian/COPYING.full+lite COPYING cp -v debian/nxagent.keyboard nxagent.keyboard cp -v debian/x2goagent.keyboard x2goagent.keyboard diff --git a/debian/rules b/debian/rules index ad9ddded6..e0b4166f5 100755 --- a/debian/rules +++ b/debian/rules @@ -24,10 +24,9 @@ override_dh_clean: rm -f nx-X11/programs/Xserver/hw/nxagent/changelog rm -f nx-X11/programs/nxauth/changelog . ./replace.sh; set -x; ls debian/*.install.in | while read file; do rm -f $$(string_rep $$file .install.in .install); done - rm -fR bin etc/rgb VERSION.x2goagent etc/keystrokes.cfg etc/nxagent.keyboard etc/x2goagent.keyboard + rm -fR bin etc/rgb etc/keystrokes.cfg etc/nxagent.keyboard etc/x2goagent.keyboard rm -f debian/libnx-xinerama1.postinst rm -fR .preserve/ - if [ -f nxcomp/.VERSION.NoMachine ]; then mv nxcomp/.VERSION.NoMachine nxcomp/VERSION; fi dh_clean override_dh_installchangelog: @@ -91,7 +90,6 @@ override_dh_auto_build: # create copies of upstream changelogs so that names apply to Debian policy... cp -a nx-X11/CHANGELOG nx-X11/changelog cp -a nxcomp/CHANGELOG nxcomp/changelog - if [ -f nxcomp/VERSION ]; then cp nxcomp/VERSION nxcomp/.VERSION.NoMachine; fi cp -a nxcompext/CHANGELOG nxcompext/changelog cp -a nxcompshad/CHANGELOG nxcompshad/changelog cp -a nx-X11/programs/Xserver/hw/nxagent/CHANGELOG nx-X11/programs/Xserver/hw/nxagent/changelog @@ -105,8 +103,6 @@ override_dh_auto_build: ln -s ../debian/x2goagent.keyboard etc/x2goagent.keyboard mkdir -p doc/ ln -s ../debian/changelog doc/changelog - ln -sf debian/VERSION VERSION.x2goagent - ln -sf ../debian/VERSION nxcomp/VERSION # let's prep the libnx-xinerama1.postinst script with the value of the build systems's DEB_BUILD_MULTIARCH variable sed debian/libnx-xinerama1.postinst.in -e 's/#DEB_BUILD_MULTIARCH#/$(DEB_BUILD_MULTIARCH)/' > debian/libnx-xinerama1.postinst diff --git a/nx-X11/programs/Xserver/hw/nxagent/VERSION b/nx-X11/programs/Xserver/hw/nxagent/VERSION new file mode 120000 index 000000000..9ca2cfb9d --- /dev/null +++ b/nx-X11/programs/Xserver/hw/nxagent/VERSION @@ -0,0 +1 @@ +../../../../../VERSION \ No newline at end of file diff --git a/nx-libs.spec b/nx-libs.spec index b5ac8d92f..c037a2662 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -668,8 +668,6 @@ cp -v debian/keystrokes.cfg etc/keystrokes.cfg cp -v debian/rgb etc/rgb cp -v debian/nxagent.keyboard etc/nxagent.keyboard cp -v debian/x2goagent.keyboard etc/x2goagent.keyboard -cp -v debian/VERSION VERSION.x2goagent -cp -v debian/VERSION nxcomp/VERSION # remove build cruft that is in Git (also taken from roll-tarball.sh) rm -Rf nx*/configure nx*/autom4te.cache* diff --git a/nxcomp/VERSION b/nxcomp/VERSION deleted file mode 100644 index 1545d9665..000000000 --- a/nxcomp/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.5.0 diff --git a/nxcomp/VERSION b/nxcomp/VERSION new file mode 120000 index 000000000..6ff19de4b --- /dev/null +++ b/nxcomp/VERSION @@ -0,0 +1 @@ +../VERSION \ No newline at end of file diff --git a/nxcompext/VERSION b/nxcompext/VERSION deleted file mode 100644 index 1545d9665..000000000 --- a/nxcompext/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.5.0 diff --git a/nxcompext/VERSION b/nxcompext/VERSION new file mode 120000 index 000000000..6ff19de4b --- /dev/null +++ b/nxcompext/VERSION @@ -0,0 +1 @@ +../VERSION \ No newline at end of file diff --git a/nxcompshad/VERSION b/nxcompshad/VERSION deleted file mode 100644 index 1545d9665..000000000 --- a/nxcompshad/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.5.0 diff --git a/nxcompshad/VERSION b/nxcompshad/VERSION new file mode 120000 index 000000000..6ff19de4b --- /dev/null +++ b/nxcompshad/VERSION @@ -0,0 +1 @@ +../VERSION \ No newline at end of file diff --git a/nxproxy/VERSION b/nxproxy/VERSION deleted file mode 100644 index 1545d9665..000000000 --- a/nxproxy/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.5.0 diff --git a/nxproxy/VERSION b/nxproxy/VERSION new file mode 120000 index 000000000..6ff19de4b --- /dev/null +++ b/nxproxy/VERSION @@ -0,0 +1 @@ +../VERSION \ No newline at end of file -- cgit v1.2.3 From 5464a6dba5742a9f22ba18c9b307d4ee42394378 Mon Sep 17 00:00:00 2001 From: Clemens Lang Date: Sun, 15 Mar 2015 17:22:38 +0100 Subject: nx{comp{,ext,shad},proxy}: use path discovery for finding makedepend. Remove old cruft. --- debian/changelog | 4 ++-- nxcomp/configure.in | 15 +-------------- nxcompext/configure.in | 15 +-------------- nxcompshad/configure.in | 15 +-------------- nxproxy/configure.in | 15 +-------------- 5 files changed, 6 insertions(+), 58 deletions(-) (limited to 'nxproxy') diff --git a/debian/changelog b/debian/changelog index 3b4175f92..664717898 100644 --- a/debian/changelog +++ b/debian/changelog @@ -12,8 +12,8 @@ nx-libs (2:3.5.99.0-0~build1) UNRELEASED; urgency=medium nx-libs (2:3.5.0.31-0x2go1) UNRELEASED; urgency=low - [ X2Go Release Manager ] - * Continue development + [ Clemens Lang ] + * Use path discovery for finding makedepend. Remove old cruft. -- X2Go Release Manager Sun, 15 Mar 2015 00:48:06 +0100 diff --git a/nxcomp/configure.in b/nxcomp/configure.in index 6fa9757a7..2378a9398 100644 --- a/nxcomp/configure.in +++ b/nxcomp/configure.in @@ -362,20 +362,7 @@ fi dnl Find makedepend somewhere. AC_SUBST(MAKEDEPEND) - -if test -x "../nx-X11/config/makedepend/makedepend" ; then - MAKEDEPEND=../nx-X11/config/makedepend/makedepend -else - if test -x "/usr/X11R6/bin/makedepend" ; then - MAKEDEPEND=/usr/X11R6/bin/makedepend - else - if test -x "/usr/openwin/bin/makedepend" ; then - MAKEDEPEND=/usr/openwin/bin/makedepend - else - MAKEDEPEND=/usr/bin/makedepend - fi - fi -fi +MAKEDEPEND="$(which makedepend)" dnl Determine what to build based on the platform. dnl Override the LIBS settings on Cygwin32 so that diff --git a/nxcompext/configure.in b/nxcompext/configure.in index 08c48a751..6159e84c1 100644 --- a/nxcompext/configure.in +++ b/nxcompext/configure.in @@ -219,20 +219,7 @@ CFLAGS="$CFLAGS -DVERSION=\\\"${VERSION}\\\"" dnl Find makedepend somewhere. AC_SUBST(MAKEDEPEND) - -if test -x "../nx-X11/config/makedepend/makedepend" ; then - MAKEDEPEND=../nx-X11/config/makedepend/makedepend -else - if test -x "/usr/X11R6/bin/makedepend" ; then - MAKEDEPEND=/usr/X11R6/bin/makedepend - else - if test -x "/usr/openwin/bin/makedepend" ; then - MAKEDEPEND=/usr/openwin/bin/makedepend - else - MAKEDEPEND=/usr/bin/makedepend - fi - fi -fi +MAKEDEPEND="$(which makedepend)" dnl Determine what to build based on the platform. dnl Override the LIBS settings on Cygwin32 so that diff --git a/nxcompshad/configure.in b/nxcompshad/configure.in index 13149b3a0..a76c6b9a1 100644 --- a/nxcompshad/configure.in +++ b/nxcompshad/configure.in @@ -269,19 +269,6 @@ fi dnl Find makedepend somewhere. AC_SUBST(MAKEDEPEND) - -if test -x "../nx-X11/config/makedepend/makedepend" ; then - MAKEDEPEND=../nx-X11/config/makedepend/makedepend -else - if test -x "/usr/X11R6/bin/makedepend" ; then - MAKEDEPEND=/usr/X11R6/bin/makedepend - else - if test -x "/usr/openwin/bin/makedepend" ; then - MAKEDEPEND=/usr/openwin/bin/makedepend - else - MAKEDEPEND=makedepend - fi - fi -fi +MAKEDEPEND="$(which makedepend)" AC_OUTPUT(Makefile) diff --git a/nxproxy/configure.in b/nxproxy/configure.in index b86828d02..914e70738 100644 --- a/nxproxy/configure.in +++ b/nxproxy/configure.in @@ -167,19 +167,6 @@ fi dnl Find makedepend somewhere. AC_SUBST(MAKEDEPEND) - -if test -x "../nx-X11/config/makedepend/makedepend" ; then - MAKEDEPEND=../nx-X11/config/makedepend/makedepend -else - if test -x "/usr/X11R6/bin/makedepend" ; then - MAKEDEPEND=/usr/X11R6/bin/makedepend - else - if test -x "/usr/openwin/bin/makedepend" ; then - MAKEDEPEND=/usr/openwin/bin/makedepend - else - MAKEDEPEND=makedepend - fi - fi -fi +MAKEDEPEND="$(which makedepend)" AC_OUTPUT(Makefile) -- cgit v1.2.3 From d8de5928e1e7a0677ed2d38fa4d9f53a58514ebe Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Mon, 16 Mar 2015 03:29:16 +0100 Subject: nx{comp{,ext,shad},proxy}: try really hard to find makedepend. Do not fail if it is not available. --- nxcomp/Makefile.in | 4 ++-- nxcomp/configure.in | 10 ++++++++++ nxcompext/Makefile.in | 4 ++-- nxcompext/configure.in | 10 ++++++++++ nxcompshad/Makefile.in | 4 ++-- nxcompshad/configure.in | 10 ++++++++++ nxproxy/Makefile.in | 4 ++-- nxproxy/configure.in | 10 ++++++++++ 8 files changed, 48 insertions(+), 8 deletions(-) (limited to 'nxproxy') diff --git a/nxcomp/Makefile.in b/nxcomp/Makefile.in index 2234474ec..e571b3c90 100644 --- a/nxcomp/Makefile.in +++ b/nxcomp/Makefile.in @@ -271,9 +271,9 @@ depends: depend.status depend: depend.status depend.status: - if [ -x $(MAKEDEPEND) ] ; then \ + if [ -n "$(MAKEDEPEND)" ] && [ -x "$(MAKEDEPEND)" ] ; then \ $(MAKEDEPEND) $(CXXINCLUDES) $(CCINCLUDES) \ - $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) \ + $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) \ $(CXXSRC) 2>/dev/null; \ fi touch depend.status diff --git a/nxcomp/configure.in b/nxcomp/configure.in index 07c88df77..43b51573a 100644 --- a/nxcomp/configure.in +++ b/nxcomp/configure.in @@ -364,6 +364,16 @@ dnl Find makedepend somewhere. AC_SUBST(MAKEDEPEND) MAKEDEPEND="$(which makedepend)" +# Try to desperately find makedepend. +# Set MAKEDEPEND to the shipped makedepend binary. This will not +# exist in nx-libs-lite, though, in which case MAKEDEPEND +# will stay empty. +if test -z "${MAKEDEPEND}"; then + if test -x "../nx-X11/config/makedepend/makedepend"; then + MAKEDEPEND="../nx-X11/config/makedepend/makedepend" + fi +fi + dnl Determine what to build based on the platform. dnl Override the LIBS settings on Cygwin32 so that dnl we always link with the exact set of libraries. diff --git a/nxcompext/Makefile.in b/nxcompext/Makefile.in index 8777ceeed..da464bd6d 100644 --- a/nxcompext/Makefile.in +++ b/nxcompext/Makefile.in @@ -152,9 +152,9 @@ depends: depend.status depend: depend.status depend.status: - if [ -x $(MAKEDEPEND) ] ; then \ + if [ -n "$(MAKEDEPEND)" ] && [ -x "$(MAKEDEPEND)" ] ; then \ $(MAKEDEPEND) $(CXXINCLUDES) $(CCINCLUDES) \ - $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) \ + $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) \ $(CXXSRC) 2>/dev/null; \ fi touch depend.status diff --git a/nxcompext/configure.in b/nxcompext/configure.in index 6159e84c1..e6f13c0ea 100644 --- a/nxcompext/configure.in +++ b/nxcompext/configure.in @@ -221,6 +221,16 @@ dnl Find makedepend somewhere. AC_SUBST(MAKEDEPEND) MAKEDEPEND="$(which makedepend)" +# Try to desperately find makedepend. +# Set MAKEDEPEND to the shipped makedepend binary. This will not +# exist in nx-libs-lite, though, in which case MAKEDEPEND +# will stay empty. +if test -z "${MAKEDEPEND}"; then + if test -x "../nx-X11/config/makedepend/makedepend"; then + MAKEDEPEND="../nx-X11/config/makedepend/makedepend" + fi +fi + dnl Determine what to build based on the platform. dnl Override the LIBS settings on Cygwin32 so that dnl we always link with the exact set of libraries. diff --git a/nxcompshad/Makefile.in b/nxcompshad/Makefile.in index 2f6e50bf9..5ea286395 100644 --- a/nxcompshad/Makefile.in +++ b/nxcompshad/Makefile.in @@ -187,9 +187,9 @@ depends: depend.status depend: depend.status depend.status: - if [ -x $(MAKEDEPEND) ] ; then \ + if [ -n "$(MAKEDEPEND)" ] && [ -x "$(MAKEDEPEND)" ] ; then \ $(MAKEDEPEND) $(CXXINCLUDES) $(CCINCLUDES) \ - $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) $(CXXSRC) 2>/dev/null; \ + $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) $(CXXSRC) 2>/dev/null; \ fi touch depend.status diff --git a/nxcompshad/configure.in b/nxcompshad/configure.in index 4e91361ff..8dd1b2e21 100644 --- a/nxcompshad/configure.in +++ b/nxcompshad/configure.in @@ -271,4 +271,14 @@ dnl Find makedepend somewhere. AC_SUBST(MAKEDEPEND) MAKEDEPEND="$(which makedepend)" +# Try to desperately find makedepend. +# Set MAKEDEPEND to the shipped makedepend binary. This will not +# exist in nx-libs-lite, though, in which case MAKEDEPEND +# will stay empty. +if test -z "${MAKEDEPEND}"; then + if test -x "../nx-X11/config/makedepend/makedepend"; then + MAKEDEPEND="../nx-X11/config/makedepend/makedepend" + fi +fi + AC_OUTPUT(Makefile) diff --git a/nxproxy/Makefile.in b/nxproxy/Makefile.in index c00df91dc..3a27cbd29 100644 --- a/nxproxy/Makefile.in +++ b/nxproxy/Makefile.in @@ -80,9 +80,9 @@ depends: depend.status depend: depend.status depend.status: - if [ -x $(MAKEDEPEND) ] ; then \ + if [ -n "$(MAKEDEPEND)" ] && [ -x "$(MAKEDEPEND)" ] ; then \ $(MAKEDEPEND) $(CXXINCLUDES) $(CCINCLUDES) \ - $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) $(CXXSRC) 2>/dev/null; \ + $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) $(CXXSRC) 2>/dev/null; \ fi touch depend.status diff --git a/nxproxy/configure.in b/nxproxy/configure.in index 914e70738..268584216 100644 --- a/nxproxy/configure.in +++ b/nxproxy/configure.in @@ -169,4 +169,14 @@ dnl Find makedepend somewhere. AC_SUBST(MAKEDEPEND) MAKEDEPEND="$(which makedepend)" +# Try to desperately find makedepend. +# Set MAKEDEPEND to the shipped makedepend binary. This will not +# exist in nx-libs-lite, though, in which case MAKEDEPEND +# will stay empty. +if test -z "${MAKEDEPEND}"; then + if test -x "../nx-X11/config/makedepend/makedepend"; then + MAKEDEPEND="../nx-X11/config/makedepend/makedepend" + fi +fi + AC_OUTPUT(Makefile) -- cgit v1.2.3 From 779d546456ee7fabe5a8193e2f18aac29104d176 Mon Sep 17 00:00:00 2001 From: Mike DePaulo Date: Sun, 28 Jun 2015 01:50:00 -0400 Subject: Correct nxproxy manpage also: --help -> -help xorg-server does not follow the convention of using 2 dashes, and apparently nx-libs doesn't either. Note that --help does produce the help output. However, it produces this additional output after it: Error: NX transport initialization failed. Therefore, we should instruct users to call -help instead. --- nxproxy/man/nxproxy.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nxproxy') diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index 0432380f8..d389d1068 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -20,7 +20,7 @@ the NX compression libraries. \fBnxproxy\fR is a backend application utilized by the X2GoClient GUI and some other NX/X2Go clients. .PP .SH OPTIONS -For an insight in \fBnxproxy\fR options use \fBnxproxy \-\-help\fR on the command line. +For an insight in \fBnxproxy\fR options use \fBnxproxy \-help\fR on the command line. .PP .SH AUTHOR This manual has been written by Mike Gabriel for the X2Go project -- cgit v1.2.3 From d650a0b47eadeb675e2d2cf03ad10a4dbc564971 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Thu, 23 Jun 2016 14:27:15 +0200 Subject: OPTFLAGS: Properly propagate build option flags to nxcomp{,ext,shad} and the nx-X11 build scripts. Note: - The "normal" way to inject CFLAGS (and CPPFLAGS) into nx-X11 builds is copying those options over into the variable CDEBUGFLAGS. - LDFLAGS have to be handed to nx-X11 via LOCAL_LDFLAGS. This change also includes a slight change in the nx-X11 build order. Old build order: Main Makefile: - [...] - libNX_X11 + implicitly building nxcomp + implicitly building nxcompext - [...] - nxagent + implicitly building nxcompshad - [...] New build ordner: Main Makefile: - [...] - nxcomp - setup nx-X11 build env + cd nx-X11 && make BuildEnv - nx-X11/lib/* - nxcompext - nxcompshad - [...] - nxagent - [...] Fixes ArcticaProject/nx-libs#141 Fixes X2GoBTS#84 --- Makefile | 14 +++++++++++--- debian/rules | 2 +- nx-X11/Makefile | 16 ++++++++++------ nx-X11/lib/X11/Imakefile | 38 -------------------------------------- nx-X11/programs/Xserver/Imakefile | 22 +--------------------- nx-libs.spec | 1 + nxcomp/Makefile.in | 6 ++++-- nxcomp/configure.in | 8 ++++++-- nxcompext/Makefile.in | 6 ++++-- nxcompext/configure.in | 8 ++++++-- nxcompshad/Makefile.in | 6 ++++-- nxcompshad/configure.in | 12 ++++++++---- nxproxy/configure.in | 8 ++++++-- 13 files changed, 62 insertions(+), 85 deletions(-) (limited to 'nxproxy') diff --git a/Makefile b/Makefile index e2077ed5b..daff448cd 100644 --- a/Makefile +++ b/Makefile @@ -49,9 +49,7 @@ build-lite: build-full: # in the full case, we rely on "magic" in the nx-X11 imake-based makefiles... - cd nxcomp && autoconf - cd nxcompext && autoconf - cd nxcompshad && autoconf + cd nxcomp && autoconf && (${CONFIGURE}) && ${MAKE} # prepare nx-X11/config/cf/nxversion.def sed \ @@ -62,6 +60,16 @@ build-full: nx-X11/config/cf/nxversion.def.in \ > nx-X11/config/cf/nxversion.def + # prepare Makefiles and the nx-X11 symlinking magic + cd nx-X11 && make BuildEnv + + # build libNX_X11 and libNX_Xext prior to building + # nxcomp{ext,shad}. + cd nx-X11/lib && make + + cd nxcompext && autoconf && (${CONFIGURE}) && ${MAKE} + cd nxcompshad && autoconf && (${CONFIGURE}) && ${MAKE} + cd nx-X11 && ${MAKE} World cd nxproxy && autoconf && (${CONFIGURE}) && ${MAKE} diff --git a/debian/rules b/debian/rules index a37478c21..275956c9a 100755 --- a/debian/rules +++ b/debian/rules @@ -66,7 +66,7 @@ override_dh_auto_install: override_dh_auto_build: - LOCAL_LDFLAGS="$(LDFLAGS)" SHLIBGLOBALSFLAGS="$(LDFLAGS)" SHLIBDIR="$(LIBDIR)" PREFIX=/usr dh_auto_build --parallel + PREFIX=/usr dh_auto_build --parallel -- CDEBUGFLAGS="$(CPPFLAGS) $(CFLAGS)" LOCAL_LDFLAGS="$(LDFLAGS)" SHLIBGLOBALSFLAGS="$(LDFLAGS)" SHLIBDIR="$(LIBDIR)" override_dh_strip: dh_strip -plibnx-x11-6 --dbg-package=libnx-x11-6-dbg diff --git a/nx-X11/Makefile b/nx-X11/Makefile index cb8c86b2b..1096e62cf 100644 --- a/nx-X11/Makefile +++ b/nx-X11/Makefile @@ -39,6 +39,15 @@ World: @echo "" @date @echo "" + if [ ! -f xmakefile ]; then ${MAKE} ${MFLAGS} BuildEnv; fi + ${MAKE} ${MAKE_OPTS} $(MFLAGS) $(WORLDOPTS) World + @echo "" + @date + @echo "" + @echo Full build of $(RELEASE) complete. + @echo "" + +BuildEnv: @if [ -f xmakefile ]; then \ ${MAKE} ${MAKE_OPTS} -k distclean || \ ${MAKE} ${MAKE_OPTS} -k clean || \ @@ -52,12 +61,7 @@ World: ${MAKE} ${MAKE_OPTS} $(MFLAGS) BOOTSTRAPSUBDIRS= clean ${MAKE} ${MAKE_OPTS} $(MFLAGS) includes ${MAKE} ${MAKE_OPTS} $(MFLAGS) depend - ${MAKE} ${MAKE_OPTS} $(MFLAGS) $(WORLDOPTS) World - @echo "" - @date - @echo "" - @echo Full build of $(RELEASE) complete. - @echo "" + .PRECIOUS: Makefile diff --git a/nx-X11/lib/X11/Imakefile b/nx-X11/lib/X11/Imakefile index 81a1cfd3d..1ba1e4818 100644 --- a/nx-X11/lib/X11/Imakefile +++ b/nx-X11/lib/X11/Imakefile @@ -1139,44 +1139,6 @@ includes:: ks_tables.h CONFIGURE ?= ./configure -#if NXLibraries - -$(NX_XCOMPCONFIGTARGET): - cd ../../../nxcomp && \ - ${CONFIGURE} - -$(NX_XCOMPEXTCONFIGTARGET): - cd ../../../nxcompext && \ - ${CONFIGURE} - -#ifdef SunArchitecture -$(NX_XCOMPLIBTARGET): $(NX_XCOMPCONFIGTARGET) - ${MAKE} -C $(NX_XCOMPLIBDIR) - -$(NX_XCOMPEXTLIBTARGET): $(NX_XCOMPEXTCONFIGTARGET) - ${MAKE} -C ../../../nxcompext - -#else -$(NX_XCOMPLIBTARGET): $(NX_XCOMPCONFIGTARGET) - ${MAKE} -C $(NX_XCOMPLIBDIR) - -$(NX_XCOMPEXTLIBTARGET): $(NX_XCOMPEXTCONFIGTARGET) $(NX_XCOMPLIBTARGET) lib$(LIBNAME).so.$(SOXLIBREV) - ${MAKE} -C ../../../nxcompext - -#endif - -depend:: - -lib$(LIBNAME).so.$(SOXLIBREV): $(NX_XCOMPLIBTARGET) - -all:: $(NX_XCOMPLIBTARGET) - -depend:: $(NX_XCOMPLIBTARGET) - -all:: $(NX_XCOMPEXTLIBTARGET) - -#endif - depend:: ks_tables.h clean:: diff --git a/nx-X11/programs/Xserver/Imakefile b/nx-X11/programs/Xserver/Imakefile index 0d820fad2..50031217e 100644 --- a/nx-X11/programs/Xserver/Imakefile +++ b/nx-X11/programs/Xserver/Imakefile @@ -455,27 +455,7 @@ NX_XSHADOWLIBNAME = cygXcompshad.dll NX_XSHADOWLIBNAME = libXcompshad.so #endif -NX_XSHADOWLIBDIR = $(XTOP)/../nxcompshad -NX_XSHADOWLIBTARGET = $(NX_XSHADOWLIBDIR)/$(NX_XSHADOWLIBNAME) -NX_XSHADOWCONFIGTARGET = $(NX_XSHADOWLIBDIR)/config.status - -CONFIGURE ?= ./configure - -$(NX_XSHADOWCONFIGTARGET): - cd $(NX_XSHADOWLIBDIR) && \ - ${CONFIGURE} - -#ifdef SunArchitecture -$(NX_XSHADOWLIBTARGET): $(NX_XSHADOWCONFIGTARGET) - cd $(NX_XSHADOWLIBDIR) && \ - ${MAKE} -#else -$(NX_XSHADOWLIBTARGET): $(NX_XSHADOWCONFIGTARGET) - cd $(NX_XSHADOWLIBDIR) && \ - rm -f *.o && ${MAKE} -#endif - -ServerTarget(nxagent,$(NX_XSHADOWLIBTARGET) $(NXAGENTDIRS),$(NXAGENTOBJS), \ +ServerTarget(nxagent,$(NXAGENTDIRS),$(NXAGENTOBJS), \ $(LIBCWRAPPER) $(NXAGENTLIBS) $(LOADABLEEXTS),$(NXAGENTSYSLIBS) $(NXAGENTNXLIBS)) /* diff --git a/nx-libs.spec b/nx-libs.spec index 770f1870a..8b2ecb09a 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -454,6 +454,7 @@ chmod a+x my_configure; %{!?__global_ldflags: %global __global_ldflags -Wl,-z,relro} export SHLIBGLOBALSFLAGS="%{__global_ldflags}" export LOCAL_LDFLAGS="%{__global_ldflags}" +export CDEBUGFLAGS="%{__global_cppflags} %{__global_cflags}" make %{?_smp_mflags} CONFIGURE="$PWD/my_configure" PREFIX=%{_prefix} USRLIBDIR=%{_libdir} SHLIBDIR=%{_libdir} %install diff --git a/nxcomp/Makefile.in b/nxcomp/Makefile.in index 759ab6a4f..ee12c3dbb 100644 --- a/nxcomp/Makefile.in +++ b/nxcomp/Makefile.in @@ -41,6 +41,8 @@ CXXFLAGS = @CXXFLAGS@ @X_CFLAGS@ @DEFS@ \ CXXINCLUDES = CXXDEFINES = +CPPFLAGS = @CPPFLAGS@ + # # C programs have their own CFLAGS. # @@ -87,9 +89,9 @@ DEPENDINCLUDES = -I/usr/include/c++ -I/usr/include/g++ -I/usr/include/g++-3 .SUFFIXES: .cpp.c .cpp.o: - $(CXX) -c $(CXXFLAGS) $(CXXINCLUDES) $(CXXDEFINES) $< + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CXXINCLUDES) $(CXXDEFINES) $< .c.o: - $(CC) -c $(CCFLAGS) $(CCINCLUDES) $(CCDEFINES) $< + $(CC) -c $(CPPFLAGS) $(CCFLAGS) $(CCINCLUDES) $(CCDEFINES) $< LIBRARY = Xcomp diff --git a/nxcomp/configure.in b/nxcomp/configure.in index 47b29e7bc..6586f22b2 100644 --- a/nxcomp/configure.in +++ b/nxcomp/configure.in @@ -10,8 +10,12 @@ AC_SUBST(pkgconfigdir) dnl Set our default compilation flags. -CXXFLAGS="$CXXFLAGS -O3 -fno-rtti -fno-exceptions" -CFLAGS="$CFLAGS -O3" +if test "x$CXXFLAGS" = "x"; then + CXXFLAGS="-O3 -fno-rtti -fno-exceptions" +fi +if test "x$CFLAGS" = "x"; then + CFLAGS="$CFLAGS -O3" +fi dnl Reset default linking directives. diff --git a/nxcompext/Makefile.in b/nxcompext/Makefile.in index dd18c8053..415ffabb1 100644 --- a/nxcompext/Makefile.in +++ b/nxcompext/Makefile.in @@ -34,6 +34,8 @@ CXXFLAGS = @CXXFLAGS@ @X_CFLAGS@ @DEFS@ \ CXXINCLUDES = -I. -I../nxcomp CXXDEFINES = +CPPFLAGS = @CPPFLAGS@ + CC = @CC@ CCFLAGS = @CFLAGS@ @X_CFLAGS@ @DEFS@ \ -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \ @@ -78,9 +80,9 @@ DEPENDINCLUDES = -I/usr/include/c++ -I/usr/include/g++ -I/usr/include/g++-3 .SUFFIXES: .cpp.c .cpp.o: - $(CXX) -c $(CXXFLAGS) $(CXXINCLUDES) $< + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CXXINCLUDES) $< .c.o: - $(CC) -c $(CCFLAGS) $(CCINCLUDES) $< + $(CC) -c $(CPPFLAGS) $(CCFLAGS) $(CCINCLUDES) $< LIBRARY = Xcompext diff --git a/nxcompext/configure.in b/nxcompext/configure.in index 6078851b4..70bb9d121 100644 --- a/nxcompext/configure.in +++ b/nxcompext/configure.in @@ -10,8 +10,12 @@ AC_SUBST(pkgconfigdir) dnl Reset default compilation flags. -CXXFLAGS="$CXXFLAGS -O3" -CFLAGS="$CFLAGS -O3" +if test "x$CXXFLAGS" = "x"; then + CXXFLAGS="-O3" +fi +if test "x$CFLAGS" == "x"; then + CFLAGS="-O3" +fi dnl Reset default linking directives. diff --git a/nxcompshad/Makefile.in b/nxcompshad/Makefile.in index 68bb1fbad..9c2b6f4fd 100644 --- a/nxcompshad/Makefile.in +++ b/nxcompshad/Makefile.in @@ -36,6 +36,8 @@ CXXFLAGS = @CXXFLAGS@ @X_CFLAGS@ @DEFS@ \ CXXINCLUDES = CXXDEFINES = +CPPFLAGS = @CPPFLAGS@ + # # C programs don't share the C++ flags. They should # have their own @CCFLAGS@. @@ -99,9 +101,9 @@ DEPENDINCLUDES = -I/usr/include/g++ -I/usr/include/g++-3 .SUFFIXES: .cpp.c .cpp.o: - $(CXX) -c $(CXXFLAGS) $(CXXINCLUDES) $(CXXDEFINES) $< + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CXXINCLUDES) $(CXXDEFINES) $< .c.o: - $(CC) -c $(CCFLAGS) $(CCINCLUDES) $(CCDEFINES) $< + $(CC) -c $(CPPFLAGS) $(CCFLAGS) $(CCINCLUDES) $(CCDEFINES) $< LIBRARY = Xcompshad diff --git a/nxcompshad/configure.in b/nxcompshad/configure.in index 7ec064cc6..226b13ef8 100644 --- a/nxcompshad/configure.in +++ b/nxcompshad/configure.in @@ -10,8 +10,12 @@ AC_SUBST(pkgconfigdir) dnl Reset default compilation flags. -CXXFLAGS="$CXXFLAGS -O3" -CPPFLAGS="$CPPFLAGS -O3" +if test "x$CXXFLAGS" == "x"; then + CXXFLAGS="-O3" +fi +if test "x$CPPFLAGS" == "x"; then + CPPFLAGS="-O3" +fi dnl Reset default linking directives. @@ -80,8 +84,8 @@ case "${gcc_version}" in *) AC_MSG_RESULT([yes]) - CXXFLAGS="$CXXFLAGS -Wmissing-declarations -Wnested-externs" - CPPFLAGS="$CPPFLAGS -Wmissing-declarations -Wnested-externs" + CXXFLAGS="$CXXFLAGS -Wmissing-declarations" + CPPFLAGS="$CPPFLAGS -Wmissing-declarations" ;; esac diff --git a/nxproxy/configure.in b/nxproxy/configure.in index 268584216..12e2a08d2 100644 --- a/nxproxy/configure.in +++ b/nxproxy/configure.in @@ -7,8 +7,12 @@ AC_PREREQ(2.13) dnl Reset default compilation flags. -CXXFLAGS="$CXXFLAGS -O3" -CPPFLAGS="$CPPFLAGS -O3" +if test "x$CXXFLAGS" == "x"; then + CXXFLAGS="-O3" +fi +if test "x$CPPFLAGS" == "x"; then + CPPFLAGS="-O3" +fi dnl Prefer headers and libraries from nx-X11 if present. -- cgit v1.2.3 From 4ad29435c8549a9e27d3299957cbb190603fb080 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 5 Jul 2016 10:26:34 +0200 Subject: Drop multiple COPYING files contaning the GPL-2 license text. One COPYING file in the project's base folder is sufficient. --- nx-X11/COPYING | 339 ----------------------------- nx-X11/programs/Xserver/hw/nxagent/COPYING | 339 ----------------------------- nxcomp/COPYING | 339 ----------------------------- nxcompext/COPYING | 339 ----------------------------- nxcompshad/COPYING | 339 ----------------------------- nxproxy/COPYING | 339 ----------------------------- 6 files changed, 2034 deletions(-) delete mode 100644 nx-X11/COPYING delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/COPYING delete mode 100644 nxcomp/COPYING delete mode 100644 nxcompext/COPYING delete mode 100644 nxcompshad/COPYING delete mode 100644 nxproxy/COPYING (limited to 'nxproxy') diff --git a/nx-X11/COPYING b/nx-X11/COPYING deleted file mode 100644 index d511905c1..000000000 --- a/nx-X11/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 - - 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. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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. - - , 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 Lesser General -Public License instead of this License. diff --git a/nx-X11/programs/Xserver/hw/nxagent/COPYING b/nx-X11/programs/Xserver/hw/nxagent/COPYING deleted file mode 100644 index d511905c1..000000000 --- a/nx-X11/programs/Xserver/hw/nxagent/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 - - 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. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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. - - , 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 Lesser General -Public License instead of this License. diff --git a/nxcomp/COPYING b/nxcomp/COPYING deleted file mode 100644 index d511905c1..000000000 --- a/nxcomp/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 - - 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. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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. - - , 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 Lesser General -Public License instead of this License. diff --git a/nxcompext/COPYING b/nxcompext/COPYING deleted file mode 100644 index d511905c1..000000000 --- a/nxcompext/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 - - 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. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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. - - , 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 Lesser General -Public License instead of this License. diff --git a/nxcompshad/COPYING b/nxcompshad/COPYING deleted file mode 100644 index d511905c1..000000000 --- a/nxcompshad/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 - - 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. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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. - - , 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 Lesser General -Public License instead of this License. diff --git a/nxproxy/COPYING b/nxproxy/COPYING deleted file mode 100644 index d511905c1..000000000 --- a/nxproxy/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 - - 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. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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. - - , 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 Lesser General -Public License instead of this License. -- cgit v1.2.3 From d38ccd197413f6fad830c314d904904368d3770d Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 5 Jul 2016 10:33:08 +0200 Subject: LICENSE files: Have a main LICENSE file and one for nxcomp in the project's base folder. Drop other LICENSE files added by NoMachine scattered all over the code tree. --- LICENSE | 26 +++++++++ LICENSE.nxcomp | 90 ++++++++++++++++++++++++++++++ nx-X11/LICENSE | 26 --------- nx-X11/programs/Xserver/hw/nxagent/LICENSE | 26 --------- nxcomp/LICENSE | 90 ------------------------------ nxcompext/LICENSE | 21 ------- nxcompshad/LICENSE | 22 -------- nxproxy/LICENSE | 36 ------------ 8 files changed, 116 insertions(+), 221 deletions(-) create mode 100644 LICENSE create mode 100644 LICENSE.nxcomp delete mode 100644 nx-X11/LICENSE delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/LICENSE delete mode 100644 nxcomp/LICENSE delete mode 100644 nxcompext/LICENSE delete mode 100644 nxcompshad/LICENSE delete mode 100644 nxproxy/LICENSE (limited to 'nxproxy') diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..32cb52b45 --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2001, 2011 NoMachine - http://www.nomachine.com/. + +NX-X11 and NX extensions to X are copyright of NoMachine. + +Redistribution and use of this software is allowed according to the +following terms: + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License Version 2, and +not any other version, as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- +BILITY 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, you can request a copy to NoMachine +or write to the Free Software Foundation, Inc., 59 Temple Place, +Suite 330, Boston, MA 02111-1307 USA + +Parts of this software are derived from XFree86 and X.org projects. +Other copyrights and the MIT/X11 license applies to different sources. +Please check the applicable copyrights in each file or subdirectory. + +All rights reserved. diff --git a/LICENSE.nxcomp b/LICENSE.nxcomp new file mode 100644 index 000000000..02ab0e272 --- /dev/null +++ b/LICENSE.nxcomp @@ -0,0 +1,90 @@ +Copyright (c) 2001,2010 NoMachine - http://www.nomachine.com/. +Copyright (c) 2000,2003 Gian Filippo Pinzari + +NXCOMP library and NX extensions to X are copyright of NoMachine. +Redistribution and use of this software is allowed according to the +following terms: + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License Version 2, and +not any other version, as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- +BILITY 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, you can request a copy to NoMachine +or write to the Free Software Foundation, Inc., 59 Temple Place, Suite +330, Boston, MA 02111-1307 USA + +============================================================================== + +Parts of this software are derived from DXPC project. These copyright +notices apply to original DXPC code: + +Redistribution and use in source and binary forms are permitted provi- +ded that the above copyright notice and this paragraph are duplicated +in all such forms. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +Copyright (c) 1995,1996,2000,2006 Brian Pane +Copyright (c) 1996,1997 Zachary Vonler and Brian Pane +Copyright (c) 1999 Kevin Vigor and Brian Pane +Copyright (c) 2000,2006 Gian Filippo Pinzari and Brian Pane + +All rights reserved. + +============================================================================== + +Update 2015-05-21 on the nature of the original DXPC license: The +original DXPC code used to be available under a license which failed to +explicitly grant the permission to modify, but was later retroactively +re-licensed under the 2-clause BSD license (see +README.on-retroactive-DXPC-license for the copyright owners' statements; +see for more details). + +In the course of discussion, it also became evident that Gian Filippo +Pinzari never participated in any of the official DXPC releases, but +rather worked on the forked code on the NoMachine side. Thus, we +crossed-out his name in the above copyright notice and moved him to the +top list of copyright holders associated with the GPL-2 re-licensing done +by NoMachine. + +Thus, the version of DXPC where NXCOMP got forked from (most likely some +DXPC version between release 3.7.0 and release 3.8.0) can be considered +as BSD-2-clause, as quoted below: + +Copyright (c) 1995,1996 Brian Pane +Copyright (c) 1996,1997 Zachary Vonler and Brian Pane +Copyright (c) 1999-2002 Kevin Vigor and Brian Pane +All rights reserved. + +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. + +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 REGENTS 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. diff --git a/nx-X11/LICENSE b/nx-X11/LICENSE deleted file mode 100644 index 32cb52b45..000000000 --- a/nx-X11/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2001, 2011 NoMachine - http://www.nomachine.com/. - -NX-X11 and NX extensions to X are copyright of NoMachine. - -Redistribution and use of this software is allowed according to the -following terms: - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License Version 2, and -not any other version, as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- -BILITY 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, you can request a copy to NoMachine -or write to the Free Software Foundation, Inc., 59 Temple Place, -Suite 330, Boston, MA 02111-1307 USA - -Parts of this software are derived from XFree86 and X.org projects. -Other copyrights and the MIT/X11 license applies to different sources. -Please check the applicable copyrights in each file or subdirectory. - -All rights reserved. diff --git a/nx-X11/programs/Xserver/hw/nxagent/LICENSE b/nx-X11/programs/Xserver/hw/nxagent/LICENSE deleted file mode 100644 index 8446e6f55..000000000 --- a/nx-X11/programs/Xserver/hw/nxagent/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2001, 2011 NoMachine - http://www.nomachine.com/. - -NXAGENT and NX extensions to X are copyright of NoMachine. - -Redistribution and use of this software is allowed according to the -following terms: - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License Version 2, and -not any other version, as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- -BILITY 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, you can request a copy to NoMachine -or write to the Free Software Foundation, Inc., 59 Temple Place, -Suite 330, Boston, MA 02111-1307 USA - -Parts of this software are derived from XFree86 and X.org projects. -Other copyrights and the MIT/X11 license applies to different sources. -Please check the applicable copyrights in each file or subdirectory. - -All rights reserved. diff --git a/nxcomp/LICENSE b/nxcomp/LICENSE deleted file mode 100644 index 02ab0e272..000000000 --- a/nxcomp/LICENSE +++ /dev/null @@ -1,90 +0,0 @@ -Copyright (c) 2001,2010 NoMachine - http://www.nomachine.com/. -Copyright (c) 2000,2003 Gian Filippo Pinzari - -NXCOMP library and NX extensions to X are copyright of NoMachine. -Redistribution and use of this software is allowed according to the -following terms: - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License Version 2, and -not any other version, as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- -BILITY 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, you can request a copy to NoMachine -or write to the Free Software Foundation, Inc., 59 Temple Place, Suite -330, Boston, MA 02111-1307 USA - -============================================================================== - -Parts of this software are derived from DXPC project. These copyright -notices apply to original DXPC code: - -Redistribution and use in source and binary forms are permitted provi- -ded that the above copyright notice and this paragraph are duplicated -in all such forms. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -Copyright (c) 1995,1996,2000,2006 Brian Pane -Copyright (c) 1996,1997 Zachary Vonler and Brian Pane -Copyright (c) 1999 Kevin Vigor and Brian Pane -Copyright (c) 2000,2006 Gian Filippo Pinzari and Brian Pane - -All rights reserved. - -============================================================================== - -Update 2015-05-21 on the nature of the original DXPC license: The -original DXPC code used to be available under a license which failed to -explicitly grant the permission to modify, but was later retroactively -re-licensed under the 2-clause BSD license (see -README.on-retroactive-DXPC-license for the copyright owners' statements; -see for more details). - -In the course of discussion, it also became evident that Gian Filippo -Pinzari never participated in any of the official DXPC releases, but -rather worked on the forked code on the NoMachine side. Thus, we -crossed-out his name in the above copyright notice and moved him to the -top list of copyright holders associated with the GPL-2 re-licensing done -by NoMachine. - -Thus, the version of DXPC where NXCOMP got forked from (most likely some -DXPC version between release 3.7.0 and release 3.8.0) can be considered -as BSD-2-clause, as quoted below: - -Copyright (c) 1995,1996 Brian Pane -Copyright (c) 1996,1997 Zachary Vonler and Brian Pane -Copyright (c) 1999-2002 Kevin Vigor and Brian Pane -All rights reserved. - -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. - -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 REGENTS 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. diff --git a/nxcompext/LICENSE b/nxcompext/LICENSE deleted file mode 100644 index 12eb6576c..000000000 --- a/nxcompext/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2001, 2009 NoMachine - http://www.nomachine.com/. - -NXCOMPEXT library and NX extensions to X are copyright of NoMachine. -Redistribution and use of this software is allowed according to the -following terms: - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License Version 2, and -not any other version, as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- -BILITY 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, you can request a copy to NoMachine -or write to the Free Software Foundation, Inc., 59 Temple Place, -Suite 330, Boston, MA 02111-1307 USA - -All rights reserved. diff --git a/nxcompshad/LICENSE b/nxcompshad/LICENSE deleted file mode 100644 index 2c7f95a2d..000000000 --- a/nxcompshad/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2001, 2011 NoMachine - http://www.nomachine.com/. - -NXCOMPSHAD and NX extensions to X are copyright of NoMachine. - -Redistribution and use of this software is allowed according to the -following terms: - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License Version 2, and -not any other version, as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- -BILITY 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, you can request a copy to NoMachine -or write to the Free Software Foundation, Inc., 59 Temple Place, -Suite 330, Boston, MA 02111-1307 USA - -All rights reserved. diff --git a/nxproxy/LICENSE b/nxproxy/LICENSE deleted file mode 100644 index 64522ca4c..000000000 --- a/nxproxy/LICENSE +++ /dev/null @@ -1,36 +0,0 @@ -Copyright (c) 2001, 2011 NoMachine - http://www.nomachine.com/. - -NXPROXY and NX extensions to this software are copyright of NoMachine. -Redistribution and use of this software is allowed according to the -following terms: - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License Version 2, and -not any other version, as published by the Free Software Foundation. - -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 - -Parts of this software are derived from DXPC project. These copyright -notices apply to original DXPC code: - -Redistribution and use in source and binary forms are permitted provided -that the above copyright notice and this paragraph are duplicated in all -such forms. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -Copyright (c) 1995,1996 Brian Pane -Copyright (c) 1996,1997 Zachary Vonler and Brian Pane -Copyright (c) 1999 Kevin Vigor and Brian Pane -Copyright (c) 2000,2001 Gian Filippo Pinzari and Brian Pane - -All rights reserved. -- cgit v1.2.3 From b38f01092ab65f41fc0a525c46c874a228676f71 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 5 Jul 2016 10:40:11 +0200 Subject: NoMachine documentation files: Move to doc/_attic_/ folder. --- .../NoMachine_documentation_files/nx-X11_CHANGELOG | 1085 ++++ .../nx-X11_programs_Xserver_hw_nxagent_CHANGELOG | 6359 ++++++++++++++++++++ .../NoMachine_documentation_files/nxcomp_CHANGELOG | 3778 ++++++++++++ .../NoMachine_documentation_files/nxcomp_README | 21 + .../nxcomp_README-IPAQ | 21 + .../nxcompext_CHANGELOG | 806 +++ .../NoMachine_documentation_files/nxcompext_README | 15 + .../nxcompshad_CHANGELOG | 404 ++ .../nxproxy_CHANGELOG | 216 + .../NoMachine_documentation_files/nxproxy_README | 14 + .../nxproxy_README-IPAQ | 27 + .../nxproxy_README-VALGRIND | 39 + nx-X11/CHANGELOG | 1085 ---- nx-X11/programs/Xserver/hw/nxagent/CHANGELOG | 6359 -------------------- nxcomp/CHANGELOG | 3778 ------------ nxcomp/README | 21 - nxcomp/README-IPAQ | 21 - nxcompext/CHANGELOG | 806 --- nxcompext/README | 15 - nxcompshad/CHANGELOG | 404 -- nxproxy/CHANGELOG | 216 - nxproxy/README | 14 - nxproxy/README-IPAQ | 27 - nxproxy/README-VALGRIND | 39 - 24 files changed, 12785 insertions(+), 12785 deletions(-) create mode 100644 doc/_attic_/NoMachine_documentation_files/nx-X11_CHANGELOG create mode 100644 doc/_attic_/NoMachine_documentation_files/nx-X11_programs_Xserver_hw_nxagent_CHANGELOG create mode 100644 doc/_attic_/NoMachine_documentation_files/nxcomp_CHANGELOG create mode 100644 doc/_attic_/NoMachine_documentation_files/nxcomp_README create mode 100644 doc/_attic_/NoMachine_documentation_files/nxcomp_README-IPAQ create mode 100644 doc/_attic_/NoMachine_documentation_files/nxcompext_CHANGELOG create mode 100644 doc/_attic_/NoMachine_documentation_files/nxcompext_README create mode 100644 doc/_attic_/NoMachine_documentation_files/nxcompshad_CHANGELOG create mode 100644 doc/_attic_/NoMachine_documentation_files/nxproxy_CHANGELOG create mode 100644 doc/_attic_/NoMachine_documentation_files/nxproxy_README create mode 100644 doc/_attic_/NoMachine_documentation_files/nxproxy_README-IPAQ create mode 100644 doc/_attic_/NoMachine_documentation_files/nxproxy_README-VALGRIND delete mode 100644 nx-X11/CHANGELOG delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG delete mode 100644 nxcomp/CHANGELOG delete mode 100644 nxcomp/README delete mode 100644 nxcomp/README-IPAQ delete mode 100644 nxcompext/CHANGELOG delete mode 100644 nxcompext/README delete mode 100644 nxcompshad/CHANGELOG delete mode 100644 nxproxy/CHANGELOG delete mode 100644 nxproxy/README delete mode 100644 nxproxy/README-IPAQ delete mode 100644 nxproxy/README-VALGRIND (limited to 'nxproxy') diff --git a/doc/_attic_/NoMachine_documentation_files/nx-X11_CHANGELOG b/doc/_attic_/NoMachine_documentation_files/nx-X11_CHANGELOG new file mode 100644 index 000000000..ffbbe0a61 --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nx-X11_CHANGELOG @@ -0,0 +1,1085 @@ +ChangeLog: + +nx-X11-3.5.0-2 + +- Fixed TR0202420. XKB utility functions wrote out of bounds. + +- Upgraded RandR server extension to version 1.2. + +nx-X11-3.5.0-1 + +- Opened the 3.5.0 branch based on nx-X11-3.4.0-4. + +- Updated copyright to year 2011. + +nx-X11-3.4.0-4 + +- Fixed TR06H02359. Removed compiler warnings. + +nx-X11-3.4.0-3 + +- Updated copyright to year 2010. + +nx-X11-3.4.0-2 + +- Fixed TR04G02208. Added a path to rgb file. + +nx-X11-3.4.0-1 + +- Opened the 3.4.0 branch based on nx-X11-3.3.0-7. + +- Updated copyright to year 2009. + +nx-X11-3.3.0-7 + +- Fixed TR08G02257. The maximum client condition was reached because + available fd exhausted. This bug was caused by a function in font + library not closing the file before a return on error breaking the + flow of normal execution. + +- Fixed TR06G02225. The implementation of Xvprintf() has been reviewed + to work on more platforms. Previous implementation caused a failure + in the build of keyboard map on some platform like Solaris 8 and 9. + +nx-X11-3.3.0-6 + +- Fixed TR03G02198. Reimplemented Xvprintf() in Xserver/os to handle + the case in which vsnprintf returned -1. + +- Returning from _XSeqSyncFunction() and _XReply() if an I/O error is + detected. + +nx-X11-3.3.0-5 + +- Fixed TR01G02163. Signals need to be blocked before the call to + fork() in the Popen() utility. + +- Fixed TR01G02164. Trapezoid data need to be validated before use. + This issue was the same of CVE-2007-2437. + +nx-X11-3.3.0-4 + +- Enabled the code resetting the Xlib buffer if an IO error occured. + +nx-X11-3.3.0-3 + +- Fixed the search path for the XKB base directory. + +nx-X11-3.3.0-2 + +- Fixed TR10F02116. The X11 agent could enter an indefinite wait state + if connection to X display is broken and libX11 output buffer is not + empty. + +nx-X11-3.3.0-1 + +- Opened the 3.3.0 branch based on nx-X11-3.2.0-2. + +nx-X11-3.2.0-2 + +- Imported patch fixing issues from X.Org security advisory, June + 11th, 2008: Multiple vulnerabilities in X server extensions. CVE + IDs: CVE-2008-1377, CVE-2008-1379, CVE-2008-2360, CVE-2008-2361, + CVE-2008-2362. + +nx-X11-3.2.0-1 + +- Opened the 3.2.0 branch based on nx-X11-3.1.0-6. + +nx-X11-3.1.0-6 + +- Modified Xserver Imakefile to link the Xfixes library. + +nx-X11-3.1.0-5 + +- Disabled the terminate action, just in case the TerminateServer + symbol is binded to a non default key sequence. + +nx-X11-3.1.0-4 + +- Imported patch fixing issues from X.Org security advisory, January + 17th, 2008: Multiple vulnerabilities in the X server. CVE IDs: + CVE-2007-5760 CVE-2007-5958 CVE-2007-6427 CVE-2007-6428 + CVE-2007-6429 CVE-2008-0006. + +nx-X11-3.1.0-3 + +- Moved a variable definition placed in _mesa_make_current(). + +nx-X11-3.1.0-2 + +- Fixed TR10E01924. A crash could occur in _mesa_make_current(). + +- Initialized after_ret variable in _XcmsGetProperty(). + +nx-X11-3.1.0-1 + +- Opened the 3.1.0 branch based on nx-X11-3.0.0-37. + +nx-X11-3.0.0-37 + +- Changed the Xserver Imakefile to link against Xcomposite on the + Cygwin platform too. + +nx-X11-3.0.0-36 + +- Fixed TR07E01806. Modified host.def to build GLX code with symbol + __GLX_ALIGN64 defined on Solaris platform. + +nx-X11-3.0.0-35 + +- Flush explicitly the NX link before entering the select() in the + WaitForReadable() and WaitForWritable() routines. + +nx-X11-3.0.0-34 + +- Changed the agent Imakefile to link to the Xcomposite library. + +nx-X11-3.0.0-33 + +- Fix the NX_TRANS_WAKEUP stuff in WaitForSomething() to not over- + ride a valid timeout. + +- Check if the requesting client is gone in the XFixes functions + sending the cursor events. + +nx-X11-3.0.0-32 + +- Define DDXOSVERRORF and DDXOSFATALERROR symbols on Sun. + +- Changed the copyright attribution from Medialogic to NoMachine. + +nx-X11-3.0.0-31 + +- Make SmartScheduleStopTimer() visible outside Xserver/os/utils.c + so that it can be called by the agent. Export the declaration in + dixstruct.h. + +nx-X11-3.0.0-30 + +- The OsVendorVErrorFFatal flag is set to 1 if the function pointed + by OsVendorVErrorFProc is called due to a fatal error. + +- Give the possibility to the agent to redirect the standard error + during a Popen() or a System() by setting the OsVendorStartRedir- + ectErrorFProc and OsVendorEndRedirectErrorFProc function pointers. + +nx-X11-3.0.0-29 + +- Changed the default message printed on a fatal server error. The + new message is: + + Error: Aborting session with 'Error text...'. + +- Hacked LogVWrite() to force all fatal error messages to have an + uppercase initial. Also remove the trailing newline and the full- + stop, if present. + +nx-X11-3.0.0-28 + +- Corrected the typos in the ChangeLog. + +nx-X11-3.0.0-27 + +- Fixed the cleanup of the X_RenderCompositeText16 padding bytes. + +- More code cleanup in the NX changes to the Xrender library. + +- Changed host.def to build the freetype and fontconfig libraries + if the agent server is also built. Freetype is built as a shared + library: this avoids the link error on 64 bit platforms. + +nx-X11-3.0.0-26 + +- Applied the following security patches, from the X.Org security + advisory, April 3rd, 2007 "Multiple vulnerability in X server, + libXfont and libX11": + + xorg-xserver-1.2.0-xcmisc.diff + xorg-libXfont-1.2.7-bdf-fontdir.diff + xorg-libX11-1.1.1-xinitimage.diff + +nx-X11-3.0.0-25 + +- Added the missing *.X.original file for ChkIfEv.c and Xlib.h. + +nx-X11-3.0.0-24 + +- Changed Xrender to clean up the padding bytes in XRenderComposite- + Text functions. + +- Added function XRenderCleanGlyphs() cleaning the padding bytes in + the data section of RenderAddGlyphs requests. + +nx-X11-3.0.0-23 + +- Removed the additional parameter from the call to NXTransFlush() + in _XReply(). + +- Call NXTransExit() on AbortServer() (called by FatalError()) to + give the proxy a chance to shut down the NX transport. + +nx-X11-3.0.0-22 + +- Moved the replacement of XCheckIfEvent() ChkIfEv.c with the name + XCheckIfEventNoFlush(). + +nx-X11-3.0.0-21 + +- Set BUFSIZE to 8192 bytes. While the output buffer size can be + configured by setting the XLIBBUFFERSIZE in the environment (see + OpenDis.c), this constant is still used when reading from the + socket. + +nx-X11-3.0.0-20 + +- If set, the handler pointed by _NXDisplayWriteFunction is called + after that more data is written to the display connection. + +nx-X11-3.0.0-19 + +- Added a RejectWellKnownSockets() stub to make possible to compile + the agent when the NX transport is disabled. + +- Added more useful logs to _XWaitForWritable(). + +nx-X11-3.0.0-18 + +- Changed Imakefile of X11 and Xserver in order to build nxcompshad + just before the NX agent server. + +- Changed Imakefile in Xserver to add NXdamage.o to NXAGENTOBJS. + +nx-X11-3.0.0-17 + +- Changed host.def in order to build Xdamage and Xrandr libraries. + +- Changed host.def in order not to build NXWin. + +nx-X11-3.0.0-16 + +- Changed host.def in order to build Xtst as a shared library. + +nx-X11-3.0.0-15 + +- Changes to comply with nxcompshad library. + +- Changed configuration to statically build Xtst library. + +- Restored parser directory under Xserver/hw/xfree86. + +nx-X11-3.0.0-14 + +- Changed the LICENSE file to state that the software is only made + available under the version 2 of the GPL. + +- Added file COPYING. + +- In nx-X11/programs and nx-X11/programs/Xserver/hw/xfree86, removed + files and directories not needed to build servers. + +nx-X11-3.0.0-13 + +- Changes aimed to link servers with static versions of Xdmcp and Xau + libraries. + +nx-X11-3.0.0-12 + +- Added references to implented FR in the ChangeLog. + +- Removed nx-X11/fonts and nx-X11/doc directories. They are not needed + for building the NX components. + +nx-X11-3.0.0-11 + +- Updated the copyright notices to year 2007. + +nx-X11-3.0.0-10 + +- Applied the following security patches: + + x11r6.9.0-cidfonts.diff + x11r6.9.0-dbe-render.diff + x11r6.9.0-geteuid.diff + x11r6.9.0-mitri.diff + x11r6.9.0-setuid.diff + +nx-X11-3.0.0-9 + +- Merged the NX changes to X11 with the X11R6.9.0 version of X.org. + +nx-X11-3.0.0-8 + +- Changes to build Xshadow library when building X11. + +- Changes to Xserver Imakefile to link Xshadow library. + +- Changes to host.def in order to build on old distributions. + +nx-X11-3.0.0-7 + +- Imported changes up to nx-X11-2.1.0-2 + +- Fixed TR08D01485. Updated rgb file paths validation in order to + support Ubuntu distribution. + +- Added Xtst to libraries to be linked by nxagent. + +- Changed Xpm Imakefile to build a shared library on Solaris. + +- Fixed build error on Solaris in xtrans. + +- Changed host.def not to build Xnest server. + +- Changed Xserver Imakefile to link nxaccess library. + +nx-X11-3.0.0-6 + +- Added the path of nxaccess library to the server link command. + +nx-X11-3.0.0-5 + +- Implemented FR10C01079 and FR10C01080. The merge of NX changes to + the X.org code is complete. + +- Merged changes in config/cf. The NX-*.def files have been dismissed. + Main platform dependent configurations have been moved to host.def. + +- Removed *.reference files from config/cf. + +- Fixed compilation for Cygwin platform. + +nx-X11-3.0.0-4 + +- Imported all changes up to nx-X11-2.0.0-32. + +- Cleaned up lib/zlib directory. + +- Added missing file programs/Xserver/os/utils.c.NX.original. + +- Updated the copyright notice to year 2006. + +- The pointer to the display buffer is reset after an I/O error. + This prevents leaving the buffer in an inconsistent state if the + error occurs inside _XFlush(). + +- Removed the modifications to the Xrender library. The cleanup of + the padding bytes is now performed by the NX transport. + +- NX uses the updated ZLIB from its build tree, so Imake.tmpl will + now assume that the platform as ZLIB unless otherwise stated. + +- The path of the SecurityPolicy file is searched and validated at + runtime. + +- Added the _X11TransSocketProxyConnInfo() function to Xtranssock.c + It returns the pointer to the XtransConnInfo private, if it is a + valid _NXProxyConnInfo structure. + +- The above function is used by OpenDis.c to detect if the NX trans- + port was requested on the display and avoid spurious error messa- + ges in the case of a connection failure. + +- Added NXmiwindow.o to the NXAGENTOBJS in the Xserver's Imakefile + and imported NXmiwindow.c in nxagent. This allows us to check the + pointer to the pOldClip region in miSetShape() before going on + freeing it. + +- The path of the XKB base directory and of the xkbcomp comand is + validated at runtime. + +- Also added a check to verify the validity of the rgb file path. + +- Added NXresource.o to NXAGENTOBJS in the Imakefile of nxagent. We + need this to a assign a resource to the pixmaps and other server + objects which need to be enumerated at reconnection. Some objects, + being created by the X server and not by the clients, don't pass + through the resource assignment process operated by the dix. To + ensure that all objects get a resource, we add a resource at the + time the object is created and temporarily assign the resource to + the server client. If the dix later assigns the resource to a va- + lid client, the resource is removed from the server client's list. + +- The display block handler registered by the client is called in + WaitForReadable() and WaitForWritable() before every select(), + not only upon entering the function. The reason is that more + data can be possibly produced for the NX link by the proxy it- + self and, when setting the flush policy to deferred, the client + may not have the chance of flushing the NX link. + +- Fixed a bug in XkbUseExtension() that caused Xlib to query the + presence of the XKEYBOARD extension multiple times. This partial- + ly implents the FR01D01275. The complete implementation required + modifications to the X11 agent, implemented in nxagent-2.0.0-33. + +- Updated to comply with the new NXTransFlush() interface. + +- Both nxwin and nxagent now read the X authority file by using an + fopen() instead of the system command 'cat'. + +- Removed NXmiwindow.o from the NXAGENTOBJ list. The agent will now + use the original miwindow.c. + +- Added some additional logs in Xtranssock.c to follow the creation + and removal of the X server's Unix listener. + +- Avoided the sleep of 5 seconds forced by Xtransutil.c if the dir- + ectory where the Unix listener is created is not owned by root. + This sleep is not executed on Cygwin (where the X socket can be + hardly owned by root) but may delay the startup of the agent if + the user chose a different NX_TEMP directory. Furthermore, it is + unclear what real benefits such sleeps are intended to bring to + the security of the X server. This can be controlled by defining + the NX_TRANS_SLEEP directive in Xserver/os/Imakefile. + +- Added NXmiexpose.o to the NXAGENTOBJ. + +- Ensured that _X11TransSocketCloseConnInfo() now initiates the NX + shutdown by calling NXTransClose(). + +- Corrected a misplaced #else that made SocketUNIXConnect() skip a + block if the connection was not to the NX transport. + +- Updated to comply with the new NX function prototypes introduced + in nxcomp-2.0.0-31. + +- Moved the most important Xtranssock.c modifications into separate + functions. + +- Ensured that the modifications enabling the internal connections + to the proxy are compiled only when the TRANS_CLIENT directive is + defined. + +- Solved a bug that prevented the X11 socket to be deleted at the X + server shutdown. This needs further tests. + +- Added nxcompext to the link of nxagent, now that the dependency + of libX11 from nxcompext is removed. + +- Improved the Xtranssock routines to never loop through the array + of connection info. + +- Added a congestion flag to the connection info structure and a + function querying the transport and reporting if a change in the + congestion state has occurred. The code is currently not enabled, + because instead of polling the transport, we let the proxy notify + the changes in congestion state by using the callback. The code + can be used in future to extend the library, for example, by add- + ing some counters tracking the bandwidth usage of the socket con- + nection, so that we can make the congestion notifications work + even with a plain X11 connection. + +- Profiled the routines in XlibInt.c to reduce the number of calls + to the error predicate function provided by the client. + +- Fixed the nxcompext build problem that caused make World to fail. + +- Added a 'CONF' target to the X11 and Xext Imakefiles so that the + configure script is not run if the config.status exists. + +- Added the _NXDisplayBlockHandler hook. The function is called by + Xlib before blocking. The parameter says if Xlib is going to wait + for more input or because it needs to write to the display socket. + The client can use the hook to perform any internal operation that + may require some time to complete. The user, though, should not + try to read or write to the display inside the callback routine. + +- Removed the outdated NX_TRANS_PROCESS, NX_TRANS_THREAD and NX_TR- + ANS_INCLUDE defines. + +- Reverted the lib/Xext Imakefile to the original XF86 version and + moved the build of the nxcompext library among the libX11 depend- + encies. + +- Corrected the lib/X11 Imakefile so that a new build of nxcomp and + nxcompext is not attempted if the libraries are up-to-date. + +- Removed the unused display buffer and image cleanup functions. + +- Reverted the PutImage.c file to the original XF86 version. + +- Added the _NXDisplayErrorPredicate function in XlibInt.c. It is + actually a pointer to a function called whenever Xlib is going to + perform a network operation. If the function returns true, the + call will be aborted and Xlib will return the control to the ap- + plication. It is up to the application to set the XlibDisplayIO- + Error flag after the _NXDisplayErrorPredicate returns true. The + function can be used to activate additional checks, besides the + normal failures detected by Xlib on the display socket. For exam- + ple, the application can set the funciton to verify if an inter- + rupt was received or if any other event occurred mandating the + end of the session. + +- Modified XIfEvent(), XMaskEvent() and XPeekIfEvent() to check the + _NXDisplayErrorPredicate function and return immediately if the + function returns true. + +- Modified _XWaitForReadable() to never enter the loop if the dis- + play is broken. + +- Corrected a make problem on Windows that caused the nxcomp and + nxcompext libraries to be referred with the wrong name, with the + result that a new configure and make was attempted at each build + attempt. + +- Merged all the changes to os, Xext, xkb, dix. + +- Changed host.def to build only the agent server. + +- Merged the changes to Xtranssock.c + +nx-X11-3.0.0-3 + +- Merged the changes to lib/X11. Restored original PutImage.c and + ClDisplay.c files. + +nx-X11-3.0.0-2 + +- Created a directory named 'reference' to keep files that are chan- + ged during the development of nx-X11 since the 1.5.0-16 to 2.0.0-32 + version. These files will be removed as long as the differences are + merged to the 3.0.0 version. When all differences are merged, this + directory will be removed. + +nx-X11-3.0.0-1 + +- Opened the 3.0.0 branch based on the nx-X11-2.0.0-9. The 3.0.0 + branch will now support the migration toward the X.org tree. Due + to time concerns, the 2.0.0 branch is going to be based on the + same nx-X11 as the 1.5.0. + +nx-X11-2.0.0-9 + +- Modified the agent link arguments to explicitly include the NX + libraries. + +- Disabled the Xinerama extension to avoid further clashes with + the redefinition of GC in Xlib. + +- Added os/libos.a at the end of the agent link. + +nx-X11-2.0.0-8 + +- Moved the declarations of _NXEnable* and related structures from + Xlibint.h to NXlibint.h. + +- Added provision for building the agent. This can be controlled by + setting NXAgentServer to YES in host.def. + +- Setting the NXUpgradeAgentServer variable to YES in the host.def + file will make the agent assume that it is being built in the new + environment. This variable is normally unset when building in the + 1.5.0 tree. + +nx-X11-2.0.0-7 + +- Fixed a problem on AMD64 due to the size of the area pointed by + the argument of _X11TransBytesReadable(). BytesReadable_t is long, + at least on Linux, while the ioctl() requires a pointer to an int. + The original _X11TransBytesReadable() function simply calls the + ioctl() by passing the pointer that is provided. NXTransReadable(), + instead, was correctly returning the value assuming a pointer to + a long, but this crashes some applications, among them xterm. Now + NXTransReadable() follows the same schema of the ioctl() call and + stores the result assuming a pointer to an int. + +- Removed the outdated NX_TRANS_PROCESS and NX_TRANS_THREAD code. + +nx-X11-2.0.0-6 + +- Made xterm work with the NX transport. This required small changes + to the Xt toolkit's and the xterm's files to let them use the NX + aware select(). This is useful to test the NX transport until the + nxagent server is integrated. + +- When the transport is gone _X11TransSocketBytesReadable() returns + EPIPE. This makes the client become aware of the closure of the + connection. + +- Added a call to NXTransDestroy() in XCloseDisplay(). + +- The exit() function in XlibInt.c causes a call to NXTransExit(). + +- Merged changes to dix/pixmap.c, xkb/xkbDflts.h, mi/Imakefile. + +- Removed unneeded changes and files containing patches already in + the latest X.org distribution: dix/dispatch.c, fb/fbcompose.c, fb/ + fbgc.c, xkb/ddxList.c, font/fontfile/dirfile.c, font/fontfile/ + encparse.c, font/fontfile/fontfile.c, font/FreeType/fttools.c, + Xrender/FillRect.c, Xrender/Picture.c. + +nx-X11-2.0.0-5 + +- Changes to the lib/X11/Imakefile to cleanly build the tree. This + is obtained by creating a link to the Xcomp library in exports/lib + without having to modify the programs' Imakefiles. + +- Finished merging the NX changes in the lib/X11 files. + +- Merged the CHANGELOG with the one from the 1.5.0 tree. + +nx-X11-2.0.0-4 + +- Merged the NX changes in most Xtrans and lib/X11 files. + +nx-X11-2.0.0-3 + +- Temporarily disabled the use of the MMX extensions in the Xserver's + fb code to successfully compile with GCC 4. + +nx-X11-2.0.0-2 + +- Imported the *.NX.reference and *.XF86.reference files that will + be needed for the merge. These files are the *.original from the + 1.5.0 tree. They will be removed as long as the merge advances. + +nx-X11-2.0.0-1 + +- Created the 2.0.0 branch based on X.org the 6.8.99.16 snapshot. + +nx-X11-1.5.0-16 + +- Added the missing *.XF86.original and *.NX.original files. + +nx-X11-1.5.0-15 + +- Made the nxagent server use select() instead of poll() on Solaris + so that it can leverage the new NX transport. + +- Moved the NXTransFlush() call to _XReply(). + +nx-X11-1.5.0-14 + +- Added the 'synchronous' parameter in the _XWaitForReadable() call + to NXTransFlush(). + +nx-X11-1.5.0-13 + +- Removed the log entry in XlibInt.c on calling the NXTransFlush(). + +nx-X11-1.5.0-12 + +- Changed XlibInt.c and utils.c to call NXTransExit(). + +nx-X11-1.5.0-11 + +- Changed XlibInt.c to comply with the new NXTransFlush() interfa- + ce introduced in nxcomp-1.5.0-42. + +- Cosmetic changes to messages printed for debug. + +nx-X11-1.5.0-10 + +- Ensured that all calls to _XIOError() are followed by a return. + +- Put exiting the client program in the case of an I/O error under + the control of the _NXContinueOnDisplayError flag. If set, the + I/O error routine will simply return, leaving to the application + the responsibility of checking the state of the XlibDisplayIOEr- + ror flag. + +- Added some checks whenever a read or write is performed on the X + connection, so that we can exit the I/O loop if the X channel is + gone. It is likely that more work will be needed when trying to + support XTHREADS enabled connections. This should not be a pro- + blem for now, as the default is still to quit the application un- + less the _NXContinueOnDisplayError flag is explicitly set. + +nx-X11-1.5.0-9 + +- Removed the references to the cygipc library in NXWin. Now use the + cygserver daemon to provide the MIT-SHM extension. + +- Fixed an error in the UseCygIPC definition. + +- Changed the cygwin.cf file to avoid redefinition of the BuildGlxExt, + XWinServer and BuildGlxExt symbols. + +nx-X11-1.5.0-8 + +- Added provision for deferred writes in the NX transport. When en- + tering _XWaitForReadable() we must ensure that data is flushed to + the proxy link. + +- Added the UseCygIPC define to NX-Cygwin.def. + +- Updated the NoMachine copyright notice on the modified files. + +nx-X11-1.5.0-7 + +- Added the GLX extension in NX-Sun.def. + +- Added some more logs in WaitFor.c. + +nx-X11-1.5.0-6 + +- Modified Xlibint.h and XlibInt.c to remove the _NXFlushSize para- + meter. New agents run the NX transport in-process, so we don't get + any benefit from increasing the display buffer size. + +- Modified NX-Darwin.def to not build the NXDarwin server. Since the + 1.4.0 version the NXDarwin server is unsupported and the NX client + for the Mac requires that the Apple X server is installed. + +- Changed NX-Linux.def to avoid the warning due to "SharedLibGLw" + being not defined. + +nx-X11-1.5.0-5 + +- Modified the Xserver Imakefile to link nxagent with FbPostFbLibs + and avoid including mfb/libmfb.a. + +- Added the GLX extension in NX-Linux.def. This provides unaccelera- + ted support in nxagent, with GLX operations translated into core X + protocol primitives. + +- Fixed x-X11/programs/Xserver/GL/dri/Imakefile to look in ../../hw/ + /xfree86/os-support/bus for includes. + +nx-X11-1.5.0-4 + +- Avoid calling NXTransSelect() if the transport is gone, so that we + don't have to wait until the timeout. + +- Added the "-fno-strict-aliasing" option to linux.cf when compiling + with a GCC version >= 4. In the words of Stefan Dirsch: "The opt- + ion, which is default since gcc 3.1, can result in wrong code when + the gcc warnings related to it are ignored. And as there are seve- + ral warnings in X11 related to it, it has been disabled for X11 + from the beginning. This didn't change for gcc4, so it still needs + to be used." + +- Added more logs in XlibInt.c and utils.c. A warning is printed if + the SmartScheduler is initialized. + +nx-X11-1.5.0-3 + +- Started integration of nxcomp with the X libraries. The Xtrans + code creates an internal connection to the nxcomp library instead + of a child proxy process. + +- Changed Xpoll.h and XlibInt.c to replace the standard Select + with a version giving NX a chance to check its own descriptors. + +- Implemented the NXTransReadVector() and the NXTransWriteVector() + functions to replace READV() and WRITEV(). + +- Implemented memory-to-memory communication with the NX proxy by + making use of the NXTransAgent() interface. + +nx-X11-1.5.0-2 + +- We think that the way LoadAuthorization() is working is wrong. + It doesn't reset the list of stored authorizations before reading + the new cookies. Our take is that if a new auth file is to be + read, the only cookies that are to be accepted are those that are + in the new file, not those in the file -plus- those that have + been in the file in the past. Furthermore, if the list can't be + read or it is empty, it should assume that it ignores which co- + okies are valid and thus it should disable any access. Your mile- + age can vary. A less draconian approach could be to leave the old + cookies if the file can't be read and remove them only if the + file is empty. + + Adding the cookies without removing the old values for the same + protocol has an important implication. If an user shares the co- + okie with somebody and later wants to revoke the access to the + display, changing the cookie will not work. This is especially + important with NX. For security reasons, after reconnecting the + session to a different display, it is advisable to generate a + new set of cookies, but doing that it is useless with the current + code, as the old cookies are going to be still accepted. On the + same topic, consider that once an user has got access to the X + server, he/she can freely enable host authentication from any + host, so the safe behaviour should be to reset the host based + authenthication at least at reconnection, and keep as valid only + the cookies that are actually in the file. This behaviour would + surely break many applications, among them a SSH connection run + inside a NX session, as ssh -X reads the cookie for the display + only at session startup and does not read the cookies again + when the auth file is changed. + + Another bug (or feature, depending on how you want to consider + it) is that if the authority file contains entries for different + displays (as it is the norm when the authority file is the default + .Xauthority in the user's home), the X server will match -any- of + the cookies, even cookies that are not for its own display. This + means that you have to be careful when passing an authority file + to nxagent and maybe keep separate files for letting nxagent find + the cookie to be used to connect to the remote display and for + letting it find what cookies to accept. If the file is the same, + clients will be able to connect to nxagent with both the cookies. + This bug obviously affects any X server, also the real X server + running on the workstation, so it is common to see nxagent being + able to connect to the X server even if no cookie matches the + real display. + +- Added a check in lib/Xau/AuRead.c to prevent the fread() call to + be interrupted by SIGCHLD while reading the auth file. Due to the + way the old code worked, this could lead to the server enabling + local host access to the display. This problem had been identified + in the past. We just found that all the code dealing with reading + the auth file was affected. The code calls sigprocmask() to block + the signal (though it leaves some other calls unprotected) but the + SIGCHLD was not included in the set. + +- Added SIGCHLD to the set of signals that are blocked when reading + the authorization file. + +- As I was at it, I changed the path to the SecurityPolicy file. A + few Linux ditributors ship the file in $LIBDIR/xserver, a few only + in /etc/X11/xserver, most others in both places. It seems that + those who ship in $LIBDIR/xserver do also in /etc/X11 but the op- + posite is not true, so I switched to /etc/X11. + +nx-X11-1.5.0-1 + +- Opened the 1.5.0 branch. + +nx-X11-1.4.1-2 + +- Set parameter UseCygIPC on cygwin conf file in order to force the + build of MIT-SHM estension. + +- Removed some spurius object file. + +nx-X11-1.4.1-1 + +- Opened the 1.4.1 branch. + +nx-X11-1.4.0-8 + +- Changed DefaultFontPath and DefaultRGBDatabase in + NX-Cygwin.def. + +nx-X11-1.4.0-7 + +- Imported dispatch in nxdarwin package, in order to let + nxdarwin being able to detect new client connection. + +- Changed the Xpm Imakefile to make also .a static library + on Solaris. To link nxviewer and nxdestkop staticaly. + +nx-X11-1.4.0-6 + +- XInput extension enabled on MacOSX. + +- Added some missing backup files of the original XFree86 + package. + +nx-X11-1.4.0-5 + +- Changed the mi Imakefile in order to let xfree86 servers use + the normal mi extension initialization for the XInput exten- + sion. + +- XInput extension enabled on Solaris. + +nx-X11-1.4.0-4 + +- Removed the RejectWellKnownSocket for the cygwin and + MacOSX environments that doesn't use the Xtransport library. + +nx-X11-1.4.0-3 + +- Changed the implementation of the reject method in the + Xtransport library, now close any new incoming connection + immediately without reading or writing to it. + +nx-X11-1.4.0-2 + +- Implemented a reject method in the Xtransport library, + this function accept and close every connection attempt, + on the specified listening socket. + +- Added the new function RejectWellKnownSocket to the os + connection code. + This function use the new transport reject function on + all listening socket. + +nx-X11-1.4.0-1 + +- Opened the 1.4.0 branch. + +- Removed forgotten nxagent-1.3.2-20 directory. + +nx-X11-1.3.2-9 + +- Prevents NX Darwin server going through the reset. On Darwin + we found that the it is not possible to get the correct key- + board layout unless it is set on the local machine, before + the NX session is started, by using xmodmap. As we set the + keyboard locally, we must prevent the X server to reset, or + we would loose any local configuration. + +nx-X11-1.3.2-8 + +- Removed action associated to keysym XK_Terminate_Server. This + could cause agent to be terminated when pressing shift + back- + space if using the default US keyboard mapping. + +- Disabled the remaining debug logs in lib/X11/PutImage.c + +nx-X11-1.3.2-7 + +- Fixed the wrong programs/Xserver/Imakefile in 1.3.2-6 package. + +nx-X11-1.3.2-6 + +- Changed the define from NX_CLEAN_IN_PLACE to NX_CLEAN_INPLACE. + Definition of symbol is now placed in the Imakefile. + +- The new _NXEnableCleanInplace Xlib variable does control which + algorithm is used to clean the images. Setting NX_IMAGEINPLACE + in the environment will activate the in-place cleanup. + +- The default value of _NXEnableCleanInplace is -1. Leaving it to + a value <= 0 disables use of CleanInplace. + +nx-X11-1.3.2-5 + +- Patch in config/cf/sun.cf. Fix for libfontconfig compilation + during gmake Everything on Solaris. + +- Patch in lib/X11/Imakefile. Fix for nxcomp compilation during + gmake World on Solaris. + +nx-X11-1.3.2-4 + +- Image cleanup is now performed by using NXCleanInPlaceImage from + nxcompext. This function saves a buffer copy by cleaning the + padding bytes in the same buffer provided by the caller. Note that + to prevent memory violations in the case the image was allocated + in a static buffer, the function will temporarily redefine the + SIGSEGV handler. The former handler is restored before returning + to the caller. This can potentially affect some multithreaded + clients. Is to be decided if the function is safe enough to be + included in the production release. + +nx-X11-1.3.2-3 + +- More debug logs in programs/Xserver/xkb/ddxLoad.c. + +nx-X11-1.3.2-2 + +- Added NXmiwindow.o to NXAGENTOBJS in programs/Xserver/Imakefile. + File was not linked into the resulting nxagent. This solves the + problem of missing repaints in CDE and other Xt applications. + +nx-X11-1.3.2-1 + +- Added some debug logs in programs/Xserver/xkb/ddxLoad.c. Function + XkbDDXCompileKeymapByNames is called by OpenOffice to read the + keyboard configuration whenever a drop-down menu is accessed. It + seem to always fail with the following error: + + The XKEYBOARD keymap compiler (xkbcomp) reports: + > Error: Can't find file "unknown" for geometry include + > Exiting + > Abandoning geometry file "default" + +- Opened the 1.3.2 development branch. + +nx-X11-1.3.1-12 + +- Fixed a problem in xkb/ddxLoad.c on Solaris where Pclose was + always returning an error code despite the fact that command + was executed properly. + +nx-X11-1.3.1-11 + +- Changed default GCC flags from '-O2 -fno-strength-reduce' to + -O3. No platform where NX is targeted is currently using a + GCC 2.x affected by the -fno-strength-reduce bug. Note also + that nxcomp is already compiled with -O3 since 1.1.1, so it + can be considered safe. + +nx-X11-1.3.1-10 + +- Imported an updated fbcompose.c file from XFree86-4.3.99.902. + This fixes "uninitialized value" problems reported by Valgrind. + +- Fixed further buffer overflows by updating the following file + with recent versions coming from the XFree86-4.3.99.902 tree. + + nx-X11/lib/font/fontfile/dirfile.c + nx-X11/lib/font/fontfile/encparse.c + nx-X11/lib/font/fontfile/fontfile.c + +- Fixed a possible buffer overflow in lib/font/FreeType/fttools.c. + Verified that the change is already in the XFree86 4.4.0 CVS. + +nx-X11-1.3.1-9 + +- Fixed Xserver/Imakefile which was still referencing NXpixmap.o. + +nx-X11-1.3.1-8 + +- Imported an updated fbgc.c from XFree86-4.3.99.902. This fixes + some minor problems reported by Valgrind. + +- A major problem was reported by Valgrind about reading after + the block allocated in fbCreatePixmap from AllocatePixmap. The + file pixmap.c has been modified so that 4 bytes are added to + the pixmap buffer at any new allocation. This quick hack should + solve the problem for both nxagent and the NXWin server. Further + investigation is planned for the next release. + +- Fixed Xtranssock.c to compile on Solaris where struct sigaction + doesn't have the sa_restorer member. + +nx-X11-1.3.1-5 + +- Renamed the NX-sun.def configuration file to NX-Sun.def. + +- Renamed the non-standard NX_iPAQ_XServer and NX_Zaurus_XServer + symbols to NXiPAQXServer and NXZaurusXServer. + +- Added the missing sun.cf.XF86.original file in config/cf. + +- Added the missing empty file host.def.XF86.original in the + same directory. + +- Added initialization of sa.sa_mask when setting sigaction() + for SIGCHLD. The problem was reported by Valgrind running + nxagent. + +- Removed an unused block of code from WaitFor.c. The code had + been commented out in previous versions. + +- Removed the non-standard colon at the end of version in this + CHANGELOG. + +- Removed the spurious spaces in this CHANGELOG. + +nx-X11-1.3.1-4 + +- Added a little workaround to the top Imakefile intended to + hide the makedepend warnings about non portable whitespaces + in sources. + +nx-X11-1.3.1-3 + +- Fixed compilation problem with nxagent-1.3.1-13. + +nx-X11-1.3.1-2 + +- Changes in NX-sun.def configuration file for Solaris to allow + compilation of the XKB extension. + +nx-X11-1.3.1-1 + +- Opened the 1.3.1 development branch. + +nx-X11-1.3.0-6 + +- Original output buffer size in stock XFree86 is 2048. We try + to reduce context switches and help stream compression by + increasing the maximum size of the buffer 8192. _NXFlushSize + determines when the display buffer is actually flushed. It is + set by default to 4096 but agents should set it to 0 if they + want to disable early flush. + +- Added the _NXLostSequenceFunction function pointer to let NX + agents suppress the error message and modify the default Xlib + behaviour when out-of-order sequence numbers are received. diff --git a/doc/_attic_/NoMachine_documentation_files/nx-X11_programs_Xserver_hw_nxagent_CHANGELOG b/doc/_attic_/NoMachine_documentation_files/nx-X11_programs_Xserver_hw_nxagent_CHANGELOG new file mode 100644 index 000000000..0a82773f4 --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nx-X11_programs_Xserver_hw_nxagent_CHANGELOG @@ -0,0 +1,6359 @@ +ChangeLog: + +nxagent-3.5.0-9 + +- Fixed an issue with cursor position set in XTest extension. + +nxagent-3.5.0-8 + +- Fixed TR01J02646. Performance issues with cairo version 1.12. + +- Fixed TR01J02667. Changes to mouse sensitivity couldn't be forwarded + to NX client host although -noignore was among extra options. + +- Fixed TR05J02705. Agent ignore WarpPointer requests. + +- Fixed TR05J02706. Suspended sessions could not be recovered using + a client form a different version. + +- Fixed TR05J02703. Agent failed because of missing checks on source + drawables in the render code. + +nxagent-3.5.0-7 + +- Fixed TR10I02622. Corrected function searching for icon file. + +nxagent-3.5.0-6 + +- Fixed TR10I02621. Avoided explicit call to XMapWindow() at recon- + nection stage. + +- Fixed TR10I02620. Solved error in default visual set up. + +- Fixed TR10H02390. Get the actual remote key code for CapsLock and + NumLock. + +nxagent-3.5.0-5 + +- The NX agent failed to resize its own window to fit the desktop size + in shadow sessions. TR07I02561 is now fixed also in shadow mode. + +nxagent-3.5.0-4 + +- Fixed TR07I02530. Solved a buffer overflow occurring when the '-fp' + option value exceeds 1024 characters. + +- Extended list of the available screen geometries. + +nxagent-3.5.0-3 + +- Fixed TR08I02572. Upgraded RandR extension to version 1.2. + +- Fixed TR07I02561. The NX agent failed to resize its own window to + fit the desktop size. + +nxagent-3.5.0-2 + +- Fixed TR0502449. Initialized font server path even if font server + connection fails. + +nxagent-3.5.0-1 + +- Opened the 3.5.0 branch based on nxagent-3.4.0-16. + +- Updated copyright to year 2009. + +- Fixed TR0302438. Added a check in function exporting property in + order to handle the case looking up an atom name returns a null + pointer. + +nxagent-3.4.0-16 + +- Updated copyright to year 2011. + +nxagent-3.4.0-15 + +- Added reference to fixed TR11H02405. + +nxagent-3.4.0-14 + +- Reverted fix for TR03H02335 implemented in nxagent-3.4.0-6. The + emulation of right click by Control key + left click introduces + issues for some applications changing the reaction to the left click + depending on the state of Control key. Issue reported in TR03H02335 + affects Apple laptop touchpads having a single button acting as + left button: on those devices the right button can be emulated by + a double-fingered tap (using two fingertips simultaneously). + +nxagent-3.4.0-13 + +- Fixed TR12H02414. Exported property must be split if ChangeProperty + request exceeds 262140 bytes. + +- Reset AllScreens option at reconnection time if full screen mode + have to be automatically turned off. + +nxagent-3.4.0-12 + +- If one of the two full screen modes is active ('one screen' or 'all + screens') both keystrokes Ctrl-Alt-F and Ctrl-Alt-Shift-F change the + mode back to 'windowed'. + +- Fixed TR11H02405. XRenderFreePicture is called only for pictures + that were actually created on the X server side. + +- Ctrl+Alt+f switch fullscreen to all monitors, while Ctrl+Alt+Shift+f + does it to one monitor only. + +- If the fullscreen option is enabled at the startup, session starts + in the fullscreen mode on all monitors. + +- Added a call to XReparentWindow in the nxagentSwitchAllScreens(). + +- Corrected focus and grab when switching to fullscreen on + all monitors. + +- Removed a compile warning e deleted some unused variables. + +- Removed nxagentPointerAndKeyboardGrabbed variable. + +- Use the override redirect attribute to switch to fullscreen to all + monitors instead of send _NET_WM_FULLSCREEN_MONITORS hint to the WM. + +- Added nxagentMinimizeFromFullScreen(), nxagentMaximizeToFullScreen() + and nxagentCreateIconWindow(). + +- Removed check on EnterNotify to grab the keyboard in fullscreen + mode not only if mode is 'NotifyNormal'. + +nxagent-3.4.0-11 + +- Corrected switching between viewport mode and resize mode. + +- Fixed TR04H02340. Keycode is correctly translated in shadow sessions + also if the remote X display is using evdev. + +nxagent-3.4.0-10 + +- Handled XGrabKeyboard() return value. + +- Fixed TR10D01512. NumLock and CapsLock keys are now synchronized + between local and remote. + +nxagent-3.4.0-9 + +- Fixed TR06H02362. No icon was swown in the task bar. + +- Fixed keyboard grab in fullscreen mode. + +- Fixed compiler warnings. + +nxagent-3.4.0-8 + +- Grab the keyboard in fullscreen mode on EnterNotify only if mode is + 'NotifyNormal'. + +- Yield control in the dispatch loop in case we stop the smart sche- + duler timer while waiting for a reply from the remote display. + +nxagent-3.4.0-7 + +- Fixed TR08D01478. The communication with the compiz window manager + by means of the _NET_WM_PING property was not handled properly. + +- Fixed a type mismatch in XKB events on 64 bit platforms. + +- Moved grab/ungrab keyboard from focus in/out event to enter/leave + notify event. + +- Removed nxagentIconWindow because it's not longer used. + +nxagent-3.4.0-6 + +- Fixed TR09F02102. Problem was with pointer buttons map. + +- Fixed TR02H02327. Some KeyRelease events was discarded. + +- Fixed up Num and Caps locks. + +- Fixed TR03H02335. Emulated right mouse button for Mac clients. + +- Added utilities to print info about internal and remote windows. + +- Fixed TR01F01995. Solved a picture resource leak by destroying remo- + te pictures only when their reference counter returns to zero. + +- Fixed TR04H02337. Errors occurred because pictures with no drawable + were handled badly. + +- Implemented handling nxagent's private for gradient pictures and so- + lid fill picture. + +- Fixed BadMatch condition check in function ProcRenderComposite. + +- Fixed nxagentComposite() to handle situations with source picture + drawable pointing to NULL. + +- Implemented render acceleration for requests: CreateSolidFill, + CreateLinearGradient, CreateRadialGradient, CreateConicalGradient. + +- Fixed TR03G02196. Dialogs are shown to the fore when the NX session + is in fullscreen mode. + +- Changed mechanism to switch to fullscreen mode. Now the override + redirect attribute is no longer used and _NET_WM_STATE_FULLSCREEN + hint is sent to the WM. + +nxagent-3.4.0-5 + +- Updated copyright to year 2010. + +nxagent-3.4.0-4 + +- Fixed TR07F02090. Now XDMCP sessions start without problems. + +- Fixed TR08G02259. Corrected window border granularity of rootless + session at reconnection on 64 bit platforms. + +- Fixed TR11G02290. Forcing null timeout with queued events only if + display connection is up. This prevents the flood of session log. + +- Fixed TR10G02287. Now QueryTree's loop is aborted in case of failure + and session log isn't filled anymore with repeated warning messages. + +- Fixed TR01G02154. Corrected window placement when switching between + fullscreen and windowed mode. + +- Fixed TR09G02276. Now the agent does not receive unwanted characters + while interacting with the local window manager. + +- Implemented FR02G02174. Added ability to do large screen pans in + viewport mode through key combination Ctrl+Alt+Shift+Arrow. + +- Corrected parsing of the 'client' option when the client OS is Mac. + +nxagent-3.4.0-3 + +- Fixed TR09G02271. The array containing the font name fields was not + correctly initialized for non-standard font names. + +nxagent-3.4.0-2 + +- Updated copyright to year 2009. + +nxagent-3.4.0-1 + +- Opened the 3.4.0 branch based on nxagent-3.3.0-19. + +- Changed the printed version number. + +nxagent-3.3.0-19 + +- Fixed TR09G02266. A proper error message is printed in the session + log if the shadowing initialization fails because of a mismatch in + the visual class. + +- Added a workaround for X servers that doesn't return 1 among the + available depths. + +nxagent-3.3.0-18 + +- The area to restore from the backing store is limited by the screen + size instead of the visible screen. + +nxagent-3.3.0-17 + +- Fixed TR12F02150. The agent could crash when copying text from VNC + viewer. Fixed by aborting the procedure in case the retrieved pro- + perty has not a valid format. + +nxagent-3.3.0-16 + +- Fixed TR07G02247. Don't try to call XSetWindowColormap() if the + window has no colormap, e.g. if its class is InputOnly. + +nxagent-3.3.0-15 + +- Fixed TR04G02210. Region is cut to the visible screen before re- + storing areas from the backing store. + +- Fixed TR07G02246. Box is shrinked if bounds can't stay in a short + signed integer. + +nxagent-3.3.0-14 + +- Fixed TR03G02206. waitpid() call was missing for the "Fonts replace- + ment" dialog type. + +- Fixed TR03G02195. Added a properties structure compatible with 32 + and 64 bit platform types. + +nxagent-3.3.0-13 + +- Handle the window unmap immediately. Don't add it to the configure + queue. + +nxagent-3.3.0-12 + +- Fixed TR03G02200. Timestamps could be in the future in KeyRelease + events sent to the X clients. + +- Added debug logging of input devices state Logging can be enabled + or disabled via the Ctrl+Alt+x shortcut. State info is dumped every + 5 seconds. + +- Added Ctrl+Alt+y shortcut used to deactivate input devices grab for + debug purposes. + +nxagent-3.3.0-11 + +- Changed the message logging the screen size changes, in order to + show the fullscreen state. + +- Handle the window unmapping in the nxagentConfigureWindow queue. + +nxagent-3.3.0-10 + +- Fixed TR12F02146. Compare the drawable and the bitmap data before + realizing the image update, in order to delay the data clean up that + caused the memcmp() failure. + +- Fixed TR01G02156. Reduce the exposing area by subtracting the ex- + posed region. + +- Fixed a compile warning in Drawable.c. + +- Added detailed logs in the nxagentSynchronizeRegion() function if + the data memory allocation fails. + +nxagent-3.3.0-9 + +- Added /usr/NX/share/base to alternate font paths. This would fix + TR11F02130 if fonts fixed and cursor are installed there. + +- Changed Keyboard initialization and reset. This change should fix + TR11F02129, TR11F02131, TR11F02132. + +nxagent-3.3.0-8 + +- Fixed TR12F02144. Image bits of render glyphs are copied before they + are cleaned. This will avoid a memory corruption. + +- Fixed TR12F02145. When dispatching a MotionNotify event, check if a + top-level window has been entered before trying to show the pulldown + dialog. + +nxagent-3.3.0-7 + +- Added debug code for pointer input. + +nxagent-3.3.0-6 + +- Fixed compile warnings. + +nxagent-3.3.0-5 + +- Disabled verbose logging in Rootless.c. + +nxagent-3.3.0-4 + +- Fix the XKB map load in the case of 64 bit server. + +nxagent-3.3.0-3 + +- Fixed TR10F02119. If the remote X display is using evdev keyboard + then copy maps from remote. + +- Upgraded VERSION to 3.3.0. + +nxagent-3.3.0-2 + +- Fixed TR10F02115. Painting errors occurred when screen areas beyond + the current viewport became viewable in the NX Client for Windows. + +- Using a new struct type nxagentWMHints to avoid type mismatch on + 64 bit platforms. + +- Added debug utilities for pointer input. + +nxagent-3.3.0-1 + +- Opened the 3.3.0 branch based on nxagent-3.2.0-12. + +nxagent-3.2.0-12 + +- Ignore 'resize' option at reconnection if viewport mode is on. + +- Fixed TR08E01814. Added shadow keymap initialization in order to + enable nxcompshad to translate keycodes across different layouts. + +nxagent-3.2.0-11 + +- Fixed TR08F02098. Function splitting font names has to be instruct- + ed to handle the right number of fields. + +nxagent-3.2.0-10 + +- Extended fix for TR07F02091 to include font names having zero in + fields RESOLUTION_X and RESOLUTION_Y. + +nxagent-3.2.0-9 + +- Fixed TR07F02091. Scalable fonts were not correctly listed among + available fonts. + +- Fixed TR06F02080. Use the corrupted area extents as maximum size of + the image data. + +nxagent-3.2.0-8 + +- Fixed TR07F02082. The agent server could be unable to init core + keyboard on 64 bit systems. + +nxagent-3.2.0-7 + +- Imported patch fixing issues from X.Org security advisory, June + 11th, 2008: Multiple vulnerabilities in X server extensions. CVE + IDs: CVE-2008-1377, CVE-2008-1379, CVE-2008-2360, CVE-2008-2361, + CVE-2008-2362. + +nxagent-3.2.0-6 + +- Fixed TR05F02063. Ignore ReparentNotify events for non-rootless + sessions. + +- Fixed TR06F02068. Try to pack images only if format is ZPixmap. + +- Don't require reparent on close of NX window. + +nxagent-3.2.0-5 + +- Fixed TR04F02044. Restored the original MakeRootTile() function in + order to create the root window background pixmap. + +- Fixed TR04F02041. Gnome panels stayed on top of the NX session win- + dow with desktops running Compiz. This fix provides a solution for + the Fullscreen mode. + +- Improved for the shadow session the handling of master session win- + dow resize. + +nxagent-3.2.0-4 + +- Fixed TR10D01535. The agent window is not minimized anymore when + pointer leaves. + +- Changes aimed to avoid possible type mismatch in XDisplay struct + on 64 bit architectures. + +nxagent-3.2.0-3 + +- Fixed a build issue on Solaris. + +nxagent-3.2.0-2 + +- Code clean up. Moved a variable definition to the beginnning of a + block. + +nxagent-3.2.0-1 + +- Opened the 3.2.0 branch based on nxagent-3.1.0-9. + +nxagent-3.1.0-9 + +- Fixed TR03F02025. German umlauts couldn't be pasted into a remote + Windows application. Now also the UTF8_STRING target is available + for ConvertSelection requests. + +- Fixed TR03F02031. Moved SetScreenSaverTimer() call in order to avoid + undesired reset of the auto-disconnect timeout when a screen saver + turns on. + +nxagent-3.1.0-8 + +- Added reference to fixed TR02F02007 and TR07E01762 in the CHANGELOG. + +- Set the GC trap before calling fbPolySegment. + +- Fixed TR09E01863. A flag is set if a resource has been added or fre- + ed and it is checked in FindClientResourcesByType(). + +- Added void entries to nxagentRequestLiteral vector in order to avoid + a wrong string is printed to the output for NoOperation request. + +- Fixed TR11E01948. Now keyboard status is initialized again after + the NX session is reconnected. This avoids CAPS LOCK and NUM LOCK + synchronization problems. + +- Added nxagentXkbCapsTrap and nxagentXkbNumTrap to avoid CAPS LOCK + and NUM LOCK synchronization problems when CAPS LOCK or NUM LOCK is + the first key to be pressed in the NX session. + +- Corrected subSize variable initialization in nxagentRealizeImage(). + +- Fixed various memory leaks. + +- Fixed TR11E01950. Copy and paste via edit menu didn't work for some + applications. + +- Corrected property type in nxagentRequestSelection(). Some external + applications didn't enable their paste button when nxagent was the + owner of the CLIPBOARD selection. + +- Added struct to save values queried by XQueryExtension for XFixes + extension. + +nxagent-3.1.0-7 + +- Imported patch fixing issues from X.Org security advisory, January + 17th, 2008: Multiple vulnerabilities in the X server. CVE IDs: + CVE-2007-5760 CVE-2007-5958 CVE-2007-6427 CVE-2007-6428 + CVE-2007-6429 CVE-2008-0006. + +- Fixed TR02F02007. Handled the case if nxagentCreateDrawableBitmap() + fails to create the pixmap intended to store the bitmap data. + +nxagent-3.1.0-6 + +- Fixed a compile warning in Args.c. + +- The synchronization loop breaks if the drawable is clean when it's + not supposed to be. + +- Fixed TR12E01966. Emacs tooltips were not displayed properly. Added + a check on the event mask before calling miWindowExposures(). + +- Fixed TR01F01982. ConfigureNotify warning is printed in verbose mode + only. + +nxagent-3.1.0-5 + +- Moved some variable definitions placed in ProcGetProperty(). + +nxagent-3.1.0-4 + +- Fixed TR06D01397. The problem was: drag & drop operations between + windows of Java applications didn't work in NX Client for Windows. + +- Implemented FR12E01957. Added a limit to the amount of data that can + be pasted from an NX session into an external application. The new + option - named 'copysize' - can be read from the 'options' file. + +nxagent-3.1.0-3 + +- Fixed TR12E01963. The window tree is revalidated explicitly after + recomputing the root window clip regions. + +nxagent-3.1.0-2 + +- Fixed TR11E01946. Forcing exposures on regions saved in the backing + store could bring to unexpected results. + +- Fixed TR11E01928. Animated cursors were not properly disconnected + and reconnected. + +nxagent-3.1.0-1 + +- Opened the 3.1.0 branch based on nxagent-3.0.0-93. + +nxagent-3.0.0-93 + +- Fixed TR10E01913. Now bell settings are restored after the agent + reconnects. + +nxagent-3.0.0-92 + +- Fixed a compilation error on 64 bit platforms. + +nxagent-3.0.0-91 + +- Checked the window synchronization status before subtracting an ex- + posed area from the corrupted region. + +nxagent-3.0.0-90 + +- Fixed TR11E01932. In case of rootless session displayed by NXWin X + server, synthetic ConfigureNotify events are generated by the X11 + agent. This helps to correct menu navigation in Java 1.6.0. + +- Fixed the handling of 'client' parameter. + +- Fixed bad refreshes in viewport navigation in the case of Windows + client. + +- Fixed TR11E01930. If the defer level is set by means of the command + line, the DeferLevel option is not reset while resuming the session. + +- Fixed TR07E01762. Problem in comparison of font names. + +- Printed the new geometry in the session log when the agent screen is + resized. + +nxagent-3.0.0-89 + +- Fixed TR10E01919. The agent could crash in the routine in charge of + find a replacement for a missing font. + +- Removed an unuseful log message. + +nxagent-3.0.0-88 + +- Fixed TR10D01539. Some XKEYBOARD requests are disabled if the option + 'keyboard' has value 'query'. This locks the initial keyboard map. + Enabling/disabling of XKEYBOARD requests is done at run time. + +- Added -noxkblock command line option enabling the XKEYBOARD requests + even if the option 'keyboard' value is 'query'. + +nxagent-3.0.0-87 + +- Reworked the handling of CT_PIXMAP client clips. Clips are always + converted in regions for internal use, while bitmap are saved for + operations involving the remote X. + +nxagent-3.0.0-86 + +- Fixed TR07E01749. Now using different resolution between shadow + and master session with shadow display option 'As on the server' + doesn't display black borders. + +- Fixed TR09E01852. The GC clips of type CT_PIXMAP are not converted + in regions. This avoids generating regions made up by thousands of + rectangles. Backing store function SetClipmaskRgn is implemented by + a stub doing nothing. + +nxagent-3.0.0-85 + +- Fixed TR08E01841. Exposed are forced to new areas exposed by the + viewport. + +- Fixed TR02E01645. Remote exposures was blocked if the NX client was + running on Linux without window manager. + +- Even if the agent window is fully obscured, synchronization is not + skipped if the Composite extension of the remote display is in use. + +- Fixed TR08E01851. Exposures events have to be internally generated + for regions that can't be restored because the backing pixmap is + corrupted. + +- Fixed TR08E01847. The initial values of store used to save XChangeGC + calls are set to the default GC values. + +- When a drawable becomes synchronized, its outdated bitmap is destro- + yed. + +- If a pixmap is not fully synchronized after a synchronization loop + it is cleared, just like windows. + +- Solved a problem causing some pixmaps to remain among the corrup- + ted resources even if they were synchronized. + +nxagent-3.0.0-84 + +- Renamed Misc.h as Utils.h to solve name clashes on Windows platform. + +nxagent-3.0.0-83 + +- Changes to include correctly declaration of _XDisplay structure on + 64 bit platforms. Further tests are needed to confirm that it fixes + TR08E01824. + +nxagent-3.0.0-82 + +- Fixed TR08E01821. Changed nxagentAddItemBSPixmapList() to check if + the pixmap item has already an entry in the list before adding it. + +- Fixed TR07E01795. Sun Studio main window showed only its grey back- + ground. Changed clipboard events handling to let the agent notify + a failure in converting selection. + +nxagent-3.0.0-81 + +- Based on nxagent-3.0.0-78. + +- The agent options are saved before reopening the display in the + reconnection procedure. If the new initialization fails the backup + values of options are restored. + +- Keyboard device info are saved before the keyboard reset occuring + in the reconnection procedure. If the new initialization of the + keyboard fails, the old values are restored. + +- The initialization procedure of keyboard device returns with error + if it fails to retrieve the keyboard mapping information from the + remote display. + +- The reconnection fails if the default depth of the new display is + different from the previous one. + +- The session can be migrated if the visuals don't match for color + masks swapping. At the moment there are no conversions to line up + the RGB masks, so even if the session can be migrated, incorrect + colors may be shown. + +nxagent-3.0.0-80 + +- The agent options are saved before reopening the display in the + reconnection procedure. If the new initialization fails the backup + values of options are restored. + +- The flag storing that a SIGHUP has been received is reset if the + function reconnecting the session fails. + +nxagent-3.0.0-79 + +- Changed the SIGHUP handler not to ignore the signal if the state + is SESSION_GOING_UP or SESSION_GOING_DOWN. + +- Keyboard device info are saved before the keybord reset occuring + in the reconnection procedure. If the new initialization of the + keyboard fails, the old values are restored. + +- The initialization procedure of keyboard device returns with error + if it fails to retrieve the keyboard mapping information from the + remote display. + +- The reconnection fails if the default depth of the new display is + different from the previous one. + +- The session can be migrated if the visuals don't match for color + masks swapping. At the moment there are no conversions to line up + the RGB masks, so even if the session can be migrated, incorrect + colors may be shown. + +nxagent-3.0.0-78 + +- Fixed TR07E01747. Fixed warnings occuring when compiling for AMD64. + +- Fixed TR07E01753. NoMachine WM icon in the title bar is displayed + correctly. + +- Fixed TR03E01656. If client and server endianess didn't match, glyph + images bits have to be only temporarily swapped. + +- Fixed TR07E01746. Terminate the shadow agent if the option 'shadow' + is empty. + +- Added option '-verbose'. It enables the printing of errors received + by the agent from the remote X server. + +- Warnings related to missing fonts are printed only if verbose mode + is enabled. + +- Disabled a log message related to the use of Composite extension. + +nxagent-3.0.0-77 + +- The pixmap formats are initialized without taking care of which are + supported on the remote display. + +- Removed the check for pixmap format compatibility when migrating the + session to a new display. + +- Fixed TR06E01725. A minimum set of available picture formats is + used to ensure a wide migration from/to different displays. + +- The PictFormat structures used by nxagent are no longer filtered + with the ones available on the real display. + +- The background pixmaps are cleared while reconnecting in order to + make them usable. + +- Fixed TR01E01619. Changed the RandR implementation to return a re- + fresh rate other than zero. + +nxagent-3.0.0-76 + +- Changed the keystroke to force the drawable's synchronization to + CTRL-ALT-J. + +nxagent-3.0.0-75 + +- If the backing store tries to restore areas from a corrupted pixmap, + such areas are subtracted from the saved region, so that exposures + will be sent for them. + +nxagent-3.0.0-74 + +- Don't skip the synchronization when there are more clients ready. + This temporarily solves the synchronization problems observed in + the previous versions if one or more clients kept the agent busy. + +nxagent-3.0.0-73 + +- If the PolyFillRect() uses a FillStippled or a FillOpaqueStippled + fill style and the destination is corrupted, the area affected by + the operation is first synchronized. + +nxagent-3.0.0-72 + +- Fixed the bug affecting the position of the input window when a + session was migrated to a linux X server with no window manager + running. + +- The color used to fill the corrupted backgrounds is converted de- + pending on the depth of remote X server. + +- The PolyFillRect() does not clean the corrupted destination region + if a stipple pixmap is used as mask. This solution is adopted to + reduce the region fragmentation and to solve the text drawing pro- + blems affecting rdesktop. + +nxagent-3.0.0-71 + +- Force a flush of the display buffer if the coalescence timeout is + expired. Set the timeout according to the link type, from 0 to 50 + ms for link MODEM. + +- In nxagentRealizeImage() the width in byte is computed newly if + the image has been scaled. + +- The shadow agent clips the screen updates in tile only if the link + type is MODEM or ISDN. + +- Split the abort conditions in the synchronization loop to check + separately the congestion and the blocking status. + +- Implemented a workaround in order to avoid graphical problems with + render composite operations on Xfree86 remote server. + +nxagent-3.0.0-70 + +- Various adjustments aimed at using the best defer rules depending + on the congestion state. + +- Fixed a problem with icons of message boxes in shadow sessions. + +- Changed the log message printed when the shadow agent can't connect + to the master session. + +- If Composite is in use, don't skip the PutImage and CopyArea opera- + tions even if the agent window is fully obscured. + +nxagent-3.0.0-69 + +- The option -nodamage prevents the shadow agent from using the damage + extension. + +- Changed the scaling feature to set the byte order of the source + image according to the local endianess. + +- Changed the scaling feature in order to handle different ratios for + horizontal and vertical sizes. + +- Force the shadow sessions to be non-persistent. + +- When a pixmap background is synchronized, an expose is sent to its + owners. + +nxagent-3.0.0-68 + +- Changed the type of parameters passed to nxagentRootlessRestack in + order to be compliant with Xlib types on 64 bit platfors. + +- The nxagentCompositeRects() checks for the render operation type to + determine if the corrupted destination region must be cleared. + +nxagent-3.0.0-67 + +- Fixed a condition discarding the expose events received from the X + server. + +nxagent-3.0.0-66 + +- The corrupted resources are removed when a session suspends, and are + reallocated only at reconnection. This is aimed at avoiding synchro- + nization loops when the link is down. + +nxagent-3.0.0-65 + +- Initialize for now the tile size at 64x64 in shadow mode. + +- The height and width of the tiles used for synchronizing drawables + are set without overriding command line option 'tile'. + +- Avoid calling miWindowExposures() for empty regions. + +- Fixed a bug while clearing corrupted regions with window exposures. + +- The corrupted drawable counters are not reset if there are bitmaps + to synchronize. + +nxagent-3.0.0-64 + +- The synchronization bitmap is used only when requesting a full + drawable synchronization, otherwise the frame-buffer is used as + source. + +- Fixed some bugs in the synchronization loop. + +- Removed the remaining debug output. + +nxagent-3.0.0-63 + +- Don't start the synchronization loop if the wakeup handler found + some clients ready. + +- Don't flush the display buffers if the synchronization was inter- + rupted and there are more drawables to synchronize. + +- Changed the backing store functions to not save the obscured areas + which are inside the corrupted region of a window. + +- Added the code to send the XClearArea() commands in shadow mode at + the end of the synchronization loop. In this way large images are + still split in tiles but, on fast links, the final result can made + visible all at once. + +- Modified the corrupted drawable counters to only report the number + of resources needing synchronization. This allows the block hand- + ler to avoid spinning through the synchronization loop if there is + nothing to do. + +- On a window exposure remove the corrupted region of the destinat- + ion window. + +- For testing purposes, the pixmap synchronization loop starts only + if there are corrupted backgrounds. + +nxagent-3.0.0-62 + +- The image scaling is applied only if the destination drawable is the + pixmap shadowing the frame buffer of the master session. + +- The shadow agent exits with a fatal error if it can't connect to the + master session. + +nxagent-3.0.0-61 + +- Forward the SIGCHLD to the NX transport instead of letting the NX + transport forward the signal to us. This allows the agent to set + and replace the signal handler at any time, without having to ta- + ke care of the state of the NX transport. + +- Improved the synchronization loop by implementing a simple round- + robin mechanism between the resources needing synchronization. + +nxagent-3.0.0-60 + +- Use a new set of functions to install, post-install and reset the + signal handlers. + +- Reset the signal handlers to their initial state after a display + failure, as part of the disconnection procedure. + +- Don't set SA_RESTART in the sigaction flags. Make the signal int- + errupt the system call. + +- Terminate all the running dialogs before exiting. + +nxagent-3.0.0-59 + +- Use the value of nxagentCongestion in nxagentUserInput() instead + of calling NXDisplayCongestion(). + +nxagent-3.0.0-58 + +- The clip mask of the scratch GC used by nxagentDeferCopyArea() is + reset before releasing the GC. + +- The MotionNotify event can now break the synchronization loop. + +- In the case of shadow sessions, if synchronization aborts then the + remaining data to synchronize are not stored in a bitmap. + +- If a table rebuild occurs in a loop searching for resources, the + loop restarts from beginning not to use the out of date table. + +nxagent-3.0.0-57 + +- The synchronization bitmap is created only if the corrupted area + of the source drawable is visible. + +- The synchronization loop skips the last synchronizing drawable to + give a chance to the next resources to be synchronized. + +- Removed the session starting infos concerning the mismatching ver- + sions of render and the window manager detection. + +- Split the gliph lists in Render.c only if the symbol SPLIT_GLYPH_- + LISTS is defined. + +- Read again the events in the block handler after the flush. + +- The nxagentCongestion variable is now a value ranging from 0 to 9, + not a boolean flag. + +- Added some experimental code dynamically reducing the size of the + display output buffer when the agent is blocking for write. + +nxagent-3.0.0-56 + +- The synchronization loop is now aborted when a short timeout exp- + ires. If the drawable synchronization cannot be completed, the + remaining data is stored in a bitmap. The synchronization loop is + then restarted using the data from the bitmap, instead of pulling + the latest image from the framebuffer. This allows the agent to + show a complete frame when displaying videos and animations, while + at the same time giving a chance to the clients to update the + screen in background. When an image from the saved bitmap is put + on the remote display, the image is compared with the actual data + in the framebuffer. If the two bitmaps match, the corresponding + region of the drawable is marked as synchronized, otherwise the + drawable remains dirty and will be synchronized at the next loop + using the new data taken from the framebuffer. + +- If the smart schedules is enabled, let the dispatcher decide when + it is time to yield and process the next client. + +nxagent-3.0.0-55 + +- Disable the smart scheduler in the case of shadow sessions. + +- If the smart scheduler is enabled, stop the timer before returning + from the block handler. WaitForSomething() sets a zero timeout if + there are clients with input but doesn't stop the timer. The select + is then interrupted to update the schedule time even if, what the + dispatcher cares, is only the ticks count at the time the client + is scheduled in. + +- Fixed a compilation warning in NXresource.c. + +- The main window of the shadow agent is mapped in nxagentMapDefault- + Windows, like for non shadow agents, if the remote display has no + window manager running. This avoids a flickering effect on the !M + logo having place if the shadow session was displayed from a Wind- + ows client. + +- Some code related to the use of the Composite extension is not built + in the agent being not necessary anymore. + +nxagent-3.0.0-54 + +- Get SmartScheduleStopTimer() from dixstruct.h. + +- Updated the NoMachine icon file. + +nxagent-3.0.0-53 + +- Changed the message 'NXAGENT: Fatal IO error on display' into 'Info: + Disconnected from display'. + +- Fix a problem occurring when the FindClientResourcesByType() needs + to reallocate the resource table. + +- The popup window synchronization breaks if an user input is caught. + +- Implemented FR05E01712. The stderr and stdin are redirected to the + 'clients' file in the session directory. + +- The nxagentRealizeImage function does nothing if the agent is not + connected to the display. + +- Removed the code implementing the redraws of the viewport frame. + Such code is not needed because is't enough for the agent to handle + the expose event received from the X server. + +nxagent-3.0.0-52 + +- Where it is necessary to wrap the function PaintWindowBackground, + the original function pointer is saved and restored afterwards. This + let other code wrapping that function (e.g. the damage extension) to + work correctly. + +- If the agent works in shadow mode, the defer parameters are ignored. + +nxagent-3.0.0-51 + +- Use the smart scheduler on platforms where it is enabled. + +- Check ClientsWithInput in the wakeup handler and update the number + of clients ready if any descriptor is set. + +nxagent-3.0.0-50 + +- Fixed TR05E01714. Changed VisibilityNotify event so that it forces + a refresh on the root window, but only if on the agent Composite is + enabled and its window moves from a VisibilityFullyObscured to ano- + ther state. + +- Grant the availability of core fonts in master sessions also after + the disconnection. This makes possible to start new clients inside + a shadow sessions while the master is down. + +- Changed nxagentGlyphs() to send a single glyph list per request. + +- Major rewrite of the agent dispatch handler. + +- Some name changes to the functions handling the session states. + +nxagent-3.0.0-49 + +- Made the dispatch loop yield control to a different client after a + fair amount of time even if the current client doesn't produce any + output. + +nxagent-3.0.0-48 + +- Modified the message in the suspend dialog to say 'Disconnect' in + place of 'Suspend'. + +- Added macros in Pixels.h to determine the behavior of the lazy en- + coding. + +- Changed the copyright attribution from Medialogic to NoMachine. + +- Reset all options to their defaults before processing the session + arguments. This fixes the problem with the DeferLevel option not + being set at reconnection. + +nxagent-3.0.0-47 + +- Initialized the arguments of NXGetControlParameters(), NXGetShmem- + Parameters() and NXGetUnpackParameters() to end up with valid data + also in the case of a display failure. + +- Converted the coordinates in the X_PolyFill requests to relative + mode. This makes all the requests independent from the origin and + helps the caching by the proxy. + +nxagent-3.0.0-46 + +- Don't print the 'Display failure' message on a SIGTERM. + +- Ensure that the NX transport is shut down after the 'Terminating + session at...' message if the session is killed by the user. + +- Let the agent filter the error output by setting the OsVendorVEr- + rorFProc function pointer. + +- Give the possibility to the agent to redirect the standard error + during a Popen() or a System() by setting the OsVendorStartRedir- + ectErrorFProc and OsVendorEndRedirectErrorFProc function pointers. + +- Fixed a problem in nxagentPolyFillRect() not properly propagating + to the destination. + +- Added nxagentPolyFillRect() and nxagentGlyphs() among the funct- + ions increasing the pixmaps usage counter. + +- Cleaned up some of the FIXME related to the lazy encoding. + +nxagent-3.0.0-45 + +- Use the three distinct functions in nxcompext to query the state + of the display connection. + +- Terminate gracefully on a fatal server error by printing the fol- + lowing in the session log: + + Error: Aborting session with 'Error text...'. + Session: Aborting session at '...'. + Session: Session aborted at '...'. + +- Removed more debug messages from the session log. + +nxagent-3.0.0-44 + +- Guess whether to compress an image with a lossless encoder based + also on the width and height, not only on size. + +- Corrupted pixmaps used as tiles propagate the dirty area when they + are involved in a PolyFillRect() operation. + +- On link settings ADSL to LAN, images are not split in tiles to bet- + ter fill all the available bandwidth. + +- Pixmaps referenced often as source in deferred operations or used + as backgrounds, are now synchronized as long as when the network + congestion level remains 0. + +- Use nxagentPaintWindowBorder() to update the window's border in + the framebuffer. + +- Fixed a problem with the new handling of the X_RenderChangePicture + requests that caused the text to be erroneously clipped. + +nxagent-3.0.0-43 + +- Don't pass the uid of the shared memory segment to the nxcompshad + library if it can't be retrieved from the options. + +- Fixed the new handling of the RenderChangePicture requests to work + on 64 bit platforms. + +nxagent-3.0.0-42 + +- Added support for the 'lossy', 'lossless' and 'adaptive' pack me- + thod literals. These values activate the dynamic selection of the + pack method by the agent. + +- Use the newer constant PACK_NONE instead of NO_PACK. + +nxagent-3.0.0-41 + +- Fixed a bug in the disconnection procedure introduced with the new + handling of the display events. + +- Realize the XRenderChangePicture() request only if a change of the + remote picture's attributes is detected. + +nxagent-3.0.0-40 + +- Dynamically select a lossy or a lossless encoder based on the num- + ber of pixels that appear to be different in the image. + +- Use the new PACK_BITMAP_16M_COLORS image encoding. Handle the case + when the packed image data points at the same data as the original + image. This is useful to save a copy. + +- The PACK_BITMAP_16M_COLORS method is now the default for lossless + encoding. + +- Don't use compression for the alpha channel. This is also intended + to better leverage the stream compression. + +nxagent-3.0.0-39 + +- The nxagentComposite() function doesn't check the source and mask + synchronization status, but defers the XRenderComposite() operation + by checking the defer level only. + +- If the target of an XCompositeText() function is an hidden window, + the operation is prevented. + +- Passing the uid of master X server process to nxcompshad library. + +- Before the call of XRenderAddGlyphs(), call the new library function + XRenderCleanGlyphs() cleaning the padding bytes of data section of + request. + +nxagent-3.0.0-38 + +- Don't warp the cursor if the requesting client is a shadow agent. + +- Changed a call to NXFlushDisplay in order to align to nxcomp version + 3.0.0-15. + +- Updated the NoMachine icon file. + +- Changed Agent.h in order to include NX version of Xlib.h avoiding + missing declarations. + +- If the NXDisplayCongestion notifies an optimum congestion state, + the continuous user input, due to unreleased buttons/keys, doesn't + break the drawable's synchronization. + +- Renamed the option 'block' as 'tile'. + +- Implemented a way to guess if the destination drawable of a copy + area is a popup window. In such a case, the source is synchronized + before doing the copy to avoid ugly effects like text items floating + on an invisible background. + +- In order to reduce the number of clip mask changings, if the clean + region of a corrupted source drawable is formed by a single rectan- + gle, its coordinates are used to change extents and position of the + area involved in the copy area operation. + +- Fixed a crash caused by a reference to a resource table freed by a + table rebuilding. This was happening because during the pixmap re- + connection some new GC resources went beyond the resource table li- + mit, causing a table relocation. As a general rule, a function loop- + ing across a resource table should not add or remove resources. + +nxagent-3.0.0-37 + +- To improve the efficiency of the algorithm deferring the trapezoid + operations, the composite does not propagate the glyphs flag to + the destination. + +- Moved the replacement of XCheckIfEvent() to nx-X11 with the name + XCheckIfEventNoFlush(). + +nxagent-3.0.0-36 + +- Changed nxagentDisplayFlushHandler() according to the new semantic + of the handler. The function is called by nxcomp when new data is + sent to the remote proxy. + +- After the flush handler is called, use NXQueryDisplay() with query + type NXDisplayCongestion to update the congestion flag. + +- Modified the boxes list defragmentation to merge only those rectan- + gles which fully overlap. + +- During the synchronization loop the nxagentDispatchHandler() takes + care of reading the enqueued events, while the nxagentUserInput() + checks only for state changes due to a processed key/button event. + +- Set the display output buffer size according to the link type. + +- Removed the congestion and synchronization callbacks. + +nxagent-3.0.0-35 + +- In order to avoid the lossy encoding of text regions, the nxagent- + GlyphsExtents is computed even if the mask format is not specified. + In this case, the render implementation was not calculating the ex- + tents of composite text operation, whose coordinates are useful only + to build a mask pixmap. + +nxagent-3.0.0-34 + +- Removed message 'Could not init font path element' from the output. + +- Moved initialization of picture support before the call to miDCInit- + ialize in the screen opening procedure. This is because miDCInitial- + ize calls DamageSetup that wraps the picture screen functions. + +- Implemented FR05E01686. Added option 'menu' enabling/disabling the + pulldown menu in the rootless agent. + +- Added a flag to each drawable to record if they have been the dest- + ination of a glyph operation. This is used to skip the deferral of + some operations (e.g. render trapezoids) if they can cause the + drawable to be synchronized using a lossy encoding. + +- The render trapezoids are deferred if the operation falls inside + a dirty region or if the destination drawable does not contain + glyphs. + +- Imported the NXmitrap.c file from render directory. + +- Improved the algorithm queuing multiple writes across a proxy + flush. + +nxagent-3.0.0-33 + +- Read the event queue after each request processed. Doing this + is expensive but it seems to work best. + +- Don't split the big trapezoid requests. Splitting the requests + doesn't seem to provide any benefit with the clients tested. + +- By defining BLOCKS in Handlers.c, Events.c and NXdispatch.c, log + the begin and end of the most sensitive routines. + +nxagent-3.0.0-32 + +- Use NXSetDisplayWriteHandler() to register a callback invoked + by Xlib after some data is written to the display socket. This + callback allows the agent to better determine when it is time + to send the sync requests. + +nxagent-3.0.0-31 + +- The operation of adding glyphs to remote glyphset has been defer- + red, in order to avoid to add unused glyphs. When a composite text + operation looks for a certain glyph, if it has not been added to + the selected glyphset, an XRenderAddglyphs is requested. + +- The forced synchronization timeout is now dependant on link type. + +- Force the mi to process the events just after having processed + any input. + +- Added an experimental 'hard' sync request intended to wait for + the X server to complete an image operation. This also affects + the agent only when the NX transport is not running. + +- Added a synchronization mechanism intended to let the agent de- + tect if the X server is not able to process its input when the + NX transport is not activated. The algorithm uses asynchronous + X_GetInputFocus replies to minimize the impact of latency on + slow connections. A new request is sent at any given amount of + bytes read from our clients. When the number of pending replies + is exceeded, the agent stops accepting additional requests and + waits for the remote until the number of pending replies returns + below the limit. Note that when the NX transport is running, the + algorithm is disabled to not interfere with the proxy's own + token-based flow control. + +- Added the nxagentDispatchHandler() function. It is called by the + dispatcher after a client's request has been processed. + +- Added the nxagentWaitEvents() function. It blocks waiting for + more input with an optional timeout. It handles the case when + the NX transport is not running and is able to recover gracely + from a display failure by returning the error. + +- Replaced most of the code that was relying on NXTransContinue() + to use the new function. + +- Moved the new event-related functions to Events.h and Events.c. + +- Disabled the code raising the splash screen at reconnection. + +- Reverted change done in 3.0.0-8 version, dealing with expose events + not having entries in the queue. They are not collected in a global + region but sent immediately. + +nxagent-3.0.0-30 + +- Let the block handler check if there are events queued after the + flush before entering the select. + +- Changed the dispatch loop to read the incoming events more often. + +- Added the nxagentReadEvents() and nxagentCheckEvents() functions. + Differently from XCheckIfEvent(), nxagentCheckEvents() doesn't + flush the output buffer if no event is available. nxagentReadEv- + ents(), instead, it's like XEventsQueued() but forces the use of + the QueuedAfterReading mode. These functions should be used when- + ever XEventsQueued() and XCheckIfEvent() would be required. + +- The nxagentQueuedEvents() macro uses XQLength() to return the + number of events that have been read and need to be dispatched. + +- The nxagentPendingEvents() function returns true if there is any + event queued. If not, it queries the transport to find if more + events can be read. + +- Ripristinated the code preventing the agent to connect to its own + display. The code was disabled while migrating to the new tree. + +- Removed the dependencies from the NXAGENT_QUERYBSIZE, NXAGENT_NO- + EXPOSEOPTIMIZE and NXAGENT_ONEXIT. Removed the unused code. + +- Removed more unused code in Clipboard.c. + +- The shadow agent calls NXShadowDestroy before exiting. + +- Reverted a change done in 3.0.0-8 dealing with expose events. If the + result of the subtraction is not sent immediately, some duplicated + refresh is shown. + +nxagent-3.0.0-29 + +- The splash screen is removed as soon as the session is started in + the case of shadow session. + +- The rules to verify when the synchronization loop can be stopped + are specified by means of a bitmask passed as parameter to synch- + ronization functions. + +- The glyphsets are no longer reconnected during a session resuming, + but only when they are used. + +- Initialized the timeout parameter in block handlers in case of NULL + value. + +- Added option 'block' to specify the size of image slices sent during + the synchronization. + +- Fixed a memory leak in nxagentParseOptions(). + +nxagent-3.0.0-28 + +- Improved the nxagentGetOptimizedRegionBoxes() function to optimize + the high fragmented rectangle lists. + +- When resizing nxagent window the fictitious resize for all top level + windows, triggering the window tree validation, is not executed if + rootless mode is off. + +- The nxagentInputWindows cannot be resized in rootless mode because + they are not created. + +- Added NXdamage.c to the source files. + +- Changed damage's GCOps functions drawing text. This was needed be- + cause the original functions didn't call agent GCOps if the drawable + was registered for damage events. + +nxagent-3.0.0-27 + +- Fixed TR04E01677. Changed the reconnection procedure to call the + function destroying the NoMachine splash window. It rarely happened + that the splash window was not removed after resuming a session. + +- Ignored the ForceScreenSaver requested by X clients to avoid clashes + with our screen saver handling. + +- Cleanup of code handling the screen saver timeout to remove referen- + ces to the old drawable's synchronization method. + +- Fixed TR04E01664. The session is terminated instead of suspended if + the auto-disconnect timeout expires and the persistence is not allo- + wed. + +- Reverted an optimization in nxagentCheckWindowConfiguration() in + order to avoid inconsistencies in the stacking order. + +- Fixed a segmentation fault in rootless mode. + +nxagent-3.0.0-26 + +- Some fixes to build in the Cygwin environment. + +nxagent-3.0.0-25 + +- Renamed the option 'lazylevel' to 'defer'. + +- Added a flag to windows to know if they have transparent children, + in order to reduce to minimum the put images on windows covered by + their children. + +- Created a generic list of graphic contexts, used when synchronizing + drawables between the nxagent and the remote X server. All the GCs + are created with IncludeInferiors property. This solves problem when + trying to synchronize windows covered by children with transparent + backgrounds. + +- The nxagentUserInput checks if keys are pressed. + +- Fixed some memory leaks. + +- In shadow mode, removed the handling of events of the source display + from the code. They can be handled in the nxcompshad library. + +- In shadow mode, allow the synchronization loop to break in case of + input event. + +- Moved the call to miDCInitialize after the initialization of poin- + ters to screen functions. This was needed to make DAMAGE work pro- + perly. + +- In shadow mode, not breaking the polling if a mouse button is down. + +- In shadow mode, allow events to break the loop sending updates. + +- At reconnection the input window is raised after the root window is + mapped. + +- Fixed an invalid read. The call to the function nxagentSetInstalled- + ColormapWindows() has been moved from nxagentDestroyWindow to Dele- + teWindow. + +nxagent-3.0.0-24 + +- The corrupted drawables are added to dedicated lists of resources + to speed up the synchronization process. + +- The nxagentUserInput checks if a mouse button is pressed. + +- Created the nxagentGetScratchGC which resets the scratch GCs to de- + faults values also on the remote X server. + +- The synchronization cycle is forced when a timeout expires, albeit + the remote display is blocked. + +- Added a parameter to synchronization functions to specify if loops + can break. It's useful to force the synchronization in some circum- + stances. + +- Keystroke CTRL-ALT-R is enabled in shadow mode too. It is used to + switch scaled and non-scaled modes. + +- Some changes to adjust the window position. + +- Moved some macros to Misc.h. + +- Some changes to adjust the behaviour of scaling feature in case of + resize and switch to full screen. + +- Freeing the buffer used for scaling if no needed anymore. + +nxagent-3.0.0-23 + +- Fixed TR02E01648 and TR10D01534. Changed pointer motion events han- + dling. In desktop mode the nxagent creates a InputOnly window that + collects the MotionNotify events. This window is mapped over the + root window. In rootless mode the nxagent creates all windows on + real X server with PointerMotionMask. + +- Not exiting from the block handler with zero timeout if drawables to + be synchronized are pixmaps only. + +- Reduced the margin around the glyph extent from 5 to 3 pixels. + +nxagent-3.0.0-22 + +- Fixed initialization of XImage used for scaling. + +- Changes to fix the position of the shadow main window. + +nxagent-3.0.0-21 + +- Moved the implementation of scaling feature in nxagentRealizeImage. + +- Disabled log message 'Font not found' in Font.c. + +- The synchronization loop is called inside the BlockHandler. Synch- + ronization goes on until the display is not blocked. + +- Exiting the BlockHandler with timeout zero if corrupted drawables + have not been synchronized because of blocked display connection. + +- Changed the synchronization loop to slice the dirty regions. + +- The updates by shadowing nxagents are now sent using the lazy me- + chanics: the remote buffer pixmap is marked as dirty, then synch- + ronized. + +- Traversing the tree to synchonize windows. + +nxagent-3.0.0-20 + +- Fixed a bug in the nxagentGetOptimizedRegionBoxes() function which + was causing a bad merging of boxes. + +- Added a margin of 5 pixels around the glyphs extents before synch- + ronizing them. + +- The synchronization cycle has been reactivated for the first lazy + level, in order to synchronize the window's background. + +- The CopyArea between pixmaps doesn't mark the full destination as + corrupted, but clips the operation with the synchronized area of the + source as happens for the windows. + +- Implemented scaling feature for the shadow agent. To do: run-time + control of this feature by keystrokes and window resize; adapting + the window size to the scaled dimensions. + +- Setting the shadow session scaling ratio equal to the size chosen + from the user divided by the size of the main session. + +- Scaled mouse motion events according with the ratio. + +- Implemented the nxagentScaleImage() function. + +- Updated version number and copyright in the output log. + +- Fixed TR06D01390. When resizing nxagent window, we make a fictitious + resize for all top level windows, in order to trigger the window + tree validation. + +nxagent-3.0.0-19 + +- Force LazyLevel to 0 in case of shadowing session. + +- If shadowing poller returns that nothing is changed and no updates + have to be sent, call WaitForSomething select with 50 ms timeout. + +- The shadow agent doesn't break the sending of updates in case of + mouse motion events. + +- The scratch GC's clip mask was not cleared during a drawable synch- + ronization. Now the GetScratchGC() function is called after changing + the nxagentGCTrap flag. + +- Implemented the function nxagentGetOptimizedRegionBoxes(). It gets + the list of boxes forming a region and operates on it to merge as + much boxes as possible, checking their width and position. + +- Implemented the function nxagentClearRegion(). It does an XClearA- + rea() for each box belonging to a region, using the color returned + by nxagentGetCorruptedRegionColor() as background of target window. + +- Implemented the function nxagentGetCorruptedRegionColor(). It gets + the color of first outer pixel in the bottom right corner of re- + gion. + +- Fixed some memory leaks. + +- Checked and removed some FIXME concerning the lazy encoding. + +- Fixed and added some debug messages in Render.c, GC.c and GCOps.c. + +- Added to the Literals.h file the Render and Shared memory requests. + +nxagent-3.0.0-18 + +- Changes to comply with nxcompshad library. + +nxagent-3.0.0-17 + +- The master agent holds the number of shadow nxagents connected to + itself. The shadow nxagent notify its presence to master nxagent + by setting the _NX_SHADOW property. + +nxagent-3.0.0-16 + +- Rearranged the lazy level rules. All the link types now use the lazy + level 1: the pixmaps are always corrupted, and they becomes synchro- + nized only when they're sources of an operation (i.e. CopyArea, ren- + der). + +- The lazy levels greater than 1 don't synchronize automatically. It's + possible to synchronize with two keystrokes: CTRL+ALT+Z forces the + windows synchronization without take care of the congestion; CTRL+ + ALT+X synchronizes the windows and the background until there is + enough bandwidth. + +- Only the tile, stipples and glyphs are always synchronized. + +- The height of glyphs region has been doubled to obtain a better vi- + sual effect after the synchronization. + +- Fixed a problem causing the background pixmaps to be used also if + they were not fully synchronized. + +- Added a function to convert a PolyPoint in a dirty region. The fun- + ction is now disabled because it is not advisable to use the exten- + ts. + +- The XCopyArea is not requested if the clip region is NIL. + +- The nxagentPutImage does not update the framebuffer when it is + doing a synchronization. + +- Moved all the code handling the drawables synchronization in the + Drawable.c file. + +- As the shared memory pixmaps are never synchronized with the re- + mote X server, now they're marked as dirty when they're created. + +- An XFillRectangles request now marks the rectangles of the desti- + nation drawable as synchronized. + +- Fixed a bug that was causing the CopyArea to propagate wrongly the + corrupted region on the destination drawable when the GC uses a + clip mask. + +- Implemented a test function useful to show on the windows all the + dirty regions as colored rectangles. It is used with the CTRL+ALT+A + keystroke. + +- Before sending the XRenderComposite operations (trapezoids, trian- + gles, TriStrip, TriFan), the drawables involved are synchronized if + they are dirties. + +- Changes to shadow mode. + +- Moved the code splitting the screen shadowing updates to a separate + function. + +- Suspend the sending of updates if input is received from the user. + +- Make use of callback mechanism implemented in the nxshadow library + to suspend screen polling when input is received from the user. + +- Flush the display link when requested by the proxy. + +nxagent-3.0.0-15 + +- Print the following info when the screen is resized: "Info: Resized + screen [] to [x]. + +- Changes to comply with nxshadow library. + +- Fixed the height of screen updates in shadowing mode. + +- Terminate cleanly if shadowing initialization fails. + +- Split shadowing screen updates in smaller rectangles for slow links. + +nxagent-3.0.0-14 + +- Fixed a compilation error in NXrender.c. + +nxagent-3.0.0-13 + +- Changed the LICENSE file to state that the software is only made + available under the version 2 of the GPL. + +- Added file COPYING. + +- Updated the files imported from X.org to the 6.9.0 release. + +nxagent-3.0.0-12 + +- Fixed compilation on Sun platform. + +nxagent-3.0.0-11 + +- Implemented an algorithm adapting colors if the target display have + different depth than the shadowed display. It requires that visuals + are TrueColor and depths are 16 or 24 or 32. + +- Added the option shadowmode. If this option is '0' the shadowing + session doesn't interact with the attached session. + +nxagent-3.0.0-10 + +- Changes to comply with the nxshadow component. + +nxagent-3.0.0-9 + +- Applied changes to files imported from X.org sources. + +- Updated copyright notices to the current year. + +nxagent-3.0.0-8 + +- Imported changes up to nxagent-2.1.0-17. + +- Fixed problem with font path on Solaris 10. + +- Disabled some log messages. + +- If the agent has blocked when trying to write to the display, try to + read other events from the connection. + +- After synchronizing expose events, the result of subtraction is not + sent immediately, but added to a region. Expose events will be for- + warded to clients after exiting from the event loop. + +- Critical output is set when button mouse events are received. + +- Fixed TR12D01584. X11 sessions could not be started on Mandriva Li- + nux 2007 because of a different location of fonts. The font path + used by this distribution is now added to the alternates font paths. + +- Fixed TR11D01550. Modified the collection of visuals when nxagent + opens a display. Now we only use the ones with the same depth than + the default one set in the screen. + +- Modified the reconnection of pict-format structures, to avoid an + error that arises when migrating a session by a Linux machine to + a Windows one. + +- Small changes in handling of expose events. + +- GraphicsExpose are no more forwarded to clients immediately. They + are merged with remote-only exposures and sent later. + +- Invalidated expose queue elements dealing with destroyed windows. + +- Cleaned up code in nxagentSynchronizeExpose(). + +- Fixed TR10D01541. Now when destroing a window if lastClientWindowPtr + point to this window then in nxagentClearClipboard() we put nxagent- + ClearClipboard to NULL and lastClientStage to SelectionStageNone. + +- Fixed a problem with LazyLevel option that wasn't correctly read + from command line. + +- Fixed an arithmetic exception raised when the viewable corrupted + region is empty but not nil. + +- Removed the obsolete 'sss' option. + +- Fixed a warning related to the expose queue. + +- Modified the queue of exposed region to remove some memmov() calls. + +- Remote expose events not having entries in the queue are collected + in a global region and sent later, instead of being sent immediate- + ly. + +- Changed nxagentCheckWindowConfiguration() to prevent unuseful calls + to XQueryTree(). + +- Fixed TR10D01530. Fixed an invalid write in doOpenFont(). + +- Fixed some invalid write/read in nxagentVerifyDefaultFontPath(). + +- Fixed TR10D01518. If needed, a restack is performed on the top level + windows in rootless mode. + +- Fixed TR10D01520. Reviewed session termination and log messages in + the case of indirect XDMCP. + +- In PictureCreateDefaultFormats(), cleaned the PictFormatRec struct + when the format is not supported. + +- Fixed TR09D01498. As it is possible to use multiple paths where to + store the fonts, now the agent concatenates all the existing font + paths used in various XFree/Xorg distributions to obtain a unique + default font path. + +- Fixed TR09D01502. The privates of the real pixmap are initialized + before trying to allocate a virtual pixmap, avoiding the possibility + to access an inconsistent structure in case the allocation fails. + +- Fixed a memory leak due to a missing deallocation of a virtual pix- + map's region. + +- Fixed TR08D01486. Removed a warning in NXrender.c. + +- Implemented FR08D01470. Now in the reconnection phase missing fonts + are replaced by the most similar picked among the available ones. + +- Fixed TR08D01480. A condition inside the nxagentWindowExposures + function was ignoring the possibility that the first region para- + meter could be a null region. + +- Fixed TR06D01409. Now NXCollectGrabPointer() is called with the + owner_events true in ActivatePointerGrab() . + +- Fixed TR03D01317. Increased the time after wich the session termina- + tes. + +- Fixed TR08D01475. In rootless, ConfigureWindow requests are only + forwarded to the X server, even if no window manager has been detec- + ted. + +- Fixed TR04D01367. An XKB event is sent to notify that keyboard map- + ping has changed. + +- Check the number of regions in the list before running nxagentSynch- + ronizeExpose(). + +- Reduced the number of GCs used during the drawable synchronization. + +- Optimized the corrupted region synchronization trying to use the + extents is some circumstances instead of split the full region. + +- Checked and removed some FIXME. + +- Fixed TR05D01384. Xgl server uses less picture formats than nxagent + usually does. Now the PictFormat structures used by nxagent are fil- + tered with the ones available for the real display. + +- Fixed TR06D01410. Function nxagentRestoreAreas have to make use of + a GC with subwindow mode ClipByChildren for preventing from repaint + also children of restored window. Children are restored in a separ- + ate call, if they have backing store on. + +- Fixed TR07D01426. The cursor data were swapped in place if the dis- + play had different bitmap bit order. Let Xlib do this work on a copy + of the image, preventing from messing up the original data. + +- Fixed TR07D01450. Some fonts were missing in the list of available + fonts because the ListFonts pattern used to build this list was too + much generic. To build a full font list two different patterns have + been used. + +- Fixed TR07D01449. Some X clients might affect the X screen saver + functioning modifying the default properties. The SetScreenSaver + request now correctly checks the parameters changes to avoid any + issue. + +- Fixed TR07D01432. X11 sessions could not be started on Debian 'Etch' + because of a different location of fonts. The font path provided by + the Debian Policy is now added to the alternates font paths. + +- Fixed TR07D01437. The auto suspend timer was reset when it should + not. + +- Fixed a conditional jump on uninitialised value. + +- Fixed TR05D01380. Now migrating a session when display have a 16-bit + depth does recover all visuals, avoiding reconnection failure. + +nxagent-3.0.0-7 + +- Fixed problems occurring when the main session is terminated and the + connection is refused to the shadow agent. + +- Fixed include directory order for Solaris. + +nxagent-3.0.0-6 + +- The shadow agent works only in viewport mode. + +- Added nxagentShadowCreateMainWindow function. This function creates a + pixmap and a window for mirroring the display root window. + +- Added NXShadowUpdateBuffer() function in order to create the buffer + for the poller with the same sizes of the root window of the master + agent. + +- Added NXxrandr.c NXxrandr.h and NXxrandrint.h files. + +- If the main agent screen is resized, the shadow agent adapts to the + new size of the root window. + +- Changed option activating mirror to -S. + +- Removed usleep() call when the agent is suspended. + +- Input events are sent to the main session even if it is in sus- + pended state. + +- Updates are made from top to bottom. + +- Added the option IgnoreVisibility. If this option is set, PutImage + is not skipped when the window is fully obscured. + +- Added the option 'shadow' saying the display to attach. + +nxagent-3.0.0-5 + +- Added the mirror mode. It is activated by -M option. + +- Recovered the state of keys when the agent in access mode loses + focus in mirror mode. + +- Changes to work with 16-bit depth display in mirror mode. + +- Changed the Imakefile in order to include NXaccess.h and NXaccess- + Event.h files. + +- The layout keyboard is passed to NXShadowCreate() function in order + to load the right keymap file in mirror mode. + +nxagent-3.0.0-4 + +- Small changes to build on 64 bit x86 platform. + +nxagent-3.0.0-3 + +- Fixes to build on Cygwin platform. + +- Change the order of include directories in Imakefile. + +- Renamed GC.h, Window.h and Pixmap.h to avoid name clashes. + +- Undefined NXAGENT_UPDRADE in Composite.c and NXcomposite* files. + +- Defined ddxBeforeReset() in Init.c. + +nxagent-3.0.0-2 + +- Merged changes to NXdispatch.c, NXdixfonts.c, NXmiwindow.c, NX- + picture.c, NXproperty.c, NXrender.c, NXresource.c, NXwindow.c. + +nxagent-3.0.0-1 + +- Opened the 3.0.0 branch based on nxagent-2.0.0-88. + +nxagent-2.0.0-88 + +- Fixed a memory leak in the code handling the remote font list. + +- Removed some log message. + +nxagent-2.0.0-87 + +- The box size is checked during the region synchronization to avoid a + possible arithmetic exception. + +nxagent-2.0.0-86 + +- Checked the validity of the colormap in nxagentChangeWindowAttri- + butes(). + +nxagent-2.0.0-85 + +- Fixed the bad destination coordinates of shared memory pixmap synch- + ronization in nxagentCopyArea() and nxagentCopyPlane() functions. + +nxagent-2.0.0-84 + +- Discard the Terminate Server key sequence Ctrl-Alt-BackSpace. + +nxagent-2.0.0-83 + +- Added a workaround to prevent the use of an inconsistent client poi- + nter in the nxagentNotifyConvertFailure() function. + +nxagent-2.0.0-82 + +- Fixed the parsing of option 'backingstore'. + +nxagent-2.0.0-81 + +- The agent window visibility on the real X server is used together + with the internal state to decide if graphics operations can be + avoided. + +- When restoring areas, if the backing pixmap is corrupted, an expose + event is sent to the region that can't be restored. + +nxagent-2.0.0-80 + +- The core protocol requests internally used to accomplish a Render + extension request are no longer propagated to the real X server. To + be more precise in this way we can save many XCreatePixmap, XChange- + GC and XSetClipRectangles. + +- Corrected a minimal incoherence in nxagentCopyArea in managing the + creation and deallocation of a region. + +- Fixed a double synchronization of an aged drawable during a put ima- + ge operation, due to a missing check of nxagentSplitTrap value. + +- Added the VisibilityChangeMask bit to the event masks. + +- Improved the algorithm which prevents the server client's resource + duplication. + +nxagent-2.0.0-79 + +- Added the 'lazylevel' option usable in the command line to specify + how much the Agent should be lazy. The default level is 2. Each + level adds the following rules to the previous ones: + + Level 0 The lazy is off. + + Level 1 The put images are skipped if we were out of bandwidth, + unless that the destination drawable has an old corru- + pted region. + + Level 2 No data is put or copied on pixmaps, marking them always + as corrupted and synchronizing them on demand. + + Level 3 The put images over the windows are skipped marking the + destination as corrupted. When a copy area to a window is + requested, the source is synchronized before copying it. + + Level 4 The source drawable is no longer synchronized before a + copy area, but the operation is clipped to the synchro- + nized region. + +- Implemented a dynamic synchronization mechanism, based on user ac- + tivity: if the input devices are not used for a variable amount of + time (depending from the configured link type), the synchronization + starts and goes on until there is enough bandwidth. + +- Minor fixes to the way the copy area propagates the corrupted re- + gion. + +- Whenever a put image is done, a full synchronization is forced on + the destination drawable if it has an old corrupted region. + +- During the overall synchronization a drawable is skipped if its + timestamp is lower than the synchronization interval. + +- Updated the copy plane to skip the operations from a corrupted pix- + map to another pixmap. + +- Fixed the pixmaps synchronization which was not checking the avai- + lable bandwidth. + +- In rootless mode, ConfigureWindow requests are not internally per- + formed for top level windows if a window manager is running. Anyway + they are forwarded to the X server. + +- Enabled the DPMS extension. + +- Fixed the -dpi option. + +nxagent-2.0.0-78 + +- When the remote proxy supports the alpha encoding, the alpha data + is sent compressed. When connected to an old version, the agent + uses the NXSetUnpackAlphaCompat() call. + +- Added support for the RLE pack method. + +nxagent-2.0.0-77 + +- Fixed the check for special keystrokes. State mask for Alt and Meta + keys are inferred from the X server modifier map. + +nxagent-2.0.0-76 + +- Fixed application icon in rootless mode. + +- If SYNC_WHOLE_GLYPH_DRAWABLE is set in Render.c the whole drawables + used in the composite glyphs are synchronized. This is useful to + evaluate the policy we should use to minimize the put images. + +- Code cleanup in Pixmap.c concerning the synchronization functions. + +- Added the nxagentSynchronizeBox() function. + +- Setting a wide band link (ADSL, WAN, LAN) disables Lazy and Strea- + ming options. + +- Now the Lazy option can be switched by the Ctrl+Alt+E keystroke. + +- Set a timestamp on a drawable to verify how much old its data are. + If we didn't update it since two seconds, the put image operations + are not skipped. + +- The image data split in chunks smaller than a threshold is now mo- + ved from the nxagentPutImage() to the nxagentRealizeImage() func- + tion. If a chunk is going to be put on an hidden area of a window, + the operation is skipped. + +- Fixed the value assigned to the id of the alpha visual. Now it is + assigned by XAllocID(). + +- Removed a call to XSetInputFocus() before mapping the default win- + dows. + +- Restored the backup display pointer when failing to reconnect the + display. + +- Fixed some return value in the options parser function. + +- Fixed the parsing of environment variable. + +nxagent-2.0.0-75 + +- Optionally split the long X_RenderTrapezoid requests in multiple + messages to help the compression. + +nxagent-2.0.0-74 + +- Fixed a bug preventing the reconnection of pictures. + +- Fixed the way the agent notify its start up to NX Client. Now the + ownership of agent atom is set before the reconnection of pixmaps. + +nxagent-2.0.0-73 + +- Added a check on the display pointer in nxagentTerminateDisplay() + to ensure that we don't try to force an I/O error if the display + is already down. + +- The image operations now are clipped to the visible area of the + drawable. As this may hamper the caching algorithm, only source + images bigger than 32K are clipped. + +- Code cleanup in Render.c. + +- When setting SKIP_LOUSY_RENDER_OPERATIONS in Render.c the realiza- + tion of some operations is skipped. This is useful to determine + how clients (mis)use the RENDER extension to achieve even worse + performance than they were able to achieve using the core protocol. + +nxagent-2.0.0-72 + +- Ensured that SIGUSR1 and SIGUSR2 are ignored if the NX transport + is not running. + +nxagent-2.0.0-71 + +- Modified the following messages used to track the session state: + + From: "Session: Session starting at..." + To: "Session: Starting session at..." + + From: "Session: Session terminating at..." + To: "Session: Terminating session at..." + +nxagent-2.0.0-70 + +- Removed the obsolete 'Info' messages related to the 'fast' versus + 'slow' copy area and get image modes. The -slow and -fast options + are now ignored as ignored are the keystrokes that allowed switch- + ing between the two modes. + +- Removed more obsolete warnings and commented the logs left around + for test purposes. + +- Removed the code in NXdispatch.c handling the fake get-image. + +- Removed the flags related to the use of the frame-buffer. + +- Major code cleanup in GCOps.c, Window.c, GC.c, Pixmap.c, Screen.c. + +nxagent-2.0.0-69 + +- Added a check to avoid parsing an empty DISPLAY variable. + +- Added parsing of the 'streaming' option. + +- GetTimeInMillis() function is compiled only if DDXTIME is defined, + to avoid double definition errors on Solaris platform. + +- Messages "Suspending session..." and "Session suspended..." are not + printed if the DE_TERMINATE dispatch exception is set. + +- When synchronizing the shared memory pixmaps the image is no longer + put on the framebuffer. + +- Code cleanup in the nxagentSynhronizeRegion() function. + +- Added the 'lazy' option to enable or disable the lazy policy. It is + activated by default. At the moment this is configured at compile + time and can't be changed through a command line or the option file. + +- Fixed the counter of the corrupted backgrounds by checking if the + pixmap was already marked. + +- The option SharedPixmaps is now activated by default. + +- Fixed a problem when synchronizing the shared memory pixmaps with + the operation being erroneously skipped. + +nxagent-2.0.0-68 + +- If we are doing a copy area to a pixmap and the source drawable is + not synchronized, the destination is marked as corrupted and the co- + py area request is not propagated to the X server. As a general rule + the source drawables are now synchronized only when they are copied + to a visible window. + +- The nxagentSynchronizeRegion() function synchronizes the region one + box at a time. This solves the incorrect pictures synchronization. + +- When a new element is added to the list of exposed region, sending + the synchronization request to the X server is postponed to the next + call of nxagentFlushConfigureWindow(). + +nxagent-2.0.0-67 + +- Ensured that NXTransDestroy() is called when getting rid of the NX + transport. + +nxagent-2.0.0-66 + +- The various messages used by the NX server to control the state of + the session have been changed and the NX server will have to be mo- + dified accordingly. + + At the early startup the agent will print the following message: + + "Info: Agent running with pid '...'." + + Followed by: + + "Session: Session starting at '...'." + + The ellipsis here represent the current timestamp, as reported by + the POSIX function ctime(): + + Example: Mon May 22 15:07:11 2006. + + After the connection to the remote display has been established, + the agent will print the following message: + + "Session: Session started at '...'." + + This replaces the old messages: + + "Info: Session started, state is [SESSION_UP]." + + Or: + + "Info: XDMCP session started, state is [SESSION_UP]." + + And: + + "Info: Entering dispatch loop with exception 0x0." + + If the display connection can't be established, due to a network + failure, for example, the agent will exit with a fatal error, for + example: + + "Fatal server error: + Error: Unable to open display 'nx/nx,options=...'." + + This is a special case, as the X server is still initializing and + the agent can't intercept all the possible causes of errors. + + When suspending the session, the agent will print one of the fol- + lowing messages, depending on the reason of the disconnection: + + "Session: Suspending session at '...'." + + Or: + + "Session: Display failure detected at '...'." + "Session: Suspending session at '...'." + + As soon as the disconnection procedure is completed, the agent will + notify the server with the message: + + "Session: Session suspended at '...'." + + This message replaces the old message: + + "Session: Session suspended." + + When entering the reconnection procedure, the agent will print: + + "Session: Resuming session at '...'." + + If the session can be successfully resumed, the agent will print: + + "Session: Session resumed at '...'." + + Otherwise, if the display cannot be opened or if the proxy is not + able to negotiate the session, the agent will return in suspended + mode by printing: + + "Session: Display failure detected at '...'." + "Session: Session suspended at '...'." + + At the time the session be terminated, the agent will print: + + "Session: Session terminating at '...'." + + Followed by: + + "Session: Session terminated at '...'." + + This replaces the old message: + + Info: Exiting dispatch loop with exception 0x2. + + The message 'Session terminated at...' should be the last message + parsed by the NX server. From that moment on the NX server will + wait the agent process to ensure that the cleanup procedures are + completed without errors and that the process successfully termi- + nates with the exit code 0. + +nxagent-2.0.0-65 + +- Many improvements to the block handler and to the drawable synch- + ronization loop. + +- Anyway the synchronization loop is skipped, at the moment, to bet- + ter test the new copy area implementation. Also all the put-image + on pixmaps are skipped, so that the pixmaps are only synchronized + on demand. + +- Small fix in the put image to always use the region already allo- + cated when marking a region as corrupted. + +nxagent-2.0.0-64 + +- The realization of the put image operations now depends on the + state of the link, as reported by the proxy through the synchroni- + zation handler. If the proxy link is aproaching a congestion, the + destination area of the drawable is marked as corrupted and the + operation is skipped. + +- At the moment the synchronization strategy is quite unsophistica- + ted. The drawables are synchronized when a timeout expires in the + block handler. The synchronization loop is aborted as soon as the + link approaches again the congestion and is restarted at the next + timeout. + +- Imported miwindow.c from the DIX layer. The code has been changed + to prevent miSetShape() from trying to destroy a null region. The + bug appears to be related to the backing store but it is unclear + if can also affect the sample server. The region is allocated at + the beginning of the function only if the backing store is set for + the window. Then miSetShape() calls miChangeSaveUnder(), that, in + turn, calls miCheckSubSaveUnder(). The latter can change the back- + ing store attribute of -some- windows, including, apparently, the + window that miSetShape() is processing. miSetShape() then destroys + the region if the backing store is set, but it doesn't verify if + the region was actually allocated. The problem is fixed by simply + adding a check on the pointer. + +nxagent-2.0.0-63 + +- Added the nxagentDisplaySynchronizationHandler() callback. The NX + transport uses the callback to report when it is possible synchro- + nize the pixmaps and the other X objects that are corrupted or in- + complete. + +- Fixed nxagentClearSelection() to correctly validate the selection + owner before clearing the record. + +- Changed the NXGetControlParameters() call to reflect the changes + to the reply. + +nxagent-2.0.0-62 + +- At reconnection the pixmap data is sent to the remote X server only + in two cases: if the pixmap is associated to a picture (glyphs, for + example) or if its depth is 1 (clip masks of GCs). All the other + pixmaps are marked as corrupted and synchronized on demand as soon + as the drawable is used as a source. This code is not enabled by + default and is currently being tested. + +- Implemented a new copy area function synchronizing the corrupted + region of a drawable before using it as a source. + +- Imported resource.c from the DIX. This makes possible to avoid the + duplication of the RT_GC, RT_FONT and RT_PIXMAP resource types. + +- Added the RT_NX_GC resource type and removed the old code dealing + with the reconnection of the GCs used by the GLX extension. + +- Fixed a problem in the synchronization of the window background. + +- Checked and removed some FIXMEs related to the streaming code. + +- Changed nxagentRestoreAreas() to take care of the width of the win- + dow's border. + +- Changed nxagentSaveAreas() to be independent from the window's pos- + ition. + +- Called nxagentMapDefaultWindows() before pixmaps' reconnection. + +- Changed nxagentMapDefaultWindows() to notify the client about the + agent's startup also when running in rootless mode. + +- Added the delete and backspace keystrokes to the routine removing + duplicated keys. + +- Wehn resizing the desktop the clip region of the children windows + is clipped to the new size of the root. This fixes a crash occur- + ring when resizing the desktop to the minimum height. + +nxagent-2.0.0-61 + +- Changed the extraction of alpha channel from images to be endianess + independent. + +nxagent-2.0.0-60 + +- nxagentReleaseSplit() now uses the NXAbortSplit() request to force + the proxy to discard the pending splits. + +- Added the value of the SharedMemory and SharedPixmaps options in + the log, together with the size of the shared memory segment used + by the remote proxy. + +- Fixed the compilation problem affecting the previous version. + +- The location of xkb base directory is checked by calling _NXGetXkb- + BasePath() function. + +- Fixed TR05D01371. nxagentVerifyDefaultFontPath() is called only if + the default font path is not defined on the command line. + +- Removed some log message. + +nxagent-2.0.0-59 + +- Improved the composite text operation to synchronize the regions + affected by the operation instead of the whole drawable. + +- Updated the copy plane to better propagate the corrupted region + to the destination. + +- The background pixmaps are synchronized with a deferred strategy. + Tiles and stipples are still synchronized as soon as the GC needs + to be used. + +- Completed the new copy area implementation. + +- Shared memory pixmaps are not synchronized after a RenderChange- + Picture operation. This needs further testing. + +- Added a nxagentNotifyKeyboardChanges() function that sends a Map- + pingNotify event to clients when the keyboard is reloaded or re- + configured. The SendMappingNotify() function is not used anymore. + This hopefully solves the TR01D01284. + +- Moved the nxagentResetKeyboard() function in Keyboard.c. + +- Checked if the previous sibling of a window is changed before try- + ing to restack it. This saves the redundant window configuration + requests of the previous version. + +nxagent-2.0.0-58 + +- Before composite glyphs operations, only areas intersecting the + glyphs extents are synchronized. + +- When a new split resource is allocated, a copy of the GC used by + the put image operation is created. Such copy will be safely used + by the commit operation even if the original GC is changed or + destroyed. + +nxagent-2.0.0-57 + +- Region saved by the backing store and corrupted region of backing + store pixmaps are emptied at suspend and resume time. This makes + the exposures go to the clients that will redraw their windows. + +- Changed the nxagent root window cursor. The cursor of the parent + window is used instead of the default 'X' cursor. + +nxagent-2.0.0-56 + +- Rewritten the state machine handling the streaming of the images. + +- By calling FatalError(), the normal server shutdown was skipped + and left the X server socket in .X11-unix. This happened also if + for any reason the agent couldn't complete the session startup. + Now the DDX abort routine, if the agent is not exiting because of + an exception, calls nxagentAbortDisplay() which closes down the + well known sockets. + +- Upon a failure of the reconnection procedure, if the alert shown + to the user by leveraging the proxy control channel is not set + to a valid code, the function in will use a default. + +nxagent-2.0.0-55 + +- Added an explicit link flush in the display block handler. The + block handler should now be called by nx-X11 before entering the + select, not only the the agent has entered WaitForReadable() or + WaitForWritable(). + +- Removed the checks on the value of the Streaming option. The way + a drawable is treated only depends from its previous state. + +- Started reimplementing the copy area operation to better propaga- + te the corrupted region to the destination. + +- Shared pixmaps are now synchronized before a copy plane operation. + +- The unpack alpha is discarded before the drawable synchronization. + This fixes the problems with the synchronization of the cursor. A + better way to deal with the condition is to be considered for the + future. + +- Added a check in the nxagentPutImage() function to skip the opera- + tion if the window is fully obscured. + +nxagent-2.0.0-54 + +- Fixed a bug in nxagentPaintWindowBackground(). A region passed as + parameter was modified by this function and this affected subseq- + uent operations involving the region. + +- In rootless mode, the map state of a top level window is uncondit- + ionally reflected in the internal state when receiving a map event + from the real display. + +nxagent-2.0.0-53 + +- Regions are marked as synchronized after an image operation if the + image didn't generate a split. + +- When an image operation takes place on a drawable which is already + being streamed, the resource is marked as invalid and the commits + are discarded. + +- A specific trap is used at the time a drawable is synchronized. + +- Fixed Render.c to use the latest streaming code. + +nxagent-2.0.0-52 + +- Fixed a problem in rootless mode where some windows could have mis- + sed to update the mapped flag after a MapNotify event. + +nxagent-2.0.0-51 + +- Realization of images is skipped, if the link is down, and a small + delay is introduced before returning from the image function. + +- Started implementing a new handler to let the agent include arbit- + rary data in the transport statistics. For now, only the interfa- + ces and the stubs exist, and the handler is not registered to the + proxy. + +nxagent-2.0.0-50 + +- Removed the unused code in nxagentCheckPixmapIntegrity(). + +- Instead of calling nxagentShapeWindow() immediately, windows to be + reshaped are added to the list of windows that have to be configur- + ed at later time. This allows SaveAreas() to work even when windows + change shape, as in the case of the "bouncing cursor" as implement- + ed in some versions of the KDE. + +- Added a missing call to nxagentFlushConfigureWindow() in the recon- + nection procedure. + +nxagent-2.0.0-49 + +- Code cleanup in the lazy encoding. Implemented distinct utilities + to allocate the split resources and manage the corrupted areas. + +- The Render.c file is taken from the previous version because the + updates break the composite code. + +- Renamed the option 'Lazy' to 'Streaming'. + +nxagent-2.0.0-48 + +- Made the image cache use the agent data, instead of allocating and + copying. + +- Fixed a memory leak in the image routines. + +- The image cache is freed at exit. This helps investigating other + eventual leaks. + +nxagent-2.0.0-47 + +- Solved the problem at reconnection with lazy encoding enabled. + +nxagent-2.0.0-46 + +- Solved a bug in the parsing of the pack method that made the agent + select an unavailable id. + +nxagent-2.0.0-45 + +- Ensured that images are explicitly byte swapped before sending to + an X server using a different byte order. In the attempt of saving + an expensive operation, the previous code let the unpack procedure + do the job, but this could fail to work in some special cases. + +- Cleaned the bitmaps used for the core cursors before putting the + image. + +- Left the display error handler installed during all the lifetime + of the session so that other parts of the code don't have to inst- + all it explicitly before entering a critical Xlib routine. + +- Removed more unused code. + +nxagent-2.0.0-44 + +- Fixed the problem with the cursor image being encoded with a lossy + method. The fix is a temporary. The final solution requires changes + to the lazy encoding. + +- Reworked the code dealing with the alpha visual. The color mask is + set based on the endianess of the remote display and is recreated + after a session resume. + +- Removed more unused code. + +nxagent-2.0.0-43 + +- Corrupted regions are now correctly clipped to the visible area of + the drawable. + +- Fixed a problem with the clip mask when calculating the intersect- + ion of the clip region with the destination region. + +- Drawables involved in a composite glyph operation are now synchro- + nized prior to being used. + +- The nxagentRealizeDrawable() function is now called only for draw- + ables that are not already synchronized. + +- Pixmaps are now skipped in the synchronization loop. Synchronizat- + ion of pixmap is to be implemented. + +nxagent-2.0.0-42 + +- Improved the algorithm removing the duplicated keys by trying to + read more events. + +nxagent-2.0.0-41 + +- Made use of the NXFinishSplit() request to speed up the completion + of a pending split. + +- Added an explicit NX transport flush before any operation that may + block waiting for data from the X server. + +- Set the NX flush policy to deferred after reconnection. + +- Solved refresh problems when reconnecting in rootless mode. + +- Modified the routine removing duplicated arrow key events. Now the + routine deals with page down and page up keys as well. + +- Added a check for xkb base directory path, in order to support new + Linux distributions. + +- Disabled backing store support for rootless sessions, as implement- + ation is not very functional, yet. + +nxagent-2.0.0-40 + +- Removed code related to old managing of backing store. + +- Added initialization of backing store by calling miInitializeBack- + ingStore(). + +- Implemented nxagentSaveAreas() and nxagentRestoreAreas() functions. + These functions are based on fb code. Calls to XCopyArea() have been + added in their implementation to make them be effective also on the + real X server. + +- Instead of calling nxagentConfigureWindow() in ClipNotify() and + PositionWindow(), windows to be configured or mapped are added to a + list, together with a mask storing operation that have to be done. + Windows in the list will be configured or mapped later by calling + nxagentFlushConfigureWindow(). This avoids that windows were mapped + or configured before saving areas in the backing store pixmaps. + +- The function nxagentFlushConfigureWindow() is called before resto- + ring areas on the X server in nxagentRestoreAreas() and at the end + of ConfigureWindow and MapWindow in the DIX layer. + +- Blocked the NoExpose events at the proxy side. + +- Fixed an error in nxagentCompareRegions(). + +nxagent-2.0.0-39 + +- Ensured that the display errors are detected while waiting for a + split operation to complete. + +- Removed more unused code. + +nxagent-2.0.0-38 + +- Changed nxagentSetCursorPosition() to avoid warping the cursor if + the requesting client is NULL or the serverClient. + +- Added a specific trap to avoid compressing an image associated to + a RENDER cursor using a lossy encoding. + +nxagent-2.0.0-37 + +- Added a check in nxagentPaintWindowBackground() to avoid calling of + XClearArea() if the window is not realized. + +- Modified nxagentAtomNames in Atoms.c to include CLIPBOARD and TIME- + STAMP atoms, avoiding further calls to XInternAtom in Clipboard.c. + +- Solved TR04D01356. Auto repeat mode setting is no more propagated to + the X server keyboard. + +- Cleaned up the code in the routine removing duplicated arrow key + events. + +nxagent-2.0.0-36 + +- Added the Literals.h file. For now it just contains a table used + to translate a request opcode to the name of the X request, to be + used for test purposes. + +nxagent-2.0.0-35 + +- Major code rewrite in nxagentPutSubImage(). Removed support for the + deprecated image encodings. Ensured that padding bytes are cleaned + before trying to locate the image in the nxcompext cache. Avoided + to store the image in the cache if it is coming from a XVideo or + GLX operation. + +- Added support for the new RGB image encoder. This allows the agent + to use the simplest encoding by still separating the alpha channel + from the image data. + +- Added the missing check in nxagentRedirectWindow() verifying that + use of the composite extension is enabled. + +- Updated to use the new NXCleanImage() function. + +- Removed more debugging output. + +nxagent-2.0.0-34 + +- Updated to use the 'what' parameter in NXFlushDisplay(). + +- Removed the duplicated arrow key events from the event queue. + +- Solved the TR04D01355. The X11 agent now tries to locate the + fonts.dir file in the misc directory, to verify the validity of + the font path. + +- Added a check in nxagentChangeClip to avoid creating a new clip + mask if the old clip mask matches the former. + +- Use the 'fixed' font to replace fonts that are not found a the + display reconnection. This should overcome one the most common + sources of troubles when migrating the session to a different + display, and constitute the base for improving the algorithm + trying to match a substitute font. + +- Implemented the FR04D01360. Now the user can enable/disable the + streaming of the images by using the option 'streaming'. + +- Implemented the FR04D01358. The backing-store can be enabled or + disabled by using the option 'backingstore'. + +- Forced the reconnection routine to call the IOError handler in + the case the display cannot be opened. + +nxagent-2.0.0-33 + +- The GetImage requests in 'slow' mode are now served by retrieving + the content of the drawable from the frame buffer. + +- Replaced a call to XQueryExtension() by one to XRenderQueryExten- + sion(). This function caches previous QueryExtension requests. This + partially implements FR01D01275. + +- At reconnection, the keyboard is reset only if the keyboard option + has been changed. + +- Fixed the fonts reconnection procedure. Now the remote fonts list + is refilled before fonts reconnection and after failed fonts + reconnection, so as to store the correct list of available fonts. + +- Added a check in nxagentLoadQueryFont to look up selected font in + the list of available fonts. This check avoid filling FontStruct + with invalid data. + +- Added TIMESTAMP to handled selection targets. + +nxagent-2.0.0-32 + +- Implemented FR03D01323. Added the 'clipboard' option to enable or + disable copy and paste operations from the user's desktop to the NX + session or vice versa. This option can take four values: + + client The content copied on the client can be pasted inside the + NX session. + + server The content copied inside the NX session can be pasted + on the client. + + both The copy & paste operations are allowed both between the + client and the NX session and viceversa. + + none The copy&paste operations between the client and the NX + session are never allowed. + +nxagent-2.0.0-31 + +- Implemented FR03D01337. Now the X11 agent is able to read the op- + tions from different places according to the following order: the + DISPLAY variable, the options file, the command line. + +- Implemented FR03D01347. Added 'composite' to parsed options. + +- Always activate shared memory support in the remote X server proxy. + +- Modified nxagentCopyArea for the case the source is a shared memory + pixmap. The pixmap on the X server is not synchronized, but the con- + tent of the shared pixmap mantained by the agent is placed directly + on the destination drawable. This allows to skip the following Copy- + Area operation. + +nxagent-2.0.0-30 + +- Added the missing flush of the Xlib buffer at the beginning of + the block handler. + +nxagent-2.0.0-29 + +- Changes in the block and wakeup handlers to queue multiple reads + and flush the link on demand. + +- Removed the unused code in Control.h and Control.c. Renamed the + files as Client.h and Client.c. + +- Added support for the '-nocomposite' command line option. + +nxagent-2.0.0-28 + +- Moved the composite code to Composite.h and Composite.c. + +- Redirected the top-level windows when running in rootless mode. + +nxagent-2.0.0-27 + +- When the composite extension is supported by the remote display, + the agent window is redirected to the off-screen memory of the + X server. + +- Imported Xcomposite.c, Xcomposite.h and xcompositeint.h from the + 3.0.0 branch to be able to activate the off-screen redirection of + the top level windows. + +- Added Composite to the list of agent options. The default is to + use the composite extension, when available. + +nxagent-2.0.0-26 + +- Avoided to suspend the clients on excess of karma or after a get + input focus request. + +- Images are now split only when the agent is in congestion state. + +- Moved all the image related functions from GCOps.h and GCOps.c to + Image.h and Image.c. + +- Removed the unused includes in GCOps.c and Image.c. + +- Added the karma delay field to the NXGetControlParameters() call. + +- Renamed placeholder.xpm as nxmissing.xpm. Renamed the Icon.h file + as Icons.h. Added there a define to point at nxmissing.xpm in the + include. + +nxagent-2.0.0-25 + +- Implemented the FR03D01334. Option keyboard is now a synonym of + option kbtype. + +nxagent-2.0.0-24 + +- Ensured that the split procedure is completed before executing a + render operation that required a synchronization of a shared mem- + ory pixmap. + +- Added the appropriate checks to avoid synchronizing the same sha- + red memory pixmap multiple times. + +nxagent-2.0.0-23 + +- Imported changes to NXrender.c and NXshm.c in the files for the + 3.0.0 port. + +nxagent-2.0.0-22 + +- Implemented FR03D01331. Options shpix and shmem enable/disable the + use of shared pixmaps and shared memory extension. + +- Implented handling of value "query" for nxagentKbtype. This value + is passed by the NX client for MacOSX. If value of nxagentKbtype is + "query" or NULL we init keyboard by core protocol functions reading + the keyvoard mapping of the X server. The property _XKB_RULES_NAMES + is always set on the root window with default values of model and + layout. + +- Fixed TR11C01223. When the XDM connection can't be established the + agent creates an alert to notify the user that XDM session failed + to start. + +- Changed Clipboard.c to fix invalid read errors in nxagentGetClip- + boardWindow() function. + +- Implemented FR11C01218. Modified Font.c introducing the new function + nxagentLoadQueryFont, this function loads the font_struct struct + locally instead of sending a QueryFont request. + +- Modified nxagentListRemoteFontsfunction to fill nxagentFontList + struct with all remote fonts, avoiding further calls to XListFonts. + +- Added two functions, nxagentFreeRemoteFontList and nxagentFreeFont, + used in disconnect phase to empty the nxagentFontList struct and + the cached FontStruct elements, respectively. + +nxagent-2.0.0-21 + +- Updated to include the remote proxy version in the NXGetControl- + Parameter reply. + +- Updated to use the NXDisplayFlush() and NXSetDisplayPolicy() int- + erfaces. + +nxagent-2.0.0-20 + +- NXInitDisplay() and NXResetDisplay() are called at the time we + open or close the display, to let nxcompext set up its internal + structures. + +nxagent-2.0.0-19 + +- Activated the streaming of the images even in the case of a link + type LAN. + +- In NXmiexpose.c, if the number of rectangles in an exposed region + exceeds 4, we let a predicate function decide if it is better to + send the window extents, rather than the rectangles in the region. + +- Added the NXAGENT_SERVER define in the Imakefile. It will be used + in future to mark all the modifications made to files we imported + from other layers. + +- Removed the warnings from NXmiexpose.c. + +nxagent-2.0.0-18 + +- Imported NXmiexpose.c in the agent code. + +- Removed NXmiwindow.c from the agent code. We now use the original + miwindow.c + +- Removed the static qualifier from the _NXFontPath definition. + +- Started implementing the new lazy encoding mechanism. For each of + the drawables, the agent will create a "corrupted" region and will + try to synchronize the drawable when there is bandwidth available. + This is a work in progress. + +- Implemented the function nxagentFbOnShadowDisplay. This is a test + facility which opens a window on the display showing the content + of the agent's framebuffer. + +nxagent-2.0.0-17 + +- The image streaming procedure is now activated also when using a + link of type LAN. + +- Removed the call to NXTransDestroy() in nxagentCloseDisplay. The + NX transport is now implicitly shut down by either NXForceDisplay- + Error() or XCloseDisplay(). + +- Updated to comply with the new NX function prototypes introduced + in nxcomp-2.0.0-31. + +nxagent-2.0.0-16 + +- Fixed a bug in the nxagentModifyPixmapHeader function that was + causing some glyphs to be displayed incorrectly. + +- Implemented the test function nxagentPixmapOnShadowDisplay, useful + to display a pixmap on the real screen to check its consistency. + +nxagent-2.0.0-15 + +- Ensured that, before restarting a client after a no-split, all the + pending image commits are executed. + +- Installed the display error predicate function before trying to + open the display even at session startup. This prevents the agent + from disappearing silently if a failure occurs before the display + initialization is completed. + +- Moved the initialization of the callback functions in Display.c. + +- Added some interfaces to manipulate the callbacks and the error + handlers and verify the state of the display flags. + +nxagent-2.0.0-14 + +- Implemented stub versions of the nxagentDisplayCongestionHandler() + and nxagentDisplayBlockHandler() callbacks. See nx-X11-2.0.0-17. + +- Added the nxagentDisplayErrorPredicate() function. In combination + with changes implemented in nx-X11-2.0.0-16, this allows the agent + to abort a blocking operation and shutdown the display in a timely + fashion if a signal or any other error condition is received insi- + de Xlib. + +- Modified nxagentWaitSplitEvent() to use XIfEvent() as we can trust + the proxy to either send the event or give up the proxy connection. + The function will also give up when an error condition is raised, + like for example a session termination requested by the user. + +- Removed any remaining reference to the unused display buffer and + image cleanup functions. + +- Fixed exposures problems when reconnecting. + +- Solved TR05C00896. The problem was due to window manager utilizing + zero-thick-lines drawing requests. These drawing operations are now + performed by calling fbPolySegment() instead of miPolySegment(), + which doesn't handle the zero-thick-lines drawing case. + +nxagent-2.0.0-13 + +- Improved the management of the expose events. We now create the + fake window used to keep the agent synchronized with the X server + only once, instead of creating and configuring a different window + for each generated region. + +- A warning is printed if the changes requested for the fake window + don't match the changes reported in the subsequent ConfigureNotify + event. + +- Imported previous changes in NXevents.c into the 3.0.0 port. + +nxagent-2.0.0-12 + +- Activated the image streaming also during the reconnection. This + makes possible to leverage the remote disk cache. + +- Ensured that all clients are restarted when the session is suspen- + ded. This is required because the proxy is gone but we may have + some client still waiting for the completion of a split procedure. + +- Skipped the reset of the keyboard device if the display breaks at + the time it is being reconnected. + +- As the reset of the keyboard may have failed before we were able + to set a valid DeviceIntPtr, also added a check in ProcessPointer- + Event(), in NXevents.c to verify that the state of the display is + valid before accessing any of the device members. This is to be + better investigated. + +nxagent-2.0.0-11 + +- Solved TR02D01298. The clip region associated to the current glyph + was not updated because the serial number of the virtual pixmap + pointed by the picture was not incremented. + +- Imported the NXmiglyph.c file from render directory. + +- Removed the patch added in the release 1.3.2-6 temporary fixing this + problem. + +nxagent-2.0.0-10 + +- Various improvements the wakeup procedures. + +- Implemented the FR10C01110. Now, the X11 agent manages both the + PRIMARY and CLIPBOARD selections. It is possible copy and paste text + also by using Ctrl+C and Ctrl-V. + +- Modified NXdispatch.c in order to correctly include header files. + +- More cosmetic changes and code cleanup. + +- Imported changes into the files for the 3.0.0 port. + +nxagent-2.0.0-9 + +- Rewritten the procedures suspending and resuming the clients in + Control.c. This solves a problem with clients that were restarted + at wrong time and should ensure that multiple events for the same + client are correctly handled. + +- Removed the calls to NXSetUnpackGeometry() setting the parameters + for the client 0. The geometry is now set only at the right time, + just before trying to unpack the image. + +- Removed the sample code using the NXTransChannel() interface. + +nxagent-2.0.0-8 + +- Added test code showing how to open a new NX channel by using the + NXTransChannel() interface. + +- Streaming of images is not attempted in the case of link LAN. + +- Added preliminary code to the tell the proxy to flush the link if + the agent is idle. + +- Imported changes from nx-X11-2.0.0-14 in NXdixfonts.c. + +nxagent-2.0.0-7 + +- Modified exposures managing: agent synchronizes both with remote X + server and remote window manager for every generated region. Synch- + ronization is reached sending a ConfigureWindow request for a fake + window created on purpose. This way the exposures for the resulting + region coming from calculating the difference between local region + and the remote region are sent to clients in order to avoid duplica- + ted refreshes. + +- Improved new algorithm for managing exposures in order to work pro- + perly also in rootless mode: added privates to windows in order to + get information about mapping of windows on remote X server and vi- + sibility state too. This way local exposures are replaced by remote + ones if windows are mapped only for agent or windows are not fully + visible. This solves TR08C00971. + +- Window attributes values about backing store and save-under are re- + spectively set to NotUseful and False when creating a window on re- + mote X server and ignored when a client requests to change these + attributes. + +- Removed a no more needed function call to generate exposures when + resizing windows. + +nxagent-2.0.0-6 + +- Updated the NoMachine copyright notices. + +nxagent-2.0.0-5 + +- Added handling of font reconnection failure. In case of failure in + reconnecting some font, the agent adds the font server connection + forwarded by nxcomp to the font path of the X server. + +- Fixed TR09C01022. Moved the handling of the session states into + main cycle. The session states are not more handled into SIGHUP and + IOError handlers but into nxagentHandleConnectionStates() called in + nxagentWakeupHandler(). + +- In ResizeChildrenWinSize(), privates storing window geometry are + updated even if the call to PositionWindow() is skipped. This have + to be done because the window is moved by the X server accordingly + with window gravity. This prevent some window positioning error on + the real display evidenced with OpenOffice and GNOME. + +nxagent-2.0.0-4 + +- Solved TR12C01234. In some conditions Alt-F4 keystroke made the user + unable to open the Gnome Menu panel. This was due to the agent dis- + carding KeyRelease events for Alt-F4 and Alt-F2. + +- Undefined TEST and DEBUG in Dialog.c + +- Changed the NXAGENT_VERSION define from 1.5.0 to 2.0.0 + +- Caching and streaming of images is now disabled when dispatching + requests from the GLX and XVideo extensions. + +- Added the NXxvdisp.c and NXglxext.c files. These files are needed + to intercept calls to the XVideo and GLX extensions. Only files + in the main directory are imported. Files in the X directory, used + for the 3.0.0 port, for now are empty. + +- Added the nxagentXvTrap and nxagentGlxTrap flags. These flags are + set when dispatching requests from the XVideo and GLX extensions. + +- Added the GL and Xext include directories to the Imakefile to be + able to compile the NXxvdisp.c and NXglxext.c sources. + +- Modified the NXrender.c and NXshm.c files to set the nxagentGCTrap + nxagentRenderTrap and nxagentShmTrap even when dispatching requests + from swapped clients. Files for the 3.0.0 port are not updated. + +nxagent-2.0.0-3 + +- Solved a problem in the export of WM_SIZE_HINTS properties in root- + less mode on 64 bit machines. + +- Modified Render.c in order to correctly process Xrender header fi- + les on 64 bit machines. + +- Made changes in order to compile the agent in the Cygwin environ- + ment. + +- Renamed the files Time.* to Millis.* + +- Specified the relative path of some included header files. + +- In the Imakefile added a new include paths order related to the + Cygwin environment to avoid name clashes. + +- Disabled the MIT-SHM extension in the Cygwin environment. + +- Fixed TR11C01186. Added -timeout item to the usage message. + +- Fixed TR08C00945. Scrolling a document in Firefox caused image left- + overs with animated banners. Set the right window gravity on windows + created in the real X server. Let X move children for us accordingly + with window gravity attribute, without dix interferences. + +- Removed logs related to parsing of the options file. + +- Modified dialogs in order to show the name of the session in the + caption. + +nxagent-2.0.0-2 + +- Imported changes up to nxagent-1.5.0-112. + +- Fixed TR12C01241. The failure condition returned by the XQueryTree + function is managed in order to avoid the subsequent errors. + +- Fixed the TR11C01165. X11 sessions could not be started on Ubuntu + 5.10 because of the different location of fonts. Now we check the + existence of the fonts directory pointed by the default XF86 and + X.org font path and, if the directory does not exist, we use the + alternate font path used on Ubuntu. + +- Set the default value of DeviceControl option to False before resu- + ming a session. + +- Added a warning message printed if reset of keyboard fails at recon- + nection. + +- Fixed TR11C01185. Solved by checking if there are windows iconized + when a window is destroyed. + +- Fixed TR11C01164. The xkbcomp process used LD_LIBRARY_PATH as it was + a child of the agent. Added a call to NXUnsetLibraryPath() in Init.c + in order to remove LD_LIBRARY_PATH before executing a child process. + +- Check if there are windows iconized before terminating a rootless + session. + +- Modified CHANGELOG to include reference to fixed TRs TR08C00967 and + TR08C00969. Removed some typo. + +- Fixed TR11C01194. The agent crashed if launched with -kb option. + +- Fixed TR10C01042. The keyboard didn't work if the session migrated + from Apple X server to another platform and viceversa. This has been + solved by initializing the keyboard device whenever the session is + resumed. This feature can be disabled by the new option -nokbreset. + +- Fixed some compilation error arising if TEST was enabled in the file + Keyboard.c. + +- Fixed TR11C01167. During the disconnection the font structures poin- + ted by the font cache were freed leaving inconsistent data in the + corresponding privates. Now they are nullified and the GCs are che- + cked to guarantee a correct font handling in the suspended state. + +nxagent-2.0.0-1 + +- Opened the 2.0.0 branch based on the 1.6.0-11. + +nxagent-1.6.0-11 + +- Updated the NX.original copies of files in X directory. + +- Merged the NX changes: + + - From dix/extension.c to NXextension.c. + - From dix/dixfonts.c to NXdixfonts.c. + - From dix/glyphcurs.c to NXglyphcurs.c. + +- Export of CARDINAL properties are expanded to 64 bit units on 64 + bit machines. + +- Solved a segmentation fault when handling configure notify events + in rootless mode on 64 bit machines. + +- Merged the NX changes from dix/property in X/NXproperty.c. + +- Correctly allocated the local variable used in the call to NXGet- + CollectedInputFocus to be of 64 bit on 64 bit machine. + +- Defined symbolic constants XlibWindow in order to propertly handle + export property on 64 bit machine. + +- Moved the XlibAtom define from Atoms.h to Agent.h. + +- Modified export properties of type Window and Atom in order to han- + dle correctly Window and Atom types on 64 bit machines. + +- Removed some invalid read in Atom handling code when compiled for 64 + bit, due to mismatched size of Atom type between Xlib and Xserver + code. + +- Modified some header files in order to properly see the correct pro- + totypes of some Xlib structures on 64 bit machines. + +- The variable currentDispatch is always defined. + +- The dispatch current time is updated, this way the initial timeout + can elapse and the splash window is removed. + +nxagent-1.6.0-10 + +- Imported changes from nxagent-1.5.0-103. + +- Removed some redundant redeclarations. + +- Merged the NX changes from randr/randr.c to NXrandr.c. + +- Removed some warnings in NXrandr.c. + +- Removed NXAGENT_FORCEBACK and NXAGENT_INTERNALBS code. + +- Added ddxInitGlobals function in order to compile with the new X.org + tree. + +- Converted nxagentSynchronizeShmPixmap from macro to function to + solve a graphical render problem caused by the variable's scope. + +nxagent-1.6.0-9 + +- Imported changes from nxagent-1.5.0-102 + +- Fixed TR10C01124. Function nxagentSetPictureFilter() filled the log + with a debug message. + +- Removed a debug message in Events.c. + +- Run function nxagentSetTopLevelEventMask() only in rootless mode. + +- In the Java application IntelliJ the dropdown menus was shown in a + wrong position when the main window was moved or minimized. The + problem is solved for KDE desktop environment. + +- Fixed TR08C00967, TR08C00969, TR08C00941. Our incomplete implementa- + tion of the MIT-SHM X11 extension was a problem for some applica- + tions using the Shared Memory Pixmaps. Now the extension support has + been completed, so the nxagent can handle the Shared Memory Pixmaps + requests. Introduced some changes in the render implementation to + synchronize the content of the Shared Memory Pixmaps with the X ser- + ver before performing the ChangePicture and Composite operations. + +nxagent-1.6.0-8 + +- Fixed TR09C01028. The problem was the GC foreground was not updated + on the X server. This was due to the private fields was not copied + from a GC to another in the function nxagentCopyGC(). Added macro + nxagentCopyGCPriv in GC.h. + +- Solved TR11C01162. Removed the dialog shown by nxcomp/nxagent when + the resume of a session is happening over a slow link. + +nxagent-1.6.0-7 + +- Imported changes up to nxagent-1.5.0-100. + +- Fixed some compilation errors. + +- Fixed a typo in nxagentChangeClip() declaration. + +- Fixed TR10C01040. After the session resume the applications using + OpenGL were not correctly resumed because some GCs were not recon- + nected. Now we save these GCs in a safe vector, so we can't lose + them. + +- Improved font reconnection procedure in order to take advantage of + new font channel provided by nxcomp. If resuming session fails be- + cause missing fonts, the font channel provided by nxcomp is added + to font paths of X server. After reconnection succeded the font + channel is removed from font paths. + +- In the Java application IntelliJ the dropdown menus remained opened + and shown in a wrong position when the main window was moved or + minimized. This problem has been solved by sending a sinthetic event + to client. This solves partially TR09C01012. + +- In the same application the caret was not shown in the text window. + Solved the problem by setting nxagentGCTrap before calling a MI + function in every GC operations. + +- Merged the NX changes: + + - From render/glyph.c to NXglyph.c. + - From Xext/shm.c to NXshm.c. + - From render/render.c to NXrender.c. + - From mi/miwindow.c to NXmiwindow.c + - From render/glyphstr.h to NXglyphstr.h. + - From render/picturestr.h to NXpicturestr.h. + - From render/picture.c to NXpicture.c. + - From dix/dispatch.c to NXdispatch.c. + - From dix/events.c to NXevents.c. + +- Changed picturestr.h glyphstr.h to remove some formatting changes + compared to the original files. + +- Disabled Xinerama extension in order to fix a type conflict in NX- + dispatch.c. + +- The current directory has been moved in front of the include dire- + ctory list. + +- Removed NXAGENT_FORCEBACK code in files imported from DIX. + +- Changed NXshm.c NXrandr.c NXproperty.c NXpicture.c NXglyphcurs.c + NXglyph.c NXextension.c NXrender.c NXdixfonts.c NXdispatch.c NXmi- + window.c to remove some formatting changes compared to the original + files. + +- Added copyright notice to file NXrandr.c. + +- All files, except those from mi and dix, compile fine in the new + tree. Problems remain with different size of Atoms and other XID + objects. + +- More compilation fixes for the new tree. + +- Merged the NX changes from dix/window.c to NXwindow.c. + +- Changed NXwindow.c and NXevents.c to remove some formatting chan- + ges compared to the original files. + +- More compilation fixes aimed at porting the agent to the new tree. + +- Started porting the agent to the 6.8.99.16 X.org tree. + +- Lot of compilation fixes aimed at building in the new environment. + +- Files imported from the X.org tree's dix and mi will have to be + recreated in the nxagent/X directory. The new files will be inclu- + ded and built from the nxagent/X director if the NXAGENT_UPGRADE + symbol is defined (as it is the case when building in the 2.0.0 + nx-X11 tree), otherwise the usual NX* files in the nxagent's dir- + ectory will be compiled. + +- Fixed TR09C01021. SIGHUP it was not received from the proxy. The + handler of SIGHUP must be installed also in the case of not persi- + stent sessions. + +- In non persistent case: if session is normally running, SIGHUP sig- + nal is dealt like SIGTERM, otherwise it is passed to the proxy. + +- Fixed TR09C01027. Changed function nxagentHandleConfigureNotify() + in order to get changes of the staking order in a rootless session + even if no window manager is running. + +- Fixed TR09C01025. The problem was XView application could be unable + to respond to user's input. Modified the Event Mask for non top le- + vel windows reparented by the root window. Set the input member of + XWMHints to communicate the window manager the keyboard focus model + used by the application. + +- Fixed TR09C01026. Added 'fast' and 'slow' to the set of accepted + command line parameters. 'fast', 'slow' and 'geometry' command line + parameters have precedence regarding the options file. + +- Fixed TR08C00968. There was a problem in the implementation of the + render extension. + +- Fixed TR09C01016. In rootless mode when the session was resumed, + the cursor was shown with a wrong shape. + +- Fixed TR09C01011. Allowed clients to monitor the root window for + structure redirect, button press and resize redirect events in root- + less mode. This is a quick hack to make the java bean shell work + flawlessy with the agent. + +- Solved TR08C00961. Improved the algorithm updating the sprite win- + dow. Now it is updated based upon crossing and motion event. Since + on some X server, like Windows and MacOsX X servers, the only cros- + sing event is not a reliable method to trace the sprite window chan- + ges. + +- Fixed TR08C00966. Solved the problem on Windows when a rootless + session is suspended and some of the application windows are + minimized. + +- Fixed TR08C00960. Updated the internal screen dimension in rootless + sessions at reconnection. + +- Fixed TR09C01005. The problem was that the 'render' option on the + command line was overridden by the one provided in the options file. + +- Implemented the HandleEmptySplitEvent function that synchronizes all + the drawables after the depletion of the split store, when the lazy + option is activated. + +- Some changes in order to avoid duplicated refreshes when display- + ing Mandrake's kde menu. + +- Changed level of some logs from WARNING into TEST in Window.c and + in Rootless.c. + +- Fixed TR08C00958. Changed the log message printed when the user re- + quest to resume the session. + +nxagent-1.6.0-6 + +- When reconnecting, try to estimate the shift on the main window due + to WM reparenting. + +- In the handling of configure events, if a WM is running save the po- + sition of the main window only if event is synthetic. + +nxagent-1.6.0-5 + +- Command line option -noshmem disables shared memory extension in the + agent. + +- Changed level of some logs from WARNING into TEST. + +nxagent-1.6.0-4 + +- Some changes in order to improve handling of expose events in root- + less. The GetInputFocus request is not sent after reconfiguring a + top level window: window manager intervention could give race condi- + tions. The request is placed in WindowsRestructured() in order to be + sure it is sent after any event that could generate expose. + +- Zero lenght change property are now imported in rootless mode. + +- Corrected few typos. + +- Replaced the function usleep with NXTransContinue when NX transport + is running. + +- Changed the session state to GOING_DOWN as soon as the reconnection + is failed. + +nxagent-1.6.0-3 + +- Updated rootless toplevel window map when a window is reparented to + the root window. + +- Renoved duplicated entry in rootless toplevel window map. + +nxagent-1.6.0-2 + +- Removed TEST and DEBUG in Color.c. + +- Removed a compilation error in Atoms.c if DEBUG is enabled. + +- Removed invalid read at server reset in rootless mode, now the a- + toms description are duplicate before that we cache them. + +- Now the local atom in the atom cache are reset when exiting from + the dispatch loop. + +nxagent-1.6.0-1 + +- Opened the 1.6.0 branch based on nxagent-1.5.0-87. + +nxagent-1.5.0-87 + +- Corrected the enable-disable lazy encoding dialog in order to show + the correct keystroke Ctrl-Alt-E. + +nxagent-1.5.0-86 + +- Reset agent position at reconnection when the new size of display + doesn't match the old size and fullscreen is on. + +- Inserted a comment about handling of expose events. + +nxagent-1.5.0-85 + +- If fullscreen and resize options are true when reconnecting, geo- + metry option is ignored and the root window is resized to the en- + tire screen. + +- Read the position of the main window at startup from geometry op- + tions. + +nxagent-1.5.0-84 + +- Changed the keystroke Ctrl-Alt-L to toggle the image encoding on + and off to the new combination Ctrl-Alt-E. + +- Enabled the keystroke Ctrl-Alt-M to minimize the root window also + in window mode. + +nxagent-1.5.0-83 + +- Replaced the call to XIfEvent() with something less efficient but + safer, based on XCheckIfEvent(). The previous version might never + return if an I/O Error was encountered waiting for the event. The + new version fails gracefully, and returns after having restarted + the client. + +nxagent-1.5.0-82 + +- Removed some debug logs. + +nxagent-1.5.0-81 + +- Forced window mode if X server geometry has changed at reconnection. + +nxagent-1.5.0-80 + +- Reset resize desktop at startup flag before reconnection. + +nxagent-1.5.0-79 + +- Removed race condition in the parsing order of the options parame- + ter, now the geometry parameters are set in screen initialization. + +nxagent-1.5.0-78 + +- Disabled auto-resize and viewport mode dialog in case of rootless + session. + +- Removed no more used -backingstore option from usage messages. + +- Modified -bs command line option: now the default value "when_re- + quested" is always set. + +- Fixed wrong size of root window when switching from full screen to + window mode and viewport navigation mode is enabled. + +- Added option that solved a minimize bug in LeaveNotify when the + root window is in full screen and the user is using viewport navi- + gation mode. + +- Forwarded HUP signal to NX transport, when session state is up and + running. + +nxagent-1.5.0-77 + +- Do PutImage in every case. Don't check if the drawable is synchro- + nized. + +- Do CopyArea, CopyPlane, Composite in every case, don't check whether + the source is dirty. + +nxagent-1.5.0-76 + +- Terminate rootless session 15 seconds after the last mapped window + has been destroyed. + +nxagent-1.5.0-75 + +- Ctrl-Alt-T shows suspend/terminate dialog also in rootless mode. + +- Sleeps 50 ms in the block handler if the session state is down. + +- In rootless mode, the focus window is changed following FocusIn + events received from the real X server, also in the case no win- + dow manager has been detected. + +nxagent-1.5.0-74 + +- Changed the alerts names to comply with nxcomp-1.5.0-57. + +- Moved loading of placeholder from startup to the first time it is + needed. + +- Corrected a typo in the CHANGELOG. + +nxagent-1.5.0-73 + +- Ignored put image on not synchronized drawables, when the image + doesn't cover the entire surface. + +- Added parsing of render parameter in option file. + +- Ignored I/O Error when session is suspended. + +- Managed I/O Error at reconnection. + +nxagent-1.5.0-72 + +- Fixed offset of the default window at reconnection and after switch- + ing from fullscreen in window mode. + +- Suppressed the -lazy command line option. + +- Made some slightly changes in GCOps.c and Pixmap.c in order to com- + ply with the new 'Lazy' option. + +- Avoided to do CopyArea, CopyPlane and Composite operations when the + source drawable is dirty. + +- Rootless disconnect dialog has changed. This dialog is launched + after some time the last window has been closed. + +- Ignored geometry changes at reconnection if resize at startup is + not set. + +- Removed reset of the offset of the root window in viewport mode at + reconnection. + +- Fixed some refreshes problems in viewport mode and in desktop resize + mode. + +- Fixed a memory leak in nxagentWindowExposures(). + +- Added predicate to nxagentDispatchEvents. + +- Implemented framework in order to wait for a free resource entry, + when calling the asynchronous Collect* functions. + +nxagent-1.5.0-71 + +- Added keystroke Ctrl+Alt+L switching lazy encoding option. + +- Disabled viewport movement in resize mode. + +- Changed agent geometry at screen resize. + +- Changed agent geometry at initialization. + +nxagent-1.5.0-70 + +- Restored the set of blocked signal after the dialog pid just laun- + ched has been stored. + +- Removed an already fixed FIXME. + +- Updated the copyright message. + +nxagent-1.5.0-69 + +- Started working at the integration of the lazy encoding functiona- + lity. Made the agent draw the placeholder if the image is split and + never suspend the client. There is no provision for synchronizing + the drawables yet. + +- Made the lazy encoding configurable by the new 'Lazy' option. + +- Updated to include the changes in the NXStartSplit() and NXCommit- + Split() requests. + +- This version requires nxcomp-1.5.0-55 and nxcompext-1.5.0-16. + +nxagent-1.5.0-68 + +- Fixed reconnection of iconified windows. + +- Ignored the X server's scratch pixmap at reconnection. + +- The desktop gets automatically resized at reconnection if the desk- + top resize option is enabled. + +- Added the resize option in nxagentProcessOptionsFile() to allow the + user to change the geometry of both the root and the default window + at reconnection. + +- Fixed max size of the default window at startup when auto-resize + mode is enabled or in the case of a reconnected session. + +- Made some minimal changes in Atoms.c and NXdispatch.c. + +nxagent-1.5.0-67 + +- Changed handling of expose events received from real X server. A re- + gion is composed from expose events by checking the count field. + +- Reimplemented the exposures managing. Now the GetInputFocus request + is sent after a window has been configured or unmapped. We use a + vector to store windows originating expose events while waiting for + the reply to GetInputFocus. + +nxagent-1.5.0-66 + +- Added the DisplayLatency value in the agent options. This is int- + ended to give a hint about the latency of the current display + connection. The value is currently used to determine if the agent + is running across a slow link, and so it's appropriate to display + the begin-reconnection alert. + +nxagent-1.5.0-65 + +- Added the DesktopResize option. It controls the behaviour of the + automatic (RandR) resize of the desktop when dragging the agent's + window border. + +- Automatic resize is again the default. + +- Disabled the test logs in Events.c, GCOps.c Pixmap.c, Handlers.c, + Reconnect.c. + +- More cosmetic changes and code cleanup. + +nxagent-1.5.0-64 + +- Rewritten the image streaming procedure to better leverage the new + infrastructure. The start-split/end-split procedure is always init- + iated by the agent, including when the size of the image is below + the threshold, but the client is only suspended when the split has + taken place in the NX transport. + +nxagent-1.5.0-63 + +- Updated image streaming to use the new NX notification events. + +- Removed the references to the NXSync() operation, not used anymore + by the agent. + +nxagent-1.5.0-62 + +- Fixed wrong position of the root window in case of viewport naviga- + tion mode. + +- Added a field to the client private to trace the client type. + +- Tracked which clients are nxclient dialogs in order to not run the + pulldown dialog on them. + +nxagent-1.5.0-61 + +- Disabled server reset if not needed by XDMCP. + +- Disabled persistence for indirect XDMCP session until the first gre- + eter with the list of host has disappeared. + +- Created a small data structure to contain information about integri- + ty status and placeholder status of a drawable. + +- Modified the call to nxagentRealizeOnePixmap function in order to + avoid errors during the signal handling. + +nxagent-1.5.0-60 + +- Added the XDMCP option. If both Rootless and XDMCP are selected the + session will fail. + +nxagent-1.5.0-59 + +- Limited the permission to reset the agent only to indirect XDMCP + sessions, only one reset is allowed. + +- Fixed max size of the default window when switching from fullscreen + to window mode and auto-resize is disabled. + +nxagent-1.5.0-58 + +- Enabled reset mechanism, in order to make XDMCP session work proper- + ly. + +- Added XSync for window manager detection, after a server reset since + the XInternAtom already used should be cached. + +- Now the pixmap status is always tested on real pixmap. + +- The placeholder is drawn only once per drawable. + +- Implemented nxagentUnmapWindows() in case of failed reconnection if + the session was running in fullscreen mode and NX transport is not + enabled. + +- In nxagentPutSplitImage(), passing leftPad to XCreateImage(). + +- This version avoids sending the XSync() to the remote when a large + amounts of GetInputFocus requests are issued by the same client. + It will require more testing, especially to verify how it works on + old Windows machines. + +- Changed the NXCommitSplit() call to comply with the new interface. + +- The drawable status is now propagated on graphic operations where + the source is using the tile and stipple components on the graphic + context and the tile or stipple are not synchronized. This affects + the following operations: + + - PolyLines + - PolySegment + - PolyRectangle + - PolyArc + - FillPolygon + - PolyFillRect + - PolyFillArc + - PolyText8 + - PolyText16 + +nxagent-1.5.0-57 + +- Removed two XSync() operations at screen initialization. + +- Modified keyboard initialization in order to load the correct rules. + This is choosen according to the vendor string of X-Window system in- + stalled on the local machine. + +- Corrected a few typos. + +- When the NX transport is present, the failed reconnection dialog is + launched on the remote X server by using the NXTransAlert() function. + The same dialog is managed by NXTransDialog() when a session is run + by connecting directly to the display. + +- Removed the function nxagentUnmapAllWindows(). + +nxagent-1.5.0-56 + +- Set the parent window for the pulldown dialog. + +nxagent-1.5.0-55 + +- Added an alert at the time the reconnection procedure begins. The + alert is shown only when the NX transport is present and the link + type is not LAN and is removed at the end of the resume operation. + +- Removed the former code used for testing the alert functionality. + +- Moved the function removing the splash window in Splash.c. + +nxagent-1.5.0-54 + +- Fixed initialization of window privates storing exposed regions. + This solves a bug affecting the refresh of windows introduced in + nxagent-1.5.0-42. + +- Added a STARTING state to nxagent. Until the agent is in this state + the suspension mechanism is not activated. + +nxagent-1.5.0-53 + +- Added the special keystroke Ctrl+Alt+R to enable or disable the + auto-resize mode. + +- A dialog notifies the user when the auto-resize mode is toggled. + +- Added a test alert at startup, to verify that NXTransAlert() is + working as expected. + +nxagent-1.5.0-52 + +- Changed the code to call NXTransDialog() and NXTransExit(). + +nxagent-1.5.0-51 + +- Solved a bug that prevented the clients that had been restarted + to be immediately selected for input. + +- Removed some code that was added for debugging. + +nxagent-1.5.0-50 + +- Fixed a memory leak in nxagentHandleExposeEvent(). + +- Fixed a memory leak in nxagentDestroyWindow(). + +- Now rootless dialog is launched only when last mapped window is + deleted, since we have pulldown window to control the session. + +- Added pulldown dialog to handle NX windows in rootless sessions. + This dialog is activated from a "magic" slice of window under the + top border. + +- Solved a problem with sessions that might fail at reconnection. + +- Now the message text of the dialog launched in case of failed re- + connection explains the reason why the agent cannot be resumed. + +- Implemented function nxagentUnmapAllWindows() to unmap all windows + if nxagent has failed to migrate the session to the new display. + +nxagent-1.5.0-49 + +- Fixed the problems with propagation of the drawable status. + +- Modified nxagentPutSplitImage in order to set the correct height + of the last split image. + +- Code cleaning and optimization in Dialog.c. + +- Solved bug that switched on the full screen state in rootless se- + ssion. + +- Changed the way dialog caption are set in rootless mode. It is set + upon the session name or session id value. + +- Corrected the function nxagentFailedReconnectinDialog(). + +nxagent-1.5.0-48 + +- Solved bug that switched on the full screen state in rootless se- + ssion. + +- Changed the way dialog caption are set in rootless mode. It is set + upon the session name or session id value. + +- Corrected the function nxagentFailedReconnectinDialog(). + +nxagent-1.5.0-47 + +- Now we call NXContinueOnDisplayError() with value 1 just after + having opened the display. This will cause the NX Xlib to return + in the case of an I/O error, instead of quitting the application. + +- Removed the references to Context.h and the related elements. + +- Reflected the changes occurred in NXlib.c regarding NXDisplayErr- + ror() and inverted the logic compared to NXDisplayIsValid(). + +- Added a dialog box to notify the user when nxagent has failed to + migrate the session to the new display. Because the main X agent + connection is unavailable, this dialog uses the auxiliary nxcomp + keyboard channel. + +- Disabled the special keystroke Ctrl+Alt+S if any dialog is already + running. + +- Started implementing lazy synchronization of pixmaps. At the pre- + sent moment the implementation doesn't try to perform any optimi- + zation on the windows' regions that have to be redrawn and neither + it checks the congestion state. After having synchronized a reaso- + nable number of pixmaps, it simply sends to all the affected win- + dows an expose event, mandating the repaint of the whole area. + +- Removed a warning in Atoms.c. + +nxagent-1.5.0-46 + +- Removed the longjmp() at the time an I/O error was encountered on + the display. + +nxagent-1.5.0-45 + +- Removed UNDEFINED status for drawables. + +- Now lazy encoding affects only windows. + +- Changed the block handler to call NXTransFlush() with 'if needed'. + +nxagent-1.5.0-44 + +- After reconnection, stored exposed regions are reset and the manag- + ing of duplicate expose events is restarted. + +- Detection of window manager has been moved to the start of screen + initialization. Screen dimensions and fullscreen option are over- + ridden if no window manager is detected. + +- Added a call to XSync() in switching fullscreen function in order + to synchronize it with the network behaviour. + +- Started adding provision for deferred writes in the NX transport. + When the flush policy will be set accordingly, X data accumulated + by the proxy will be written to the network under the control of + the block and wakeup handlers. + +- Fixed a bug in nxagentCopyArea(). In some cases, pixmap drawables + was erroneusly supposed to be windows. This produced invalid reads + when trying to access to fields of WindowRec structure. + +nxagent-1.5.0-43 + +- In the code managing the property notify events, NXCollectProperty + is not called if the window is not found in the tree mantained by + the agent. + +- Changed managing of screen resize in order to avoid repeated resize + of desktop. The agent sleeps one second, then all configure event + are read from the queue and the server connection. The desktop re- + size is performed after the last read configure event. + +- Changed nxagentImportProperty() in order to use NXCollectProperty + instead of XGetWindowProperty. This avoids many round-trips in root- + less mode. + +- Fixed Invalid write problem in nxagentRRSetScreenConfig(). + +nxagent-1.5.0-42 + +- Modyfied test of NXSetUnpackGeometry for visuals, so now the compa- + rison between visuals is based on their IDs and not on the memory + area allocated for their visual structure. + +- Modified exposure managing in order to avoid duplicated refreshes. + Now only exposed regions not formerly managed yet are sent to the + clients. + +nxagent-1.5.0-41 + +- Modified nxagentCloseScreen() in order to free the frame buffer. + +- Added information of the integrity of the windows. Now the integrity + has became a drawable property that will expand in every drawable to + drawable operation. + +nxagent-1.5.0-40 + +- Splitting of images now happens only if the display is a valid con- + nection. + +- The isItTimeToYield flag is now set in the dispatcher only when the + client has been actually suspended because of a karma, a sync, or + a split operation. + +nxagent-1.5.0-39 + +- Improved the handling of the PutImage request to offer provision + for splitting images coming from orders generated by extensions. + +- Fixed a problem with clients being unexpectedly restarted instead + of waiting for the end of split. + +nxagent-1.5.0-38 + +- Added a persistent dialog when agent is running in rootless mode. + +- Modified the policy of management of nxclient dialogs. + +- Fixed memory leak problem in nxagentPutSplitImage(). + +- Modified printing of some debug messages to avoid passing a null + pointer to fprintf(). + +nxagent-1.5.0-37 + +- Implemented initial support for streaming the packed images in the + handling of the MIT-SHM extension. + +nxagent-1.5.0-36 + +- Updated the pixmap status when a placeholder is copied on the pix- + map and when the pixmap is the target of a RENDER composite opera- + tion. + +- Solved the TR05C00900. The NX transport was forced to be set when- + ever the display name contained the nx prefix. + +- Implemented the FRSA052393. Removed the compression filters applied + by nxagent to cursor pixmaps. + +- Modified RANDR implementation to make the user able to resize the + desktop by simply dragging the agent window's border. Screen resize + is made after a small timeout, to give time to the last configure + event to come from the server and avoid multiple re-configurations + of the screen. + +nxagent-1.5.0-35 + +- Added the current screen size to the set of sizes returned by the + RANDR extension. + +nxagent-1.5.0-34 + +- Corrected the placeholder xpm image. + +- Added a client dialog to notify the user that nxagent is running in + fast or in slow mode after pressing Ctrl + Alt + S. + +- Modified RANDR implementation to give a set of screen sizes. Im- + plemented functions actually performing screen resize on a RANDR + request. Now toggling to fullscreen make the desktop cover the en- + tire screen area. + +nxagent-1.5.0-33 + +- Added an auto-disconnect feature similar to the one present in the + Windows Terminal Server. The feature is modeled on the built-in X + server's screen-saver. If the agent doesn't receive any input from + the user in a given timeout, it will either terminate the session, + if no client is connected to the display, or will suspend it, so + that applications will be left running. + +- The default is to disable the auto-disconnect option. The feature + is activated by specifying a "-timeout s" parameter on the command + line, with s being the timeout in seconds. The minimum allowed ti- + meout is 60 seconds. + +- The waitpid() call now only checks the agent's own children. + +- Moved the longjmp() context declaration to a new Context.h file to + avoid clash with redefinitions by the PNG headers. + +- Few other cosmetic changes. + +nxagent-1.5.0-32 + +- Added a check on the type of the connection to avoid cleaning the + images when not needed. + +nxagent-1.5.0-31 + +- Modified the placeholder frames, now it has a left top black border + and a bottom right grey one. + +- Modified fbShmPutImage() in order to set the correct size for the + temporary pixmap. + +- Modified nxagentForceExposure() and nxagentHandleExposeEvent() in + order to clip exposed regions to the window size region of the root + window. + +- Added a new placeholder xpm image. + +- Corrected few typos. + +- Added function to synchronize GC tiles and stipples whenever those + pixmaps have been realized. + +nxagent-1.5.0-30 + +- Hidden viewport windows to clients in QueryTree request in order + to make work XDMCP properly. + +nxagent-1.5.0-29 + +- Removed some warnings with gcc 3.4. + +- Added desktop -D switch to usage. + +- Paint window background draw on framebuffer only with OpenOffice + client. + +- Now fast copy are and fast getimage are no more set according to + the link type, their default value has been set to true. + +nxagent-1.5.0-28 + +- Modified nxagentUpdateViewportFrame() in order to solve a refresh + problem. Windows composing the external frame must be always on top + to be sure that agent sends expose events for every window. + +- In rootless mode agent doesn't export anymore the properties when + disconnected from the X server. + +- Changed the way agent check if the connection with the X server + is available. Instead of using a state machine it uses the display + flag. + +- Removed the SIGTERM handling function in persistent code. We don't + need anymore those function since agent is no more sleeping when + disconnected. + +- Implemented nxagentFreePropertyList() function in order to empty the + list of exported properties when the rootless agent is disconnected. + +- Added special keystroke Ctrl + Alt + S toggling between fast and + slow mode for GetImage and CopyArea. + +- Added missing handling of down arrow key in Keystroke.c. + +- Modified nxagentForceExposure() in order to intersect exposed re- + gions with the clip region of the root window. This prevents window + functions from painting outside the frame buffer. + +- Added the field usesFrameBuffer in struct nxagentPrivClient. Modifi- + ed GC funtion and DoGetImage() in order to write in the frame buffer + only if usesFrameBuffer is True. + +- Removed code performing PutImage in the frame buffer, as it is use- + less at the moment. + +- Modified ProcChangeProperty() to check WM_NAME property. + +- Added a piece of code in nxagentOpenScreen() checking for and remo- + ving duplicated visuals. + +- Added the Dialog.c Dialog.h files. Unified all calls to NXDialog, + and blocked SIGCHLD before calling in order not to get the signal + before the child pid has been stored. + +- Modified the algorithm that disconnect the running session in + order to avoid the opening of a new dialog box for closing or + suspending the nxagent. + +nxagent-1.5.0-27 + +- Changed the disconnect/reconnect procedure in order to have a pro- + per default colormap vector when session is suspended, solving a + segmentation fault in create window function. + +- Corrected few errors in slow copy area mechanism. + +- Modified screen initialization in order to allocate memory for the + internal frame buffer. + +- Modified some GC functions for writing to and reading from the frame + buffer. + +- Modified nxagentCreateWindow() for initializing the window in the + frame buffer. + +- Modified nxagentCreateColormap() in order to use the default visual + if a matching one is not found. + +- Modified function DoGetImage() in order to call nxagentGetImage() in + place of nxagentGetDefaultImage() if fast option is on. + +- Added nxagentCheckWindowIntegrity() function verifying the matching + between the internal frame buffer and the X server for a window. + +nxagent-1.5.0-26 + +- Added the property "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR" to the list + of exported property in rootless mode, in order to let clients use + the system tray. + +- Modified import of WM_STATE properties in rootless mode in order + to better handle null resources. + +- Enhanced the slow CopyArea mechanism in case of one part of the + image is out of the X server screen or out of nxagent screen. + +- Changed type for variables width and height of default window + from 'unsigned int' to 'int'. + +nxagent-1.5.0-25 + +- Added a new signal handler for SIGCHLD. The transport is set to + forward the signal (by means of a new NX_SIGNAL_FORWARD action). + This allows the agent to wait for its own children. + +nxagent-1.5.0-24 + +- Set up the RANDR extension. When querying the configuration, the + clients get 3 sizes, the first being the current size, the second + being the maximum size of the remote display, the third being the + minimum size (arbitrarily set to 100x100 pixels). Screen sizes in + millimeters are calculated based on the size reported for the real + display. + + An example of xrandr -q output is below: + + SZ: Pixels Physical Refresh + *0 800 x 600 ( 270mm x 203mm ) + 1 100 x 100 ( 33mm x 33mm ) + 2 1400 x 1050 ( 474mm x 356mm ) + Current rotation - normal + Current reflection - none + Rotations possible - normal + Reflections possible - none + + As you can note, reflections and rotation is not possible. + +- Set up the GLX extension. This provides basic support with GLX op- + erations being translated into core X protocol primitives. + +- Moved initialization of GLX and RANDR to the Extensions.c file. + +- Removed the references to the unused mfb library. Modified Screen.c + to allocate the right privates for the fb code. + +- Modified the Xserver Imakefile to link nxagent with FbPostFbLibs + and avoid including mfb/libmfb.a. + +nxagent-1.5.0-23 + +- Fixed an incorrect buffer length calculation when retrieving a re- + mote property. + +- Added a check to avoid the use of a NULL pointer when changing the + window cursor. + +- Implemented a function to lookup the remote pixmaps. + +- Changed the RENDER initialization messages. + +- Corrected a few typos in symbol names. + +nxagent-1.5.0-22 + +- Added the nxagentNeedConnectionChange() macro. + +- Small optimizations in the block and wakeup handlers. + +nxagent-1.5.0-21 + +- NXCollectGrabPointer() is called by passing nxagentDefaultClient(). + This is a macro that checks the validity of requestingClient and, + if the pointer is NULL, defaults to NXNumberOfConnections - 1. + +nxagent-1.5.0-20 + +- Replaced all calls to XGrabPointer with the asynchronous version + provided by nxcompext. + +- In DeactivatePointerGrab() function, mouse button state is set to + up if the window entered by the pointer is the root window and the + agent is in rootless mode. This change is needed because the sub- + sequent KeyRelease event could be not received by the agent (for + example if the focus had left the window), so that agent could be + unable to update the mouse button state. + +- In rootless mode, grabs exported to X in ActivatePointerGrab() are + always made asynchronous. The synchronous behaviour is implemented + by the agent, so that requiring a further synchronous grab down to + the real X server is of little use and potentially harmful. + +- Modified function XYToWindow() in order to manage the case that + mouse pointer is located on the title bar of a top level window in + rootless mode. + +- Reflected name changes to NXImageCache variables. + +nxagent-1.5.0-19 + +- Changed the implementation of the SIGHUP handler to forward the sig- + nal to the proxy only when appropriate. This allows nxagent to close + the NX connection without having to go through an I/O error on the + display. + +- Modified nxagentBreakXConnection() to check if the NX transport is + running and thus use NXTransDestroy(). Using a simple shutdown() may + not work, for example if NX is using the memory to memory transport. + +- Added the -D option, to let users specify that agent must be run in + desktop mode. This is presently the default. + +nxagent-1.5.0-18 + +- Set the PropertyChange mask on input/output window in rootless mode + in order to get the PropertyNotify events. + +nxagent-1.5.0-17 + +- Cleaned of the reconnection routines, removed the NXAGENT_RECONNECT + macro. + +- Now the SIGHUP handler forwards the signal also to the NX transport. + +- Moved the NXTransDestroy() call in the closure of the display, so + we can avoid going through the I/O error handler. + +- Removed an invalid free in the function that closes the display. + +- Commented out more code in Display.c to avoid the segfault on exit. + +- In rootless mode, now function XYToWindow() starts search from the + last window originated an EnterNotify event. In this way, we can + prevent shaded windows from getting mouse events. + +- The variable to disable the smart scheduler is set at its definition + instead of setting it in the Dispatch function. This avoids the call + to SmartScheduleInit. + +- Changed implementation of cursor visualization in rootless mode. We + made the cursor attributes changes go transparently to the X server + while in desktop mode we ignore any client request to change the cu- + rsor on the X side, and we just set the cursor on the default window + any time the pointer cross a window border. + +- Expanded the range of properties exported on the remote Xserver, + this way we export properties whose atom name starts with "WM_" and + "_NET_". + +- In Rootless mode PropertyChangeMask is added to top level window in + order to get PropertyNotify Events. + +- First implementation in rootless mode of nxagentImportProperty fun- + ction with which after reception of PropertyNotify Events, all chan- + ging properties coming from external clients such as Window Manager + will be imported in agent windows. + +- Changed the GetEventMask function in order to handle the InputOnly + windows that need to be notified of property changes in rootless + mode. + +nxagent-1.5.0-16 + +- Implemented the -B command line switch, to let nxagent impersonate + a "pure" proxy on the NX server side (that is without X connections + having to be managed by the nxagent's dispatcher). Such a "nxagent + -B" is going to replace the corresponding nxproxy process that in + previous version of NX server was run with the same options. + +- When running nxagent in 'bind' mode the X port where the the proxy + has to listen for connection must be specified after the -B option. + The other NX options must be passed in the DISPLAY environment. + + Example: + + nxagent -B :9 + +- The initialization procedure will check that the display included + on the command line matches the one specified in the NX display + options. + + For example, given the command: + + nxagent -B :9 + + The NX options must be something like: + + DISPLAY=nx/nx,link=modem:9 + + This allows users to find out which display the agent is impersona- + ting by running a 'ps' and inspecting the command line. + +- Fixed a bug preventing the proxy's ClientMessage to reach the right + function when activating rootless mode. + +- Removed unused function nomachineLogo. + +- Code cleaning and soem optimizations in Rootless.c. + +- We want to import all properties changed by external clients to our + internal windows. But we must ignore property notify generated by + our own requests. For this purpose we implement a list to record + every change property that we dispatch. This way when processing + a property notify we can distinguish between the notify generated + by our request and those generated by an 'outside client'. + +- In rootless mode, optimized window configurations mantaining inter- + nal stacking order. + +- Fixed focus troubles in rootless mode. Now focus window is set fol- + lowing FocusIn events. + +- In rootless mode, now fake KeyRelease events on FocusOut are sent + only if keys having down state are modifiers. This prevents from + sending key events to a wrong client. + +- Removed unused function nxagentRootlessNextSibling in Rootless.c. + +- Removed unused function nxagentRootlessStackingOrder in Rootless.c. + +- Fixed compilation error if TEST log is enabled in Events.c. + +- Changed Options variables to comply with NX naming rules. + +- Some additional cosmetic changes. + +nxagent-1.5.0-15 + +- Modified functions nxagentPutImage and DoGetImage for XYPixmap fo- + rmat. + +- Completed implementation of shared memory extension. + +- Implemented a mechanism that prevents monitoring of SubStructure- + Redirect ResizeRedirect and ButtonPress events by any clients simu- + lating the presence of a window manager running inside the agent. + +- Added debug functions in order to check the status of syncroniza- + tion between the pixmaps residing on the X server and the local + framebuffer ones. + +- Changed the policy used when realizing all the pixmaps in 'lazy en- + coding' mode so that the agent now switches to 'eager' policy. + +- Fixed the routine handling the pixmaps realization: pixmaps with + an invalid id are not processed anymore. + +- Solved a bug in the routine taking care of clearing the NoMachine + logo: the state of the background was set to 'pixel' without de- + stroying an eventual backround pixmap. + +- Solved a bug in the 'MakeRootTile' function: the value returned by + 'AddResource' was not interpreted in the correct way causing the + function to bail out without drawing the NoMachine logo and set- + ting the background state to Pixmap. + +- Renamed PlaceHolder.c to Lazy.c and PlaceHolder.h to Lazy.h. + +- Inserted a test feature that cleans the framebuffer pixmaps when + they are created. + +nxagent-1.5.0-14 + +- Changed some reconnection messages. + +- Now the disconnect procedure is called also after an IO Error is + received. + +- The rootless agent now doesn't filter anymore keystrokes combina- + tion related to desktop feature, like viewport navigation the full- + screen state and minimization. + +- In rootless mode, internal stacking order is updated by comparing + the stack of top level windows mantained by the X server with the + one mantained by the agent. A global configuration of windows is + performed from top to bottom through the stack. + +- In rootless mode, map state of top level windows is kept up to date + by managing map and unmap events. + +- In rootless mode, enter events are managed to keep track of top + level window position. It is very useful for managing differences + among window manager behaviours. It should be reimplemented follo- + wing the advice given in ICCCM 4.1.5. + +- In rootless mode, requests of configure top level windows are di- + rectly forwarded to the real X server. Internal configuration is up- + dated when configure events are managed by the agent. In order to + mantain internal stacking order up to date, a query tree request is + performed on the real root window. + +- Added viewport navigation by Ctrl + Alt + keypad arrows. + +- Fixed wrong internal configuration of agent top level windows, while + agent runs in rootless mode with metacity window manager. + +- Fixed segmentation fault in nxagent running in rootless mode with + OpenOffice. + +- Fixed wrong internal stacking order of drop down menus of firefox + with nxagent in rootless mode. + +nxagent-1.5.0-13 + +- Fixed compilation problem on solaris. + +- Modified the modify pixmap header function. Previously this function + has been modified in order to solve a glyph problem, enlarging both + the pixmaps dimensions by four. Corrected the misbehaviour that + modify the pixmaps dimension even if the caller doesn't want to + change it. + +nxagent-1.5.0-12 + +- Fixed erroneous behaviour of Root Window in fullscreen mode caused by + wrong value of XSpan and YSpan. + +- Fixed wrong clients' position at Reconnection in Rootless mode, + setting offset and WinGravity fields in XsizeHints structure. + +- Fixed segmentation fault on closing windows that stay always on top. + +- Moved the handling of configure notify events in the appropriate + functions, and cleaned it. + +- In rootless mode, internal stacking order of top level windows is + mantained up to date by monitoring events from window manager top + level windows. + +- Modify the creation of screen at reconnection for detecting an + eventual failure. + +- Removed export of window properties on the X server in desktop mode. + +- Changed the events mask for client's window set on the X server. + We don't use anymore the window mask choosen by clients. In rootless + mode for a top level window we use the default event mask and for a + child only the exposure mask. + +nxagent-1.5.0-11 + +- Restored default event mask at reconnection. + +- Fixed abnormal behaviour in rootless mode if application windows are + close to the lower and right bounds of the screen. This trouble was + due to the wrong size of the agent root window. + +- Fixed abnormal behaviour in rootless mode for mouse button events if + the application window is not fully contained in the screen. + +- In rootless mode, exposed region are extended a few to take in ac- + count border width offsets caused by window managers. + +- In rootless mode, grab pointer requests from clients are forwarded + to X server. This makes application able to close their pop up win- + dows on a pointer event. + +- Fixed wrong position of the agent root window after resize of main + window. + +- Changed the size of viewport frame windows in order to avoid re- + freshing problems. + +nxagent-1.5.0-10 + +- Handled the Client messages on rootless mode. + +- Initializations of event masks have been moved in a unique group of + functions. + +- Disabled the SmartScheduler in dispatcher as it seems to affect the + responsiveness of nxagent. + +- Modified the block and wakeup handlers. We could have left data to + write to our display connection when entering in WaitForSomething() + so we now flush everything before entering the select() and let the + proxy do all the buffering. + +- Fixed the wakeup handler to match the correct prototype. + +- Few cosmetic changes. + +- Inserted a test feature that cleans the framebuffer pixmaps when + they are created. + +- Adjusted pixmap status information in almost every gc operations. + +- Removed a warning for usleep not defined on Suse 9.0. + +- Adjusted pixmap status information in copy plane operations. + +- Throwed fatal error if on lazy encoding the place holder pixmap + couldn't be loaded. + +- Removed the static path to xpm file in place holder initialization. + +- Removed useless signal handler initialization multiple times. + +- Refined validation of atoms in the atom cache code. + +- Corrected few errors in atom cache initialization. + +- Added a primitive atom cache that mantain the map between internal + and external atoms. + +- Window properties export began on the X server side in rootless + mode, this way nxagent open the communication between local clients + and the window manager on the X server. + +nxagent-1.5.0-9 + +- Fixed wrong position of the main window in case of maximizing in + window mode. + +- Set the correct scan line lenght for XYPixmap created in PutImage + and GetImage. + +- Removed a segmentation fault in GetDefaultImage. The problem arose + because the XYPixmap created with a data storage taking in account + of only some planes instead of all the depths planes. Despite XPut- + Pixel was treating the image as a complete XYPixmap of that depth. + +- Removed MapWindow Error at reconnection caused by wrong value of + IconWindow. + +- Now nxagent_WM_START is intialized as soon as the Atoms are + queried. + +- Removed Geometry restrictions. + +- Changed the configuration of the agent window in window mode. + +- The agent window is correctly reconnected even if is resized. + +nxagent-1.5.0-8 + +- Updated copyright notices. + +- Removed a segmentation fault in font cache cleaning routine. The + problem arise when the session is disconnected and the font struct + are not allocated. + +- Used the return mask of XParseGeometry to correctly set only the + parameters that are involved. + +- Unified the initialization of all the geometry related parameters. + +- Updated the offset of the four viewport frames windows at recon- + nection. + +- Changed the way the geometry parameter is used. Now the first time a + session is started it set the internal dimension of the agent root + window, afterwards it only affects the dimension of the external + window on the X server. + +- Corrected splash screen offset at reconnection in fullscreen mode. + +- Agent can be launched in fullscreen mode and his geometry can differ + from the X server geometry. + +- Now Width and Height options are used to store geometry of the + default window even on fullscreen mode, and to restore the correct + dimension when switching back to window mode from fullscreen + we added two more options. + +- Removed an error in the move viewport procedure that didn't upgrade + the offset of the internal root window when the external root win- + dow was maximized. + +- Unified the initialization of all the geometry related parameters. + +- The window manager detection procedure is now started whenever there + is an attempt to minimize the fullscreen window or to pass to window + mode. + +- Function's optimization for detecting if WM is running. + +- Switching to window mode has been disabled when the window manager + is not running. + +nxagent-1.5.0-7 + +- Now background pixel is not reset at reconnection. + +- Now geometry is parsed also as a command line parameter. + +- Fixed wrong offset of the root window after a reconnection in case + of window mode. + +- Fixed wrong geometry of the nxagent window after a reconnection + in case of window mode. + +- Fixed wrong position of the main window after a reconnection in + case of fullscreen mode. + +- Fixed refreshing windows problems in viewport navigation. Four in- + visible windows are created around the agent window to automatica- + lly generate exposure when the viewport frame is moved or a windows + come out from the non visibile part of the agent window. + +- We need to store the GC records in a list that will be freed in case + the reconnection succed and will be restored in case of failure. We + have to do this because we cannot destroy the GC records in the + disconnect or reconnect procedure, because this way we couldn't + recover from a disconnection or a reconnection failure. + +- Rewritten the reconnection procedure. Since we cannot be sure + that the reconnection will succed we cannot destroy the display + structure, so we postpone the closing of the previous display + with the creation of the new connection. + +nxagent-1.5.0-6 + +- Adjusted usage list in order to show the R parameter for rootless + mode. + +- Added handling of display parameter to option file. + Corrected few typos error, in option file parsing. + +nxagent-1.5.0-5 + +- Removed error that prevented the realization of cursor in eager + mode. + +nxagent-1.5.0-4 + +- Fixed abnormal behaviour of termination dialog, after the keystroke + Ctrl + Alt + T. + +- Fixed segmentation fault in function parsing option file. + +- Fixed various errors on eager encodings. + +- Added lazy command line switch in order to switch lazy encoding + on. + +- Code cleaning. + +- Implemented a signal to switch between two pixmap + realization policies. + +- Corrected an error while defining pixmaps status. + +- Implemented a debug feature, consisting in a method that pushes + the synchronized realization of all the pixmaps. + +- Began implementation of place holders in replacing of images while + they are being loaded. + +- Performed some changes on spreading of pixmaps status information + on copy area. + +- Began implementation of lazy encoding. + +- Changed version to 1.5.0. + +nxagent-1.5.0-3 + +- Removed the option -nogetimage (FRSA052305). + +- Code cleaning in Font.c. + +- Removed NXAGENT_FONTMATCH macro. + +- Removed NXAGENT_FONTCACHE macro. + +- Handled the ReparentNotify event we get when in rootless mode + ours window are reparented from the window manager. Inserted + fake windows to take account of this new parents. + +- Removed the redirection of client message in rootless mode, and + the configuration of the WM_PROTOCOLS properties on all the top + level windows. + +- Removed parent ID from the windows private structure. + +- Implemented screen operation ReparentWindow. + +- Redirect all client message of type WM_PROTOCOLS and value WM_DELETE- + _WINDOW to internal clients in rootless mode. + +- Set the WM_PROTOCOLS property on all the top level window. + +nxagent-1.5.0-2 + +- Changed viewport navigation, in order to make it works in fullscreen + mode. + +- Changed special keystrokes used for closing session and minimizing + fullscreen window. + +- Removed the message 'NX was unable to negotiate a cache + for this session' (FRSA052296). + +- Fixed a minor bug. It made metacity produced a warning when the agent + started up. + +- Code cleaning. + +- Implemented dynamic handling of the main window's size in the X11 + agent (FRSA052264). + +- Implemented dynamic navigation of the main window's viewport in the + X11 agent (FRSA052265). Users can navigate the viewport while keys + Ctrl + Alt are pressed, either by arrows keys or dragging it by the + pointer. + +- Implemented dynamic handling of the full-screen attribute in the + X11 agent. + +- First implementation of dynamic handling of the full-screen + attribute (FRSA052263). + +- Now the X connection descriptor is not closed when disconnected, + because the transport layer still has reference to it. So we want + it busy till we don't close the display, so we shutdown it instead + of closing it. + +- Removed replys when disconnected. + +- Added the X connection number to the set of enabled input devices, at + reconnection. + +- Rewritten the disconnect/reconnect layout. + +- Now in the suspend status nxagent doesn't sleep. + +- Implementing toggle fullscreen special keys. + +nxagent-1.5.0-1 + +- Opened the 1.5.0 branch. + +nxagent-1.4.1-7 + +- Imported changes from nxagent-1.4.0-64 version. + +nxagent-1.4.1-6 + +- Implemented a GC cache for reconnecting pixmap. + +nxagent-1.4.1-5 + +- Handled the situation of disconnect when the pointer has been grabbed. + We disconnect and reconnect the "grabbing" cursor and after reconnection + we fake a button release in order to let client know that the pointer + button has in effect been released. + +- Code cleanup. + +nxagent-1.4.1-4 + +- Imported changes from nxagent-1.4.0-63 version. + +nxagent-1.4.1-3 + +- Imported changes from nxagent-1.4.0-62 version. + +nxagent-1.4.1-2 + +- Cleaned code in the GC reconnection area. + Scratchs GC are now reconnected before of the pixmaps. + +nxagent-1.4.1-1 + +- Opened the 1.4.1 branch. + +nxagent-1.4.0-65 + +- Cosmetic changes to the diagnostic output. + +nxagent-1.4.0-64 + +- Changed the RENDER version advertised to X clients to be the lowest + value between the version of RENDER of nxagent and of the remote X + server. + +- Disabled fast copy area and fast get image flags, if RENDER extension + is not available. + +- At the screen initialization, if we don't have window manager we + grab keyboard to let nxagent get keyboard events. + +- Completely rewritted the handling of KeyPress events, now we moved + all the test for 'special' keybindings in file keystroke.c. Added the + combination MOD1/2-CTRL-SHIFT- for terminate/suspend the session, + we used the combination MOD1/2 in order to let it work even on MacOS + where Alt(MOD1) doesn't seem to be set. + +- Ignored visibility notify events on the icon windows, that were + messing up the agent visibility state. + +- Changed nxagent reaction on VisibilityNotify event. It fixed the + problem with refresh session under Mac OS X with NXDarwin. + +nxagent-1.4.0-63 + +- Reset the congestion state at transport initialization. + +nxagent-1.4.0-62 + +- Fixed the disconnection and reconnection of window that have attached + an animated cursor. + +nxagent-1.4.0-61 + +- Removed the XInputExtension initialization in order to use the more + general mi extension initialization enabled on new mi version. + +- Removed some useless test and logging info on copy area function. + +nxagent-1.4.0-60 + +- Changed the implementation of CopyArea and CopyPlane. + If both drawables are on framebuffer we send NoExpose to clients, + otherwise we use the mi function HandleExposure to calculate the + region to be exposed instead of let mi redo all the copy operation. + +nxagent-1.4.0-59 + +- Disabled use of caching and cleaning of images, if NX transport is + not used. + +nxagent-1.4.0-58 + +- Added timeout on convert selection operation. If timeout has not + expired and is there a pending operation any new request is dropped + and the client notified, until timeout expiration. + +- Corrected a bug that prevented to correctly store last convert se- + lection request time. + +nxagent-1.4.0-57 + +- The Xinput extension is now initialized at startup. This is of + little use because nxagent only needs to support the core pointer + and keyboard. Anyway this allows nxagent to get rid of the warn- + ings printed by some X clients on recent Linux versions when the + extension is not found. + +nxagent-1.4.0-56 + +- Fixed value returned by ConvertSelection. It was the cause of + possible slowndowns during KDE sessions. + +nxagent-1.4.0-55 + +- Agent icon now is loaded from a binary- + embedded Xpm image, if any attempt to + load the default Xpm file from the image + directory or from the path fails. + Removed code used in the old logo drawing + function. + +nxagent-1.4.0-54 + +- Enabled code for sending to client graphics + exposures. Redirecting the ones coming from + remote X server, only if agent window is not + fully visible, and calculating ourselves failure + in CopyArea/Plane and notifying clients. + The only drawback is that we can have double + refresh effect if agent window is covered. + +NOTE: Partially enabled MIT-SHM extension has + been developed but has not been included + in stable release. Included in version + nxagent-1.4.0-53-DAR1. + +nxagent-1.4.0-53 + +- Implemented a reliable technic to detect + if is there any window manager running on + the X server. + +nxagent-1.4.0-52 + +- Fixed a bug that prevented to correctly + notify the client of a successfull convert + selection. + +nxagent-1.4.0-51 + +- Removed a logging error in render initialization. + +nxagent-1.4.0-50 + +- Now we take the ownership of the selection + on "NX_CUT_BUFFER_SERVER" twice, in order + to solve bug in communication with nxclient + to let him see our main window and know that + agent established connection with X server. + +nxagent-1.4.0-49 + +- Fixed the colormask layout of the visual + used to put images on the real X server when + the drawable has an alpha channel, according + to the endianess of the X server. + +nxagent-1.4.0-48 + +- Moved up the render compatibility limit, + due to the inclusion of the support for render + cursor missing on the 0.2 version. + +nxagent-1.4.0-47 + +- Changing artsd forwarding port from display + + 8000 to display + 7000 + +- Stoping key release event if key press was + catched before. For Alt-F2/F4 combination. + +- Preserved the alpha data on drawables that + are not used by picture but have a depth of 32. + +nxagent-1.4.0-46 + +- Rewritten all the code regarding to the + acceleration for the Render creation of the + cursor, and removed the acceleration for + the animated cursor. + +nxagent-1.4.0-45 + +- The two RENDER operations creating cursors and + animated cursors have been accelerated by for- + warding the original operation to the X server. + +nxagent-1.4.0-44 + +- Fixed a problem in the clipboard procedure. + Now when we get a request of the selection + from an internal client we have to, if the + owner is on the X server, forward the request + to X, otherwise we have to pass the request + to our internal client. + But for a problem in this procedure we passed, + in some situation, the request to the internal + client even if the owner was on the other side. + +- Fixed a segmentation problem in the render + extension by removing composite trapezoid + operation on window. + +nxagent-1.4.0-43 + +- Added some pointer sanity check in the discon- + nect procedure. The problem was arising because + we were executing the code twice when after + began a voluntar disconnection the X connect- + ion was broken for a network failure. + +- Changed directory where nxagent gets the icon. + +- Fixed missing implementation of rendering + trapezoids. + +- Fixed bug in render extension when the nxagent + create cursor diffrent then 32 bits format. + +nxagent-1.4.0-42 + +- Solved segmentation fault, caused by a longjmp + on a stack context not previously saved. + +nxagent-1.4.0-41 + +- Added an exposures of the window in a resize + operation. + +nxagent-1.4.0-40 + +- Implemented a timeout on the opening of the X + display, if we get it we reject all well known + sockets. + +nxagent-1.4.0-39 + +- Corrected minor error on events handling. + +nxagent-1.4.0-38 + +- Removed in the resize window code some exposure + that generated useless traffic. + +- Option geometry is no more parsed in the option + file. + +nxagent-1.4.0-37 + +- When session is suspended and we get TERM signal + nxagent just exit instead of just breaking out of + dispatch loop because we get a terminate exception. + Cleared display variable after having closed the + connection with the X server. + +nxagent-1.4.0-36 + +- Refined some details in the ICC with nxclient. + +nxagent-1.4.0-35 + +- Implemented a new method to comunicate to nxclient, + the raise of the agent root window, taking the ownership + of the selection "A-{MD5 of session}". + Used the same selection to let nxclient comunicate to agent + by changing the property on the same string, when the user + choose by the administrator to terminate or suspend the + session. + +nxagent-1.4.0-34 + +- Key sequence to Suspend/Terminate session (Alt-F4). + +- Key sequence to Minimize session in fullscreen mode (Alt-F2). + +- Check if WM is started, for Alt-F2 sequence. + +- Corrected calculation geometry of exposed region + sent to client after reconnection. + This solve a serious memory leak of nxagent. + +- Fixed a bug in validate GC code that passed + a wrong pointer of tile to framebuffer. + +nxagent-1.4.0-33 + +- Changed the reconnection state machine in order + to let agent exit if has got the TERM signal. + +nxagent-1.4.0-32 + +- Fixed memory leak in option parser that wasted + memory if more than one occurence of 'option' + argument would have been parsed. + +- Removed a invalid read in Keyboard initialization. + Now kbtype option value is copyed instead that + referenced. + +- The X connection number is recorded only after + having cheched for display being successfully opened. + +nxagent-1.4.0-31 + +- Fixed memory leak problem caused by region not + beeing destroyed previously. + +- Fixed a memory leak in keyboard initialization. + +- Fixed a bug in the function that parse the option file, + we were reading the options in the format NAME=VALUE and + were passing it to the argument parser in the format + {NAME, VALUE}, without the prepending '-' in front of NAME. + +nxagent-1.4.0-30 + +- Readded option persistent in order to let nxagent + works with older nxserver that are still launching + nxagent with the persistent option. + +nxagent-1.4.0-29 + +- Corrected the message of the client dialog + asking if user want to suspend or terminate the + session. + +- Chenged the default value for persistence of session + in nxagent to true. Change the persistent option to + nopersistent in order to disable it. + +nxagent-1.4.0-28 + +- Added check on screen initialization of possible + memory allocation failure. + +- Changed the parsing policies of the option file. + Now we are just considering kbtype and geometry + options. + +- Removed testing code that forced rootless mode + when geometry is 100X100. + +- Correctly initialized and mapped the icon window + on fullscreen mode. + +nxagent-1.4.0-27 + +- Fixed lost memory problem caused by second + initialization of screen privates. Screen + privates is already initialized by miScreenInit + function. + +nxagent-1.4.0-26 + +- Added option command line option. This parameter + is used to show complete path to option file. + +- Added parser of the option file. + +- Now default value for fast copy area and fast + getimage is true. + +nxagent-1.4.0-25 + +- Done some cleanup to the initialization of the + defaults drawables at reconnection, and removed + a memory leak in the reopening of the Display. + +nxagent-1.4.0-24 + +- Changed the version number, printed at startup. + +- Removed a memory leak in the font reconnection stage. + +nxagent-1.4.0-23 + +- Removed a bug that messed up the render status info + if reconnected to a display with no render support. + Anyway nxserver should prevent agent to trying reconn- + ecting to such display. + +nxagent-1.4.0-22 + +- Enhanced the reconnection error reporting function. + +nxagent-1.4.0-21 + +- Get the ownership of selection NX_CUT_BUFFER_SERVER at reconnection + in order to let client knows that agent windows has started + successfully. + +nxagent-1.4.0-20 + +- Now we draw splash logo at reconnection. And destroy it and show + all other windows when reconnection has done all in once. We draw + it on default window instead that on root window, and we map root + window when reconnection has finished. + +nxagent-1.4.0-19 + +- Removed the old Xconnection descriptor and added the new one + to the device set, instead of resetting the entire enabled + device set, at reconnection. + +nxagent-1.4.0-18 + +- Reset the enabled devices set of descriptors, and properly + add to this set the the Xconnection descriptor. + +NOTE: This solves all the known solaris reconnection problems. + (The problem appear only on solaris because on this machine + the Xconnection descriptor is changing at reconnection.) + +nxagent-1.4.0-17 + +- Restored the previously owned primary selection, at reconnection. + Removed the handling of the return value of XSetSelectionOwner, + man page doesn't specify any return value. + +nxagent-1.4.0-16 + +- Added compatibility with older windows clients(Xserver) + that send a WM_DELETE_WINDOW client message WM_DELETE_WINDOW + to all top level window and so agent show more than one + NXDialog asking for confirmation, instead of sending just the + message to top level window that are visible and haven't set + the override redirect option. + +nxagent-1.4.0-15 + +- Ignored unmatched DirectColor visuals at reconnection + on a different display not providing it. + +nxagent-1.4.0-14 + +- Moved the render query extension in display + initialization from screen initialization. + +- Changed reconnection policy to disallow reconnect a + session that is using render to a server not providing it. + +nxagent-1.4.0-13 + +- Unified the screen opening function. + +- Changed the reconnection requirements + policy about geometry of X server. + Now agent doesn't accept changes of X server + root window size only if in fullscreen mode. + +nxagent-1.4.0-12 + +- Improved failure notification messagges in Display and + font code. + +nxagent-1.4.0-11 + +- Now visuals are properly recreated, in order to reconnect + to another X server. + +- Updated render formats at reconnection. + +nxagent-1.4.0-10 + +- Removed a serious memory leak at reconnection. + +nxagent-1.4.0-9 + +- Added after window reconnection the redisplay of the current + cursor. Done some general cleanup at cursor reconnection code. + +nxagent-1.4.0-8 + +- Unified tha atom creation at reconnect. + +nxagent-1.4.0-7 + +- Dix layer when creating a GC use a default real pixmap as + stipple but agent need a virtual one. This can cause + segmentation fault to agent if is there any apps that use the + default GC stipple created by dix, without changing it. + +nxagent-1.4.0-6 + +- Imported 1.4.0-1-DAR6 from the 1.4.0 development branch. + +- Handled reconnection of window's cursor still not + reconnected at window reconnection. (This because that cursor + is no more a server[nxagent] resource). + +- Set the last image client variable at reconnection in order + to use the visual cache indexed for client number. + Without this we could get a segmentation fault. + +- Handled properly the reconnection of animated cursor. + Modified the procedure of animated cursor creation + in order to empty some unused fields. + +- Removed a 4 bytes memory leak at reconnection. + +- Synced new tree with nxagent-1.3.2-23. + +- Finished the unify of PutImage at reconnection. + Added a Reconnection Trap in order to let screen functions + (like PutImage) knows that are working at reconnection time + and can behave differently. + +- Unified the code for the normal PutImage and the one's used at + reconnection. But the code that calculate the split is still + doubled. + +nxagent-1.4.0-5 + +- Imported 1.3.2-23 from the 1.3.2 development branch, and dropped + the previous 1.4.0 versions. + +nxagent-1.3.2-23 + +- Pixel hints are set according to the display's depth. Added the + defaults to be used on 16 bits. + +nxagent-1.3.2-22 + +- The pixel hint on Solaris is by default 0xffffff. The value can be + overridden by using the -hint option followed by the hex represen- + tation of the color, as in -hint 0xaabbcc. + +nxagent-1.3.2-21 + +- Asynchronous GetImages are now disabled. If fast GetImage mode is + enabled, agent will always try to guess the pixel to be used for + the solid pattern, based, at its best, on the geometry of the pro- + vided area. This behaviour can be overridden by passing the -slow + parameter on the command line. Slow mode is also the default when + selecting WAN or LAN link settings. + +- Code cleanup in preparation of the final release. + +nxagent-1.3.2-20 + +- New code uses sigaction to set the SIGHUP handler in persistent + mode. Contrarily to signal(), the sigaction call doesn't seem to + reset the handler to SIG_DFL after the signal has been caught. + This problem seems to be specific of Solaris. + +- Client messages of type WM_PROTOCOLS are now handled even when + a window manager is not detected at agent startup. + +- Removed handling of GraphicsExposure coming fron the real server. + Agent will still generate events in the MI. Code dealing with the + remote events needs to be better tuned as it seems to cause some + troubles with double refreshes. + +nxagent-1.3.2-19 + +- Starting from this version agent doens't use NXSync and NXKarma + messages to manage bandwidth arbitration among clients but makes + efficient use of the congestion notification messages introduced + in 1.3.1. A new handler has been added to manage the congestion + state. The handler will block, if needed, waiting for the decon- + gestion notification coming from proxy. + +nxagent-1.3.2-18 + +- Rewritten the block handlers to check the event queue more often. + The new code seems to greatly enhance responsiveness, especially + on fast links. + +- Now agent will handle the expose events coming from the remote + display inside the event dispatcher. + +- Created a new function collecting the expose events. Function is + optimized to add all the expose events for the same window to a + single region. Region is passed to the mi when the last event + has been processed. + +- Still dealing with GetImage from OpenOffice. Now we try to match + the geometry of the incoming requests with known geometry of most + of its graphic elements. It seem to work on Fedora. + +nxagent-1.3.2-17 + +- Added swapping of image data in nxagentGetImage() when connecting + to a display having a different image byte order than the agent + server. + +- Added a new nxagentImageReformat() function in GCOps.c. + +- Now agent will not try to pack images having a data size smaller + than 768 bytes. The previous threshold was set to 64. The Mandrake + vesion of KDE seems to send lot of such small images. Compressed + through JPEG, these images obtain a very poor ratio of nearly 1:1. + +- Added a function translating and sending the GraphicsExposures + events received from the remote server to the agent's clients. + +- Renamed the functions providing the ad-hoc handling of remote X + events. + +nxagent-1.3.2-16 + +- Implemented a cache for the alpha channel data. With clients + making heavy use of the alpha blending, the new cache is able to + cut by nearly 30% the traffic incoming to proxy, offering compara- + ble savings in CPU performance. While proxy is usually able to + cache almost all the alpha traffic, when caching is not enabled + (f.e. when link setting is WAN or LAN) this data is sent uncomp- + ressed by the agent. Tests running common desktop environments + showed that alpha channel could weight up to 2 times the corres- + ponding data generated by the packed images. + +- Fixed the compilation warnings in NXrender.c. + +nxagent-1.3.2-15 + +- Rewritten handling of GetImage from dispatcher down to GCOps. If + the fast GetImage mode is enabled agent will use the asynchronous + calls provided by nxcompext to get data from the real server. Data + collected from the last get image performed is preserved and the + upper left pixel is used to guess a solid background. + +- Added a nxagentGetBackgroundImage() function to apply a similar + mechanism when the nxagent window isn't fully visible. Previously + a solid white background was returned. The new handling seems to + correctly match the window background in most cases. + +- Fixed a problem passing the bytes per line value when creating a + XYPixmap image. The previously calculated value didn't take into + account the depth of the image. + +- Now image's bytes per line, length and visual are calculated by + using a few utility functions added to GCOps.c. + +- Added declaration of the nxagentVisibility related variables to + Window.h. + +nxagent-1.3.2-14 + +- On Fedora xbcomp configuration fails when agent is run nested. + This causes keyboard to ignore most AltGr keys. Strangely enough + this behaviour has been observed only with KDE while GNOME does + not seem to be affected. Reason is to be investigated. + +- Auto-repeat mode of the agent's keyboard device is now always + disabled. Agent will leverage auto-repeated keystrokes genera- + ted on the real server even when propagating device configura- + tion changes. + +- The info output telling if agent will propagate the changes to + devices' setting is now printed after having initialized the + screen. The purpose would be to verify if agent is running in + fullscreen mode and there is no WM on the real display. In this + case we should forcibly propagate device configuration changes. + Unfortunately, due to the way intern atoms are collected, this + is not going to work on platforms where sessions are likely to + run on an existing X server. + +nxagent-1.3.2-13 + +- Fixed a problem with XYPixmaps being used in PutImage with the + wrong left pad. This is a step forward in the solution of the + corrupted masks displayed by Mozilla when showing some animated + GIFs. + +- By selecting 'fast' mode nxagent will now skip real XGetImage + operations on windows. This becomes the default in the case of + MODEM, ISDN and ADSL links. In theory X clients should never do + that. In practice a few naive programs and libraries (like, sur- + prisingly enough, a famous Linux office automation suite) do, + mainly to compose images with the window's backgound. Why don't + they compose content into a Pixmap? + +- Improved the implementation of CompositeGlyphs. It now uses a + single call to XRenderCompositeText instead of splitting the + output in multiple RENDER requests. + +- In previous versions file NXmiwindow.o was not linked into the + resulting nxagent. This solves the problem of missing repaints + in CDE and other Xt applications. Be sure you upgrade nx-X11 + to version nx-X11-1.3.2-2. + +- Added a warning when the change keyboard control or the change + pointer control functions are called. + +nxagent-1.3.2-12 + +- Added bit-swapping of glyphs having depth 1 when agent has a + different bitmap-bit-order than the X server. + +- The KeyRelease event's timestamp calculation, accounting for + differences in time between the local and the remote machine, + will now use the timestamp taken from the last KeyPress. Using + the timestamp of the last event was sometimes causing time to + go backward with the result that server could remain grabbed. + This solves the long-standing "mouse stop responding" problem. + +- Fixed a problem handling the alpha channeled visual introduced + while experimenting with the new server endianess layout. + +nxagent-1.3.2-11 + +- Added the Reset option to options repository. By default agent + will skip server reset when the last client disconnects. This is + equivalent to passing the -noreset option to a standard XFree86 + server. To restore the original behaviour the new -reset option + can be used on the command line. + +- Moved the SharedMemory and DeviceControl options to the options + repository. + +- A basic session, still leveraging all the default facilities, can + now be run as: nxagent -name NX -geometry 800x600+10+100 :1. The + -fp unix/:7100 option can be added to enable access to the X font + server. + +- Fixed a "unused variable" warning in Cursor.c. + +nxagent-1.3.2-10 + +- Rootless mode. Some cleanup in initialization. + +- Rootless mode. Working at the configure-window errors. + +nxagent-1.3.2-9 + +- Removed limitations when running nxagent nested inside another + nxagent server. Now both render extension and packing of images + are enabled. + +- The nxagent X server now inherits its endianess from the host + architecture, instead of assuming the same endianess of the con- + necting client. This fixes the remaining problems running ses- + sions nested inside another nxagent server. + +- Removed any reference to ReformatImage(). + +nxagent-1.3.2-8 + +- Changed the way the agent server handles images internally. + The inherited Xnest code used to set the server's image order + to the same order of the remote X display. This caused agent + to create images in the internal frame-buffer with a different + endianess in respect to images got from X clients. + +- The new image handling code seems to solve all the known image + endianess problems, for example cursors created on big-endian + displays with a wrong shape or glyphs being showed flipped when + retrieving the image data from the virtual frame-buffer. + +- As an added bonus the new code seems to double the performance + of the SPARC Solaris server when accessing i386 clients. + +- Commented out all the existing calls to ReformatImage(). Code + needs now extensive testing to see if any of the calls must be + actually restored. + +- Replaced calls to index() with strchr(). + +nxagent-1.3.2-7 + +- Solved a potential memory error when accessing a client or a + window pointer in clipboard management code after the resources + had been destroyed. Added a nxagentClearClipboard() function to + be called before a client or a window is destroyed to get rid + of any reference to the disposed resources. + +- Auto-repeated keystrokes generated by agent from inside the + virtual keyboard device are now ignored. Agent will correctly + honor auto-repeated keystrokes generated by the real X server. + This is actually the expected behaviour. The former implemen- + tation triggered an annoying bug, with keystrokes being inad- + vertedly auto-repeated in the case of high latency on the + network link. + +- Agent will now ignore the pointer settings changes generated + inside the remote session. The original behaviour was to reset + the pointer values (for example acceleration) to the X factory + settings at session startup. Agent will now inherit whatever + values are set on the real X display. + +- Added a -noignore parameter. When passed, agent will propagate + to the real X server any change to keyboard and pointer control + settings operated by its own X clients. + +nxagent-1.3.2-6 + +- Fixed problem with glyphs being drawn clipped in the virtual + frame buffer. This is not yet the final solution but it seems + to work in all the circumstances where problem was observed + in the past. Problem seems to be caused by scratch pixmaps + being requested with a width and height smaller than actually + required. Note anyway that pixmap's buffer seems to be never + accessed beyond its boundary. This probably means that memory + for the pixmap is originally allocated using the right size. + +- Moved backing-store selection to options repository. Now by + default the backing-store mode is set to WhenRequested. This + means that, in most cases, there is no need to pass the -bs + option on the command line. + +- Code cleanup in Render.c, NXrender.c, NXglyph.c. + +nxagent-1.3.2-5 + +- Fixed initialization of all the supported depths. Previous + versions correctly initialized the various depths but still + failed to advertise the support of any other depth than the + default depth supported by the remote X server. + +- Persistent mode. We now correctly propagate the pixmap ID of + the parent to the virtual pixmap at reconnection. This fixes + the reconnection errors when render extension is enabled. + +- Persistent mode. Solved the refresh problems at reconnection. + Problems were generated by the lack of window parent's ID at + the time session was reconnected. + +- Changed the agent's behaviour at the time the close button is + pressed. If agent is running in persistent mode a new dialog + is showed with the option to suspend the session. + +nxagent-1.3.2-4 + +- Persistent mode. At the time the proxy connection is reset the + per-client unpack geometry information is cleared. This makes + agent find out that a new unpack geometry is needed as soon as + the display is reconnected. + +- Persistent mode. Lot of logging added in order to trace use of + resources as long as they are recreated. The current version + fails to correctly restore the picture information when render + is enabled. + +nxagent-1.3.2-3 + +- Finally fixed all the problems with missing initialization of + pixmap formats. The screen info is now correctly set up even + when the remote display doesn't support all the target depths. + Many thanks to Michael L Torrie who helped me to reproduce the + problem and come to a solution. + +- Moved initialization of depths, default drawables and pixmap + formats to their own functions in Display.c. + +nxagent-1.3.2-2 + +- Fixed the nxagentDestroyPixmap() function to correctly take into + account the reference counter of the virtual pixmaps. This solves + the crashes observed when running some GTK clients like xchat. + +- Added a function Pixmap.c to forcibly destroy the pixmaps created + in the virtual framebuffer when the parent pixmap is destroyed. + +- This version contains some verbose output intended to better test + the new behaviour. The output will be removed in future versions. + +nxagent-1.3.2-1 + +- More cleanup in Pixmap.c. + +- Rewritten nxagentCreatePixmap(). Corrected an error where the + bitsPerPixel field was set to the pixmap's depth instead of the + result of BitsPerPixel(depth). This finally solves the problem + of text being incorrectly rendered in the virtual framebuffer. + +- Corrected the X error returned at the end of session when trying + to free a pixmap with an invalid id. + +- Opened the 1.3.2 branch. + +nxagent-1.3.1-32 + +- Cleanup of Pixmap.h/Pixmap.c. Renamed macros according to the + nxagent naming conventions. + +nxagent-1.3.1-31 + +- When running in fullscreen mode, grab and ungrab of pointer and + keyboard is performed in new functions, placed in Events.c. + +- The event loop now checks if the enter/leave notify carries a + NotifyInferior detail and, in this case, doesn't perform the grab. + This saves half the amount of grabs (and the related roundtrips) + performed by the previous version. + +- Ungrab of pointer is now performed whenever the cursor leaves the + fullscreen window. In previous version only the keyboard was + explicitly ungrabbed. + +- Added a warning in the event loop when receiving a MappingNotify. + This event is presently unhandled and seems to be reported, as a + consequence of the selected event mask, only by some X servers. + +nxagent-1.3.1-30 + +- Reverted the patch introduced in Pixmap.c. The whole issue is + being investigated in its ramifications up to the virtual frame + buffer. + +nxagent-1.3.1-29 + +- Fixed a problem in the nxagentDestroyPixmap function where the + reference counter of pixmaps could be decremented twice. This + could lead to agent trying to free the pixmaps more than once. + +- On Solaris there is no description for pc105 keyboard model. As + a workaround we consider pc104 to be the closest approximation. + +nxagent-1.3.1-28 + +- Fixed a bug in the create window procedure. With some clients, + like Maelstrom and xmame, the creation of the main window was + failing due to the wrong colormap and visual attributes used + by agent on the real X server. + +- In fullscreen mode the keyboard is now grabbed at the time we + receive an EnterNotify event. This fixes a problem at startup + observed on some Debian based distributions where agent didn't + receive the keyboard focus until user had minimized and then + brought to front the agent's window. The grab is now correctly + performed by using the timestamp of the remote X server ins- + tead of our local timestamp. + +- In NXdixfonts.c strings corresponding to names of fonts and + font aliases cached by nxagent were missing the terminating + zero. + +- In function InitClientPrivates fixed the missing initializa- + tion of the is_ignored member of the ClientPriv structure. + +- Added the Persistent option to Options repository. The flag is + intended to replace the old nxagentEnableReconnect variable. + +nxagent-1.3.1-27 + +- Fixed a memory allocation problem in Keyboard.c. A string was + allocated in the heap without making enough room for the trail- + ing zero. + +nxagent-1.3.1-26 + +- Added further run-time checks to verify that pixmaps are not + created with bad bit-per-plane settings. This problem seems to + be caused by lack of support by nxagent of some combinations + of depth and visual when the render extension is enabled. If + this is the case, hide the render extension to new clients and + force any subsequent render operation to return a BadRequest + error. This required including extension.c from dix. A new + NXextension.c file is added to the distribution. + +- A problem was reported by Valgrind about reading the first 4 + bytes just after the block allocated in fbCreatePixmap from + nxagentCreatePixmap. A quick fix was added to pixmap.c from + dix so that AllocatePixmap adds 4 additinal bytes to each + buffer. + +nxagent-1.3.1-25 + +- Fixed a memory corruption error. The original AllocateGlyphSet + from render/glyph.c could be called instead of the NX counter- + part defined in NXglyph.c. This could lead to the missing + allocation of the trailing remote glyphset id field. + +- Added initialization of an otherwise usused string in function + nxagentPropagateArtsdProperties(). The whole string is probably + to be removed in future versions. + +- Moved the flag used to avoid reentrancy in GCOps to a separate + Trap header and source. + +- Further cleanup. Removed the zombie file NXglyphcurs.h. + +- Added missing initialization of the picture pointer in private + window's data in nxagentCreateWindow. + +nxagent-1.3.1-24 + +- Added the missing timeout when calling WaitForSomething() at + startup. The bug caused the splash to remain on screen until + a further event was received. + +- Fixed a BadAtom error on Windows during initialization. Error + was caused by a bad attempt to change the NX_AGENT_SIGNATURE. + +- Hunting the 0 bits-per-plane drawable bug in nxagentValidateGC. + Added tracing output and additional checks. GC validation is + skipped if it is not possible to recover an appropriate value. + +- Ensured that nxagentDisplayName is set before calling the post + initialization procedure. + +nxagent-1.3.1-23 + +- When session is run nested inside another NX X agent, all the + optimizations regarding remote expose events on fully visible + windows are disabled. This solves the refresh problems encoun- + tered when covering the nested session with a window from the + local X server. + +- Reusing NX_AGENT_SIGNATURE atom to detect nested operation. + Atom is created internally to the agent server at startup, + before any atom on the real display. + +- Fixed construction of caption used for dialog boxes spawn by + agent. The previous algorithm failed to identify the correct + string in parameter -name passed on the command line. + +nxagent-1.3.1-22 + +- Ensured that state of keyboard modifiers is initialized with + values from the real X server when the first key stroke is + pressed by the user. + +- Fixed the X_SetInputFocus errors generated at session startup. + +- Rootless mode. Ensured that remote expose events are always + reported by the remote proxy. This is a temporary fix looking + forward for better handling of visibility events. + +nxagent-1.3.1-21 + +- Saved a GetWindowAttributes and a GetGeometry in the function + drawing the splash screen. + +- Better handling of splash at startup. Removed the flickering on + Windows without recurring to another atom. This is achieved by + optimizing drawing and delaying mapping of the main windows. + +- Modified the magic values activating rootless mode to 100x100. + +- Removed modifications introduced in 1.3.1-20. + +nxagent-1.3.1-20 + +- Working on eliminating the splash screen flickering on Windows + and Darwin. Checked if the NX_SPLASH atom has been created by + the NX X server. If this is the case, we let the NX X server + show the splash screen on our behalf. + +nxagent-1.3.1-19 + +- Improved the initialization phase by removing a GetProperty, an + InternAtom and two GetInputFocus round-trips. + +- Added appropriate masking of the state bits reported by the + XkbStateNotifyMask event. + +- Added a simple mechanism during the itialization phase to trace + the use of X server replies. + +nxagent-1.3.1-18 + +- Made some order in functions loading the NX icon. + +- Removed some more zombie files from agent distribution. Now only + the files imported from DIX and MI have name prepended with NX. + +nxagent-1.3.1-17 + +- Moved names and values of intern atoms created by agent in their + specific header and source. + +- We temporarily force rootless mode if user provides a geometry + of 801x601. This is intended to simplify testing. Note that if + rootless is selected, we'll anyway disregard any geometry set + by the user, assuming the geometry of the real display. + +nxagent-1.3.1-16 + +- We are checking now whether NX_IDENTITY intern atom is created + before NX_SPLASH. We want NX X servers to show the splash on our + behalf, so if NX_SPLASH is already interned, than we just skip + the splash procedure. + +nxagent-1.3.1-15 + +- Rootless mode. Fixed a segfault handling ConfigureNotify events + on top-level windows. + +- Moved handling of ClientMessages coming from proxy in a separate + function. + +nxagent-1.3.1-14 + +- Rewritten the code dealing with key modifier changes. Now we + use XKB events instead of synchronous XkbGetIndicatorState() + calls. + +- Moved activation of keyboard and pointer events to Events.c. + +- Removed pointer motion optimizations as a better logic, taking + in account the selected link speed, is already implemented in + proxy. + +nxagent-1.3.1-13 + +- Renamed the -reconnect option as -persistent. + +- Rootless mode. Agent's root windows are not mapped at startup. + +- Removed the zombie file glyphcurs.c from agent distribution. + +nxagent-1.3.1-12 + +- Corrected a typo in the new CopyArea code in GCOps.c where: + + if (srcx > nxagentWidth) srcx = nxagentWidth; + if (srcy > nxagentHeight) srcx = nxagentHeight; + + had to be: + + if (srcx > nxagentWidth) srcx = nxagentWidth; + if (srcy > nxagentHeight) srcy = nxagentHeight; + +- Added handling of the fullscreen command line parameter to the + options repository. + +- Added agent geometry parameters to the options repository. + +nxagent-1.3.1-11 + +- Rootless mode. Added handling of configuration events reported + for the top-level windows. + +- Rootless mode. Children of the root window get the event mask + selected when the window is created. This makes the keyboard + work at least with xterm and other simple clients. There are + still problems with the pointer events. + +- Created new Splash.h and Splash.c sources file to contain the + few splash screen procedures that were previously sparsed in + multiple files. + +- Added traces in all the window creation procedures and in the + initialization routines called at startup. + +- Renamed some source files to make simpler to identify what is + imported from DIX and what actually pertains to agent. + +nxagent-1.3.1-10 + +- Added the missing RestackWindow screen operation. This solves + problems of incorrect stacking order observed in menus when + using the drop shadow feature in the latest KDE versions. + +nxagent-1.3.1-9 + +- The new standard for checking previous inclusion of headers is + by verifying definition of _Filename_H_ where Filename is the + base name of the file, for example __Options_H__ in the case + of "Options.h". This is intended to be a step in reducing the + number of defines in code prefixed with NXAGENT. + +- Updated NX copyright to year 2004. Placed copyright statement + regarding NXAGENT and NX modifications to the Xnest software + at the beginning of the file. Checked again if credit is given + to all the existing copyright owners. + +nxagent-1.3.1-8 + +- Added a new Options repository to store the values currently + dispersed all over around. The new macros nxagentOption(option) + and nxagentChangeOption(option, value) should be used from now + on to access the important values affecting agent's operations. + +- General cleanup of code. Removed the remaining references to + the Xnest legacy code. + +nxagent-1.3.1-7 + +- Some steps forward toward rootless agent. Now all the top level + windows are correctly created. Drawing to the real screen seems + to work without problems. It is still not possible to get events + in the event loop and the remote WM is interfering with the WM + on the local display. + +- More cleanup of code. Some changes to parts added since 1.3.1-5. + +nxagent-1.3.1-6 + +- A drawable with 0 bpp can somehow arrive to the fb layer. The + problem needs to be better investigated. In the meanwhile a + quick check is added to correctly identify the ill condition. + +- Small fix to allow Num/Caps lock synchronization also on the + windows platform. This is still to be considered beta quality. + +- New options -slow and -fast added to agent. When "fast mode" is + not set, agent will query the remote X server to get real content + of drawables. When fast mode is enabled, agent will save the + round-trip by just clearing the drawable to its background. The + default mode is "slow", thus agent will always query the remote + server. When "fast mode" is explicitly set or when NX transport + is detected and the link is one of MODEM, ISDN and ADSL, agent + will default to "fast mode". This behaviour can be overridden by + system administrators by setting the key AGENT_EXTRA_OPTIONS_X + to "-slow" in node configuration. + +nxagent-1.3.1-5 + +- Created framework for rootless agent. Added a -rootless option. + +- Slowly going toward a better organization of nxagent internals. + Renamed some files and moved things around. Changed some comments + in Screen.c to be more explainatory. + +nxagent-1.3.1-4 + +- Changed default keyboard model to "pc102" (was "pc101") to correct + problems with "<" and ">" keys on the German keyboards and, poten- + tially on other layouts. + +- Added new parameter -kbtype to handle both geometry and layout in + a single form, for example pc102/pl. Parameter -keyboard is still + supported for backward compatibility. + +- Synchronization of Num and Caps lock status is now done comparing + the real keyboard and the internal state at the time nxagent gets + the focus. If state doesn't match, a fake keyboard event is sent. + +nxagent-1.3.1-3 + +- Fixed a further problem on CopyArea between windows and pixmaps. + +nxagent-1.3.1-2 + +- Implemented CopyArea on framebuffer when copying from windows to + pixmaps. Added the -slow command line switch to let nxagent get + the real content of the window from the X server. This requires + an expensive round-trip so it is disabled by default. + +nxagent-1.3.1-1 + +- Opened the 1.3.1 branch. + +nxagent-1.3.0-32 + +- Fixed a bug on 16 bpp displays using render extension. Now only + images which are used by render pictures and which have depth 32 + are created with a different visual color mask. This saves a big + amount of SetUnpackColormap requests. + +nxagent-1.3.0-31 + +- Fixed a bug in nxagentComposite routine. The macro nxgentPicturePriv + was used without checking for a null pointer argument. + +nxagent-1.3.0-30 + +- Limitations on bandwidth introduced whenever the agent's window + is covered are now disabled by default. They can be enabled by + specifying the -limit option on the command line. The -nolimit + option is left for compatibility with the previous versions. + This handy feature caused complaints in the past from users who + instruct window managers to not move the window having focus on + top of the stacking order. + +nxagent-1.3.0-29 + +- Removed the warnings issued at compile time. + +nxagent-1.3.0-28 + +- Replaced the corrupted file nxagent.xpm with the original version. + +nxagent-1.3.0-27 + +- Hopefully fixed all the remained memory leaks. Most problems were + due to agent's render extension not freeing resources on X server. + +- Added support for big-endian X server display on render extension. + Glyphs are reformatted according with the destination order. + +- Added per client information for SetUnpackGeometry, now the unpack + routines should have the correct information for the color mask at + the end of the split process. + + +nxagent-1.3.0-26 + +- Changed the message printed in the log when leaving the dispatch + loop from 'Error' to 'Info'. + +- Moved initialization of _NXFlushSize to nxcompext in order to set + value at the time NXGetControlParameters() is called. + +nxagent-1.3.0-25 + +- Content of selection is now acquired using a single round-trip. + If content exceeds 262144 bytes, it is truncated at that size. + This works in most situations, at least with text, that, by the + way, is the only target supported at the moment. An improvement + would be to modify the state machine in a way that the remaining + data part is got using a second round-trip. This is not difficult + to do and can be considered for future releases. + +- In handling of clipborad we had to disable check on multiple + convert selection requests from the same client. There is a bug + in the algorithm that prevents the counter to be reset at the + appropriate time. This is to be investigated. + +nxagent-1.3.0-24 + +- Added asynchronous handling of GetProperty requests and replies + using the NXCollectProperty and NXGetCollectedProperty requests + and the NXCollectPropertyNotify event in NXclipboard.c and in + Event.c. Implementation is not complete yet and can sometimes + cause X clients to misbehave. + +- Function xnestBitBlitHelper() now always returns NullRegion. + Handling of graphical expose events should be rewritten so that + regions are always generated internally to nxagent. Returning a + null region without checking our event queue, anyway, saves a + flush of the display buffer and doesn't seem to affect the + functionalities. + +- This version comprises modifications to Events.c, GCOps.c, + NXClipboard.c, NXwindow.c and Window.c where I found XSync() + messages (or code used to just send XSync() messages) outside + any #ifdef ..._DEBUG. + +nxagent-1.3.0-16 + +- A dialog is showed at startup if proxy was not able to load a + persistent cache. + +- Reflected changes introduced in NXGetControlParameters() to add + more detailed information about the compression settings. + +- Fixed a potential bug with the name of the agent's display at the + time a dialog had to be showed. String was allocated with only 6 + characters. This could lead to dialogs not being showed using + display ports greater than 9999. + +- NX.h is now included by NXControl.h. Removed #include directives + from other files. diff --git a/doc/_attic_/NoMachine_documentation_files/nxcomp_CHANGELOG b/doc/_attic_/NoMachine_documentation_files/nxcomp_CHANGELOG new file mode 100644 index 000000000..b0323d4a7 --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxcomp_CHANGELOG @@ -0,0 +1,3778 @@ +ChangeLog: + +nxcomp-3.5.0-2 + +- Fixed TR11H02398. Solved a race condition when creating channels. + +nxcomp-3.5.0-1 + +- Opened the 3.5.0 branch based on nxcomp-3.4.0-7. + +- Updated copyright to year 2011. + +nxcomp-3.4.0-7 + +- Fixed TR03H02334. Modified the UNIX domain socket checks on MacOSX + to be compliant with the standard introduced in OSX 10.6.3. + +nxcomp-3.4.0-6 + +- Solved compilation problems on Solaris. + +nxcomp-3.4.0-5 + +- Solved compilation problems on GCC 4.4. + +nxcomp-3.4.0-4 + +- Added reference to fixed TR02H02325. + +nxcomp-3.4.0-3 + +- Updated copyright to year 2010. + +nxcomp-3.4.0-2 + +- Fixed TR03G02204. Changed the parsing of X authority entries in + order to handle the case where the hostname includes white spaces. + +- Fixed TR02H02325. Bug in PNG decompression on 16bpp displays. + +nxcomp-3.4.0-1 + +- Opened the 3.4.0 branch based on nxcomp-3.3.0-4. + +- Changed version number. + +- Updated copyright to year 2009. + +nxcomp-3.3.0-4 + +- Check if the variable storing the ping time exceeded the maximum + integer value. + +- Recover incorrect sequence number when the proxy is not connected + to an agent. + +nxcomp-3.3.0-3 + +- Removed a condition in ClientChannel that caused a loss in event + sequence numbers. + +nxcomp-3.3.0-2 + +- Updated VERSION. + +nxcomp-3.3.0-1 + +- Opened the 3.3.0 branch based on nxcomp-3.2.0-7. + +nxcomp-3.2.0-7 + +- Solved a compilation problem on GCC 4.3. + +nxcomp-3.2.0-6 + +- Changes considering that unsetenv() returns void on Mac OS X. + +nxcomp-3.2.0-5 + +- Fixed TR03F02024. Assume the launchd unix socket as X socket. + +- Changed the authorization cookie retrieval when using the launchd + socket on MacOSX, in order to wait for the X server start. + +nxcomp-3.2.0-4 + +- Fixed TR03F02026. Unset environment variable LD_LIBRARY_PATH before + calling the exec function running nxclient. + +nxcomp-3.2.0-3 + +- Fix addMsTimestamp() and subMsTimestamp(). Remove the check for + a valid input in diffTimestamp() and diffUsTimestamp(). + +nxcomp-3.2.0-2 + +- Fixed TR12E01973. Now the correct number of bits are used for the + number of points in a X_FillPoly request. + +nxcomp-3.2.0-1 + +- Opened the 3.2.0 branch based on nxcomp-3.1.0-6. + +nxcomp-3.1.0-6 + +- Always use a timeout of 50 ms to update the congestion counter. + +nxcomp-3.1.0-5 + +- Solve the possible deadlock caused by both proxies running out of + tokens at the same time. + +- In ServerProxy::handleCheckDrop() copy the list since the function + can delete the elements. + +nxcomp-3.1.0-4 + +- Classes ProxyReadBuffer and ServerReadBuffer returned an invalid + number of characters to read in the case of a readable() failure. + +- Connections to proxy versions newer than 3.0.0 were not accepted. + +- Reading options from file could fail if options contained spaces + or other characters interrupting the fscanf()'s matching of input. + +- The proxy link could not be flushed if a ping request was replied + after the end of the read loop. + +nxcomp-3.1.0-3 + +- Fixed a compilation warning on GCC 2.95. + +nxcomp-3.1.0-2 + +- Solved TR09E01852. Modified the encoding of the number of rects + in the XSetClipRectangles request. + +nxcomp-3.1.0-1 + +- Opened the 3.1.0 branch based on nxcomp-3.0.0-46. + +nxcomp-3.0.0-46 + +- Fixed TR09E01865 and TR08E01831. Assume the old behavior of compr- + essing the CUPS, SMB, HTTP and Font channels when connected to an + old proxy version. + +nxcomp-3.0.0-45 + +- Retry the fork() 30 times, but only on Cygwin (Sob!). + +nxcomp-3.0.0-44 + +- In the case of an error, try again to fork() after a second, for + a maximum of 5 times. This seems to constitute a valid workaround + to the intermittent fork() failures observed on Windows. + +- Fixed NXTransDestroy() to show the 'broken connection' dialog in + the case of a link failure on the client. + +- Handled the 'terminating' and 'terminated' messages as new proxy + stages. + +- Force all the directories and files created by the library to be + readable only by the user. + +- Don't complain if the shared memory segment can't be initialized + on Windows. + +nxcomp-3.0.0-43 + +- Prevent the reallocation of the read buffer in the proxy and the + agent transport if the buffer was borrowed by an upper layer. + +- Let the house-keeping process remove the cache directories that + are empty and have not be used since more than 30 days. + +- Added the missing destruction of the ZLIB stream used for image + decompression at proxy shutdown. + +nxcomp-3.0.0-42 + +- In handleFastWriteReply(), moved the initialization of the 'next' + pointer inside the '#ifndef __sun' block. This should fix the re- + maining encoding problems on SPARCs. + +nxcomp-3.0.0-41 + +- VMWare virtual machines can have the system timer deadly broken. + In the case of timeout, try to send a ping regardless we are the + client or the server proxy to force a write by the remote. + +- Removed the messages 'Info: Using image cache parameters...' and + 'Info: Using image streaming parameters...' from the session log + if the image cache is not enabled. + +nxcomp-3.0.0-40 + +- Removed the messages 'Info: Shutting down the NX transport' and + 'Info: End of NX transport requested by...' at the session tear + down. + +- Removed the remaining log output. + +nxcomp-3.0.0-39 + +- Don't reset the timer on proxy shutdown. + +nxcomp-3.0.0-38 + +- Don't reinstall the signal handler if the signal was enabled and + the NXTransSignal() action is NX_SIGNAL_FORWARD. + +nxcomp-3.0.0-37 + +- Return a congestion level 9 if the agent channel is in congestion + state. + +- Set the idle timeout (used to update the congestion state) based + on the link type. The timeout is 0 ms with link LAN and 50 ms in + the case of MODEM, with the other values in the between. + +nxcomp-3.0.0-36 + +- Changed the encoding of the RenderCompositeGlyphs requests. Use + a separate cache for X and Y. Send a single bit for offset X and + offset Y if they match the source coordinates. + +- Always use the memcpy() in the handleFastWrite*() on Sun, as the + alternative code doesn't work on SPARC if the buffer is not word + aligned. + +nxcomp-3.0.0-35 + +- Ensure a smooth transition between different congestion states. + If the current congestion counter is greater than the previous, + ramp up the value quickly by taking the current counter. If the + new congestion counter is less than the previous, ramp down the + reported value slowly by calculating the average of the last 8 + updates. Reset the congestion counter to 0 if no token reply is + pending and the proxy is idle until a timeout. + +nxcomp-3.0.0-34 + +- Calculate the current congestion as the average of the last 3 + frames sent. + +nxcomp-3.0.0-33 + +- When sending a X_RenderCompositeGlyph update, send a single bit + if the source X and Y match the values in cache. + +- Save the check on the bytes readable from the proxy descriptor + after the select. + +nxcomp-3.0.0-32 + +- Send the X_GetImage replies uncompressed to better leverage the + stream compression. + +- Before entering in congestion state, force a read to see whether + the remote proxy aborted the connection. + +nxcomp-3.0.0-31 + +- Try to avoid using memcpy() in the channels' handleFastWrite*(). + +- Changed the copyright notices at the beginning of the files that + were referring to NXPROXY to refer to NXCOMP. + +nxcomp-3.0.0-30 + +- Set the agent and proxy descriptors as ready, when appropriate, + also in the case of an interrupt. + +nxcomp-3.0.0-29 + +- On the X server side, read more events from the X server just be- + fore and just after having written some data. On the X client si- + de, apply the same to the proxy link. + +- X11 channels originate a congestion control code as soon as the- + re is some data left from the previous write. + +nxcomp-3.0.0-28 + +- Displaced automatically the "channel unresponsive" and "no data + received from remote" dialogs if the error condition is ceased. + +- Rewritten the channel drain procedure. + +- Tried a different approach to the channel congestion handling. + The X11 channels are not drained after a blocking write but only + if a further write is requested and the channel is still in con- + gestion state. Benchmarks show that this is still sub-optimal, + compared to sending the congestion code immediately also for X11 + channels. See the next version. + +nxcomp-3.0.0-27 + +- Ignored the agent option 'defer'. + +- Dropped support for the 1.4.0 versions. + +- More fixes to support the 1.5.0. + +nxcomp-3.0.0-26 + +- The channel read buffer can inherit the data to be encoded from + the caller, instead of taking it from the transport. This is le- + veraged by the agent channel to save the copy. + +- Ignored the agent option 'clients'. + +- Removed the deprecated code checking the CPU limits. + +- Removed the counters that were duplicated in the Statistics and + the Control classes. + +nxcomp-3.0.0-25 + +- Improved the effectiveness of the caching of the RenderComposite- + Glyphs by using a differential encoding for the length, delta x + and delta y of the first string. + +- Better handle the compatibility between different formats of the + cache files. + +nxcomp-3.0.0-24 + +- Fixed the compatibility problem with the 1.5.0 versions. + +- Removed the constants NXDisplayReadable, NXDisplayFlushable and + NXDisplayCongestion. Now nxcompext has three distinct functions. + +nxcomp-3.0.0-23 + +- Removed support for Rdp, Tight and Hextile packed images decod- + ing since they have been made obsolete by the new NX server. + +- Use the value 0 for the action is_hit and 1 for is_added. This + increases the frequency of zeroes in the encode buffer, giving + better compression. + +- Changed the copyright attribution from Medialogic to NoMachine. + +nxcomp-3.0.0-22 + +- Implemented an alternate encoding reducing the size of the int + caches to 16 elements and transmitting the values in blocks of + 4 bits. Although this encoding reduces the effectiveness of + the differential compression, it allows better compression of + the final stream, resulting in a 10% to 20% gain in all condi- + tions. The new encoding is experimental, as it would make the + 3.0.0 incompatible with all the previous NX versions. Use this + package as a reference for future implementations. + +nxcomp-3.0.0-21 + +- Encode the first two coordinates of a FillPoly message by using + a differential encoding, thus the origin of the polygon is not + included in the checksum. This is aimed to work in combination + with the agent converting all the FillPoly requests to the rela- + tive coordinate mode. + +- Add the coordinate mode to the checksum of the PolyPoint and Po- + lyLine messages so that it doesn't need to be encoded separately. + +- Disable the streaming for all messages. This saves the encoding + of a boolean for each message that could potentially be streamed. + +- Don't try to match the block size when encoding a value based on + an IntCache. This saves the additional bool in 90% of the cases. + +- Removed support for the former RDP and RFB session types. + +- Due to the above changes, this version is incompatible with the + previous 3.0.0 releases. + +nxcomp-3.0.0-20 + +- Added support for the 'lossy', 'lossless' and 'adaptive' pack me- + thod literals. These values activate the dynamic selection of the + pack method by the agent. + +- Made the 'adaptive' pack method the default for all link types. + +- The default stream compression level is now 6 for link type ISDN, + 4 for ADSL and 1 for WAN. The default data compression level is + always 1, except for LAN that is 0. + +nxcomp-3.0.0-19 + +- Print in the session log the X11 display that the proxy is imper- + sonating or where it is forwarding the connections. + +nxcomp-3.0.0-18 + +- Implemented decoding of the PACK_BITMAP_16M_COLORS pack method. + This is a very simple encoder removing the 4th byte in 32 bits- + per-plane images. This encoder is intended to better leverage + the stream compression on low bandwidth links. + +- Removed the code cleaning the padding bytes in RenderAddGlyphs + and RenderCompositeGlyphs as the operation is now performed in + Xrender. + +- Removed the "Info: Synchronizing local and remote caches." and + "Info: Using remote server '...'." lines from the session log. + +nxcomp-3.0.0-17 + +- Determine the CPU endianess at compile time only on Linux and + Cygwin. + +nxcomp-3.0.0-16 + +- Optimized the memory allocation of the ReadBuffer classes. The + buffers from the Transport classes are used, when possible, to + avoid the copy. + +nxcomp-3.0.0-15 + +- Reworked the code dealing with the channel congestion control + messages for increased efficiency. + +- Removed the pending_ flag from the proxy and channel class mem- + bers. If needed, the classes will query the transport buffers + to see whether there is data pending. + +- Removed the additional parameter from NXTransFlush(). + +- The proxy doesn't issue anymore a sync control message on a X + reply. Anyway it will respond to the request for compatibility + with older versions. + +- Removed the dynamic selection of the encoding method for the + X_QueryColors request and X_ListFonts, X_QueryColors, X_Query- + Font replies. Now all of them use the differential encoding to + better leverage the stream compression. + +- Fixed to build on SUNs where we don't have endian.h. + +nxcomp-3.0.0-14 + +- When handling partial proxy messages, don't try to determine how + many bytes still need to be read if the ZLIB stream compression + is enabled. + +- If a message can't be located, the ReadBuffer class checks if it + is possible to consume the data already in the transport buffer. + +- Optimize the MD5 routines by determining the CPU endianess at + compile time. + +- Force Drawable and GContext to be CARD32 in NXproto.h. + +nxcomp-3.0.0-13 + +- Changed the semantic of the NXDisplayFlushHandler callback. The + function is called when new data is sent to the remote proxy or, + with a 0 length, upon receiving a new token reply, so that the + agent can update its congestion state. + +- Added the NXTransCongestion() function. It returns a value bet- + ween 0 and 9 indicating the congestion level based on the tokens + remaining. A value of 9 means that the link is congested and no + further data can be sent. + +- Removed the congestion and synchronization callbacks. They are + superseded by the new NXTransCongestion() implementation. + +nxcomp-3.0.0-12 + +- Send the token replies at the end of the encode loop instead of + flushing the buffer immediately. + +- Fixed TR05E01687. Correctly detect CTRL-ALT-SHIFT-ESC keystrokes. + +- Renamed the option 'block' as 'tile'. + +- Ignored the option 'menu', targeting the X11 agent. + +nxcomp-3.0.0-11 + +- Removed the 'interactive' attribute from generic channels. We now + use the 'prioritized' attribute which yields the same result. + +- Simplified the channels' read loop by always reading only once. + +- The channels flush the link as soon as the token is exceeded even + if the flush policy is set to deferred. + +- Reserved more cache memory for the images when running a shadow + session. + +nxcomp-3.0.0-10 + +- Added the NXDisplayWriteHandler callback definition. + +- Removed the code that forced the proxy to retain in the cache the + images referenced at session startup. + +- Disabled the persistent image cache since this is not supported + by the current agent. This will save the overhead caused by the + image house-keeping process. + +nxcomp-3.0.0-9 + +- Fixed a cast problem in GetBytesReadable(). + +nxcomp-3.0.0-8 + +- Added the NXTransTime() utility. It return the time in milliseconds + elapsed since the last call to the same function. Useful for bench- + marking the Xlib layer. + +- Ignored the option 'block' targeting the X11 agent. + +nxcomp-3.0.0-7 + +- Ignored the options 'shadow', 'shadowmode' targeting the X11 agent. + +- Added the session type 'shadow'. + +nxcomp-3.0.0-6 + +- Fixed TR08D01484. Fixed a bug in the cleanup of the RenderAddGlyphs + messages. We clean up only the glyphs with depth 8, width greater + than 1 and pixmap byte pad 4. + +- Added file COPYING. + +nxcomp-3.0.0-5 + +- Updated the copyright notices to the current year. + +nxcomp-3.0.0-4 + +- Imported changes up to nxcomp-2.1.0-6. + +- Fixed TR12D01563. Changed the configure script to always build the + library with the -fPIC option. This is related to the way SELinux + works. + +- Fixed the dependency from local endianess for 16-bit color RDP un- + packing functions. This caused wrong colors to be displayed when the + proxy and the X server were running on two separate machines having + different endianess. + +- Fixed TR10D01523. The Channel::handleDrain() method now accounts + for the fact that agent connections can't be drained. + +- Changed the Tight and Hextile decoding functions to use the X ser- + ver's byte order. + +nxcomp-3.0.0-3 + +- Changed the main loop to handle the 3.0.0 version. + +nxcomp-3.0.0-2 + +- Updated the file VERSION. + +nxcomp-3.0.0-1 + +- Opened the 3.0.0 branch based on nxcomp-2.0.0-81. + +nxcomp-2.0.0-81 + +- Fixed the dependency from local endianess for JPEG and PNG decomp- + ression functions. This caused wrong colors to be displayed when + the proxy and the X server were running on two separate machines + having different endianess. + +- Fixed the number of entries in the handleColormap() function. + +nxcomp-2.0.0-80 + +- Fixed TR06D01404. Removed the warning issued when calling the + AgentTransport::drain() method. + +nxcomp-2.0.0-79 + +- Updated copyright to year 2006. + +nxcomp-2.0.0-78 + +- Fixed a bug in the cleanup of the RenderAddGlyphs messages. + +- Minor improvements to the encoding of the RenderCompositeGlyphs + and RenderComposite requests. + +- Added 'client' to the list of the ignored options. + +nxcomp-2.0.0-77 + +- Added cleanup of the padding bytes in the RenderCompositeGlyphs + and RenderAddGlyphs requests. + +nxcomp-2.0.0-76 + +- Before adding the frame's bytes to the tokens, the frame length + is normalized based on the stream compression ratio of the last + frame sent. This avoids entering the drain loop too early when + the data is highly compressible. + +- Moved the render messages' private data in a union to reduce the + footprint of the render store. + +nxcomp-2.0.0-75 + +- The action performed on the remote message store and the affected + position are encoded as a single value. This saves approximately + 1 bit per each message. + +- Created more Compat classes to handle the backward compatibility + with the 1.4.0 and 1.5.0 versions. + +nxcomp-2.0.0-74 + +- Added support for the RLE pack method and made it the default if + the selected link type is LAN. + +- Removed the legacy support for the 'render' option provided at X + server side. + +- When defining LAME in ClientChannel.h, the channel has the chance + of suppressing more opcodes by the handleTaintLameRequest() call. + This is for test purposes. + +nxcomp-2.0.0-73 + +- The X_NXSetUnpackColormap and X_NXSetUnpackAlpha now carry their + data in compressed form. The alpha data is compressed using the + ZLIB RLE encoding, while the colormap data is compressed using + the default ZLIB deflate. + +- Thanks to the above changes, ZLIB data compression of all messa- + ges which do not have a specific encoding is turned off, so that + we can make better use of the final stream compression. + +- Created new message structures to handle the compatibility with + the old proxy versions. When connected to an old proxy version + the agent should use the NXSetUnpackColormapCompat() and NXSet- + UnpackAlpha() interfaces. + +nxcomp-2.0.0-72 + +- Solved a compatibility problem with the 1.X.X versions due to the + new render encodings. + +nxcomp-2.0.0-71 + +- Improvements to X_RenderSetPictureClipRectangles. + +- Fixed handleUnpack() to pass the correct byte order parameter to + to the unpack alpha function. + +- Added the --parent parameter to the client even in pulldown mode. + +- Fixed a deallocation bug in StaticCompressor. + +nxcomp-2.0.0-70 + +- Added compression of X_RenderSetPictureFilter, X_RenderSetPicture- + Transform, X_RenderTrapezoids and X_RenderTriangles. + +nxcomp-2.0.0-69 + +- Changed the format of the persistent cache to accommodate the new + encoding of the render opcodes. Caches from the 1.4.0 and 1.5.0 + should be still loaded and saved correctly when connected to and + old version of the library. + +- Improved the encoding of the X_CreatePixmap, X_ChangeGC, X_Render- + CompositeGlyphs, X_RenderComposite, X_RenderCreateGlyphSet, X_Rend- + erFreePicture and X_RenderCreatePicture messages. Added new classes + to handle the backward compatibility. + +- Made the static compression and decompression code reside in the + same class. + +nxcomp-2.0.0-68 + +- Improved the encoding of the X_RenderCreateGlyphSet and X_Render- + FreeGlyphSet requests. + +nxcomp-2.0.0-67 + +- Modified the following session messages: + + From: "Session: Session starting at..." + To: "Session: Starting session at..." + + From: "Session: Session terminating at..." + To: "Session: Terminating session at..." + +- Improved the encoding of the requests creating or freeing an XID. + This affects X_CreateGC, X_CreateWindow, X_CreatePixmap, X_Render- + CreatePicture, X_FreeGC, X_DestroyWindow, X_FreePixmap, X_Render- + FreePicture. + +- Added 'streaming' and 'backingstore' to the list of options used + by agents. + +- Modified the info messages to print the ZLIB compression paramet- + ers to be more compact and only use two lines. + +nxcomp-2.0.0-66 + +- When part of an agent, the proxy will wait for the NXTransDestroy() + function to initiate the shutdown. + +nxcomp-2.0.0-65 + +- Starting from this version the NX client can control the behaviour + of the client proxy by monitoring the messages marked as "Session". + + At the early initialization the proxy will print: + + "Session: Session starting at '...'. + + The ellipsis here represent the current timestamp, as reported by + the POSIX function ctime(): + + Once the session is running, the proxy will print: + + "Session: Session started at '...'. + + At the time the session is being shut down, the proxy will print: + + "Session: Session terminating at '...'. + + Followed by: + + Session: Session terminated at '...'. + + The message "Info: Starting X protocol compression." is removed, + replaced by the message 'Session started at...' with the same + meaning. + + Once the message 'Session: Session terminated at..." is read from + the output, the client can optionally wait for the proxy process + to complete and terminate with an exit code 0. + +- The "Session" messages are not printed when the proxy is running + on the NX server side, as part of an agent. + +nxcomp-2.0.0-64 + +- Reduced the default token limit from 32 to 24. The synchronizat- + ion callback is triggered by the tokens going below half the li- + mit. + +nxcomp-2.0.0-63 + +- Added -I/usr/include/c++ to makedepend. + +nxcomp-2.0.0-62 + +- The house-keeping process is now started upon the initialization, + if the memory cache is enabled, and, on the X server side, when + the remote actually requested access to the image cache. + +nxcomp-2.0.0-61 + +- Added a NX_HANDLER_SYNCHRONIZATION callback to NXTransHandler(). + The handler is called when the agent can use the available band- + width to synchronize X objects that are corrupted or incomplete. + + The reason can be: + + NX_SYNCHRONIZATION_BEGIN: The synchronizationis is allowed. + + NX_SYNCHRONIZATION_END: The synchronizationis must stop. + + The reason can be determined by agents by using the NXBeginSynch- + ronization and NXEndSynchronization values defined in NXvars.h. + +- Bytes from 14 to 24 in the X_NXGetControlParameters reply report, + respectively, the frame timeout, the ping timeout, the preferred + image split mode and the split size threshold. + +nxcomp-2.0.0-60 + +- The following messages used by the NX client and server have been + changed. The NX client and server should be modified accordingly. + + From: "Info: Shutting down the link and exiting." + To: "Info: Shutting down the NX transport." + + From: "Info: End of session requested by remote proxy." + To: "Info: End of NX transport requested by remote" + + From: "Info: End of session requested by agent termination." + To: "Info: End of NX transport requested by agent." + + From: "Info: End of session requested by signal '...'." + To: "Info: End of NX transport requested by signal '...'." + + From: "Info: Shutting down the link and exiting." + To: "Info: Shutting down the NX transport." + + From: "Info: Waiting for cleanup timeout to complete." + To: "Info: Waiting the cleanup timeout to complete." + + From: "Info: Waiting for watchdog process to complete." + To: "Info: Waiting the watchdog process to complete." + +nxcomp-2.0.0-59 + +- Added more debug information regarding the timing of packets sent + and received. + +- Added the possibility to redirect the log output to a file that can + be later shared with nxssh running in "binder" mode. This is useful + when testing the forwarding of the SSHD connection by nxssh to the + agent. Activated by defining BINDER in Loop.cpp. + +nxcomp-2.0.0-58 + +- Fixed the unpack alpha procedure to only rely on the image's byte + order. + +- Solved the X_PutImage encoding problem introduced in the 2.0.0-56 + version and restored the compatibility with the 1.5.0 version. + +nxcomp-2.0.0-57 + +- Added a NXTransFile() function. It returns the name of the files + used by the proxy for the current session. + + The type parameter can be: + + NX_FILE_SESSION: Usually the file 'session' in the user's session + directory. + + NX_FILE_ERRORS: The file used for the diagnostic output. Usually + the file 'errors' in the session directory. + + NX_FILE_OPTIONS: The file containing the NX options, if any. + + NX_FILE_STATS: The file used for the statistics output. + + The returned string is allocated in static memory. The caller must + copy the string upon returning from the function, without freeing + the pointer. + +- Fixed the PANIC in the handling of the abort split messages. + +- The encode and decode routines may write one byte past the nominal + end of the encode buffer. This additional byte is now included in + the payload. This is actually a bug, but harmless. + +nxcomp-2.0.0-56 + +- Added the X_NXAbortSplit request. It can be used to interrupt the + streaming of all the messages currently in the split store for + the specified resource. Depending if the split store did or did + not contain split messages, the client will receive an immediate + end-split or no-split notification. + +- Removed the split modes NXSplitModeEager and NXSplitModeLazy. The + available modes are now NXSplitModeSync and NXSplitModeAsync. The + mode NXSplitModeAsync replaces the two old modes and is now the + default. Similarly to NXSplitModeEager, it makes the proxy split + only messages that exceed a size threshold, but the threshold is + generally smaller than in the previous versions. + + #define NXSplitModeDefault 0 + #define NXSplitModeAsync 1 + #define NXSplitModeSync 2 + +- Renamed X_NXSplit to X_NXSplitData, X_NXAbortSplit to X_NXSplitEv- + ent. + +- The proxy now enters a drain loop, when in congestion state, and + waits until the decongestion. Also the X channels are drained if + blocked. + +- The select is restarted immediately if only the proxy is selected + and the data read doesn't make a complete message. + +- The size of the shared memory segment used by the X server proxy + is now negotiated at startup and the selected value is printed in + the session log. + +- Added the option 'encrypted'. It tells the local proxy if it is + running as part of a program providing encryption of the point to + point communication. This is useful to determine if the proxy can + block waiting for data or needs to yield to the client to let it + handle the remote connection. + +nxcomp-2.0.0-55 + +- Fixed handleRestart() to correctly send the end-split event only + after the split sequence has been closed by the client. + +- Fixed a possible memory error in the Keeper class occurring if the + image caches were erased while in the middle of a loop. + +nxcomp-2.0.0-54 + +- Added a '--parent' option when running the client in dialog mode. + This is the process id that needs to be signaled in the case the + user chooses to do so. + +nxcomp-2.0.0-53 + +- Solved a bug in the abort split procedure. The procedure assumed + that the split had to be at the head of the list. This may not be + the case if the split was loaded from disk asynchronously, after + a different split with the same checksum was recomposed. + +- By defining STRICT in Loop.cpp, the number of available tokens is + set to 1. This can be used to trigger the congestion more often + than it would possible when testing the software with the default + settings. + +- Added more debug output to the procedures handling the streaming + of the images. + +- Reset the channel's split pending and congestion flags in the fin- + ish procedure. Not doing so caused some additional loops at chan- + nel shutdown. + +- Fixed a bug on Cygwin that prevented the log files to be succes- + sfully reopened when the size limit was exceeded. + +- Failures to write to the agent transport are reported sooner when + the channel is finished. This saves a few more loops at session + shutdown. + +nxcomp-2.0.0-52 + +- Started implementing a new handler to let the agent include arbit- + rary data in the transport statistics. The parameter, in this case, + is a pointer to a pointer to a null terminated string. The pointer + is set at the time the handler is registered. The pointed string + will have to be filled by the agent with its statistics data. For + now, only the interfaces and the stubs exist. + +- Disabled the timestamp cache as it still causes rounding problems + when calculating the current bitrate. + +nxcomp-2.0.0-51 + +- Removed SelectPackMethod(), not used anymore, from Pack.c. + +nxcomp-2.0.0-50 + +- Added the X_NXFinishSplit request. It forces the proxy to comple- + tely transfer all the split messages for the given resource, and + then notify the agent. + +- Fixed the statistics to not account the split bits to the control + token. + +nxcomp-2.0.0-49 + +- Fixed a bug that caused the split timeout to be reset even if a + different channel had splits to send. + +- Removed an error condition that arose when a split operation was + requested by a different channel than the first to connect. The + reason is that an auxiliary channel (like the one created by the + server to store the keyboard configuration) can be the first to + open a connection to the X server, then can come the agent, that + is actually using the NX opcodes. The proxy will now simply print + a debug message. + +- Removed a further error condition that was assumed by the proxy + if a pending flush was detected while no channel was selected for + output. This can actually happen if the channel was dropped and, + in the meanwhile, the user requested the proxy statistics. + +nxcomp-2.0.0-48 + +- Added a 'type' parameter to NXTransFlush(). The new NX_FLUSH_IDLE + type should be used by agents when they have finished handling all + their clients and are going to wait for more input. This is the + case, for example, of the X agent returning from WaitForSomething() + after having set a small timeout to find out if there are clients + ready, or the case of a RDP agent finding that there are no opcodes + to read from the RDP server. The 'idle' flush should be requested + also when the X11 agent is waiting for a split to complete. When + the flag is used, the proxy uses the available bandwidth to encode + more low-priority data, like the payload of images being streamed. + +nxcomp-2.0.0-47 + +- Added a new RGB image encoder. For now the encoder uses a static + Z stream to compress the image data in the destination buffer and + allows the agent to use the simplest encoding by still separating + the alpha channel from the image data. The new encoder can be the + the base for implementing color reduction by dithering or a color- + mapped translation of the image similar to PNG, but without the + PNG overhead and with the colormap being sent to the client using + the NXSetUnpackColormap() opcode. + +- Put the routines implementing static deflating and inflating of + a ZLIB buffer from the Compressor and Decompressor classes to Z.h + and Z.cpp, so that they can be reused by the new RGB encoder. + +nxcomp-2.0.0-46 + +- Fixed a segfault arising when trying to start a child without the + NX transport. + +nxcomp-2.0.0-45 + +- Undefined the MATCH directive. + +nxcomp-2.0.0-44 + +- Changed the encoding of the X_CreatePixmap, X_CreateGC, X_Render- + CreatePicture, X_CreateWindow, RenderCreateGlyphSet.cpp. The Xid + of the drawable is included in the checksum of the X_CreateGC and + X_CreatePixmap message. This leverages the way GC and Pixmaps are + allocated in the X agent to obtain better compression. + +- Removed the code handling the reset of the proxy connection. This + functionality was unused since when the persistence is handled by + the agent. + +- Added a specific section in the statistics output for the render + extension. + +nxcomp-2.0.0-43 + +- Fixed a bug that could have caused the sending of multiple 'end + split' messages for the same split sequence. + +- Added handling of the option 'strict'. + +nxcomp-2.0.0-42 + +- Added a missing channel switch directive when encoding abort split + messages at the server side. This could cause a decoding error on + the client. + +nxcomp-2.0.0-41 + +- Ensured that the link is flushed immediately on the X server side + when important keyboard or mouse activity is detected in input. + +- Implemented a timestamp cache to avoid calling gettimeofday() when + it is enough to use the last timestamp gotten from the system. The + cache can be disabled by undefining CACHE_TIMESTAMP in Timestamp.h. + +nxcomp-2.0.0-40 + +- Added the karma delay field to the X_NXGetControlParameters reply. + +- Solved a bug with the decoding of split messages likely to happen + only when using link type LAN. + +nxcomp-2.0.0-39 + +- Implemented separate flow control for the generic channels and the + image streaming data. + +- Improved the split procedure to load a message from the disk cache + if found after it was originally discarded because locked. + +nxcomp-2.0.0-38 + +- Renamed the 'shmem' option as 'shseg'. The 'shmem' option becomes + specific to the agent and will be used together with 'shpix' option + to indicate if, respectively, the shared memory extension and the + use of the shared pixmaps must be enabled in the agent server. The + new option will be instead used by the proxy to determine the size + of the memory segment shared between the proxy and the X server. + +- Added the 'shmem', 'shpix', 'keyboard' and 'clipboard' to the list + of ignored options. The 'keyboard' option should become a synonym + of 'kbtype'. The 'clipboard' option will tell the NX agent if the + clipboard support should be disabled for security reasons. + +nxcomp-2.0.0-37 + +- Ensured that, when running a raw session, the persistent cache is + loaded and saved only once in the session lifetime. + +- Added the 'product' keyword to the list of recognized options. The + option is ignored by the proxy, but can be used by the client or + server to facilitate the support. + +nxcomp-2.0.0-36 + +- Added the remote version number in the X_NXGetControlParameters + reply. + +- Solved a bug related to the removal of the split stores. + +- Removed the unused code dealing with the flush timeouts. + +nxcomp-2.0.0-35 + +- Added an alert to notify the user about the failure of the XDMCP + session. + +nxcomp-2.0.0-34 + +- The active channels and the agent resources are now stored in a + list container. + +- Added the X_NXFreeSplit request. The request is currently unused + because the split store is freed automatically when it becomes + empty, but can be useful in future if we want to implement other + otpimizations. + +nxcomp-2.0.0-33 + +- There is now a split store for each agent resource. This allows + the proxy to divide the bandwidth among the agent resources. + +- A simple round-robin load-balancing is implemented, dividing the + bandwidth equally among all the split stores. + +- If there is a previous request being streamed for the same res- + ource, cached messages are appended to the split store and then + committed in the original order. This makes possible to stream + the colormap and the alpha channel data even if the split invol- + ves multiple PutImage or PutPackedImage operations in a single + start-split/end-split sequence. + +- Implemented the commit store class. Made the commit store expand + the message in the final buffer, instead of leveraging the mes- + sage store. + +- Channels having a drop command pending are checked before trying + to load or save the cache. This prevents a potential problem with + the protocol violation error that could be reported by the client + side proxy. + +- The current bitrate is now calculated at the time the transport + actually writes the data to the network, not at the time the data + is appended to the transport by the upper layers. The reason is + that the data can be compressed by the stream compressor and so + we can calculate the real bitrate only after having flushed the + ZLIB stream. This fixes the wrong numbers that could be reported + by the statistics in the previous versions. + +nxcomp-2.0.0-32 + +- More progress in the implementation of the new image streaming. + This version has been tested to work when connecting to an 1.5.0 + server. Due to the significant changes in the way the streaming + works in the newer versions, split is never activated by a 2.0.0 + server connecting to a 1.5.0 client. + +- Fixed the NXTransClose() function to check if the fd matches the + NX agent connection. + +- Fixed the includes in Socket.h to compile on Solaris and MacOSX. + +nxcomp-2.0.0-31 + +- Changed the NX transport functions that didn't require a NX fd + parameter to include one. The value can be NX_FD_ANY to signify + any running NX transport. + +nxcomp-2.0.0-30 + +- More progress in the new implementation of image streaming. + +- This version is apparently compatible with the 1.5.0 client but + needs further testing. + +nxcomp-2.0.0-29 + +- Implemented the NXTransHandler() interface and made the proxy + use the callback, when it is installed, instead of the notifi- + cation events. + +- Modified the agent transport to report an EOF condition as soon + as the channel is dropped, instead of reporting the error only + after the proxy shutdown. This allows the agent to handle its + clients while the proxy is handling the grace timeout. + +- Added a test facility to verify if the client and server caches + match at shutdown. + +- More advances in the new implementation of streaming. + +nxcomp-2.0.0-28 + +- Made the session shutdown faster, normally below 1 second. The + grace time is now 500 ms once all channels have been dropped. + +nxcomp-2.0.0-27 + +- The house-keeping process will now run a number of iterations + (currently 100) and then will exit. The proxy will check the + exit code and, if it was requested by the child, will restart + it. This is intended to keep the memory consumption low, as I + noted that after a big number of iterations the performance of + the allocator start to degrade quickly. + +nxcomp-2.0.0-26 + +- Started implementing the NXTransHandler() interface to let the X + application hook a callback and be notified by the proxy when an + event occurs. At the moment only congestion events are supported. + The interface makes possible for the caller to provide a generic + parameter. This parameter is passed back to the handler function. + The parameter is expected to be the Xlib display pointer, given + that the proxy doesn't have access to the Xlib structures. + +- Moved all the internal variables shared between Xlib, nxcompext + and the X server in nxcomp. Declarations and function prototypes + moved to NXvars.h. + +- Removed the NXGetCleanupParameters() and NXGetImageParameters() + interfaces and the remaining references to the unused display + buffer and image cleanup functions. + +- In this version the images streaming functionality is disabled. + Because of that, expect compatibility problems when connecting + to a different nxcomp version. + +nxcomp-2.0.0-25 + +- Forced the end of the session earlier if a shutdown has been re- + quested by the local side but the remote proxy is not responding. + +nxcomp-2.0.0-24 + +- Changed the loop deleting the file items in Keeper to pick the + first element instead of looping through the iterator. + +- More problems with the libstdc++ allocators. During the tests, I + found that the Keeper class can leak industrial amounts of memory. + Valgrind says that the objects that are not freed are the File + items we allocate in collect(). As this looked suspicious, I log- + ged the constructors and destructors and can say that everything + is OK on our side. Unfortunately, by removing the spleeps used + to let the program work silently in background, one can find that + the memory occupation still grows by a MB every few seconds. This + is less a problem on Windows, where the memory occupation remains + almost constant. See the comment on __USE_MALLOC below. + +- Increased the maximum size of a message that the proxy is allo- + wed to cache to 4MB. This makes possible to cache many replies + (like the X_QueryFont replies) that often exceeded the previous + limit. + +nxcomp-2.0.0-23 + +- Fixed a compatibility problem with the 1.5.0 that arose when + encoding an image with caching and streaming temporarily disa- + bled. + +- Removed the __USE_MALLOC define in Types.h because this is what + the g++ developers want. I'll try to avoid flames and will not + comment on this. + +- Added a --with-use-malloc configure option. This option should + be used when building the release packages on GCC versions that + support it. + +- Started fixing the commit procedure to be able to deal with the + alpha channel. + +nxcomp-2.0.0-22 + +- Prevented channels from being dropped while in the middle of a + read loop. + +- Added a small utility ensuring that the SIGCHLD we receive in + the main loop can be always identified as pertaining to an our + child. + +- Increased the space available for the control messages at the + beginning of the encode buffer and ensured that there is always + enough space for adding a token message, in the case this is + required by the flush procedure. + +- Made all cache files readable only by the user. + +nxcomp-2.0.0-21 + +- Solved a bug in the streaming of images that caused the agent's + clients to never resume when connected to an old proxy version. + +nxcomp-2.0.0-20 + +- Disabled again streaming of the alpha channel data. By enabling + it, the agent randomly fails to repaint the exposed regions. The + reason is to be investigated. + +nxcomp-2.0.0-19 + +- Implemented the split mode NXSplitModeSync. When this mode is + selected, the proxy will not send data for the split at the head + of the list until the remote peer has confirmed that the message + is not available in the image cache. This is going to be useful + in combination with the lazy encoding. + +- Improved the error detection in the case of failure when saving + a recomposed split on disk. + +- Added X_NXSetUnpackAlpha to the set of requests that is possible + to stream. + +nxcomp-2.0.0-18 + +- Enabled the 2.0.0 features that were disabled for test purposes. + +- Changed the LICENSE file to state that the software is only made + available under the version 2 of the GPL. + +nxcomp-2.0.0-17 + +- Introduced a new channel of type 'slave'. Opening a slave channel + should let the proxy fork a new NX client instance (or whatever + is in the NX_SLAVE environment) and pass to it the channel's desc- + riptors. This client instance should authenticate the peer, for + example using the proxy cookie (see how this is implemented in + nxsensor) and then negotiate the service to be used on the channel. + This can be used to implement forwarding of arbitrary ports or ad- + ditional services, like a simple file transfer protocol. For now + the implementation is incomplete. Opening a slave channel will + result in the remote proxy just dropping the channel connection. + +- The proxy is forcibly flushed at the end of each loop. This is a + temporary fix until the agents are updated to flush the proxy link + on demand. + +- Added a new alert to be used in the case the RDP session is closed + and replaced with a new session using the same Windows account. + +- Added a forward declaration of class RenderMinorExtensionStore in + file RenderExtension.h to compile using gcc 4.0.X. + +- Added removal of all .orig file when running a 'make clean'. + +- The code uses again the 2.0.0 style shutdown (the one waiting for + the watchdog process to terminate). + +nxcomp-2.0.0-16 + +- Added the NXTransChannel() interface to allow agents to create + new channels connected to the port that will be forwarded by the + remote proxy. The function returns 1 on success, 0 if the NX + transport is not running, or -1 in the case of error. On success, + the descriptor provided by the caller can be used for all the + subsequent I/O, including selecting the descriptor to check if + I/O is possible. The type parameter not only tells to the proxy + the remote port where the channel has to be connected, but gives + a hint about the type of data that will be carried by the channel, + so that the proxy can optimize the compression and schedule the + traffic on the slow link. + + The type can be: + + NX_CHANNEL_X: The channel will carry X traffic and it + will be connected to the remote X display. + + NX_CHANNEL_CUPS: The channel will carry CUPS/IPP protocol. + + NX_CHANNEL_SMB: The channel will carry SMB/CIFS protocol. + + NX_CHANNEL_MEDIA: The channel will transport audio or other + multimedia data. + + NX_CHANNEL_HTTP: The channel will carry HTTP protocol. + + NX_CHANNEL_FONT: The channel will forward a X font server + connection. + + Only the proxy running at the NX server/X client side will be + able to create a X, CUPS, SMB, MEDIA and HTTP channel. A proxy + running at the NX client/X server side can create font server + connections. The channel creation will also fail if the remote + end was not set up to forward the connection. + + To create a new channel the agent will have to set up a socket- + pair and pass to the proxy one of the socket descriptors. + + Example: + + #include + #include + + int fds[2]; + + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) + { + ... + } + else + { + // + // Use fds[0] locally and let the + // proxy use fds[1]. + // + + if (NXTransChannel(fds[1], NX_CHANNEL_X) <= 0) + { + ... + } + + // + // The agent can now use fds[0] in + // read(), write() and select() + // system calls. + // + + ... + } + + Note that all the I/O on the descriptor should be non-blocking, + to give a chance to the NX transport to run in the background + and handle the data that will be fed to the agent's side of the + socketpair. This will happen automatically, as long as the agent + uses the XSelect() version of the select() function (as it is + normal whenever performing Xlib I/O). In all the other cases, + like presumably in the agent's main loop, the agent will have + to loop through NXTransPrepare(), NXTransSelect() and NXTrans- + Execute() functions explicitly, adding to the sets the descript- + ors that are awaited by the agent. Please check the implementa- + tion of _XSelect() in nx-X11/lib/X11/XlibInt.c for an example. + +nxcomp-2.0.0-15 + +- Some changes aimed at finding a workaround to the unreliability + of the font server connections. The X server seems to be really + picky about the network latency, so we try to read immediately + from the channel just being created, instead of waiting for a + new loop. Additionally the proxy will keep reading from the font + server connections even after the maximum length of the frame + is exceeded, in the hope that it will be able to send a complete + message in a single frame. + +- updated the various internal consistency tests run when the TEST + or INFO flags are enabled. + +nxcomp-2.0.0-14 + +- It seems that the closure of the socket sometimes takes several + seconds, on Windows, after the connection is broken, with the + result that the alert can be shown long after the user has gone + after the failed session. We now skip the closure of the proxy + link on Windows if we are about to exit. + +- The code uses the 1.5.0 style shutdown (the one waiting for the + term signal in the main process) to be able to test the library + with the old server. To activate the new shutdown procedure be + sure the define SHUTDOWN_COMPATIBLE_1_5_0 is unset. + +nxcomp-2.0.0-13 + +- Ensured that static members in channels are reset at the time a + new proxy is created. + +- Adjusted the token parameters for link modes other than modem. + +nxcomp-2.0.0-12 + +- Handled compatibility with 1.X.X versions not sending the count + field in the token. + +- The proxy link is now flushed automatically if the agent has not + set the deferred flush mode. + +nxcomp-2.0.0-11 + +- Significant modifications to allow the proxy to keep data in the + encode buffer across multiple loops, until the data is flushed + because an explicit request by the agent or. Besides maximizing + the amount of data sent in a single frame, this makes it possi- + ble to move any packet coalescence strategy in the agent, while + still using an 'immediate' flush policy. + +- Modified the procedure handling the proxy congestion. Each token + now carries a counter which represents the multiple of TokenBytes + data bytes that need to be confirmed by the remote end. The ser- + ver side proxy will need to reply by including the value of the + counter. When sending a new token, the tokens are decremented by + the counter and the client side proxy enters in congestion when + the available tokens becomes zero or negative. + +nxcomp-2.0.0-10 + +- Implemented specific encoding of the X_NXSetCacheParameters + request. + +- Handled the compatibility with older versions not supporting the + new request. In this case the request is handled at the local si- + de, preventing the X requests to be cached or split, even without + the cooperation of the remote side. + +nxcomp-2.0.0-9 + +- Modified the shutdown procedure to not rely on the TERM signal + when the proxy needs to wait for the server to complete. We will + now print the following message in the session log: + + Info: Watchdog running with pid 'n'. + Info: Waiting for watchdog process to complete. + + The NX server will have to kill the process with the given pid + to mandate the proxy shutdown. This solves the TR11C01192. + +- Added the X_NXSetCacheParameters request. It tells to the proxy + how to handle caching of X requests, namely if requests should + be stored in the memory cache, split in smaller data chunks and, + in the case of images, saved on disk in the persistent image + cache. The request affects all the X messages until the proxy + is further configured. + +- Enabling and disabling loading and saving of persistent images + due to a X_NXSetCacheParameters is still to be implemented. + +- Implemented font channel compatibility with older versions. If + the font port is queried and the remote proxy doesn't support + the tunneling of font server connections, an empty string is + returned. + +- The option 'resize', used by agents, is now silently ignored. + This solves the TR10C01061. + +- Added the missing reference to TR08C000981. + +nxcomp-2.0.0-8 + +- Discarded the first idea of setting the font path implicitly in + the X server side proxy, by means of a multi-pass operation and + added the NXGetFontParameters() request and reply. If the proxy + has been configured accordingly, the request returns the X font + path that can be set by the agent to tunnel the font server con- + nections through the NX link. + +- Changed the parsing of the font server port to be able to handle + the defaults. + +nxcomp-2.0.0-7 + +- More work on tunneling of font server connections. + +- The synchronization requests are now replied at the same time + as a new request is received, by checking if the channel has + already gone past the awaited sequence number. This avoids the + delay caused by the previous versions in the case the expected + reply had been handled asynchronously, inside the write loop. + +nxcomp-2.0.0-6 + +- The display is again passed to the client using the -display + parameter. + +- The option 'type' is now ignored at X server side. Support at + the X server side had been left for compatibility with older + versions of the proxy. + +- Added direct support for more session types, namely 'unix-cde', + 'unix-xdm', 'unix-console', 'unix-default'. The 'unix-console' + and 'unix-default', similarly to 'unix-application', will now + trigger the 'raw' mode. + +nxcomp-2.0.0-5 + +- Renamed Png.h and Png.cpp to Pgn.h and Pgn.cpp to avoid name + clashes on Windows. + +- The distclean target now removes the autom4te.cache directory. + +nxcomp-2.0.0-4 + +- Added the 'kill=n' option to let the proxy add the process to + the list of daemons that must be terminated at session shutdown. + Multiple 'kill=n' options can be specified. The proxy will send + to each process a SIGTERM signal before exiting. + +- Removed the code that forcibly disabled the RENDER extension on + Solaris. Eventual compatibility problems will be now handled in + the NX agent. + +- The path to the client executable is now assumed to be in the + NX_CLIENT environment. If the variable is not set, the proxy + will guess the location based on the target platform. This is + part of the FR11C01215. + +nxcomp-2.0.0-3 + +- More code cleanup. Protocol step 5 and cache step 2 are assumed + by default. This allows us to remove the various channel caches + that are not used anymore. + +- Removed the outdated encodeBegin() and encodeEnd() methods. + +nxcomp-2.0.0-2 + +- Added compatibility with the 1.5.0 and 1.4.0 versions. Protocol + version older than the 1.4.0 will cause the proxy to drop the + connection. + +- Rewritten the version negotiatiation logic to better handle the + compatibility between the local and the remote version. + +- Removed the conditional code handling the compatibility with + the protocol encodings from 1 to 4. + +- Small adjustments to the session negotiation procedure to give + more hints in the case of errors. A dialog is now issued if the + remote proxy drops the connection due to a probable authentica- + tion failure or when the remote proxy version is not compatible + with our version. + +nxcomp-2.0.0-1 + +- Opened the 2.0.0 branch based on nxcomp-1.5.0-80. + +nxcomp-1.5.0-80 + +- Fixed a bug that prevented the Unix socket to be created in the + right directory. This affected the ability of the server to run + NX sessions without the agent encoding. + +nxcomp-1.5.0-79 + +- Solved a bug in the 15 to 16 bpp conversion for RDP sessions. + +- Corrected a typo in the PANIC message of Unpack16To24 function. + +- Optimized the 16 bpp RDP decompression routine. + +nxcomp-1.5.0-78 + +- Implemented the FR11C01215. The following environment variables + are checked to determine the location of the relevant NX direct- + ories: + + $NX_ROOT The root NX directory is the place where the session + directory and the cache files are created. This is + usually overridden by passing the 'root=' option. By + default, the root NX directory is assumed to be the + directory '.nx' in the user's home. + + $NX_SYSTEM The directory where NX programs and libraries reside. + If not set, the value is assumed to be '/usr/NX'. + Programs, libraries and data files are respectedly + searched in the 'bin', 'lib' and 'share' subdirecto- + ries. + + $NX_HOME The NX user's home directory. If $NX_ROOT is not set + or invalid, the user's NX directory is created here. + + $NX_TEMP The directory where the X11 Unix Domain Sockets and + all temporary files are to be created. + + $NX_CLIENT The full path to the nxclient executable. If the va- + riable is not set, the nxclient executable will be + run assuming that the program is in the system path. + This can be useful on platforms like Windows and the + Mac where nxclient is located in a different direct- + ory compared to the other programs, to make easier + for the user to execute the program from the shell. + + Other environment variables: + + $HOME The variable is checked in the case $NX_HOME is not + set, null or invalid. + + $TEMP The variable is checked whenever the $NX_TEMP direct- + ory is not set, null or invalid. + + $PATH The path where all executables are searched, except + nxclient. If $NX_CLIENT is not set, also the client + executable is searched in the system path. + + $XAUTHORITY + This is the file containing the X11 authorization + cookies. If not set, the file is assumed to be in + the user's home (either $NX_HOME or $HOME). + + $LD_LIBRARY_PATH + System-wide library search order. This should be set + by the program invoking the proxy. + +- Extended the usage message to document the relevant environment. + +- Made the WaitChild() function interruptible. This allows the user + to terminate the connection procedure immediately, by sending a + signal to the proxy process while an abort dialog is shown in the + foreground. This is part of the solution to the TR11C01216. + +- Implementation of the FR11C01215 is not yet complete. The client + program and the nxauth/xauth are still searched using the previ- + ous logic. In particular, the NX_CLIENT variable is ignored. + +nxcomp-1.5.0-77 + +- Corrected the typo in the alert dealing with VNC authentication + failures. This solves the TR11C01199. + +nxcomp-1.5.0-76 + +- Added the missing initialization in the client and server proxy + constructors. + +nxcomp-1.5.0-75 + +- Starting from this version the build procedure will automatically + create a DLL on Windows. + +- Disabled exceptions in the compiled code. + +- Disabled run-time type information to further reduce the size of + the executable. + +- Compiling with GCC 4.0.0 and -fno-exceptions produces a warning + in some files, due to control apparently reaching the end of a + non void function. This is bogus and has been confirmed to be a + GCC 4.0.0 bug solved in more recent versions. + +nxcomp-1.5.0-74 + +- Imported changes from nxcomp-1.6.0-4. + +- Solved a compilation error on Solaris and MacOSX platforms. + +- The 'font' option now accepts either a numeric value (for a TCP + port) or a 'unix/:port' or 'tcp/:port' specification. In the case + of Unix ports, we assume that a port specification "unix/:7100" + corresponds to the "/tmp/.font-unix/fs7100" socket and a port like + "unix/:-1" corresponds to "/tmp/.font-unix/fs-1". + +- An absolute file path is also accepted as a valid socket. This is + useful to test the forwarding of the font server connection, for + example by running a normal X client and pointing the socket to + the X server. + +- Protocol step 7 is now only assumed when connecting to a remote + proxy version 1.6.0 or later. + +nxcomp-1.5.0-73 + +- Use the include files from nx-X11 if the nx-X11/include directory + is found. The previous configure checked the presence of nx-X11/ + exports/include, that might not be built at the time this library + is compiled. + +nxcomp-1.5.0-72 + +- Fixed a problem on AMD64 due to the size of the area pointed by + the argument of NXTransReadable(). The ioctl() requires a pointer + to an int, at least on Linux. The original _X11TransBytesReadable() + function simply calls the ioctl() by passing the pointer that is + provided. Returning the value assuming a pointer to a long crashes + some applications, among them xterm. Now NXTransReadable() follows + the same schema of the ioctl() call and stores the result assuming + a pointer to an int. + +nxcomp-1.5.0-71 + +- Ensured that the NX trasport is destroyed on NXTransExit() even if + the parent has overridden our signal handlers. + +- Added attribute 'noreturn' to NXTransExit(). + +- Small change to the shutdown procedure to send the "Waiting for a + further signal" just after the watchdog is started. + +nxcomp-1.5.0-70 + +- Added the definition of protocol step 7. The new protocol step is + implicitly assumed when activating the font server channel, so that + NX clients and servers may decide what to do by verifying the patch + version of the peer software. This makes possible to activate the + feature without stepping up the 1.5.0 version of the software. + +nxcomp-1.5.0-69 + +- Added the -fPIC GCC flag when compiling on AMD64 architectures. + +- Small changes to configure.in to have specific CFLAGS. + +- Created a new configure using autoconf 2.59. + +- Added the 'mask=n' option to determine how channel ids are distri- + buted between client ans server. By default, channels whose ids are + multiple of 8 (starting from 0) are reserved for the client side. + All other channels can be allocated at the NX server side. + +- A check is missing on the protocol supported by the remote side, + so it is likely that mixing this version with older 1.5.0 will not + work. + +- The release has the debug logs enabled. + +nxcomp-1.5.0-68 + +- Added provision for opening new channels on both client and server + side. This required small changes to the way channel ids are mapped + and retrieved, so that both sides now support bidirectional mapping + of file descriptors to channels. + +- Made the code handling allocation of new generic channels to reside + in the base Proxy class. + +nxcomp-1.5.0-67 + +- Renamed the 'embedded keyboard' channels as 'aux' channel. + +- Renamed 'samba' channels as 'smb'. + +- The 'samba' and 'smb' options can now be used interchangeably. The + same applies to the 'keybd' and 'aux' options, used to set up the + auxiliary X channel. + +- Added a new font channel. The channel is used to forward X font + server connections from the X server on the NX client to the remote + NX server. The channel is not yet functional and requires change to + the channel allocation mechanism. + +- Added a common interface to create new listening sockets. This is + currently used for additional services, but not for the X display + sockets. + +- Simplified the interface used to accept new connections to channels + being forwarded. + +- Removed the -V option as nxproxy is not using dlopen() anymore. + +- Removed the inclusion of ClientChannel.h in Proxy.cpp that caused + test symbols to be reverted to undefined. + +nxcomp-1.5.0-66 + +- Made failures setting the IPTOS_LOWDELAY on the proxy socket to + cause a warning, instead of an error. + +- Made the clean target delete the Cygwin specific libraries. + +- Updated the configure and Message.h to deal with GCC 4. Solves the + TR08C000981. + +nxcomp-1.5.0-65 + +- Removed the warning issued on parsing the agent option 'rootless'. + Solves the TR08C00959. + +- MacOSX 10.4 defines socklen_t. Made the definition conditional so + that we can still support older versions. Solves the TR07C00926. + +- Updated the ChangeLog to include references to the solved TRs. + +nxcomp-1.5.0-64 + +- Imported the 1.6.0 changes in the maintenance 1.5.0. + +- Removed a wrong assertion that might cause the session to fail + when the software was compiled with TEST enabled in Proxy.cpp. + +- The nxclient dialog process is signaled with SIGKILL on Windows, + as the SIGTERM is ignored. This solves the TR07C00929. + +- Ensured the JPEG error flag is always set before jumping out of + the Jpeg decompression. + +- Skipped errors encontered setting the TCP_NODELAY flag on Mac. + Solves TR08C00940. + +- Few cosmetic changes. + +nxcomp-1.5.0-63 + +- Ensured that the parent is checked often in the keeper process, + so that, in the case of a premature death, the child is exited + earlier. + +nxcomp-1.5.0-62 + +- Some performance tuning of the LAN and WAN link modes. + +nxcomp-1.5.0-61 + +- Fixed the problems arisen with loading or saving the image files + on Windows by forcing the streams to be opened in binary mode. + These problems have been triggered by the recent Cygwin upgrade. + +- Removed the logs that had be left enabled for test purposes. + +nxcomp-1.5.0-60 + +- Made all errors encountered while unpacking an image just print + a warning in the session log. Such errors are not fatal but the + client monitors the state of the session at startup, so that by + marking image decompression errors as such may cause the session + to be aborted. + +- Marked as warnings also errors encountered by trying to load an + image from disk. + +nxcomp-1.5.0-59 + +- When detected, the CTRL+ALT+SHIFT+ESC sequence is removed from + the event stream. + +- Also modified the message in the session log to issue a warning, + instead of an error. + +nxcomp-1.5.0-58 + +- Added a setjmp() before yielding the control to the JPEG library. + This makes possible to recover from the JPEG decompression errors + that were previously fatal. + +- In the commit split request, the client id is now encoded by the + client channel beside the propagate flag. The client id is igno- + red by the decoding party. As in the old protocol versions, the + committing client is taken from the client id that was originally + sent together with the packed image. + +- Fixed the compilation problem when defining OPCODES in Misc.cpp. + +- Skipped the synchronous flush of the proxy link when connecting + to a previous NX version. + +- Ensured that the new alerts are only requested when connected to + a compatible proxy. + +- Ignored the option 'fullscreen', targeting the agents. + +nxcomp-1.5.0-57 + +- Added more alerts and changed the name of those dealing with the + resume of a session. + +- Added the MIXED define. When set, the proxy will let all logs go + to the standard error. This is useful to interleave the Xlib log + output with the proxy output in a single file. + +- Added a new alert to report an I/O error at agent reconnection. + This is one of those alert that can't be actually shown, but are + included to offer a consistent view to the agent implementation. + +nxcomp-1.5.0-56 + +- Added the split mode NXSplitModeSync. By selecting this mode, + the proxy will try to empty the split store immediately, until + all messages marked in such mode will be synchronized. The im- + plementation is left to future versions. + + #define NXSplitModeSync 3 + +- Added the messages specific to RDP and VNC sessions in NXalert.h. + Included are also a few alerts related to changes to the color + depth and desktop geometry that may be eventually mandated by the + remote server. + +- Corrected a typo in NXalert.h + +nxcomp-1.5.0-55 + +- Added the 'mode' field in the X_NXStartSplit request. It determi- + nes the strategy that the proxy will adopt to handle the image. + If set to 'eager', the proxy will only split the messages whose + size exceeds the split threshold (the threshold can be found in + the X_NXGetControlParameters reply). If mode is set to lazy, the + proxy will split any image that it is not able to find in its + cache. + + The opcode and the two available modes are defined in NXproto.h, + currently: + + #define NXSplitModeDefault 0 + #define NXSplitModeEager 1 + #define NXSplitModeLazy 2 + +- All requests related to image streaming now carry a 'resource' id. + The id is currently ignored by the proxy in the case of X_NXCom- + mitSplit requests. + +- Added a new NXSetSplitMode() request. It determines the strategy + that the proxy will adopt to stream the images. If set to 'eager' + the proxy will only split the messages whose size exceeds the + split threshold, otherwise it will split all the images, regard- + less their size. This is in preparation of the lazy encoding in + agent. + +- Slightly decreased the startup timeout compared to the value it + had in the 1.4.0. This timeout is used to retain the images used + during session startup in the persistent cache. + +nxcomp-1.5.0-54 + +- Modified the text of the begin-reconnection alert to mention the + speed of the connection detected by the agent. + +nxcomp-1.5.0-53 + +- Reworked the handling of the abort-split events issued by the re- + remote proxy so that we now finalize the procedure and restart the + client asynchronously, in the middle of the write loop. + +nxcomp-1.5.0-52 + +- Rewritten the internal interface to the notification events. There + are now five different split notification events: + + NXNoSplitNotify The operation didn't cause any actual split. + The client can be immediately restarted. + + NXStartSplitNotify A split is ongoing. The client should be + suspended until the end of the split. + + NXCommitSplitNotify A complete request has been recomposed. The + client can commit the given request to the + X server. + + NXEndSplitNotify The split operation was duly completed. The + client can be restarted. + + NXEmptySplitNotify No more split operation are pending. The + agent can use this information to implement + specific strategies, requiring for example + that all messages have been recomposed at + the remote end. This can include updating + the drawables that were not synchronized + because of the lazy encoding. + +- Removed the X_NXSync and X_NXKarma operations, not used anymore by + the NX agents. + +- Increasing or decreasing a timeout makes it respectively equal to + the base timeout or to the base timeout / 4. + +nxcomp-1.5.0-51 + +- Improved the mechanism by which synchronization replies are sent + to the X client proxy. + +- Using the leftPad field as passed by the nxagent 1.5.0-58 doesn't + seem to work with the MIT-SHM. The workaround is to disable the + MIT-SHM operation in the case of 1 bpp images. + +- Removed the limitation on the size of the shared memory segment + that had been introduced for test purposes. + +nxcomp-1.5.0-50 + +- Solved compilation problem when --with-info was not given. + +nxcomp-1.5.0-49 + +- Improved support for color matching from 15 and 16 bpp to 24 and + 32 bpp in RDP sessions. + +- Solved TR05C00910. This was about "shadows" that might appear in + RDP sessions when small elements like tooltips were drawn. + +nxcomp-1.5.0-48 + +- Added a 'commit' field in X_NXCommitSplit request. When zero, the + X server side proxy will unlock the message in the message store, + without actually committing the image to the X server. The new + field required changes to the encoding. This means that this ver- + sion is not compatible with older 1.5.0 nxcomp releases. + +- Added a new control message. This is used by NXTransFlush() to for- + ce a roundtrip between the proxies and speed-up the handling of + the synchronous replies. + +nxcomp-1.5.0-47 + +- Made the timeouts dynamic, based on the user input and the current + bitrate. + +- Set the available tokens to 8. This allows for 16 KB to be sent on + a modem before having to wait for a reply. + +- Added provision for removing a dialog on the remote end. This can + be used, for example, to get rid of a message that was displayed + by the agent at the beginning of a lengthy operation. + +- Fixed a fault that arose when trying to run the proxy on a display + whose name began with the 'nx' string. + +- Running a client or server session on a display host beginning with + 'nx' should be now possible. + +- Flush is now always immediate when there is already data queued in + the TCP socket. + +nxcomp-1.5.0-46 + +- Created the NXalert.h header from Alert.h to share the alert codes + with the agents. The new NXTransAlert() interface can be used to + start an alert on the remote side. + +- Created the NXTransParse*() and NXTransCleanup() wrappers. + +- Temporarily using the single-dash style when passing parameters to + nxclient until the double-dash style is fixed. + +nxcomp-1.5.0-45 + +- Motion events are now flushed at the time the X server channel is + sending the token reply. + +- Renamed NXDialog() to NXTransDialog() and added a window ID parame- + ter, to be used by the agent when starting the "pulldown" dialogs. + +- Also renamed the other NX utility functions. + +nxcomp-1.5.0-44 + +- Solved a bug that prevented auxiliary X connections from working + with the agent. + +- Added the missing check on the proxy pointer in HandleTimer() as + it may be actually called before the proxy is created. + +nxcomp-1.5.0-43 + +- Started tuning the performance. For now, the available tokens are + set to an improbable value of 10000. + +nxcomp-1.5.0-42 + +- Disabled the X server side remote expose events for test purposes. + This is intended uncover the display problems introduced by the + new handling of exposures in the X11 agent. + +- Fixed some timestamp related functions to avoid rounding problems. + +- Moved the timestamps of split, frame and flush from the Control + to the Proxy class. + +- Made the X server side proxy to skip updating the counters related + to token management. + +- Made also the X server side use deferred flushes. + +- Modified handleFrame() to manage both pings and data frames and + send the token before the actual write operation. + +- Cleaned the pseudo-files used to load the control parameters. + +- Cleaned up the FIXME's in the lower layers. More FIXME's remain in + the frontend classes. + +- Added a further counter to the statistics tracking the number of + network writes performed on the proxy link. + +nxcomp-1.5.0-41 + +- Now the watchdog process doesn't kill the parent. The termination + event is determined by monitoring the child. This is advisable to + avoid interfering with the signal handling in agent. + +- The house-keeping process is not started if differential compres- + sion (and thus caching of images) is disabled. + +- Wait for the watchdog to terminate before starting the house-keep- + ing process. + +- Fixed the problem of gray stripes in white areas when using 15bpp + RDP compression. This solves the TR06C00916. + +- Added a log in Message.cpp to tell when an image is removed from + the memory cache. + +- Removed most of the logs. Only left the logs directly related to + the deferred flushes. + +- Removed a warning due to a missing definition in NX.h. + +nxcomp-1.5.0-40 + +- Added the signal '12' to the set of blocked signal on Cygwin. This + is what is delivered to the application when it tries to create a + shared memory segment when the cygserver is not running. The call + later returns "Operation not implemented", only useful if you have + survived to the signal. + +- Modified the configure script to not link against cygipc. + +- Improved error handling in the negotiation phase. + +- Reset the last signal received when aborting a connection attempt. + Not doing that might cause a warning. + +nxcomp-1.5.0-39 + +- Both channels and proxy can now deal with incomplete messages by + waiting for the full data to become available. This is not going + to work when the transport is connected to an agent that is run- + ning in-process, so the timeout must be really small. + +- Made the main loop more compact by letting a single function read + from proxy and channels. The same change applies to writing to + descriptors that are reported to be ready. + +- Optimized the loop to report as ready the agent descriptors that + have become available after the proxy execution phase. + +- Now the proxy will try to asynchronously read from its descriptor + after having read from the channel. + +- Unified the routine setting the routines setting the read and write + descriptors and the timeouts. + +- Unified the routine handling the channel events. + +- Reintroduced the last ping timestamp to avoid sending more than a + single ping every PingTimeout milliseconds. + +- The cleanup procedure now waits for the watchdog and house-keeping + processes to terminate. + +- Reverted the change occurred in 1.5.0-35 about the byte-ordering + problem in decompression of PNG and JPEG images. + +- More coding about deferred flushes. + +- Relevant debug logs are enabled in the main loop, in the proxy and + in the channel classes, so use only for testing. + +nxcomp-1.5.0-38 + +- Started the implementation of deferred writes based on the new NX + transport. + +- Solved a problem with the statistics file affecting the Windows + platform. Basically it seems that Cygwin or the stdc++ library + don't deal correctly with files that are reopened just after + having unlinked them. + +- Implemented support for 15 bpp RDP bitmaps. + +- Added "rdpcolors" and "rdpcache" to the list of parameters that + are ignored in ParseEnviromentOptions(). + +- This version has lot of logs enabled and some forced cleanups in + the case of unexpected conditions. Avoid to use it for long-last- + ing test sessions. + +nxcomp-1.5.0-37 + +- Now splitting of images is fully disabled when running with link + LAN. Previously the split was not executed by the proxy, but the + agent was configured to send the start/end sequence. + +- Added the check protecting the proxy from token underflow. In the + previous code the check was left out to verify the conditions un- + der which this event might be encountered. + +- NXTransWrite() and NXTransWriteVector() allocate a context before + calling handleRead(), so they can correctly return in the case of + a cleanup. + +nxcomp-1.5.0-36 + +- Modified the channel write loop to interleave abort split events + between the writes to the X server socket. + +nxcomp-1.5.0-35 + +- Solved a byte-ordering problem in decompression of PNG and JPEG + images. + +- Changed the handleToken() interface to make explicit if a token + must be issued because of a ping. + +- Small fix to prevent a warning in Jpeg.cpp when TEST is enabled. + +nxcomp-1.5.0-34 + +- Solved a few problems introduced by the rewrite of the read loops + in channels. + +- Added definition of NXCollectInputFocusNotify. + +nxcomp-1.5.0-33 + +- Implemented a new control flow system based on tokens exchanged bet- + ween the proxies. When the clint side runs out of tokens it stops + sending data until a new token is returned. Tokens are sent whenever + the data written to the socket exceeds the amount of data set for a + scheduled write, so the proxy is free to send a number of smaller + frames before running out of tokens. + +- The reason the new system is introduced is because the old method + had two outstanding problems: + + - It worked very well when the proxies were directly connected, + but couldn't reliably detect a link congestion when tunneled + over SSH. + + - In the attempt of reducing the data queued to the TCP layer, it + didn't leverage all the available bandwidth. + +- Moved the final check on the state of the session at the end of + execution stage, instead of the beginning. The signals sent by the + user to request the statistics could be reset before the proxy had + entered the right procedure. + +- Added the session type 'unix-rootless', to be used for single apps + run with the agent in rootless mode. + +nxcomp-1.5.0-32 + +- Modified the main loop to skip the select when I/O is possible on + any of the agent descriptors or the proxy link. + +- Now the house-keeping process is allocated in the heap instead of + the stack. + +nxcomp-1.5.0-31 + +- The server channel now performs asynchronous reads from the display + by interleaving them with data decoded from the remote proxy. + +- Improved the handling of the memory-to-memory transport. + +nxcomp-1.5.0-30 + +- Redesigned the handling of the congestion events to work more re- + liably and to report the events to the remote peer earlier. + +- Increased the size of the shared memory segment when the MIT-SHM + extension is activated. + +- Solved a bug that prevented the ping timeout to work as expected. + +- Ensured that, when entering the main select(), neither the chan- + nels or the proxy have pending messages in the read buffers. + +- There is now only a single case where we can have pending messa- + ges, namely in the handling of the MIT-SHM events. + +- Solved a bug introduced by the 1.5.0-29 that made the proxy en- + ter the select with a null timeout. + +- Renamed LINK_TYPE_AUTO to LINK_TYPE_NONE in NXproto.h. + +nxcomp-1.5.0-29 + +- Now encoding data from the agent descriptors happens in the same + context as data is written to the buffer. + +- Optimized the handling of the congestion events to avoid running + further unneeded loops. + +- Added timer handling utilities. + +nxcomp-1.5.0-28 + +- Added code providing information about the reason of the failure + encountered connecting to the local X server. This greatly helps + when troubleshooting X authorization problems. + +- On connection failure a warning message is printed in the session + log. + +- Removed the warning that was previously printed when the MIT-SHM + extension failed to be initialized on Windows. Shared memory has + problems on Cygwin and it currently doesn't work in NXWin. + +- Reworked the message printed in the case of link failure. + +nxcomp-1.5.0-27 + +- Solved a bug in the connection procedure introduced by 1.5.0-25. + +nxcomp-1.5.0-26 + +- Transformed the errors printed on failure of the fork() creating + the children into warnings. This can happen quite often on Win- + dows, due to well known Cygwin problems. See also the ChangeLog + entry for nxcomp 1.4.0-28. This patch closes the TRSL052278 but + it's obviously not a long-term solution. + +- Set the sticky bit when creating the '/tmp/.X11-unix' directory. + +- Modified the Makefile.in to remove the *.out.* files generated by + Valgrind. + +- Updated the README files. + +nxcomp-1.5.0-25 + +- Changed the directory where the client for the Mac is searched if + it is not found in the system path. + +- Modified Auth.cpp to use nxauth also on the Mac. + +- Reworked the procedure showing the alert dialog when a timeout is + encountered in the initial connection. + +- Removed the experimental code from the official 1.5.0 branch. + +nxcomp-1.5.0-24 + +- Implemented more experimental classes. + +nxcomp-1.5.0-23 + +- Added the NX_SIGNAL_FORWARD action to NXTransSignal(). This can + be used to let the proxy call the original signal handler of the + agent after having blocked the signal. + +nxcomp-1.5.0-22 + +- Ensured that we always have a context, even before creating the + transport. + +- Suppressed the error message printed when passing the -h option. + +- Added the experimental code that is currently under development. + +nxcomp-1.5.0-21 + +- Enabled the fake X cookie authentication. This requires checking + the remote proxy version to verify that the server supports the + new authorization mechanism. + +- It's worth noting that the X client side proxy doesn't care which + cookie is sent over the connection. The problem is that clients + connecting to 1.4.0 servers don't have a method to force the ser- + ver to use the fake cookie. This means that we have to solve the + problem by letting the proxy check the remote version so that it + can omit to replace the cookie when connecting to older servers. + +nxcomp-1.5.0-20 + +- Added the NXTransCongestion() function. It returns true if proxy + is in congestion state. + +- Removed an incorrect warning that was printed when calling force() + for the memory-to-memory transport. The agent could actually re- + quire multiple loops to read all data queued for it. + +nxcomp-1.5.0-19 + +- Small optimization in NXTransReadable() to run a new NXTransConti- + nue() loop only after at least RetryTimeout milliseconds are pas- + sed since the last call and still no data is available. This cuts + the number of unneeded loops to 1/4th of the total, probably more, + on faster machines. + +- Added NXCollectGrabPointerNotify to NXproto.h. + +nxcomp-1.5.0-18 + +- Minor changes to NXTransContinue(). + +nxcomp-1.5.0-17 + +- Moved respawning of a new nxclient instance in the cleanup procedu- + re. This ensures that the respawn is executed whatever is the rea- + son of the session shutdown. + +- Added a method to force closure of a given channel in proxy. + +- Removed code handling the special case triggered on Windows by the + presence of a NX_SESSION variable in the environment. + +nxcomp-1.5.0-16 + +- Added the NXTransSignal() function to let agents tell to the proxy + how to handle the standard POSIX signals. Given the SIGINT signal, + for example, the caller can specify any of the following actions. + + NX_SIGNAL_ENABLE: A signal handler will have to be installed by + the library, so that it can be intercepted by + the proxy. + + NX_SIGNAL_DISABLE: The signal will be handled by the caller and, + eventually, forwarded to the proxy by calling + NXTransSignal() explicitly. + + NX_SIGNAL_RAISE: The signal must be handled now, as if it had + been delivered by the operating system. This + function can be called by the agent with the + purpose of propagating a signal to the proxy. + + As a rule of thumb, agents should let the proxy handle SIGUSR1 and + SIGUSR2, used for producing the NX protocol statistics, and SIGHUP, + used for disconnecting the NX transport. + +- The following signals are blocked by default upon creation of the + NX transport: + + SIGCHLD These signals should be always put under the control + SIGUSR1 of the proxy. If agents are intercepting them, agents + SIGUSR2 should later call NXTransSignal(..., NX_SIGNAL_RAISE) + SIGHUP to forward the signal to the proxy. + + SIGINT These signals should be intercepted by agents. Agents + SIGTERM should ensure that NXTransDestroy() is called before + exiting, to give the proxy a chance to shut down the + NX transport. + + SIGPIPE This signal is blocked by the proxy, but not used to + implement any functionality. It can be handled by the + NX agent without affecting the proxy. + + SIGALRM This is not blocked by the proxy, but could be used + in future. + + SIGVTALRM These signals are not used and should not be used in + SIGWINCH future versions of the library. + SIGIO + SIGTSTP + SIGTTIN + SIGTTOU + +- By calling NXTransSignal(..., NX_SIGNAL_DISABLE) nxcomp will res- + tore the signal handler that was saved at the time the proxy hand- + ler was installed. This means that you should call the function + just after the XOpenDisplay() or any other function used to init- + ialize the NX transport. + +nxcomp-1.5.0-15 + +- In NXTransContinue(), if the transport is gone, return immediately, + that is without having to wait until the NXTransSelect() timeout. + +- Ensure that NXTransCreate() has a jump context, just in the case + a subsequent operation would cause a cleanup. + +nxcomp-1.5.0-14 + +- Solved a problem with requests left in the agent's buffer when run- + ning the NX transport. The agent could have enqueued data to our + side and checked the available events but requests could not be + written to the proxy because proxy might not have had a chance to + enter a new select. We found that this behaviour was triggered by + _XEventsQueued, so now a new loop is forced when agent is calling + _X11TransDataReadable. The procedure can be optimized, by avoiding + an expensive loop when no critical I/O is pending. + +- Added a few additional logs to ClientChannel and ServerChannel. + +nxcomp-1.5.0-13 + +- Added the code handling the special cases of an user not specifying + a proxy cookie or the case of the X authorization file not contain- + ing a value matching the display. In the first case we'll forward + the same cookie that was feeded to the proxy, in the second case we + will forward to the X server a random generated cookie, similarly to + what SSH does in this same condition. + +- Rewritten the command line parser. Removed all the command line + options parsed on behalf of nxproxy except: + + -C Specify that nxproxy has to run on the "X client" + side, listening for connections and impersonating + an X server.\n\ + + -S Specify that nxproxy has to run in "X server" mode, + thus forwarding the connections to daemons running + on the client.\n\ + + -V n.n.n Request nxproxy to load the given nxcomp version. + This option is only present on Solaris and Linux. + + -v Print version information. + + host:port Put at the end, specifies the host and port of the + listening proxy. + + value=name Set the NX option to the provided value. + + Multiple NX options can be specified in the DISPLAY environment or + on the command line, by using the nx/nx,name=value notation. + +- The above information is printed on the console when incurring in + a parse error, together with a list of the available option=value + parameters. + +- Renamed the 'log' option to 'errors'. This makes sense as the de- + fault name for the log file is actually 'errors'. + +- Now the "Established X server connection" message is printed to + the session log only after the X connection has passed the X auth- + entication phase. This means that the NX client should become able + to show the details of the session log whenever the session fails + due to a cookie problem. + +- When selecting the additional services without specifying a port, + the client proxy will now automatically forward the connections to + the corresponding well-known ports of the CUPS, SMB and HTTP servi- + ces. Embedded X keyboard connections will be automatically forward- + ed to the same display port used to connect to the X server. The + user will still have to specify the port to be used for the media + connections as we don't have a suitable well-known port. + +- Starting from this version, connections to the keybd port will cre- + ate real X connection channels. This is required to let connections + leverage the fake authorization cookie. + +- By testing the forwarding of keybd connections I found that, when + letting X clients connect to the port, it is required to provide + the X cookie for the unix display. Adding only the TCP cookie will + not work. For example, by creating a cookie as in: + + xauth add localhost:2009 MIT-MAGIC-COOKIE-1 6f...f4 + + And running: + + xterm xterm -display localhost:2009 + + You will get the following error: + + Xlib: connection to "localhost:2009.0" refused by server + Xlib: No protocol specified + + Adding also the unix cookie will fix it: + + xauth add localhost/unix:2009 MIT-MAGIC-COOKIE-1 6f...f4 + + This seems to be a Xlib problem, with Xlib trying to get the cookie + for the UDS port even if the TCP port was requested by the user. + +- Fixed a bug that prevented the nxclient dialog to be displayed when + the session was abruptedly shut down. + +- Fixed the compilation error on Apple MacOSX due to the sa_restorer + field in sigaction. As long as this field is present on Linux we + will keep following the safer route and will set it explicitly to + NULL. + +- Included what needs to be included in Process.cpp to compile with + older gcc. + +nxcomp-1.5.0-12 + +- Implemented a replacement for the popen() and pclose() that do not + rely on a shell to run the command. They were required on Windows, + where we don't ship a suitable shell in the install. + +- Removed code forcing the PATH to include the bin directory on + Windows. + +nxcomp-1.5.0-11 + +- Forced Auth.cpp on Windows to have the directory containing the + nxauth executable in the PATH. This is just for testing, until + nxclient is fixed. + +- Fixed compilation errors on Cygwin and Sun. + +- Removed the NX_FORCE_* stubs. + +nxcomp-1.5.0-10 + +- Modified the memory management policies in ReadBuffer to fit all + the available bytes in a single buffer allocation. + +- The locateMessage() methods now give hints on the amount of data + that has to be read. + +- The read loop in channel now doesn't yield in the case of prio- + ritized messages. This is experimental. + +- Removed the check on isTimeToYield() between encodings of multi- + ple messages. This is aimed at reducing the risk of leaving pen- + ding messages in channels. + +- Modified the channels' read loop to always read all the available + data. + +- Disabled the log output that was selected when compiling with the + configure option --with-info. This leaves space for other log out- + put to be selected for more up-to-date scopes. + +- Implemented the NXTransReadVector() and the NXTransWriteVector() + functions to replace READV() and WRITEV(). + +- Implemented memory-to-memory communication between the agent and + the NX proxy by making use of the NXTransAgent() interface in the + nx-X11/lib/X11/Xtranssock.c file. + +- Added a check in NXTransSelect() for the EBADF and, on Solaris, + the EINVAL errors. It can happen in the X11 code that a descript- + or has become invalid before it is removed from the managed set + +- Rewritten the signal handling functions to restore the old actions + and masks when the NX transport is destroyed. + +- Added a NXTransAgent() function to let agents tell the proxy which + descriptor must be used for the controlling connection. Setting a + controlling connection has the effect of disabling further X client + connections and makes the proxy terminate when the channel is shut + down. + +- Solved a problem with setting the initial timeout in the select(). + +- Modified the Makefile.in to not include -Wno-deprecated when compi- + ling C programs. + +nxcomp-1.5.0-9 + +- Fixed a problem that prevented the 1.5.0-8 to work on the NX server + side. + +- This version has NX_FORCE_NULL_LISTEN_OPTION and NX_FORCE_NEW_SES- + SION_OPTION undefined, so it should work in a way that is compati- + ble with the old nxcomp. + +nxcomp-1.5.0-8 + +- The new code comes with a preliminary integration of nxcomp with + SSH. It is now possible to create the NX transport by just calling + the "switch" command as in the following example: + + NX> 299 Switching connection to: NX options: ... + +- Other possible forms for the NX switch command are: + + NX> 299 Switching connection to: NX mode: ... + + NX> 299 Switching connection to: NX mode: ... options: ... + + Or just: + + NX> 299 Switching connection to: NX + + The "mode" parameter is there to provide a way to run both enc- + rypted and unencrypted connections. Possible values are "encrypt- + ed", "unencrypted" or "default", the latter being an alias for + "encrypted". Unfortunately I was not able to test unencrypted + connections, so this may or may not work. + +- The top-level process can create the NX transport layer by calling + NXTransCreate(). The user has to set up a socket pair and pass the + higher descriptor to nxcomp. nxcomp will later monitor its end, by + reading and writing NX-encoded traffic. The user has to call the + NXTransExecute() function as often as it is possible, by letting + first NXTransPrepare() combine the sets of NX descriptors with the + descriptors that are used inside its process. A custom NXTransSel- + ect() is provided to optionally replace the original select(). This + function saves the original error code and the number of selected + descriptors upon exit, so the user can call it, restore the original + values as they were returned by the select() and run the rest of + the loop unmodified. + +- Future versions of the library should provide appropriate methods + for passing data to and from the proxy by means of a memcpy(), so + that it will be possible to remove the even minimal TCP overhead. + +- Note that integration is far from complete. More work is required + especially to manage the shutdown cleanly, in a way that gives to + SSH a chance to free its resources, and on adding facilities for + handling SSH and NX signals in a single function. + +- Rewritten the initialization procedure to make possible to run the + proxy in-process in an arbitrary connection manager, like SSH or a + HTTP utility. The same functionality can be used to embed nxcomp in + the NX agents, so that nxcomp has not to run in a separate process. + +- A new state-machine handles the advances through the connection + stages until the remote proxy (or the forwarder process ) is auth- + enticated, options have been negotiated and the session is started. + +- The option "session" is now used to pass the name of the session + file to the proxy. The parameter was previously used to pass the + literal name of the session, as set by the user, and was ignored + by the proxy. By default the session log is the standard error of + the process. It is anyway required to set the option when running + inside SSH, otherwise output will go to the same file as the SSH + output. In the NX client this would be the 'sshlog' file. + +- This version can be easily crafted to test the new integration by + setting the following define: + + NX_FORCE_NULL_LISTEN_OPTION + + This makes possible to test the nxcomp/nxssh integration by using + any production 1.4.0 client. To run this version you are required + to use nxproxy 1.5.0-4 and nxssh-1.5.0-6. + +- New functions handling enabling and disabling signals, based on + sigprocmask(). + +- Improved error reporting when failures are encountered while ne- + gotiating the session. + +nxcomp-1.5.0-7 + +- Caches are saved with a version identifier 1.4.0 so that they are + not discarded after upgrading the software to the 1.5.0. + +- Made values of T_* enumerations to be all lower case. + +- Updated copyright to year 2005. + +- Started working on an interface for running nxcomp in-process, as + a additional transport layer of nxssh or nxagent. + +nxcomp-1.5.0-6 + +- Modified the configure script and the makefiles to not include the + -Wstrict-prototypes and -Wmissing-prototypes compilation flags. The + -Wnested-externs and -Wmissing-declarations flags are not included + when using GCC 3. + +- Removed the initial newline from string "NXPROXY - Version" printed + at program startup. + +- Made X authentication compatible with 1.4.0 clients. This is a tem- + porary solution while code is updated to handle the new X authori- + zation scheme. + +nxcomp-1.5.0-5 + +- Added an Auth class to handle the X authentication. The NX server + should now use the same proxie cookie that is passed by the client + at session startup. The X server side proxy will forward the autho- + rization credentials by replacing the fake cookie with the real co- + okie, as it is read from the auth file using the xauth utility. The + implementation is based on the corresponding code found in the SSH + client and comes with the same limitations: only MIT-MAGIC-COOKIE-1 + cookies are checked and the authorization file is read only once, + at the time the instance is initialized. If the auth file changes + along the life of the session, the old cookie will still be used. + This works with X servers because of an undocumented "feature". + See also nx-X11. + +nxcomp-1.5.0-4 + +- Adjusted for alarm(0) returning an inconsistent value in ConnectTo- + Remote(). + +- Small changes to Types.h, Jpeg.cpp and Png.cpp to compile with gcc + 3.4.2. + +- Cosmetic changes to the ChangeLog file. + +nxcomp-1.5.0-3 + +- Removed test code from ServerChannel.cpp. + +- Small cosmetic change in Loop.cpp. + +- Tested for compatibility against 1.4.1-8. + +nxcomp-1.5.0-2 + +- Changed VERSION file according to TRCL052336. + +nxcomp-1.5.0-1 + +- Opened the 1.5.0 branch based on 1.4.1-9. + +nxcomp-1.4.1-9 + +- Implemented methods PACK_RDP_PLAIN_64K_COLORS and PACK_RDP_PLAIN_- + 16M_COLORS. It seems that 16 bpp plain bitmaps can be seldom recei- + ved. This doesn't seem to be the case of 24 bpp bitmaps. + +nxcomp-1.4.1-8 + +- The new code enables use of 16 bpp and 32 bpp RDP bitmaps. This re- + quired modifications to the following files: + + Misc.h + Misc.cpp + Loop.cpp + Control.cpp + ServerChannel.cpp + Unpack.h + Unpack.cpp + +- Lots of cosmetic changes compared to the original code in 1.4.1-7. + +- Merged the 1.4.0 and the 1.4.1 branches by importing changes up to + the 1.4.1-7. + +nxcomp-1.4.0-30 + +- Modified the function checking the Unix socket where X connections + will be forwarded. The function will not fail if the socket itself + doesn't exist yet. This solves the TRCL042203. + +- Moved the code checking for the CTRL+ALT+SHIFT+ESC sequence to a + separate function. The implementation will now look for a different + sequence on the MacOS/X platform. This should solve the TRCL042182. + +nxcomp-1.4.0-29 + +- Solved a bug that could cause proxy to stop reading data from the + X channels due to an incorrect calculation of the bytes queued on + the proxy link. The bug only affected Linux kernels of the 2.0/2.2 + series. + +- Fixed a problem in the proxy class that could let the select time- + out to become zero. + +nxcomp-1.4.0-28 + +- Prevented the main proxy process from quitting when the fork() of + any of the children fails. This can actually happen on Windows due + to conflicts in reallocating any of the Cygwin DLLs. + +- Reworked handling of the priority flag in channels when dealing + with the X_InternAtoms and X_AllocColor requests to reduce the time + of session startup. Priority is never set in case of X_InternAtom + requests and replies as we assume that most clients use the appro- + priate Xlib function to pipeline multiple requests in a single net- + work operation. + +- The timeout after which proxy will abort the peer connection is + still 120 seconds. An alert dialog will be shown earlier, after 30 + seconds instead of 60. + +nxcomp-1.4.0-27 + +- Removed the code setting priority on channels on ButtonPress and + Button release events. It seems preferrable to delay the flush and + pack more events in a single frame. This makes possible to get the + ButtonRelease together with the ButtonPress. + +- Fixed error detection in SetNoDelay() where a positive result + could produce a 'not supported' message in debug mode. + +nxcomp-1.4.0-26 + +- Reworked the check aimed at detecting the clock drifts. The previ- + ous code, introduced in 1.3.2-2, had the undesired side-effect of + resetting the proxy timeout. This could cause the proxy to never + detect that the other end had been killed. + +- The default behaviour of proxy is now to terminate the session at + the time an error is encountered. This includes network failures. + +- Added a new dialog to be shown to the user whenever the session + is terminated abnormally. + +nxcomp-1.4.0-25 + +- Fixed a bug in handling of suppression of errors generated by + committing the image splits. Other errors, unrelated to the commit + of split, could be suppressed. This might cause the hangup of the + session when the suppressed error was matching a reply. + +nxcomp-1.4.0-24 + +- When killing the proxy process -9 the watchdog could remain alive. + This caused the SSH link to keep the stderr open, with the effect + that former proxy message were not flushed to the session log. + Now the watchdog checks every second if the parent is dead, so + that file descriptors can be closed as soon as possible. + +- SetupDisplaySocket() tried to force the connections to the X + server on the UNIX port whenever the display was set to localhost. + This patch was intended to fix a bug in nxclient, using the TCP + port even when the display was set to a UNIX socket. This beha- + viour caused problems when running nxclient on a remote host by + means of a ssh -X. Proxy will now adhere to the display setting. + +nxcomp-1.4.0-23 + +- Added the possibility to respawn nxclient at the end of session. + This is an useful feature when powering thin-clients where NX + is the only application made available. + +- This configuration applies system-wide to the local client ins- + tallation. By default it is disabled. It can be enabled by the + by creating a 'noexit' file in the directory '/usr/NX/share', + or at compile time, by setting ENABLE_RESTART_ON_SHUTDOWN to 1. + +- Note that the solution is not perfect yet, as there are cases + where session could die without going through HandleShutdown(), + for example if a decoding error is raised in the communication + with the remote peer and the subsequent restore of the proxy + link fails to succeed. + +nxcomp-1.4.0-22 + +- Corrected typos in Timestamp.h and Loop.cpp. + +nxcomp-1.4.0-21 + +- Tuned the handling of RenderCompositeGlyphs. Now compression of + RENDER shows an average ratio of 8:1. This is a steady increase + compared to the 5:1 of the 1.3.2 version. The overall advantage + when running clients displaying a large amount of text is 30%. + +nxcomp-1.4.0-20 + +- Added a new message store for the CreatePixmap request. + +- Fixed handleCopy() to only send the data part past the offset. + This fix can save a significant amount of traffic, especially + when sending many small images whose size doesn't reach the + threshold set for compressing them. + +nxcomp-1.4.0-19 + +- Added tuning of all the RENDER requests. RenderCompositeGlyphs + will require further work. + +- Completed porting of the RENDER requests to the new templates. + +nxcomp-1.4.0-18 + +- Tuned the handling of RenderCreatePicture and RenderFreePicture. + +- Created a new template system for writing new message encoders. + +- Renamed getBits() in EncodeBuffer with diffBits(). The getBits() + method now returns the bits actually allocated in the buffer and + can be called multiple times. + +nxcomp-1.4.0-17 + +- Provided specific encoding of the remaining RENDER requests and + added compression of RenderCreateGlyphSet. + +nxcomp-1.4.0-16 + +- Code underwent through 7 different patch versions but seems to + be stable now. It still needs to provide specific encoding for + RenderCreatePicture RenderChangePicture and RenderFreePicture. + Code will likely include incompatible changes at any new version + until the new encoding will stabilize, so be sure that you use + the same nxcomp version at both sides. + +- Created the infrastructure for compressing extension messages + based on the minor opcode. A new class, MinorMessageStore, has + to be inherited by stores requiring specific compression, so + that all the encoding methods of the parent can be redirected + to it. The RENDER extension is now compressed using this new + class. + +- Managed to maintain the compatibility with caches created by the + 1.3.X version. Caches will be saved using the old format if the + remote version is not a 1.4.x. When restoring a cache created + by the 1.3.x with both proxies being the newest version, RENDER + mesages will be discarded without having to discard the whole + cache. + +- Added a member to the message class to store the identity size. + This field is now used instead of the default data offset to + manage the message data, that is the part of message after the + identity. + +- Removed the warnings printed in the session log when passing the + 'kbtype' and the 'geometry' options to the proxy. These options + are actually used by agents. + +nxcomp-1.4.0-15 + +- Started implementation of the new framework for handling enco- + ding of X extensions. + +- Renamed the overloaded methods handleEncode() and handleDecode() + to handleEncodeCached(), handleEncodeIdentity() and handleDecode- + Cached(), handleDecodeIdentity(). + +- Updated the copyright notice to year 2004. + +nxcomp-1.4.0-14 + +- Added the new channel for HTTP connections. This channel can be + used to let applications running on the NX server get access to + data and applications made available by a HTTP daemon running at + the client side. + + This channel is not used at the moment by nxclient. It can be + activated by passing http=1 to the NX server side proxy and the + value http=80 to the NX client side. + +nxcomp-1.4.0-13 + +- Quick patch to run on MacOS/X where inet_addr("127.0.0.1") + alone seems to fail to return a valid interface. + +nxcomp-1.4.0-12 + +- Few cosmetic changes to logging. + +- Removed the debug output. + +nxcomp-1.4.0-11 + +- Removed code used for simulating the new forwarding function- + ality without client and server support. + +nxcomp-1.4.0-10 + +- Implemented authentication of the forwarder to the listening + proxy. If a session cookie is required, the forwarder must + provide the cookie upon connection. + + An authentication phase at the time the forwarder connects + to the NX client side is strongly suggested because it is usu- + ally this side that sends the authorization cookie. Without + such a forwarder authentication, the local peer would reveal + the cookie to the first process connecting to the port. + +- If no cookie is specified in the switch command, the forward- + er is required to skip the authentication phase. This can be + useful when running the programs on the command line. + +- The implementation required appropriate changes to session + negotiation in nxssh. This version requires nxssh-1.4.0-8. + +nxcomp-1.4.0-9 + +- Fixed the startup procedure to correctly negotiate the cookie + when the X server side proxy is listening for a forwarder. + +- When listening for a local forwarder (that is when the listen + option is enabled at X server side), proxy will listen for the + forwarder on the localhost interface. + +- This version has ports and and other parameters hardcoded for + testing purposes and is not intended for normal use. + +nxcomp-1.4.0-8 + +- Slightly modified the text of FAILED_PROXY_CONNECTION alert. + +nxcomp-1.4.0-7 + +- Added provision for leaving a running dialog showing an OK box + if proxy is exiting abnormally. This seems to fail to yield the + expected results as, at the present moment, client checks if + parent has exited. + +- Added a Binder class invoked when calling proxy with -B option. + It would serve as a replacement of the modifications I'm doing + in nxssh. The class is just a framework and the implementation + is unfinished. + +nxcomp-1.4.0-6 + +- Added a line in the session log if the connection procedure is + aborted due to a signal. + +- Fixed ParseHostOption() to let it take in account the proxy + port offset when passing 'host:port' as the last parameter at + X server side. + +nxcomp-1.4.0-5 + +- Lowered the default port offsets used for CUPS and SMB services + to 2000 and 3000. Arbitrary ports can be used by passing the ser- + vice's port at proxy startup. By default, anyway, the port is at + the same offset of the proxied display. Considering that the NX + server uses to start the first session at display 1000, we must + lower some of the defaults to avoid interference with the normal + X sessions run on the server. + + Session at display ":1000" will have: + + . Forwarding of CUPS connections at 3000. + + . Forwarding of SMB connections at 4000. + + . The listening proxy (at NX server side) at 5000. This + port is not used when enabling SSH tunneling + + . The proxied X display (NX agent or proxy) at 7000. + + . Forwarding of multimedia channels at 8000. + + . Forwarding of embedded keyboard connections at 9000. + +- Turned off the log output. + +nxcomp-1.4.0-4 + +- Managed to get the X client side proxy connect to the remote + peer. This means that some parameters that were implicitly + assumed based on the proxied port simulating the X display + must be now specified in the NX display string. + +- The 'port' parameter now specifies the remote TCP port where + the local proxy will connect to the remote peer. In previous + versions this parameter also affected the proxied port. This + was mainly a side effect, as the remote peer was always con- + tacted at port 4000 plus the proxied display offset. + +- Added the 'listen' parameter to tell to the proxy that is go- + ing to accept the peer connection on which port it will be + contacted. By default, similarly to the previous version, the + proxy will listen at the proxied display offset. + +- A check has been added in order to disallow passing both the + 'accept' and the 'connect' parameter at the same time. A simi- + lar check affects the 'listen' parameter. + +- Renamed the previously unused 'sync' channel as 'cups'. + +nxcomp-1.4.0-3 + +- Preserved the ability of version 1.3.2 to load caches generated + by this version. + +nxcomp-1.4.0-2 + +- Small fixes to compile under Solaris 8. + +nxcomp-1.4.0-1 + +- Opened the 1.4.0 branch. + +nxcomp-1.3.2-4 + +- Fixed a problem with shmget(). Code in ServerChannel checked + the return value for being greater then 0, while 0 can actual- + ly be a valid segment. + +- When memory cache is disabled, nxcomp will explicitly set the + appropriate control variables dealing with loading and saving + of the persistent cache. This can be considered a cosmetic + change as nxcomp will disable NX delta compression if memory + cache is not available and this has an implicit effect on the + ability to load and save such a cache. + +nxcomp-1.3.2-3 + +- Removed inclusion of zlib.h in Png.cpp. Conflicting symbols + with zlib.h from nx-X11 could cause compilation to fail. + +nxcomp-1.3.2-2 + +- Added a function to take into account the clock drifts at the + time we check the ping from the remote proxy. This can be + caused by the user changing the system time or by small adjust- + ments introduced by the operating system making the clock go + backward. Such events could cause the proxy link to be shut + down and reconnected. + +- Reduced the length of lines printed in statistics when showing + the details of X protocol's opcodes. This is intended to help + nxclient to keep the whole statistics in the 'details' window, + so that users don't have to use the scrollbars. + +nxcomp-1.3.2-1 + +- Opened the 1.3.2 branch. + +nxcomp-1.3.1-5 + +- It seems that Solaris can return an EINVAL error selecting a + shutdown descriptor even before we actually close the socket. + We now ignore the condition on Solaris. This is definitely a + Solaris bug. + +nxcomp-1.3.1-4 + +- Increased the timeout after which proxy will abort the peer + connection to 120 seconds. An alert dialog will now be shown + after 60 seconds, instead of the 30 seconds being the default + in the previous version. Some users reported the timeout to + be too short in the case of temporary network failures. + +nxcomp-1.3.1-3 + +- Some optimizations in the cache house-keeping process. Now it + runs at lower system priority in respect to the parent. Any 2 + iterations through directories and images, it also sleeps for + a tiny amount of time. This further decreases the system load. + +- Removed the underline characters and added a colon in the + title of this ChangeLog to fully comply with format used in + the release notices. + +nxcomp-1.3.1-2 + +- Fixed a crash when running both client and server on the SPARC + Solaris. An optimization used to avoid byte-swapping when both + hosts have the same endianess doesn't work on SPARC if buffer + is not aligned to word boundary. A better version of the code + should check the CPU, not the OS, as this probably applies to + other processors. + +nxcomp-1.3.1-1 + +- Opened the 1.3.1 branch. + +nxcomp-1.3.0-50 + +- Disabled the processor limit in X client side proxy. In previous + versions the processor load limit was set to an idle time ratio + of 2. This was likely to cause an unwanted slowdown on very old + hardware or when running the server as guest OS inside a VMWare + virtual machine. + +nxcomp-1.3.0-49 + +- Last minute update on proxy shutdown bug on Cygwin. A stack + trace reveals that faillure happens in the static destructor of + the BlockCacheSet class. It seems that problem appeared just + after having upgraded to the latest version of Cygwin DLL. Now + the destructor is skipped at shutdown. + +nxcomp-1.3.0-48 + +- Further fix to overcome the shutdown problem on Windows. + +nxcomp-1.3.0-47 + +- Used T_files::value_type() in Keeper.cpp. The form without the + explicit constructor fails to compile with GCC 2.91 on RH 6.2. + +- Fixed '==' -> '=' in configure.in to build under RH 6.2 and + probably other platforms. + +nxcomp-1.3.0-46 + +- The cleanup procedure now skips deletion of the IO streams + under Windows. This is intended to overcome a strange segfault + occurring at random time, at the time proxy is being shutdown. + +nxcomp-1.3.0-45 + +- Newer versions of the stdlibc++ do not seem to be able to deal + with NULL strings or non printable characters. This caused the + standard error stream to get sometimes corrupted in the case + TEST and DEBUG logs were enabled in Loop.cpp. + +nxcomp-1.3.0-44 + +- Disabled TEST and DEBUG logs in ServerChannel. + +nxcomp-1.3.0-43 + +- Fixed a crash when unpacking an image in server proxy in the + case the unpack state for the given channel had not been + previously created. + +nxcomp-1.3.0-42 + +- Small modification to setSchedule() to not account previous + data accumulated in the encode buffer. The new code seems to + allow better use of the available bandwidth. + +nxcomp-1.3.0-41 + +- Further fix in Tight decompression. Content of the main write + buffer was not removed before flushing the unpacked data to + the X server link. + +nxcomp-1.3.0-40 + +- Removed the code marked as FIXME in Loop and ServerChannel. + Code was used in previous version to override any pack method + other than NO_PACK and to disable initialization of the shared + memory. + +nxcomp-1.3.0-39 + +- Solved the problem with unpacking of RDP text on big-endian + architectures. The width field in PutPackedImage was put as + 16 bits and extracted as 32 bits at decoding side. + +- Moved the code checking if any of the children has exited in a + specific function. This function is now called any time signals + are newly enabled. This works even on Solaris. + +- Enabled use of shared memory with Tight image decompression. + +- Added event NXCollectPropertyNotify to NXproto.h. + +nxcomp-1.3.0-38 + +- Message locks are now checked before splitting a message. + +nxcomp-1.3.0-37 + +- Added a further counter to yield encoding data if the amount + of output bytes to be written to channels exceeds a threshold. + +- Modified proxy to write data immediately if the encoding loop + was interrupted. + +nxcomp-1.3.0-36 + +- Further fix required by Tight decompression. By handling mul- + tiple writes in the Tight class we may flush the main write + buffer in the wrong order. If Tight decompression is enabled, + the buffer is now flushed before decoding the packed image. + +- A SIGCHLD is raised any time signals are newly enabled. This + allows the main loop to wait() the pid of children that had + exited while signals were disabled. + +nxcomp-1.3.0-35 + +- Fixed Tight decompression by handling multiple writes to the + channel's transport inside the decompression function. + +- Made Tight decompressor in ServerChannel a pointer instead of + an instance of the class. Class is allocated the first time it + is referenced. + +- Rewritten handleUnpack() in ServerChannel to use a switch() + on the pack method instead of multiple if(). + +nxcomp-1.3.0-34 + +- Disabled RENDER extension when running X agent sessions on + the Solaris client. Problems seem to be caused by incompati- + bilities in the implementation of RENDER on the Sun X server + shipped by default. We did not test NX with the XFree86 X + server, but it seems that, when using the Sun X server, even + plain X clients don't make full use of the extension. + +nxcomp-1.3.0-33 + +- Added 4 new fields to the X_NXGetControlParameters reply. + A dialog should be shown by agent if proxy was not able to + negotiate a persistent cache or if a cache was selected but + not loaded because incompatible or corrupted. + +- Fixed a bug on Solaris where socket() must be recreated if + the first connect() fails. Not a problem. The strange thing + is that if you reuse the socket(), the subsequent connect() + is successful and the program fails as soon as you try to + write to it. + +nxcomp-1.3.0-32 + +- Added request X_NXFreeUnpack to free the resources allocated + by the remote proxy to unpack images for the given agent's + client + +- Added an alert at X server side if proxies were not able to + negotiate a persistent cache or if a cache was selected but + not loaded at X server side (that means that probably cache + was not compatible or corrupted). The alert is not enabled + at the moment. Before enabling it, we need to find a way to + deal with full-screen mode. + +- Tuning of MIT-SHM parameters. + +nxcomp-1.3.0-31 + +- Modified the following requests to carry the id of the + agent's client: + + - X_NXSetUnpackGeometry + - X_NXSetUnpackColormap + - X_NXSetUnpackAlpha + - X_NXPutPackedImage + + Now each agent's client has its own record pointing to the + geometry, colormap and alpha channel that will be used to + unpack the image. Code is not finished yet so it is advisable + that agents' writers keep using client id 0. Note also that + the final solution will require some changes to the way split + notifications are sent to agent that I plan to implement in + the next versions. + +- The X_NXSetUnpackGeometry request has now a message store. + This should reduce the overhead to the minimum even in the + case of dumb agents not checking if the current geometry + matches the image to be unpacked. + +nxcomp-1.3.0-30 + +- Improved handling of short-circuited replies at X client + side. Request opcodes are now pushed in the sequence queue + to determine if a reply is expected. In this case tainting + of reply is skipped to preserve the sequence ordering of + any event or error that could have generated by the reply. + This seems to solve all the problems reported by people + running a NX session in virtual desktop mode nested in an + existing session being run in single application mode. + +- Modified the cleanup procedure to print the 'Waiting for' + message in the session log only at the time all X channels + have been actually shut down. This message can be used by + the NX server to find out the appropriate time to close + the session. + +- Added the selected session type to the 'Using pack method' + message printed at startup. + +- Added the option to close down the proxy link and perform + a clean shutdown of the session, re-read the whole session + configuration or restart the proxy link when a SIGHUP is + delivered to the proxy process. The default behaviour is + to close down the session. The new default (the old one was + to restart the link) is a required feature to let users run + full sessions using single application mode f.e. in a LTSP + environment. I noted that when the controlling terminal of + the X session is closed, a SIGHUP is delivered to the X + server side proxy (probably it is delivered to all the con- + nected clients, and, thus for NX, only to the proxy). This + signal can be used to terminate the whole session. + +nxcomp-1.3.0-29 + +- Changed defaults to disable image masks when running proxy + in single application mode. The new configuration requires + changes in NX server and in NX X11 library. Users should + experience much better image quality when using NX on slow + links. This comes at the cost of slightly worse compression + ratios. + +nxcomp-1.3.0-28 + +- Opcode of request was not rewritten by server channel when + using link LAN. This caused problems with taint of replies. + +nxcomp-1.3.0-27 + +- Modified the split store and the split procedures in client + channel to always return the client id in the notification + events. The new field is added to event at byte offset 28 + to preserve compatibility with previous agent releases. The + modification permits to agent to match the commit of alpha + channel with the original image, if requests are split by + proxy. + +- Temporarily set the timeout used to poll MIT-SHM completion + events coming from X server to 0. More testing is required. + +- Fixed an inconsistent message generated in statistics due to + a division by 0. + +nxcomp-1.3.0-26 + +- Modified pending timeout from 1 to 0 milliseconds. This means + that both channels and proxy are now immediately restarted to + let them consume all data left in their read buffer. + +- When querying the X server for MIT-SHM support, size of name + in X_QueryExtension request was sent as 32 bits instead of 16. + This caused request to fail on big endian architectures. + +- Modified the MIT-SHM initialization procedure to always send + all the 3 protocol requests also in the case of early failures. + +nxcomp-1.3.0-25 + +- Implemented handling of the new X_NXSetUnpackAlpha message. + Performances are very satisfactory. Using most of the current + GNOME and KDE applications, caching reaches 90% of the total + messages. + +- Modified the persistent cache management routines to handle + backward compatibility with proxy versions prior of 1.3.0. + +- It has been made possible to send both X_NXSetUnpackColormap + and X_NXSetUnpackAlpha messages with 0 entries to temporarily + disable use of the colormap or the alpha channel and free the + resources allocated by the server channel class. + +- Added function UnpackAlpha() to Unpack.cpp. + +nxcomp-1.3.0-24 + +- Using WriteBuffer::registerPointer() to track growing of the + write buffer in handleFastWrite() functions. This problem + existed even in 1.2.2 but never shown up because we didn't + have to use the pointer after data had been written to the + write buffer. Now, instead, we have to post-process the write + buffer to copy data to the shared segment. + +- Optimized memory allocations running with link LAN to save a + memcpy() any time new data is allocated in the scratch buffer. + +- When running with link LAN the scratch buffer is now used only + when: + + - A further allocation would case growing of the write buffer + (and, thus, a memcpy() of the previous content). + + - When data to added is bigger than the write threshold. + + In previous versions the scratch buffer was used any time the + total amount of data to be written (write buffer + scratch + buffer) exceeded the scheduled write threshold. This caused + small writes to be appended even when a single write could + be obtained without reallocating the buffer. + +- Preliminary support for transporting the alpha channel in a + separate message in case of 32 bits displays using the RENDER + extension. + +nxcomp-1.3.0-23 + +- Modified the mask used to open the shared memory segment on + OS/X to 0777. We have to better investigate why the previous + 0600 mask doesn't work even if the user running the proxy is + the same user running the X server. + +nxcomp-1.3.0-22 + +- Implemented MIT-SHM support on LAN connections. + +- More MIT-SHM bug fixes. + +nxcomp-1.3.0-21 + +- Better use of the shared segment through an improved + algorithm leveraging the offset field of the X_ShmPutImage + request. The new algorithm greatly reduces the amount of + polls the proxy needs to perform to find if the completion + event has arrived. + +- Implemented MIT-SHM support for X_PutImage requests. + +- Implemented option shmem=value. Use of this option is anyway + discouraged. Proxy will allocate the shared memory segment + based on the size of the in-memory cache set by the user. + Use of MIT-SHM is disabled when user did set a memory cache + smaller than 2MB (for example on the embedded client). + +- Rewritten post-processing of images in server channel loop. + +- Improved error handling to ensure we intercept all MIT-SHM + X errors before they reach the NX agent. + +- Solved a problem that was causing channels to not reflect + shared memory support flags set in control. + +nxcomp-1.3.0-20 + +- Solved a compatibility problem when mixing proxy versions + 1.2.2 and 1.3.0. + +nxcomp-1.3.0-18 + +- Rewritten interfaces to shared memory initialization in + client and server channel. + +- Server channel checks for the completion event until a + timeout before reusing the shared memory segment. + +- Flush flag was not cleared after the write buffer had been + flushed in handleWrite() of both client and server channels. + This could lead to multiple fragmented writes, affecting + the performances. + +- Added -lcygipc to linking on Windows platform. + +- Added a check on GCC version to see if -Wnested-externs + -Wmissing-declarations are valid options. + +nxcomp-1.3.0-17 + +- Implemented initial support for MIT-SHM extension in the + network path between the X server proxy and the real X + server. Presently it works only for X_NXPutPackedImages. + +- Modified configure.in to compile under FreeBSD. + +- Small changes to sources due to FreeBSD support. + +nxcomp-1.3.0-16 + +- Fixed caching of RENDER extension on MacOS/X and Solaris. + +- Under Solaris an explicit call to EnableSignal() is needed + at the end of the signal handler as raising a signal seems + to reset the previous settings. + +- Can't find a way to get bytes queued for write on Solaris as + both FIONWRITE and TIOCOUTQ don't seem to be available. This + means that NX server on Solaris is only able to detect con- + gestions on proxy link at the time a write fails with error + EAGAIN. + +- Starting from this version, render extension messages are not + automatically discarded from cache when running agent based X + sessions. This is in preparation of render support introduced + in this release. + +nxcomp-1.3.0-15 + +- Changed default to force writes if X channels exceed buffer + limits. This change was suggested by benchmarks performed on + Win32. + +- Wrapped IO on cache files in functions performing better error + checking. + +- General cleanup in handling of socket options for MacOS/X and + Solaris. + +nxcomp-1.3.0-14 + +- Corrupted persistent caches were not deleted in case loading + of any of the message stores failed. To run further sessions + on the same host, user had to delete the cache file manually. + +- Improved error handling in JPEG decompression. Now connection + is reset in case of failure. + +- Before performing JPEG or PNG decompression, image is better + checked to verify if loading from disk failed. + +- Improved error handling in case of failure loading persistent + cache from disk. On MacOS/X istream -> fail() doesn't seem to + work properly. This needs further investigation. + +- The default installation path of nxclient is searched under + MacOS/X at the time nxclient is invoked in dialog mode. + +nxcomp-1.3.0-13 + +- Fixed a (further) compilation problem under Solaris. Now static + libraries are first searched under /usr/sfw/lib (in case Sun + would decide to include them in future releases). + +nxcomp-1.3.0-12 + +- Fixed parsing of command line when passing option -V. + +- Correctly detected ENOPROTOOPT when setting TCP_NODELAY socket + option on MacOS/X and Solaris. + +nxcomp-1.3.0-11 + +- Given option in configure to specify what needs to be built + statically: + + --with-static-png enable static linking of PNG library + --with-static-jpeg enable static linking of JPEG library + --with-static-z enable static linking of Z library + +nxcomp-1.3.0-10 + +- Fixed a problem in saving of persistent cache on big-endian + machines. + +nxcomp-1.3.0-9 + +- Testing with different settings to check if it's possible to + increase the performances under Windows. + +- Solved a problem in parsing of options that prevented proxy + to connect to a remote session running at port offset 0. + +- Fixed two warnings compiling on Solaris. + +- Changed configure.in to first check for nx-X11 includes + and libraries. Added "/usr/openwin/bin/makedepend" to path + searched for the executable. + +nxcomp-1.3.0-8 + +- Small cleanup in configure.in and files modified by Gregorz + Kryza to add support for Solaris. + +- A new configure script has been generated using autoconf-2.57-3. + +nxcomp-1.3.0-7 + +- Added support for detection of Solaris in configure script. + Now Makefile.in uses ranlib instead of ar. + +- Small changes in source and header files to support Solaris. + +nxcomp-1.3.0-4 + +- Corrected a bug that could cause priority on proxy and channels + to be not taken in account at the time proxy tries to determine + if it's time to flush the proxy link. + +- Better implementation of abort split notification by X server + proxy to its remote peer. The new implementation doesn't + need to set a timeout and permits notifications to be received + earlier. + +- Improved support for 'tainting' XSync() messages coming from + X clients in single application mode. Now a X_GetInputFocus + is sent to the real X server any n such messages received by + proxy. + +- Included support for 15 bpp displays. It seems that handling + them as 16 bpp it's OK. diff --git a/doc/_attic_/NoMachine_documentation_files/nxcomp_README b/doc/_attic_/NoMachine_documentation_files/nxcomp_README new file mode 100644 index 000000000..f35cce6b5 --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxcomp_README @@ -0,0 +1,21 @@ +README +------ + +Building +-------- + +1. To compile: + + > tar zxvf nxcomp-X.Y.Z-N.tar.gz + > cd nxcomp + > ./configure + > make + + You'll have to run gmake under Solaris. + +2. The 'make install' target is not currently supported + in the Makefile, but it should be simple to fix. + +You need at least nxproxy and nxagent packages to enjoy this code. Check the +NoMachine website at http://www.nomachine.com to get the latest release. + diff --git a/doc/_attic_/NoMachine_documentation_files/nxcomp_README-IPAQ b/doc/_attic_/NoMachine_documentation_files/nxcomp_README-IPAQ new file mode 100644 index 000000000..f9418635c --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxcomp_README-IPAQ @@ -0,0 +1,21 @@ +README-IPAQ +----------- + +1. Install a cross-compiler for ARM. You can find detailed + informations at: + + http://www.ailis.de/~k/knowledge/crosscompiling/toolchain.php + + There are also binaries needed to install the cross-compiler. + +2. Configure and compile libXcomp using: + + $ ./configure --with-ipaq + $ make + + After compilation type: + + $ arm-linux-strip libXcomp.* + +3. Remember that you also need nxproxy to actually run your NX X + session. diff --git a/doc/_attic_/NoMachine_documentation_files/nxcompext_CHANGELOG b/doc/_attic_/NoMachine_documentation_files/nxcompext_CHANGELOG new file mode 100644 index 000000000..941e9b411 --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxcompext_CHANGELOG @@ -0,0 +1,806 @@ +ChangeLog: + +nxcompext-3.5.0-1 + +- Opened the 3.5.0 branch based on nxcompext-3.4.0-1. + +- Updated copyright to year 2011. + +nxcompext-3.4.0-1 + +- Opened the 3.4.0 branch based on nxcompext-3.3.0-4. + +- Updated version number. + +- Updated copyright to year 2009. + +nxcompext-3.3.0-4 + +- Fixed TR03G02199. The color palette allocated for encoding an image + having 256 colors or less was not freed. + +nxcompext-3.3.0-3 + +- Now setting the correct event serial number when sending collect + notifies back. + +nxcompext-3.3.0-2 + +- Updated VERSION. + +nxcompext-3.3.0-1 + +- Opened the 3.3.0 branch based on nxcompext-3.2.0-1. + +nxcompext-3.2.0-1 + +- Opened the 3.2.0 branch based on nxcompext-3.1.0-2. + +nxcompext-3.1.0-2 + +- Updated file VERSION to match the current release version. + +nxcompext-3.1.0-1 + +- Opened the 3.1.0 branch based on nxcompext-3.0.0-18. + +nxcompext-3.0.0-18 + +- Removed the remaining debug output. + +nxcompext-3.0.0-17 + +- Changed the copyright notices at the beginning of the files that + were referring to NXPROXY to refer to NXCOMPEXT. + +nxcompext-3.0.0-16 + +- Handle the reply failure in NXGetShmemParameters(). + +nxcompext-3.0.0-15 + +- Separated the functionalities made available by NXQueryDisplay() + in three distinct functions: + + NXDisplayReadable() Query the number of bytes readable from + the display connection. + + NXDisplayFlushable() Query the number of the outstanding bytes + to flush to the display connection. + + NXDisplayCongestion() Return a value between 0 and 9 indicating + the congestion level of the NX transport. + +- Renamed NXQueryDisplayError() to NXDisplayError(). + +nxcompext-3.0.0-14 + +- Removed support for Rdp, Tight and Hextile packed images encod- + ing since they have been made obsolete by the new NX server. + +- Changed the copyright attribution from Medialogic to NoMachine. + +nxcompext-3.0.0-13 + +- Allocate 1024 additional bytes for the Jpeg compression, instead + of 512, to avoid failures on very tiny images. + +- Removed support for the special *PNG_JPEG* pack method. + +nxcompext-3.0.0-12 + +- Implemented the NXEncodeBitmap() method. This is a very simple + encoder removing the 4th byte in 32 bits-per-plane images. For + the other pixmap depths it simply returns a pointer to the orig- + inal image data, saving the copy. This encoding is intended to + better leverage the stream compression on low bandwidth links. + +- Removed the quality parameter from the RGB/RLE encoding function. + +nxcompext-3.0.0-11 + +- Removed the additional parameter in the call to NXTransFlush(). + +nxcompext-3.0.0-10 + +- Moved the _NXRDPGlyph and _NXRDPText declarations from NXlib.h + to NXproto.h to force fields to be CARD32. + +- Fixed a typo in NXSetDisplayBuffer() that could cause a double + free. + +- Fixed a compilation error with old GCC versions. + +- Removed the warning issued on AMD64 when compiling with the logs + enabled. + +nxcompext-3.0.0-9 + +- Added the NXDisplayCongestion query type to NXQueryDisplay(). It + returns a value between 0 and 9, with 9 meaning that the link is + congested and no further data can be sent. + +- Added the NXSetDisplayBuffer() function. It allows the caller to + set the display output buffer size at runtime. + +- Removed the congestion and synchronization callbacks. + +nxcompext-3.0.0-8 + +- Removed the warnings issued when purging the collected data at + display reset. + +nxcompext-3.0.0-7 + +- Added the NXSetDisplayWriteHandler() interface. The function + registers a callback that will be invoked every time more data + is written to the display socket. + +nxcompext-3.0.0-6 + +- Made NXQueryDisplay() take into account the bytes in the display + buffer when queried for the bytes flushable. + +nxcompext-3.0.0-5 + +- Added file COPYING. + +nxcompext-3.0.0-4 + +- Updated copyright notices to the current year. + +nxcompext-3.0.0-3 + +- Imported changes up to nxcompext-2.1.0-4. + +- Fixed TR12D01564. Changed configure script to build library with + -fPIC option. + +- Added 256 byte to the size of Jpeg destination buffer. + +nxcompext-3.0.0-2 + +- Updated the file VERSION. + +nxcompext-3.0.0-1 + +- Opened the 3.0.0 branch based on nxcompext-2.0.0-33. + +nxcompext-2.0.0-33 + +- Placed the inclusion of jpeglib.h after the X includes to fix a + possible compilation error. + +nxcompext-2.0.0-32 + +- Avoid to copy the data to the scratch buffer and yield the task + of padding the output to _XSend() in the NXPutPackedImage(), NX- + SetUnpackAlpha() and NXSetUnpackColormap() requests. + +- Added support for the RLE pack method. + +nxcompext-2.0.0-31 + +- The X_NXSetUnpackColormap and X_NXSetUnpackAlpha now carry their + data in compressed form. The alpha data is compressed using the + ZLIB RLE encoding, while the colormap data is compressed using + the default ZLIB deflate. + +- Created new message structures to handle the compatibility with + the old proxy versions. When connected to an old proxy version + the agent should use the NXSetUnpackColormapCompat() and NXSet- + UnpackAlpha() interfaces. + +nxcompext-2.0.0-30 + +- Removed the unfriendly warning printed if a client tried to reset + the library multiple times. + +nxcompext-2.0.0-29 + +- Made possible to compile even if makedepend is not found. + +nxcompext-2.0.0-28 + +- Added the NXSetDisplaySynchronizationHandler() interface. The NX + transport will use the callback to report when the agent can use + the available bandwidth to synchronize the X objects that are + corrupted or incomplete. + +- Bytes from 14 to 24 in the NXGetControlParameters() reply report, + respectively, the frame timeout, the ping timeout, the preferred + image split mode and the split size threshold. + +nxcompext-2.0.0-27 + +- Changed the image cleanup functions and the Png and Jpeg encoders + to be independent from the host endianess. + +- Enabled again the image cleanup on big endian machines. + +nxcompext-2.0.0-26 + +- Added the NXAbortSplit() request. + +- Added information about the size of the shared memory segment used + by the remote proxy in the NXGetShmemParameters() reply. + +nxcompext-2.0.0-25 + +- Renamed the NXGetSplitResource() and NXGetUnpackResource() utili- + ties to NXAllocSplit() and NXAllocUnpack(). They can be called + with a NXAnyResource parameter to get the first available id or + requre a specific resource. From this version the resource must + be explicitly reserved. NXFreeUnpack() and NXFreeSplit() check + if the resource was allocated and don't do anything if it is not + the case. NXAllocSplit() and NXAllocUnpack() return NXNoResource + if the resource can't be reserved. + +nxcompext-2.0.0-24 + +- NXFlushDisplay() now verifies whether the XlibDisplayWriting flag + is set before flushing the display buffer. in this case, it only + flushes the NX link. + +nxcompext-2.0.0-23 + +- Implemented a move-to-front strategy for the image cache, to mi- + nimize the number of lookups. + +- Fixed the problems imtroduced by the new cache implementation by + modifying the memory allocation routines in Jpeg.c and Pgn.c. + +- Temporarily fixed the cleanup problems on big-endian machines by + skipping the operation. + +- Added a NXSetDisplayStatisticsHandler() to let the agent include + arbitrary data in the transport statistics. The parameter is a + pointer to a pointer to a null terminated string. The pointer is + set at the time the handler is registered. The pointed string can + be filled by the agent with its statistics data. + +nxcompext-2.0.0-22 + +- The NXCacheFindImage() returns a pointer to the checksum, if the + image is found. + +- The image cache uses the data passed to NXCacheAddImage() instead + of making a copy. + +- The Z stream used by the RGB encoder is allocated at initializat- + ion and freed at reset. + +nxcompext-2.0.0-21 + +- Removed the reliance on the local byte order in the image cleanup + functions. + +nxcompext-2.0.0-20 + +- Added the NXFinishSplit() request. It forces the proxy to comple- + tely transfer all the split messages for the given resource, and + then notify the agent. + +nxcompext-2.0.0-19 + +- Enabled again the cleanup of images. + +- Updated to comply with the new NXTransFlush() interface. + +nxcompext-2.0.0-18 + +- Moved all the declarations in Rgb.c at the beginning of the block + to avoid the possible compilation errors with old compilers. + +nxcompext-2.0.0-17 + +- Added a new RGB image encoder. For now the encoder uses a static + Z stream to compress the image data in the destination buffer and + allows the agent to use the simplest encoding by still separating + the alpha channel from the image data. The new encoder can be the + the base for implementing color reduction by dithering or a color- + mapped translation of the image similar to PNG, but without the + PNG overhead and with the colormap being sent to the client using + the NXSetUnpackColormap() opcode. + +- Created a new NXCleanImage() function that takes a XImage pointer + and uses either the CleanXYImage() or the CleanZImage() routines + to cleanup the padding bits. + +nxcompext-2.0.0-16 + +- Added a parameter to NXFlushDisplay() to specify what needs to be + flushed. The parameter can be one the following values, defined + in NXvars.h: + + NXFlushBuffer Only the Xlib buffer is to be flushed. + + NXFlushLink Flush both the Xlib buffer and any pending + data encoded by the NX transport. + + NXFlushIdle Inform the NX transport that the agent is + idle. This will let the NX transport encode + more low-priority data, and then flush the + link. + +- Ensured that the padding bytes are cleaned when creating a new + PNG image. It seems that some images are still missed. This is + to be investigated. + +nxcompext-2.0.0-15 + +- Ensured that the packed image cache is recreated only on a size + change. + +nxcompext-2.0.0-14 + +- Updated to get the karma delay field from the X_NXGetControlPara- + meters reply. + +nxcompext-2.0.0-13 + +- Added the NXSetDisplayPolicy() and NXSetDisplayFlushHandler() in- + terfaces. The second function registers a callback that will be + invoked by the NX transport when the number of bytes encoded by + the proxy exceeds the threshold set for the scheduled write. + +- Added the NXFlushDisplay() and NXQueryDisplay() interfaces. They + are used to hide the corresponding NX transport functions to the + application. NXQueryDisplay() can be called with the NXDisplay- + Flushable or NXDisplayReadable parameters, to get, repectively, + the number of bytes that are queued to the NX transport and the + number of bytes that is possible to read. + +- Included the remote proxy version in the NXGetControlParameter() + reply. + +nxcompext-2.0.0-12 + +- Added the NXGetSplitResource() and NXGetUnpackResource utilities. + These can be used by the client to find out the first unused id + available for a split or unpack operation. + +- Added the NXFreeSplit() request function. It makes the resource + available for the next operation and tells the proxy to destroy + all the storage associated to the split. + +- Renamed the NXNumberOfConnections constant to NXNumberOfResources. + +nxcompext-2.0.0-11 + +- Changed NXForceDisplayError() to also shut down the NX transport + by calling NXTransClose(). + +- Updated to comply with the new NX function prototypes introduced + in nxcomp-2.0.0-31. + +nxcompext-2.0.0-10 + +- NXQueryDisplayError() now checks the predicate function only if + the I/O error was not encountered already. + +nxcompext-2.0.0-9 + +- Added the NXSetDisplayErrorPredicate(), NXSetDisplayBlockHand- + ler(), NXSetDisplayCongestionHandler(), NXSetLostSequenceHand- + ler() interfaces to let the user set the values used internal- + ly. All functions return the previous handler. See ChangeLog + in nx-X11-2.0.0-16 and nx-X11-2.0.0-17. + +- Moved all the internal variables shared between Xlib, nxcompext + and the X server in nxcomp. Declarations and function prototypes + moved to NXvars.h. + +- Some name changes. In particular the NXContinueOnDisplayError() + function iss renamed NXHandleDisplayError() and NXDisplayError() + is now renamed NXQueryDisplayError(). To verify if the display + is valid, NXQueryDisplayError() will now call the _NXDisplayEr- + rorPredicate function, or, if the predicate function is not set, + will simply check the value of the XlibDisplayIOError flag. + +- Removed the NXGetCleanupParameters() and NXGetImageParameters() + interfaces and the remaining references to the unused display + buffer and image cleanup functions. + +- Updated the NoMachine copyright notice to year 2006. + +nxcompext-2.0.0-8 + +- Removed the unused screen parameter from XSetUnpackGeometry(). + +- NXSetUnpackGeometry() now fails if no visual is provided. + +nxcompext-2.0.0-7 + +- Changed the LICENSE file to state that the software is only made + available under the version 2 of the GPL. + +- Removed the misplaced DXPC copyright notices from the license. + They were copied from NXCOMP but they don't apply in any way to + NXCOMPEXT. + +nxcompext-2.0.0-6 + +- Added the NXSetCacheParameters() request. It tells to the local + proxy how to handle the X requests, namely if the next requests + have to be stored in the memory cache, split in smal data chunks, + and in the case of images, saved on disk in the persistent image + cache. The request will affect all X messages, including plain + and packed images. It can be used to tell the proxy to discard + images coming from some selected operations, like GLX or XVideo. + +nxcompext-2.0.0-5 + +- Added the NXGetFontParameters() request and reply. If the proxy + has been configured accordingly, the request returns the X font + path that can be set by the agent to tunnel the font server con- + nections through the NX link. + +nxcompext-2.0.0-4 + +- Initial work on font server tunneling. + +nxcompext-2.0.0-3 + +- Renamed the NXSetExposeEvents request to NXSetExposeParameters. + +nxcompext-2.0.0-2 + +- Modified the configure and the makefiles to support the Cygwin + environment. + +- Renamed Png.h to Pgn.h to avoid name clashes on Windows. + +- The distclean target now removes the autom4te.cache directory. + +nxcompext-2.0.0-1 + +- Opened the 2.0.0 branch based on nxcompext-1.5.0-20. + +nxcompext-1.5.0-20 + +- Removed the code installing a SIGSEGV handler before trying to + clean an image in NXCleanImageInPlace(). + +nxcompext-1.5.0-19 + +- Added the NXUnsetLibraryPath() function to specify the behaviour + of the Popen() in the X server. If the _NXUnsetLibraryPath flag + is set, the Popen() will remove the LD_LIBRARY_PATH variable from + the environment before running the child process. This will cause + the X server to run the process (for example the keyboard initia- + lization utilities) by using the native system libraries, instead + of the libraries shipped with the NX environment. + +nxcompext-1.5.0-18 + +- Moved the declarations of _NXEnable* and related structures from + Xlibint.h to NXlibint.h. + +- Use the include files from nx-X11 if the nx-X11/include directory + is found. The previous configure checked the presence of nx-X11/ + exports/include, that might not be built at the time this library + is compiled. + +nxcompext-1.5.0-17 + +- Added the -fPIC GCC flag when compiling on AMD64 architectures. + +- Removed all warnings when compiling with GCC4. + +- Small changes to configure.in to have specific CFLAGS. + +- Created a new configure using autoconf 2.59. + +nxcompext-1.5.0-16 + +- Added the 'mode' field in the NXStartSplit() request. It determi- + nes the strategy that the proxy will adopt to handle the image. + If set to 'eager', the proxy will only split the messages whose + size exceeds the split threshold (the threshold can be found in + the NXGetControlParameters() reply). If mode is set to lazy, the + proxy will split any image that it is not able to find in its + cache. + + The opcode and the two available modes are defined in NXproto.h, + currently: + + #define NXSplitModeDefault 0 + #define NXSplitModeEager 1 + #define NXSplitModeLazy 2 + +- All requests related to image streaming now carry a 'resource' id. + The id is currently ignored by the proxy in the case of NXCommit- + Split() requests. + +nxcompext-1.5.0-15 + +- Removed the NXSync() and NXKarma() operations, not used anymore + by the NX agents. + +- Updated to comply with changes occurred in the numbering of the + notification events and in the interface to the image streaming + functions. + +nxcompext-1.5.0-14 + +- Accounted for the missing xoffset field in clean-up of XYPixmaps. + +nxcompext-1.5.0-13 + +- Added a 'commit' field in NXCommitSplit(). When zero, the remote + proxy will remove the message from the split store, without send- + ing the recomposed image to the X server. + +nxcompext-1.5.0-12 + +- Added the NXContinueOnDisplayError() function to specify the be- + haviour of the Xlib I/O error handler. If the flag is set to true, + Xlib will simply return, instead of quitting the program. This + leaves to the application the responsibility of checking the sta- + te of the XlibDisplayIOError flag. + +- Changed NXDisplayIsValid() to NXDisplayError() and inverted the + logic. Now the function returns true if the display pointer is + NULL or the XlibDisplayIOError flag is set. + +- Added the NXForceDisplayError() function, to shutdown the display + descriptor and force Xlib to set the I/O error flag. + +nxcompext-1.5.0-11 + +- Added -I../nx-X11/exports/include to CCINCLUDES in Makefile.in. + +nxcompext-1.5.0-10 + +- Added FindLSB() to replace ffs() that may be not present on some + systems. + +- Some cosmetic changes. + +nxcompext-1.5.0-9 + +- Fixed a printf() that prevented the code to compile if TEST was + enabled. + +nxcompext-1.5.0-8 + +- Implemented the NXLib interface for asynchronous handling of the + XGetInputFocus requests and replies. + +nxcompext-1.5.0-7 + +- Removed the _NXFlushSize parameter. New agents run the NX trans- + port in-process, so we don't get any benefit from increasing the + display buffer size. + +nxcompext-1.5.0-6 + +- Added a NXDisplayIsValid() to check that the display is not NULL + and that the descriptor was not shut down after an IOError. The + reason a function is needed for this is that the flags field is + only in Xlibint and it is not visible to Xlib applications. + +nxcompext-1.5.0-5 + +- Added the NXGetCollect*Resource utility functions, returning the + first available small integer resource id that can be used in a + subsequent collect request. + +nxcompext-1.5.0-4 + +- Added the NXNumberOfConnections constant. + +nxcompext-1.5.0-3 + +- Implemented the NXLib interface for the asynchronous handling of + the XGrabPointer requests and replies. + +- Solved an error in image cleaning that prevented the 8 bits-per- + pixel images to be completely cleaned. Due to the bug, only half + of the total lines were cleaned. + +- Removed a bug that prevented the cleaning of XYPixmaps images of + bitmap unit 32 and byte order LSB. + +- Renamed the NXImageCache variables to show they are global. They + are currently used in the nxagent code. + +nxcompext-1.5.0-2 + +- Changed VERSION file. + +nxcompext-1.5.0-1 + +- Opened the 1.5.0 branch. + +nxcompext-1.4.1-1 + +- Removed the configure option --with-static. There are two options + now, --with-static-png and --with-static-jpeg, to offer a greater + degree of control on the resulting library. + +- This version differs from the 1.4.0-3-KRY1 in the way that the con- + figure script is generated by GNU Autoconf 2.57, the same version + used for nxcomp. + +- Opened the 1.4.1 branch. + +nxcompext-1.4.0-3 + +- Updated the VERSION file to reflect the 1.4.0 status. + +nxcompext-1.4.0-2 + +- Imported changes from the latest 1.3.2 development branch. + +- The 1.4.0 branch already had a 1.4.0-1 version. The changes from + the 1.4.0-1 were up to date with the 1.3.2-2 version. + +nxcompext-1.3.2-6 + +- Fixed problem with icons in KDE and Mozilla on SPARC Solaris. The + problem was related to cleaning of one-bit XYPixmaps on big-endian + hosts, where shift of the cleaning mask executed in the wrong di- + rection. + +nxcompext-1.3.2-5 + +- Changes in Clean.c to compile on Solaris. + +nxcompext-1.3.2-4 + +- Fixed a bug in clean image procedures for 1bit XYPixmaps. The bug + caused Mozilla to trash some transparent icons in web pages and + the toolbar. + +- Added cleaning of the padding bytes at the end of the data chunk + inside XImage structure + +- Implemented handling of SIGSEGV during cleanup in case of static + data. + +- Moved image cleanup and masking code in new Clean.c and Mask.c + sources. + +- Corrected few typos in NXCollectImage code. + +nxcompext-1.3.2-2 + +- Imported 1.4.0-1 changes from the 1.4.0 development branch. + +- Modified NXAllocColors to handle errors generated allocating + each requested color. A per-color result code is now returned + to the caller. + +- Code cleanup in Png.h and Png.c. + +nxcompext-1.3.2-1 + +- Opened the 1.3.2 branch. + +nxcompext-1.3.1-2 + +- Removed the underline characters and added a colon in the + title of this ChangeLog to fully comply with format used in + the release notices. + +nxcompext-1.3.1-1 + +- Opened the 1.3.1 branch. + +nxcompext-1.3.0-18 + +- Added the _NXLostSequenceHandler function to let NX agents + suppress the error message and modify the default Xlib + behaviour when out-of-order sequence numbers are received. + Pointer to function is assigned to _NXLostSequenceFunction + in XlibInt.c. + +- Original output buffer size in stock XFree86 is 2048. We try + to reduce context switches and help stream compression by + increasing the maximum size of the buffer 8192. _NXFlushSize + determines when the display buffer is actually flushed. It is + set by default to 4096 in XlibInt.c and set to 0 to use the + maximum available size at the time NXGetControlParameters() + is called. + +nxcompext-1.3.0-17 + +- In handling of asynchronous GetProperty replies a warning + message was printed in session log when a null property was + stored in the state structure. This message is now printed + only if TEST is defined. + +nxcompext-1.3.0-16 + +- Added asynchronous handling of GetProperty request and reply + by means of the NXCollectProperty and NXGetCollectedProperty + requests and the NXCollectPropertyNotify event. + +nxcompext-1.3.0-15 + +- Added 4 new fields to the X_NXGetControlParameters reply. + +nxcompext-1.3.0-14 + +- Added request X_NXFreeUnpack to free the resources allocated + by the remote proxy to unpack images for the given agent's + client + +nxcompext-1.3.0-13 + +- Modified the following requests to carry the id of the + agent's client in the field resource: + + - X_NXSetUnpackGeometry + - X_NXSetUnpackColormap + - X_NXSetUnpackAlpha + - X_NXPutPackedImage + +nxcompext-1.3.0-11 + +- Modified the MIT-SHM initialization procedure to always send + all the 3 protocol requests also in the case of early failures. + +nxcompext-1.3.0-10 + +- Added handling of X_NXSetUnpackAlpha request. + +- It has been made possible to send both X_NXSetUnpackColormap + and X_NXSetUnpackAlpha messages with 0 entries to temporarily + disable use of the colormap or the alpha channel and free the + resources allocated by the remote proxy. + +nxcompext-1.3.0-9 + +- Solved a compatibility problem when mixing proxy versions + 1.2.2 and 1.3.0 due to the missing X_NXGetShmemParameters + request. + +nxcompext-1.3.0-7 + +- Reduced the number of requests needed to setup the shared + segment at X server proxy from 4 to 3. + +- Small changes to the shared memory interface to support + path X agent to X client proxy. + +nxcompext-1.3.0-6 + +- Implemented initial support for MIT-SHM extension in the + network path between the X server proxy and the real X + server. + +- Configure script now checks for the FreeBSD environment. + +- New configure script generated using autoconf-2.57-3. + +- Removed the XFree86 CCDEFINES from Makefile.in. + +nxcompext-1.3.0-5 + +- Cosmetic changes. + +- Started to convert configure.in to the new layout adopted + for nxcomp. + +- Created file CHANGELOG. + +nxcompext-1.3.0-4 + +- More fixes in image clean-up. + +nxcompext-1.3.0-3 + +- Many fixes in image clean-up functions to handle differences + in endianess between client and X server. + +nxcompext-1.3.0-2 + +- Modified configure.in to compile under Solaris. + +nxcompext-1.3.0-1 + +- First 1.3.0 version based on nxcompext-1.2.2-12. + diff --git a/doc/_attic_/NoMachine_documentation_files/nxcompext_README b/doc/_attic_/NoMachine_documentation_files/nxcompext_README new file mode 100644 index 000000000..39648e76b --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxcompext_README @@ -0,0 +1,15 @@ +README +------ + +1. To compile: + + > tar zxvf nxcompext-X.Y.Z-N.tar.gz + > cd nxcompext + > ./configure + > make + + You'll have to run gmake under Solaris. + +2. The 'make install' target is not currently supported + in the Makefile, but it should be simple to fix. + diff --git a/doc/_attic_/NoMachine_documentation_files/nxcompshad_CHANGELOG b/doc/_attic_/NoMachine_documentation_files/nxcompshad_CHANGELOG new file mode 100644 index 000000000..3472a4afe --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxcompshad_CHANGELOG @@ -0,0 +1,404 @@ +ChangeLog: + +nxcompshad-3.5.0-2 + +- Fixed TR03G02189. Now key combinations involving the Shift keys + are recognized correctly. + +nxcompshad-3.5.0-1 + +- Opened the 3.5.0 branch based on nxcompshad-3.4.0-3. + +- Updated copyright to year 2011. + +nxcompshad-3.4.0-3 + +- Updated copyright to year 2010. + +nxcompshad-3.4.0-2 + +- Fixed TR08G02256. Now the Shadow session is shown correctly with + MIT-SHM extension disabled. + +- Improved updateShadowFrameBuffer() and ~Poller() functions. + +- Avoided memory leak. + +nxcompshad-3.4.0-1 + +- Opened the 3.4.0 branch based on nxcompshad-3.3.0-3. + +- Updated version number. + +- Updated copyright to year 2009. + +- Improved error messages logging in case of initialization failures. + +nxcompshad-3.3.0-3 + +- Fixed TR01G02158. Keymap initialization could be incorrect because + of a type mismatch on 64 bit platforms. + +nxcompshad-3.3.0-2 + +- Updated VERSION. + +nxcompshad-3.3.0-1 + +- Opened the 3.3.0 branch based on nxcompshad-3.2.0-3. + +nxcompshad-3.2.0-3 + +- Improved keycode translation. + +nxcompshad-3.2.0-2 + +- Solved a problem when sending fake modifier events. + +- Added support for keyboard events handling for the web player. + +- Changed keycodes translation for Solaris keyboard. + +- Corrected a problem for keycodes translation from Solaris keyboard. + +- Fixed TR02F02001. In shadow session the shadower's keyboard layout + could be wrong. Now keycodes are correctly translated if master and + shadow keyboards have different layouts. + +- Added NXShadowGetScreenSize() and NXShadowSetScreenSize() functions, + so that the shadow session can handle correctly the resize of the + master session window. + +- Solved a compilation problem on GCC 4.3. + +nxcompshad-3.2.0-1 + +- Opened the 3.2.0 branch based on nxcompshad-3.1.0-2. + +nxcompshad-3.1.0-2 + +- Updated file VERSION to match the current release version. + +nxcompshad-3.1.0-1 + +- Opened the 3.1.0 branch based on nxcompshad-3.0.0-19. + +nxcompshad-3.0.0-19 + +- Skip initialization of damage extension if it was already disabled. + +nxcompshad-3.0.0-18 + +- The poller destructor checks if the damage extension is in use. + +- Small changes to the function getting the screen content in the case + damage is not in use. + +nxcompshad-3.0.0-17 + +- Cleanup of some log messages. + +nxcompshad-3.0.0-16 + +- Disabled some log message in the functions initializing the poller. + +nxcompshad-3.0.0-15 + +- Before calling XTest functions, it is checked if the connection to + master X server has been initialized. + +nxcompshad-3.0.0-14 + +- After the shm segment is created, its mode is changed and it is + marked for destroying. A check on the number of attaches is done. + +nxcompshad-3.0.0-13 + +- Creating the shm segment even if the uid of master X server can't be + retrieved. + +- Fixed reallocation of update region. + +- Checking if the master X server provides XTest extension. + +nxcompshad-3.0.0-12 + +- Fixed a compiler warning on AMD64 platform. + +- Changed configure script to add -fPIC option. + +- Fixed a mismatch in UpdateManager destructor. + +nxcompshad-3.0.0-11 + +- Fixed the function setting the uid of shm segment. + +- Sync with the master X server before marking the shm segment to be + destroyed. + +nxcompshad-3.0.0-10 + +- Setting the shm segments as readable only by the master X server + process. + +- Mark shm segments to be destroyed when the last process detach. + +- Enabled keycode translation in order to allow keyboards of different + models to work. + +nxcompshad-3.0.0-9 + +- Changed the LICENSE file to state that the software is only made + available under the version 2 of the GPL. + +- Added file COPYING. + +- Changes to translate keycodes between different keyboard types. The + keycodes are translated through the keysym. + +- Changes to convert a Mode_switch key to ISO_Level3_Shift if it is + needed. + +nxcompshad-3.0.0-8 + +- Added interface function NXShadowDisableShm disabling the use of + MIT-SHM extension. + +- Added interface function NXShadowDisableDamage disabling the use of + DAMAGE extension. + +- Added interface function NXShadowSetDisplayUid setting the uid of + shadowed X server + +- Changed the owner of shared memory segments to the uid of the sha- + dowed X server. + +- Fixed logWarning method. + +- Moved the code initializing the use of shared memory to shmInit + method of X11 Poller. + +nxcompshad-3.0.0-7 + +- Removed the class qualifier in the declaration of destroyUpdate- + ManagerRegion(). + +nxcompshad-3.0.0-6 + +- Fixed build errors on 64 bit platforms. + +- Called XTestGrabControl to override possible grabs of the X server. + +nxcompshad-3.0.0-5 + +- Added some stub members to the Poller class. These are intended to + handle keyboard state. + +- Changes in the default polling algorithm to disable the line pri- + ority persistence. + +nxcompshad-3.0.0-4 + +- If a low layer handling of screen changes is available (DAMAGE in + case of X11), polling routine uses it and returns immediately. + +- Creating a Damage notify object if the extension is supported. + +- DamageNotify events are saved in the update region. After all avail- + able events have been handled, the content of screen is retrieved + by ShnGetImage requests. + +- XDamageSubtract and XSync are done before any event handling. + +- Damages are requested as raw rectangles. + +- Added Xdamage and Xrandr to required libraries. + +- Fixed a problem with some lines not refreshed in shadowing mode. + +nxcompshad-3.0.0-3 + +- Added destroyUpdateManagerRegion() method to UpdateManager class. + +- Turned off some log messages. + +- Changed configure.in to remove warnings related to deprecated header + files and options. + +- Changed Makefile.in to remove autom4te.cache dir if the target is + 'distclean'. + +- Removed multi-word file names. + +nxcompshad-3.0.0-2 + +- Changes to get the screen of original display by a ShmGetImage. + +- Exit the polling loop if more than 50 ms have elapsed. + +nxcompshad-3.0.0-1 + +- Created nxcompshad based on nxshadow-3.0.0-7. + +nxshadow-3.0.0-7 + +- Deleted files KeyCursorTmp.cpp, scancodes.h, constant.h. + +- Renamed NXshadow.h to Shadow.h. + +- Merged NXshadowEvent.h with Shadow.h. + +- Fixed configure.in, changed Makefile.in to build Xcompshad library, + rebuilt configure script. + +nxshadow-3.0.0-6 + +- Implemented a callback mechanism to ask the caller program if screen + polling have to be suspended. + +nxshadow-3.0.0-5 + +- Changes to comply with the library name. + +- Fixed a bug in CorePoller that could prevent the update of the last + line of a rectangle. + +nxshadow-3.0.0-4 + +- Removed some parameters of the NXShadowAddUpdaterDisplay() function. + +nxshadow-3.0.0-3 + +- Updated copyright notices to the current year. + +- Code cleanup in KeysCursorTmp.c file. + +nxshadow-3.0.0-2 + +- If master agent uses shared memory extension, the GetImage is rea- + lized by XShmGetImage() function. + +- Added new parameters to NXShadowAddUpdaterDisplay() function, the + depth and bit mask color of the master display. + +nxshadow-3.0.0-1 + +- Opened the nxshadow-3.0.0 branch based on the nxaccess-3.0.0-13. + +- Renamed NXaccess.h NXaccessEvent.h and RegionM.h files as NXshadow.h + NXshadowEvent.h and Regions.h. + +- Modified the Makefile.in file and configure scripts in order to + compile the component. + +nxaccess-3.0.0-13 + +- Fixed X11Poller.cpp pre-processing. + +nxaccess-3.0.0-12 + +- Fixed build problems on Solaris. + +nxaccess-3.0.0-11 + +- Added NXShadowUpdateBuffer() function. This function creates the + buffer for the polling. + +- If the scaline fails, the polling will suspend for 50 ms. + +- Added some functions in order to access data member class. + +nxaccess-3.0.0-10 + +- Used XTEST extension to make the shared display create input events. + +nxaccess-3.0.0-9 + +- Added the mouse events. + +- Now, it's possible to connect to X server display or agent display, + the display's content is captured by GetImage and sent to another + display by PutImage. + +nxaccess-3.0.0-8 + +- Added KeysCursorTmp.cpp file. + +- Solved a problem with the keys, when the window lost focus the Key- + Release events weren't propagated. + +nxaccess-3.0.0-7 + +- Added functions in order to remove issues with some keys combina- + tion. + +nxaccess-3.0.0-6 + +- Added functions to simulate keys Ctrl + Alt + Del in order to run + the Task Manager application. + +- Now nxaccess is able to manage all switches between desktops. + +nxaccess-3.0.0-5 + +- Solved a problem with the cursor shape. After a while, the cursor + shape are no more updated. + +- Now the cursor is updated only when it changes its shape. + +- Removed a dirty lines after screen updates. + +- Removed the unused file Keyboard.cpp. + +- Added the colorCorrect() macro in NXaccess.h. + +- Removed the colorCorrect() function in Updater.cpp. + +nxaccess-3.0.0-4 + +- Renamed some source files and functions conforming them to the name + of component. + +nxaccess-3.0.0-3 + +- Removed the parameter of type Display in all methods of the class + Poller. + +- Print, Break and Pause keys are enabled. + +nxaccess-3.0.0-2 + +- Modified the Makefile.in in order to avoid compiling the executive + file. + +- Removed the unused file Main.cpp. + +- The Windows keys are enabled. + +- Synchronized local and remote states of Num_Lock, Caps_Lock and + Scroll_Lock. + +- Updated the NoMachine copyright notices. + +nxaccess-3.0.0-1 + +- Opened the 3.0.0 branch based on the nxmirror-2.0.0-3. + +nxmirror-2.0.0-3 + +- Added the keyboard events for all layouts. + +- The mouse wheel button is enabled. + +nxmirror-2.0.0-2 + +- Completed implementation of the keyboard events only for italian + layout. + +- Added the mouse events and shape cursor. + +nxmirror-2.0.0-1 + +- Opened the 2.0.0 branch based on the 1.5.0-60. + +- Added CHANGELOG. diff --git a/doc/_attic_/NoMachine_documentation_files/nxproxy_CHANGELOG b/doc/_attic_/NoMachine_documentation_files/nxproxy_CHANGELOG new file mode 100644 index 000000000..e5dff2e4f --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxproxy_CHANGELOG @@ -0,0 +1,216 @@ +ChangeLog: + +nxproxy-3.5.0-1 + +- Opened the 3.5.0 branch based on nxproxy-3.4.0-2. + +- Updated copyright to year 2011. + +nxproxy-3.4.0-2 + +- Updated copyright to year 2009. + +nxproxy-3.4.0-1 + +- Opened the 3.4.0 branch based on nxproxy-3.3.0-2. + +- Changed version number. + +nxproxy-3.3.0-2 + +- Updated VERSION. + +nxproxy-3.3.0-1 + +- Opened the 3.3.0 branch based on nxproxy-3.2.0-1. + +nxproxy-3.2.0-1 + +- Opened the 3.2.0 branch based on nxproxy-3.1.0-2. + +nxproxy-3.1.0-2 + +- Updated version number. + +nxproxy-3.1.0-1 + +- Opened the 3.1.0 branch based on nxproxy-3.0.0-4. + +nxproxy-3.0.0-4 + +- Added file COPYING. + +- Changed the LICENSE file to state that the software is only made + available under the version 2 of the GPL. + +nxproxy-3.0.0-3 + +- Updated the copyright notices to year 2007. + +nxproxy-3.0.0-2 + +- Updated the file VERSION. + +nxproxy-3.0.0-1 + +- Opened the 3.0.0 branch based on nxproxy-2.0.0-2. + +nxproxy-2.0.0-2 + +- Updated copyright to year 2006. + +nxproxy-2.0.0-1 + +- Opened the 2.0.0 branch based on nxproxy-1.5.0-10. + +nxproxy-1.5.0-10 + +- Added the JPEG, PNG and Z libraries to the linker when compiling + on Cygwin. GCC 3.3.x requires that these libraries are explicitly + given while this is not required since GCC 3.4.x. + +- Created a new configure using autoconf 2.59. + +nxproxy-1.5.0-9 + +- Removed provision for dynamically loading a different version of + the nxcomp library. + +nxproxy-1.5.0-8 + +- Updated to reflect the new naming of the NX transport interfaces. + +nxproxy-1.5.0-7 + +- Modified the Makefile.in to remove the *.out.* files generated by + Valgrind when running a 'make clean'. + +- Modified the README files and removed files that were outdated. + +nxproxy-1.5.0-6 + +- Removed the NX_FORCE_IDLE_PROXY stubs. + +nxproxy-1.5.0-5 + +- This version has NX_FORCE_IDLE_PROXY undefined, so it should work + in a way that is compatible with the old nxproxy. + +nxproxy-1.5.0-4 + +- This software is crafted by default to test the new integration + between nxcomp and nxssh. The process will stay idle and will + let nxssh create the proxy. Note that the session log will go to + 'sshlog', not to 'session'. This will have to be fixed in nxcomp + in future versions. + +- Removed the references to the "bind" functionality that is not + used in the current software. + +nxproxy-1.5.0-3 + +- Added a NX_FORCE_IDLE_PROXY. If set, nxproxy will stay idle and + will not try to create a nxcomp proxy. This is used for testing + the new in-process nxcomp functionalities with the development + versions of nxclient and nxssh software. + +nxproxy-1.5.0-2 + +- Small changes to this file. + +nxproxy-1.5.0-1 + +- Opened the 1.5.0 branch. + +nxproxy-1.4.1-1 + +- Opened the 1.4.1 branch. + +nxproxy-1.4.0-3 + +- We were lucky. We found a machine where nxproxy failed exactly + in the same way described by multiple users in their reports. + The error was the same ('dlopen: win32 line 126') and neither + rebasing the Cygwin DLLs or removing all the other Cygwin li- + braries worked. So the problem had necessarily to be in a bug- + gy Cygwin dlopen() implementation. To solve this I had to make + changes to the nxproxy code on Windows, so it links to nxcomp + at compile time in the way specified below. As far as I can + tell, any other way fails. This seems to be another Cygwin bug: + the linker says that everything is OK but then the executable + can't be run. Both the Cygwin's bash and the command.com say + 'Permission denied'. + + LIBS = -L../nxcomp -lstdc++ -Wl,-e,_mainCRTStartup -lXcomp \ + -lcygipc -static -lpng -static -ljpeg -lz + +nxproxy-1.4.0-2 + +- Added a Binder class invoked when calling proxy with -B option. + It would serve as a replacement of the modifications I'm doing + in nxssh. The class is just a framework and the implementation + is unfinished. + +- Solved a potential problem in Main.c with NXExit() being called + after the dlclose(). This was unlikely to happen as proxy never + returns. + +nxproxy-1.4.0-1 + +- Opened the 1.4.0 branch. + +nxproxy-1.3.2-1 + +- Opened the 1.3.2 branch. + +nxproxy-1.3.1-2 + +- Removed the underline characters and added a colon in the + title of this ChangeLog to fully comply with format used in + the release notices. + +nxproxy-1.3.1-1 + +- Opened the 1.3.1 branch. + +nxproxy-1.3.0-7 + +- Added a check on the OS version when running on MacOS/X. + Versions 10.2 and 10.3 differ in the way names are mangled. + +- Fixed error detection on dlsym(). The previous code was not + able to correctly identify missing symbols. + +nxproxy-1.3.0-6 + +- Modified configure.in to compile under FreeBSD. + +nxproxy-1.3.0-5 + +- Fixed a (further) compilation problem under Cygwin. + +nxproxy-1.3.0-4 + +- New nxproxy is able to load libXcomp by dlopen() under + Cygwin. This simplifies both code in Main.c and the + configure.in script. + +- Changed configure.in to not link with -mwindows under + Cygwin. Linking with -mwindows prevented stderr to be + correctly output when running nxproxy on a console. + +nxproxy-1.3.0-3 + +- Changed configure.in to first check for nx-X11 includes + and libraries. Added "/usr/openwin/bin/makedepend" to + path searched for the executable. + +nxproxy-1.3.0-2 + +- Small cleanup in configure.in. A new configure script has + been generated using autoconf-2.57-3. + +nxproxy-1.3.0-1 + +- Updated internal version, so this release tries to load + libXcomp version 1.3.0. diff --git a/doc/_attic_/NoMachine_documentation_files/nxproxy_README b/doc/_attic_/NoMachine_documentation_files/nxproxy_README new file mode 100644 index 000000000..8f95d9f3f --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxproxy_README @@ -0,0 +1,14 @@ +README +------ + +1. To compile: + + > tar zxvf nxproxy-X.Y.Z-N.tar.gz + > cd nxproxy + > ./configure + > make + + You'll have to run gmake under Solaris. + +2. The 'make install' target is not currently supported + in the Makefile, but it should be simple to fix. diff --git a/doc/_attic_/NoMachine_documentation_files/nxproxy_README-IPAQ b/doc/_attic_/NoMachine_documentation_files/nxproxy_README-IPAQ new file mode 100644 index 000000000..7a8a8a958 --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxproxy_README-IPAQ @@ -0,0 +1,27 @@ +README-IPAQ +----------- + +1. Install a cross-compiler for ARM. You can find detailed + informations at: + + http://www.ailis.de/~k/knowledge/crosscompiling/toolchain.php + + There are also binaries needed to install the cross-compiler. + +2. Configure and compile nxproxy using: + + $ ./configure --with-ipaq + $ make + + After compilation type: + + $ arm-linux-strip nxproxy + +3. You need libXcomp.so to run nxproxy. Be sure you include the + library in your LD_LIBRARY_PATH. For example, you can run: + + > export LD_LIBRARY_PATH $HOME/NX/nxcomp + > nxproxy -S localhost:8 + +4. The package nxscripts contains many examples of NX usage that + you can modify to suit your needs. diff --git a/doc/_attic_/NoMachine_documentation_files/nxproxy_README-VALGRIND b/doc/_attic_/NoMachine_documentation_files/nxproxy_README-VALGRIND new file mode 100644 index 000000000..ce4d513a4 --- /dev/null +++ b/doc/_attic_/NoMachine_documentation_files/nxproxy_README-VALGRIND @@ -0,0 +1,39 @@ +README-VALGRIND +--------------- + +You can run nxproxy (and nxcomp) under the supervision of valgrind +(a very good memory debugger) by wrapping nxproxy in the following +script: + + +#!/bin/bash + +# Enable core dumps. + +ulimit -c unlimited + +# Set this to directory where nxproxy is located. + +NXPROXY_DIR=~/NX/nxproxy + +# Set this to directory where valgrind is located. + +VALGRIND_DIR=/usr/local/bin + +exec ${VALGRIND_DIR}/valgrind -v --leak-check=yes --leak-resolution=high \ + --show-reachable=yes --show-reachable=yes \ + --suppressions=${NXPROXY_DIR}/nxproxy.supp \ + --num-callers=16 --logfile-fd=2 \ +\ +${NXPROXY_DIR}/nxproxy $1 $2 $3 $4 $5 $6 $7 $8 $9 + + +Run the following commands on your shell, right in the place where +the nxproxy executable is to be placed in your setup: + +$ cat >nxproxy + +$ chmod a+x nxproxy + +Output of valgrind will go on stderr, that is in session file, if +run in NX environment. diff --git a/nx-X11/CHANGELOG b/nx-X11/CHANGELOG deleted file mode 100644 index ffbbe0a61..000000000 --- a/nx-X11/CHANGELOG +++ /dev/null @@ -1,1085 +0,0 @@ -ChangeLog: - -nx-X11-3.5.0-2 - -- Fixed TR0202420. XKB utility functions wrote out of bounds. - -- Upgraded RandR server extension to version 1.2. - -nx-X11-3.5.0-1 - -- Opened the 3.5.0 branch based on nx-X11-3.4.0-4. - -- Updated copyright to year 2011. - -nx-X11-3.4.0-4 - -- Fixed TR06H02359. Removed compiler warnings. - -nx-X11-3.4.0-3 - -- Updated copyright to year 2010. - -nx-X11-3.4.0-2 - -- Fixed TR04G02208. Added a path to rgb file. - -nx-X11-3.4.0-1 - -- Opened the 3.4.0 branch based on nx-X11-3.3.0-7. - -- Updated copyright to year 2009. - -nx-X11-3.3.0-7 - -- Fixed TR08G02257. The maximum client condition was reached because - available fd exhausted. This bug was caused by a function in font - library not closing the file before a return on error breaking the - flow of normal execution. - -- Fixed TR06G02225. The implementation of Xvprintf() has been reviewed - to work on more platforms. Previous implementation caused a failure - in the build of keyboard map on some platform like Solaris 8 and 9. - -nx-X11-3.3.0-6 - -- Fixed TR03G02198. Reimplemented Xvprintf() in Xserver/os to handle - the case in which vsnprintf returned -1. - -- Returning from _XSeqSyncFunction() and _XReply() if an I/O error is - detected. - -nx-X11-3.3.0-5 - -- Fixed TR01G02163. Signals need to be blocked before the call to - fork() in the Popen() utility. - -- Fixed TR01G02164. Trapezoid data need to be validated before use. - This issue was the same of CVE-2007-2437. - -nx-X11-3.3.0-4 - -- Enabled the code resetting the Xlib buffer if an IO error occured. - -nx-X11-3.3.0-3 - -- Fixed the search path for the XKB base directory. - -nx-X11-3.3.0-2 - -- Fixed TR10F02116. The X11 agent could enter an indefinite wait state - if connection to X display is broken and libX11 output buffer is not - empty. - -nx-X11-3.3.0-1 - -- Opened the 3.3.0 branch based on nx-X11-3.2.0-2. - -nx-X11-3.2.0-2 - -- Imported patch fixing issues from X.Org security advisory, June - 11th, 2008: Multiple vulnerabilities in X server extensions. CVE - IDs: CVE-2008-1377, CVE-2008-1379, CVE-2008-2360, CVE-2008-2361, - CVE-2008-2362. - -nx-X11-3.2.0-1 - -- Opened the 3.2.0 branch based on nx-X11-3.1.0-6. - -nx-X11-3.1.0-6 - -- Modified Xserver Imakefile to link the Xfixes library. - -nx-X11-3.1.0-5 - -- Disabled the terminate action, just in case the TerminateServer - symbol is binded to a non default key sequence. - -nx-X11-3.1.0-4 - -- Imported patch fixing issues from X.Org security advisory, January - 17th, 2008: Multiple vulnerabilities in the X server. CVE IDs: - CVE-2007-5760 CVE-2007-5958 CVE-2007-6427 CVE-2007-6428 - CVE-2007-6429 CVE-2008-0006. - -nx-X11-3.1.0-3 - -- Moved a variable definition placed in _mesa_make_current(). - -nx-X11-3.1.0-2 - -- Fixed TR10E01924. A crash could occur in _mesa_make_current(). - -- Initialized after_ret variable in _XcmsGetProperty(). - -nx-X11-3.1.0-1 - -- Opened the 3.1.0 branch based on nx-X11-3.0.0-37. - -nx-X11-3.0.0-37 - -- Changed the Xserver Imakefile to link against Xcomposite on the - Cygwin platform too. - -nx-X11-3.0.0-36 - -- Fixed TR07E01806. Modified host.def to build GLX code with symbol - __GLX_ALIGN64 defined on Solaris platform. - -nx-X11-3.0.0-35 - -- Flush explicitly the NX link before entering the select() in the - WaitForReadable() and WaitForWritable() routines. - -nx-X11-3.0.0-34 - -- Changed the agent Imakefile to link to the Xcomposite library. - -nx-X11-3.0.0-33 - -- Fix the NX_TRANS_WAKEUP stuff in WaitForSomething() to not over- - ride a valid timeout. - -- Check if the requesting client is gone in the XFixes functions - sending the cursor events. - -nx-X11-3.0.0-32 - -- Define DDXOSVERRORF and DDXOSFATALERROR symbols on Sun. - -- Changed the copyright attribution from Medialogic to NoMachine. - -nx-X11-3.0.0-31 - -- Make SmartScheduleStopTimer() visible outside Xserver/os/utils.c - so that it can be called by the agent. Export the declaration in - dixstruct.h. - -nx-X11-3.0.0-30 - -- The OsVendorVErrorFFatal flag is set to 1 if the function pointed - by OsVendorVErrorFProc is called due to a fatal error. - -- Give the possibility to the agent to redirect the standard error - during a Popen() or a System() by setting the OsVendorStartRedir- - ectErrorFProc and OsVendorEndRedirectErrorFProc function pointers. - -nx-X11-3.0.0-29 - -- Changed the default message printed on a fatal server error. The - new message is: - - Error: Aborting session with 'Error text...'. - -- Hacked LogVWrite() to force all fatal error messages to have an - uppercase initial. Also remove the trailing newline and the full- - stop, if present. - -nx-X11-3.0.0-28 - -- Corrected the typos in the ChangeLog. - -nx-X11-3.0.0-27 - -- Fixed the cleanup of the X_RenderCompositeText16 padding bytes. - -- More code cleanup in the NX changes to the Xrender library. - -- Changed host.def to build the freetype and fontconfig libraries - if the agent server is also built. Freetype is built as a shared - library: this avoids the link error on 64 bit platforms. - -nx-X11-3.0.0-26 - -- Applied the following security patches, from the X.Org security - advisory, April 3rd, 2007 "Multiple vulnerability in X server, - libXfont and libX11": - - xorg-xserver-1.2.0-xcmisc.diff - xorg-libXfont-1.2.7-bdf-fontdir.diff - xorg-libX11-1.1.1-xinitimage.diff - -nx-X11-3.0.0-25 - -- Added the missing *.X.original file for ChkIfEv.c and Xlib.h. - -nx-X11-3.0.0-24 - -- Changed Xrender to clean up the padding bytes in XRenderComposite- - Text functions. - -- Added function XRenderCleanGlyphs() cleaning the padding bytes in - the data section of RenderAddGlyphs requests. - -nx-X11-3.0.0-23 - -- Removed the additional parameter from the call to NXTransFlush() - in _XReply(). - -- Call NXTransExit() on AbortServer() (called by FatalError()) to - give the proxy a chance to shut down the NX transport. - -nx-X11-3.0.0-22 - -- Moved the replacement of XCheckIfEvent() ChkIfEv.c with the name - XCheckIfEventNoFlush(). - -nx-X11-3.0.0-21 - -- Set BUFSIZE to 8192 bytes. While the output buffer size can be - configured by setting the XLIBBUFFERSIZE in the environment (see - OpenDis.c), this constant is still used when reading from the - socket. - -nx-X11-3.0.0-20 - -- If set, the handler pointed by _NXDisplayWriteFunction is called - after that more data is written to the display connection. - -nx-X11-3.0.0-19 - -- Added a RejectWellKnownSockets() stub to make possible to compile - the agent when the NX transport is disabled. - -- Added more useful logs to _XWaitForWritable(). - -nx-X11-3.0.0-18 - -- Changed Imakefile of X11 and Xserver in order to build nxcompshad - just before the NX agent server. - -- Changed Imakefile in Xserver to add NXdamage.o to NXAGENTOBJS. - -nx-X11-3.0.0-17 - -- Changed host.def in order to build Xdamage and Xrandr libraries. - -- Changed host.def in order not to build NXWin. - -nx-X11-3.0.0-16 - -- Changed host.def in order to build Xtst as a shared library. - -nx-X11-3.0.0-15 - -- Changes to comply with nxcompshad library. - -- Changed configuration to statically build Xtst library. - -- Restored parser directory under Xserver/hw/xfree86. - -nx-X11-3.0.0-14 - -- Changed the LICENSE file to state that the software is only made - available under the version 2 of the GPL. - -- Added file COPYING. - -- In nx-X11/programs and nx-X11/programs/Xserver/hw/xfree86, removed - files and directories not needed to build servers. - -nx-X11-3.0.0-13 - -- Changes aimed to link servers with static versions of Xdmcp and Xau - libraries. - -nx-X11-3.0.0-12 - -- Added references to implented FR in the ChangeLog. - -- Removed nx-X11/fonts and nx-X11/doc directories. They are not needed - for building the NX components. - -nx-X11-3.0.0-11 - -- Updated the copyright notices to year 2007. - -nx-X11-3.0.0-10 - -- Applied the following security patches: - - x11r6.9.0-cidfonts.diff - x11r6.9.0-dbe-render.diff - x11r6.9.0-geteuid.diff - x11r6.9.0-mitri.diff - x11r6.9.0-setuid.diff - -nx-X11-3.0.0-9 - -- Merged the NX changes to X11 with the X11R6.9.0 version of X.org. - -nx-X11-3.0.0-8 - -- Changes to build Xshadow library when building X11. - -- Changes to Xserver Imakefile to link Xshadow library. - -- Changes to host.def in order to build on old distributions. - -nx-X11-3.0.0-7 - -- Imported changes up to nx-X11-2.1.0-2 - -- Fixed TR08D01485. Updated rgb file paths validation in order to - support Ubuntu distribution. - -- Added Xtst to libraries to be linked by nxagent. - -- Changed Xpm Imakefile to build a shared library on Solaris. - -- Fixed build error on Solaris in xtrans. - -- Changed host.def not to build Xnest server. - -- Changed Xserver Imakefile to link nxaccess library. - -nx-X11-3.0.0-6 - -- Added the path of nxaccess library to the server link command. - -nx-X11-3.0.0-5 - -- Implemented FR10C01079 and FR10C01080. The merge of NX changes to - the X.org code is complete. - -- Merged changes in config/cf. The NX-*.def files have been dismissed. - Main platform dependent configurations have been moved to host.def. - -- Removed *.reference files from config/cf. - -- Fixed compilation for Cygwin platform. - -nx-X11-3.0.0-4 - -- Imported all changes up to nx-X11-2.0.0-32. - -- Cleaned up lib/zlib directory. - -- Added missing file programs/Xserver/os/utils.c.NX.original. - -- Updated the copyright notice to year 2006. - -- The pointer to the display buffer is reset after an I/O error. - This prevents leaving the buffer in an inconsistent state if the - error occurs inside _XFlush(). - -- Removed the modifications to the Xrender library. The cleanup of - the padding bytes is now performed by the NX transport. - -- NX uses the updated ZLIB from its build tree, so Imake.tmpl will - now assume that the platform as ZLIB unless otherwise stated. - -- The path of the SecurityPolicy file is searched and validated at - runtime. - -- Added the _X11TransSocketProxyConnInfo() function to Xtranssock.c - It returns the pointer to the XtransConnInfo private, if it is a - valid _NXProxyConnInfo structure. - -- The above function is used by OpenDis.c to detect if the NX trans- - port was requested on the display and avoid spurious error messa- - ges in the case of a connection failure. - -- Added NXmiwindow.o to the NXAGENTOBJS in the Xserver's Imakefile - and imported NXmiwindow.c in nxagent. This allows us to check the - pointer to the pOldClip region in miSetShape() before going on - freeing it. - -- The path of the XKB base directory and of the xkbcomp comand is - validated at runtime. - -- Also added a check to verify the validity of the rgb file path. - -- Added NXresource.o to NXAGENTOBJS in the Imakefile of nxagent. We - need this to a assign a resource to the pixmaps and other server - objects which need to be enumerated at reconnection. Some objects, - being created by the X server and not by the clients, don't pass - through the resource assignment process operated by the dix. To - ensure that all objects get a resource, we add a resource at the - time the object is created and temporarily assign the resource to - the server client. If the dix later assigns the resource to a va- - lid client, the resource is removed from the server client's list. - -- The display block handler registered by the client is called in - WaitForReadable() and WaitForWritable() before every select(), - not only upon entering the function. The reason is that more - data can be possibly produced for the NX link by the proxy it- - self and, when setting the flush policy to deferred, the client - may not have the chance of flushing the NX link. - -- Fixed a bug in XkbUseExtension() that caused Xlib to query the - presence of the XKEYBOARD extension multiple times. This partial- - ly implents the FR01D01275. The complete implementation required - modifications to the X11 agent, implemented in nxagent-2.0.0-33. - -- Updated to comply with the new NXTransFlush() interface. - -- Both nxwin and nxagent now read the X authority file by using an - fopen() instead of the system command 'cat'. - -- Removed NXmiwindow.o from the NXAGENTOBJ list. The agent will now - use the original miwindow.c. - -- Added some additional logs in Xtranssock.c to follow the creation - and removal of the X server's Unix listener. - -- Avoided the sleep of 5 seconds forced by Xtransutil.c if the dir- - ectory where the Unix listener is created is not owned by root. - This sleep is not executed on Cygwin (where the X socket can be - hardly owned by root) but may delay the startup of the agent if - the user chose a different NX_TEMP directory. Furthermore, it is - unclear what real benefits such sleeps are intended to bring to - the security of the X server. This can be controlled by defining - the NX_TRANS_SLEEP directive in Xserver/os/Imakefile. - -- Added NXmiexpose.o to the NXAGENTOBJ. - -- Ensured that _X11TransSocketCloseConnInfo() now initiates the NX - shutdown by calling NXTransClose(). - -- Corrected a misplaced #else that made SocketUNIXConnect() skip a - block if the connection was not to the NX transport. - -- Updated to comply with the new NX function prototypes introduced - in nxcomp-2.0.0-31. - -- Moved the most important Xtranssock.c modifications into separate - functions. - -- Ensured that the modifications enabling the internal connections - to the proxy are compiled only when the TRANS_CLIENT directive is - defined. - -- Solved a bug that prevented the X11 socket to be deleted at the X - server shutdown. This needs further tests. - -- Added nxcompext to the link of nxagent, now that the dependency - of libX11 from nxcompext is removed. - -- Improved the Xtranssock routines to never loop through the array - of connection info. - -- Added a congestion flag to the connection info structure and a - function querying the transport and reporting if a change in the - congestion state has occurred. The code is currently not enabled, - because instead of polling the transport, we let the proxy notify - the changes in congestion state by using the callback. The code - can be used in future to extend the library, for example, by add- - ing some counters tracking the bandwidth usage of the socket con- - nection, so that we can make the congestion notifications work - even with a plain X11 connection. - -- Profiled the routines in XlibInt.c to reduce the number of calls - to the error predicate function provided by the client. - -- Fixed the nxcompext build problem that caused make World to fail. - -- Added a 'CONF' target to the X11 and Xext Imakefiles so that the - configure script is not run if the config.status exists. - -- Added the _NXDisplayBlockHandler hook. The function is called by - Xlib before blocking. The parameter says if Xlib is going to wait - for more input or because it needs to write to the display socket. - The client can use the hook to perform any internal operation that - may require some time to complete. The user, though, should not - try to read or write to the display inside the callback routine. - -- Removed the outdated NX_TRANS_PROCESS, NX_TRANS_THREAD and NX_TR- - ANS_INCLUDE defines. - -- Reverted the lib/Xext Imakefile to the original XF86 version and - moved the build of the nxcompext library among the libX11 depend- - encies. - -- Corrected the lib/X11 Imakefile so that a new build of nxcomp and - nxcompext is not attempted if the libraries are up-to-date. - -- Removed the unused display buffer and image cleanup functions. - -- Reverted the PutImage.c file to the original XF86 version. - -- Added the _NXDisplayErrorPredicate function in XlibInt.c. It is - actually a pointer to a function called whenever Xlib is going to - perform a network operation. If the function returns true, the - call will be aborted and Xlib will return the control to the ap- - plication. It is up to the application to set the XlibDisplayIO- - Error flag after the _NXDisplayErrorPredicate returns true. The - function can be used to activate additional checks, besides the - normal failures detected by Xlib on the display socket. For exam- - ple, the application can set the funciton to verify if an inter- - rupt was received or if any other event occurred mandating the - end of the session. - -- Modified XIfEvent(), XMaskEvent() and XPeekIfEvent() to check the - _NXDisplayErrorPredicate function and return immediately if the - function returns true. - -- Modified _XWaitForReadable() to never enter the loop if the dis- - play is broken. - -- Corrected a make problem on Windows that caused the nxcomp and - nxcompext libraries to be referred with the wrong name, with the - result that a new configure and make was attempted at each build - attempt. - -- Merged all the changes to os, Xext, xkb, dix. - -- Changed host.def to build only the agent server. - -- Merged the changes to Xtranssock.c - -nx-X11-3.0.0-3 - -- Merged the changes to lib/X11. Restored original PutImage.c and - ClDisplay.c files. - -nx-X11-3.0.0-2 - -- Created a directory named 'reference' to keep files that are chan- - ged during the development of nx-X11 since the 1.5.0-16 to 2.0.0-32 - version. These files will be removed as long as the differences are - merged to the 3.0.0 version. When all differences are merged, this - directory will be removed. - -nx-X11-3.0.0-1 - -- Opened the 3.0.0 branch based on the nx-X11-2.0.0-9. The 3.0.0 - branch will now support the migration toward the X.org tree. Due - to time concerns, the 2.0.0 branch is going to be based on the - same nx-X11 as the 1.5.0. - -nx-X11-2.0.0-9 - -- Modified the agent link arguments to explicitly include the NX - libraries. - -- Disabled the Xinerama extension to avoid further clashes with - the redefinition of GC in Xlib. - -- Added os/libos.a at the end of the agent link. - -nx-X11-2.0.0-8 - -- Moved the declarations of _NXEnable* and related structures from - Xlibint.h to NXlibint.h. - -- Added provision for building the agent. This can be controlled by - setting NXAgentServer to YES in host.def. - -- Setting the NXUpgradeAgentServer variable to YES in the host.def - file will make the agent assume that it is being built in the new - environment. This variable is normally unset when building in the - 1.5.0 tree. - -nx-X11-2.0.0-7 - -- Fixed a problem on AMD64 due to the size of the area pointed by - the argument of _X11TransBytesReadable(). BytesReadable_t is long, - at least on Linux, while the ioctl() requires a pointer to an int. - The original _X11TransBytesReadable() function simply calls the - ioctl() by passing the pointer that is provided. NXTransReadable(), - instead, was correctly returning the value assuming a pointer to - a long, but this crashes some applications, among them xterm. Now - NXTransReadable() follows the same schema of the ioctl() call and - stores the result assuming a pointer to an int. - -- Removed the outdated NX_TRANS_PROCESS and NX_TRANS_THREAD code. - -nx-X11-2.0.0-6 - -- Made xterm work with the NX transport. This required small changes - to the Xt toolkit's and the xterm's files to let them use the NX - aware select(). This is useful to test the NX transport until the - nxagent server is integrated. - -- When the transport is gone _X11TransSocketBytesReadable() returns - EPIPE. This makes the client become aware of the closure of the - connection. - -- Added a call to NXTransDestroy() in XCloseDisplay(). - -- The exit() function in XlibInt.c causes a call to NXTransExit(). - -- Merged changes to dix/pixmap.c, xkb/xkbDflts.h, mi/Imakefile. - -- Removed unneeded changes and files containing patches already in - the latest X.org distribution: dix/dispatch.c, fb/fbcompose.c, fb/ - fbgc.c, xkb/ddxList.c, font/fontfile/dirfile.c, font/fontfile/ - encparse.c, font/fontfile/fontfile.c, font/FreeType/fttools.c, - Xrender/FillRect.c, Xrender/Picture.c. - -nx-X11-2.0.0-5 - -- Changes to the lib/X11/Imakefile to cleanly build the tree. This - is obtained by creating a link to the Xcomp library in exports/lib - without having to modify the programs' Imakefiles. - -- Finished merging the NX changes in the lib/X11 files. - -- Merged the CHANGELOG with the one from the 1.5.0 tree. - -nx-X11-2.0.0-4 - -- Merged the NX changes in most Xtrans and lib/X11 files. - -nx-X11-2.0.0-3 - -- Temporarily disabled the use of the MMX extensions in the Xserver's - fb code to successfully compile with GCC 4. - -nx-X11-2.0.0-2 - -- Imported the *.NX.reference and *.XF86.reference files that will - be needed for the merge. These files are the *.original from the - 1.5.0 tree. They will be removed as long as the merge advances. - -nx-X11-2.0.0-1 - -- Created the 2.0.0 branch based on X.org the 6.8.99.16 snapshot. - -nx-X11-1.5.0-16 - -- Added the missing *.XF86.original and *.NX.original files. - -nx-X11-1.5.0-15 - -- Made the nxagent server use select() instead of poll() on Solaris - so that it can leverage the new NX transport. - -- Moved the NXTransFlush() call to _XReply(). - -nx-X11-1.5.0-14 - -- Added the 'synchronous' parameter in the _XWaitForReadable() call - to NXTransFlush(). - -nx-X11-1.5.0-13 - -- Removed the log entry in XlibInt.c on calling the NXTransFlush(). - -nx-X11-1.5.0-12 - -- Changed XlibInt.c and utils.c to call NXTransExit(). - -nx-X11-1.5.0-11 - -- Changed XlibInt.c to comply with the new NXTransFlush() interfa- - ce introduced in nxcomp-1.5.0-42. - -- Cosmetic changes to messages printed for debug. - -nx-X11-1.5.0-10 - -- Ensured that all calls to _XIOError() are followed by a return. - -- Put exiting the client program in the case of an I/O error under - the control of the _NXContinueOnDisplayError flag. If set, the - I/O error routine will simply return, leaving to the application - the responsibility of checking the state of the XlibDisplayIOEr- - ror flag. - -- Added some checks whenever a read or write is performed on the X - connection, so that we can exit the I/O loop if the X channel is - gone. It is likely that more work will be needed when trying to - support XTHREADS enabled connections. This should not be a pro- - blem for now, as the default is still to quit the application un- - less the _NXContinueOnDisplayError flag is explicitly set. - -nx-X11-1.5.0-9 - -- Removed the references to the cygipc library in NXWin. Now use the - cygserver daemon to provide the MIT-SHM extension. - -- Fixed an error in the UseCygIPC definition. - -- Changed the cygwin.cf file to avoid redefinition of the BuildGlxExt, - XWinServer and BuildGlxExt symbols. - -nx-X11-1.5.0-8 - -- Added provision for deferred writes in the NX transport. When en- - tering _XWaitForReadable() we must ensure that data is flushed to - the proxy link. - -- Added the UseCygIPC define to NX-Cygwin.def. - -- Updated the NoMachine copyright notice on the modified files. - -nx-X11-1.5.0-7 - -- Added the GLX extension in NX-Sun.def. - -- Added some more logs in WaitFor.c. - -nx-X11-1.5.0-6 - -- Modified Xlibint.h and XlibInt.c to remove the _NXFlushSize para- - meter. New agents run the NX transport in-process, so we don't get - any benefit from increasing the display buffer size. - -- Modified NX-Darwin.def to not build the NXDarwin server. Since the - 1.4.0 version the NXDarwin server is unsupported and the NX client - for the Mac requires that the Apple X server is installed. - -- Changed NX-Linux.def to avoid the warning due to "SharedLibGLw" - being not defined. - -nx-X11-1.5.0-5 - -- Modified the Xserver Imakefile to link nxagent with FbPostFbLibs - and avoid including mfb/libmfb.a. - -- Added the GLX extension in NX-Linux.def. This provides unaccelera- - ted support in nxagent, with GLX operations translated into core X - protocol primitives. - -- Fixed x-X11/programs/Xserver/GL/dri/Imakefile to look in ../../hw/ - /xfree86/os-support/bus for includes. - -nx-X11-1.5.0-4 - -- Avoid calling NXTransSelect() if the transport is gone, so that we - don't have to wait until the timeout. - -- Added the "-fno-strict-aliasing" option to linux.cf when compiling - with a GCC version >= 4. In the words of Stefan Dirsch: "The opt- - ion, which is default since gcc 3.1, can result in wrong code when - the gcc warnings related to it are ignored. And as there are seve- - ral warnings in X11 related to it, it has been disabled for X11 - from the beginning. This didn't change for gcc4, so it still needs - to be used." - -- Added more logs in XlibInt.c and utils.c. A warning is printed if - the SmartScheduler is initialized. - -nx-X11-1.5.0-3 - -- Started integration of nxcomp with the X libraries. The Xtrans - code creates an internal connection to the nxcomp library instead - of a child proxy process. - -- Changed Xpoll.h and XlibInt.c to replace the standard Select - with a version giving NX a chance to check its own descriptors. - -- Implemented the NXTransReadVector() and the NXTransWriteVector() - functions to replace READV() and WRITEV(). - -- Implemented memory-to-memory communication with the NX proxy by - making use of the NXTransAgent() interface. - -nx-X11-1.5.0-2 - -- We think that the way LoadAuthorization() is working is wrong. - It doesn't reset the list of stored authorizations before reading - the new cookies. Our take is that if a new auth file is to be - read, the only cookies that are to be accepted are those that are - in the new file, not those in the file -plus- those that have - been in the file in the past. Furthermore, if the list can't be - read or it is empty, it should assume that it ignores which co- - okies are valid and thus it should disable any access. Your mile- - age can vary. A less draconian approach could be to leave the old - cookies if the file can't be read and remove them only if the - file is empty. - - Adding the cookies without removing the old values for the same - protocol has an important implication. If an user shares the co- - okie with somebody and later wants to revoke the access to the - display, changing the cookie will not work. This is especially - important with NX. For security reasons, after reconnecting the - session to a different display, it is advisable to generate a - new set of cookies, but doing that it is useless with the current - code, as the old cookies are going to be still accepted. On the - same topic, consider that once an user has got access to the X - server, he/she can freely enable host authentication from any - host, so the safe behaviour should be to reset the host based - authenthication at least at reconnection, and keep as valid only - the cookies that are actually in the file. This behaviour would - surely break many applications, among them a SSH connection run - inside a NX session, as ssh -X reads the cookie for the display - only at session startup and does not read the cookies again - when the auth file is changed. - - Another bug (or feature, depending on how you want to consider - it) is that if the authority file contains entries for different - displays (as it is the norm when the authority file is the default - .Xauthority in the user's home), the X server will match -any- of - the cookies, even cookies that are not for its own display. This - means that you have to be careful when passing an authority file - to nxagent and maybe keep separate files for letting nxagent find - the cookie to be used to connect to the remote display and for - letting it find what cookies to accept. If the file is the same, - clients will be able to connect to nxagent with both the cookies. - This bug obviously affects any X server, also the real X server - running on the workstation, so it is common to see nxagent being - able to connect to the X server even if no cookie matches the - real display. - -- Added a check in lib/Xau/AuRead.c to prevent the fread() call to - be interrupted by SIGCHLD while reading the auth file. Due to the - way the old code worked, this could lead to the server enabling - local host access to the display. This problem had been identified - in the past. We just found that all the code dealing with reading - the auth file was affected. The code calls sigprocmask() to block - the signal (though it leaves some other calls unprotected) but the - SIGCHLD was not included in the set. - -- Added SIGCHLD to the set of signals that are blocked when reading - the authorization file. - -- As I was at it, I changed the path to the SecurityPolicy file. A - few Linux ditributors ship the file in $LIBDIR/xserver, a few only - in /etc/X11/xserver, most others in both places. It seems that - those who ship in $LIBDIR/xserver do also in /etc/X11 but the op- - posite is not true, so I switched to /etc/X11. - -nx-X11-1.5.0-1 - -- Opened the 1.5.0 branch. - -nx-X11-1.4.1-2 - -- Set parameter UseCygIPC on cygwin conf file in order to force the - build of MIT-SHM estension. - -- Removed some spurius object file. - -nx-X11-1.4.1-1 - -- Opened the 1.4.1 branch. - -nx-X11-1.4.0-8 - -- Changed DefaultFontPath and DefaultRGBDatabase in - NX-Cygwin.def. - -nx-X11-1.4.0-7 - -- Imported dispatch in nxdarwin package, in order to let - nxdarwin being able to detect new client connection. - -- Changed the Xpm Imakefile to make also .a static library - on Solaris. To link nxviewer and nxdestkop staticaly. - -nx-X11-1.4.0-6 - -- XInput extension enabled on MacOSX. - -- Added some missing backup files of the original XFree86 - package. - -nx-X11-1.4.0-5 - -- Changed the mi Imakefile in order to let xfree86 servers use - the normal mi extension initialization for the XInput exten- - sion. - -- XInput extension enabled on Solaris. - -nx-X11-1.4.0-4 - -- Removed the RejectWellKnownSocket for the cygwin and - MacOSX environments that doesn't use the Xtransport library. - -nx-X11-1.4.0-3 - -- Changed the implementation of the reject method in the - Xtransport library, now close any new incoming connection - immediately without reading or writing to it. - -nx-X11-1.4.0-2 - -- Implemented a reject method in the Xtransport library, - this function accept and close every connection attempt, - on the specified listening socket. - -- Added the new function RejectWellKnownSocket to the os - connection code. - This function use the new transport reject function on - all listening socket. - -nx-X11-1.4.0-1 - -- Opened the 1.4.0 branch. - -- Removed forgotten nxagent-1.3.2-20 directory. - -nx-X11-1.3.2-9 - -- Prevents NX Darwin server going through the reset. On Darwin - we found that the it is not possible to get the correct key- - board layout unless it is set on the local machine, before - the NX session is started, by using xmodmap. As we set the - keyboard locally, we must prevent the X server to reset, or - we would loose any local configuration. - -nx-X11-1.3.2-8 - -- Removed action associated to keysym XK_Terminate_Server. This - could cause agent to be terminated when pressing shift + back- - space if using the default US keyboard mapping. - -- Disabled the remaining debug logs in lib/X11/PutImage.c - -nx-X11-1.3.2-7 - -- Fixed the wrong programs/Xserver/Imakefile in 1.3.2-6 package. - -nx-X11-1.3.2-6 - -- Changed the define from NX_CLEAN_IN_PLACE to NX_CLEAN_INPLACE. - Definition of symbol is now placed in the Imakefile. - -- The new _NXEnableCleanInplace Xlib variable does control which - algorithm is used to clean the images. Setting NX_IMAGEINPLACE - in the environment will activate the in-place cleanup. - -- The default value of _NXEnableCleanInplace is -1. Leaving it to - a value <= 0 disables use of CleanInplace. - -nx-X11-1.3.2-5 - -- Patch in config/cf/sun.cf. Fix for libfontconfig compilation - during gmake Everything on Solaris. - -- Patch in lib/X11/Imakefile. Fix for nxcomp compilation during - gmake World on Solaris. - -nx-X11-1.3.2-4 - -- Image cleanup is now performed by using NXCleanInPlaceImage from - nxcompext. This function saves a buffer copy by cleaning the - padding bytes in the same buffer provided by the caller. Note that - to prevent memory violations in the case the image was allocated - in a static buffer, the function will temporarily redefine the - SIGSEGV handler. The former handler is restored before returning - to the caller. This can potentially affect some multithreaded - clients. Is to be decided if the function is safe enough to be - included in the production release. - -nx-X11-1.3.2-3 - -- More debug logs in programs/Xserver/xkb/ddxLoad.c. - -nx-X11-1.3.2-2 - -- Added NXmiwindow.o to NXAGENTOBJS in programs/Xserver/Imakefile. - File was not linked into the resulting nxagent. This solves the - problem of missing repaints in CDE and other Xt applications. - -nx-X11-1.3.2-1 - -- Added some debug logs in programs/Xserver/xkb/ddxLoad.c. Function - XkbDDXCompileKeymapByNames is called by OpenOffice to read the - keyboard configuration whenever a drop-down menu is accessed. It - seem to always fail with the following error: - - The XKEYBOARD keymap compiler (xkbcomp) reports: - > Error: Can't find file "unknown" for geometry include - > Exiting - > Abandoning geometry file "default" - -- Opened the 1.3.2 development branch. - -nx-X11-1.3.1-12 - -- Fixed a problem in xkb/ddxLoad.c on Solaris where Pclose was - always returning an error code despite the fact that command - was executed properly. - -nx-X11-1.3.1-11 - -- Changed default GCC flags from '-O2 -fno-strength-reduce' to - -O3. No platform where NX is targeted is currently using a - GCC 2.x affected by the -fno-strength-reduce bug. Note also - that nxcomp is already compiled with -O3 since 1.1.1, so it - can be considered safe. - -nx-X11-1.3.1-10 - -- Imported an updated fbcompose.c file from XFree86-4.3.99.902. - This fixes "uninitialized value" problems reported by Valgrind. - -- Fixed further buffer overflows by updating the following file - with recent versions coming from the XFree86-4.3.99.902 tree. - - nx-X11/lib/font/fontfile/dirfile.c - nx-X11/lib/font/fontfile/encparse.c - nx-X11/lib/font/fontfile/fontfile.c - -- Fixed a possible buffer overflow in lib/font/FreeType/fttools.c. - Verified that the change is already in the XFree86 4.4.0 CVS. - -nx-X11-1.3.1-9 - -- Fixed Xserver/Imakefile which was still referencing NXpixmap.o. - -nx-X11-1.3.1-8 - -- Imported an updated fbgc.c from XFree86-4.3.99.902. This fixes - some minor problems reported by Valgrind. - -- A major problem was reported by Valgrind about reading after - the block allocated in fbCreatePixmap from AllocatePixmap. The - file pixmap.c has been modified so that 4 bytes are added to - the pixmap buffer at any new allocation. This quick hack should - solve the problem for both nxagent and the NXWin server. Further - investigation is planned for the next release. - -- Fixed Xtranssock.c to compile on Solaris where struct sigaction - doesn't have the sa_restorer member. - -nx-X11-1.3.1-5 - -- Renamed the NX-sun.def configuration file to NX-Sun.def. - -- Renamed the non-standard NX_iPAQ_XServer and NX_Zaurus_XServer - symbols to NXiPAQXServer and NXZaurusXServer. - -- Added the missing sun.cf.XF86.original file in config/cf. - -- Added the missing empty file host.def.XF86.original in the - same directory. - -- Added initialization of sa.sa_mask when setting sigaction() - for SIGCHLD. The problem was reported by Valgrind running - nxagent. - -- Removed an unused block of code from WaitFor.c. The code had - been commented out in previous versions. - -- Removed the non-standard colon at the end of version in this - CHANGELOG. - -- Removed the spurious spaces in this CHANGELOG. - -nx-X11-1.3.1-4 - -- Added a little workaround to the top Imakefile intended to - hide the makedepend warnings about non portable whitespaces - in sources. - -nx-X11-1.3.1-3 - -- Fixed compilation problem with nxagent-1.3.1-13. - -nx-X11-1.3.1-2 - -- Changes in NX-sun.def configuration file for Solaris to allow - compilation of the XKB extension. - -nx-X11-1.3.1-1 - -- Opened the 1.3.1 development branch. - -nx-X11-1.3.0-6 - -- Original output buffer size in stock XFree86 is 2048. We try - to reduce context switches and help stream compression by - increasing the maximum size of the buffer 8192. _NXFlushSize - determines when the display buffer is actually flushed. It is - set by default to 4096 but agents should set it to 0 if they - want to disable early flush. - -- Added the _NXLostSequenceFunction function pointer to let NX - agents suppress the error message and modify the default Xlib - behaviour when out-of-order sequence numbers are received. diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG deleted file mode 100644 index 0a82773f4..000000000 --- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG +++ /dev/null @@ -1,6359 +0,0 @@ -ChangeLog: - -nxagent-3.5.0-9 - -- Fixed an issue with cursor position set in XTest extension. - -nxagent-3.5.0-8 - -- Fixed TR01J02646. Performance issues with cairo version 1.12. - -- Fixed TR01J02667. Changes to mouse sensitivity couldn't be forwarded - to NX client host although -noignore was among extra options. - -- Fixed TR05J02705. Agent ignore WarpPointer requests. - -- Fixed TR05J02706. Suspended sessions could not be recovered using - a client form a different version. - -- Fixed TR05J02703. Agent failed because of missing checks on source - drawables in the render code. - -nxagent-3.5.0-7 - -- Fixed TR10I02622. Corrected function searching for icon file. - -nxagent-3.5.0-6 - -- Fixed TR10I02621. Avoided explicit call to XMapWindow() at recon- - nection stage. - -- Fixed TR10I02620. Solved error in default visual set up. - -- Fixed TR10H02390. Get the actual remote key code for CapsLock and - NumLock. - -nxagent-3.5.0-5 - -- The NX agent failed to resize its own window to fit the desktop size - in shadow sessions. TR07I02561 is now fixed also in shadow mode. - -nxagent-3.5.0-4 - -- Fixed TR07I02530. Solved a buffer overflow occurring when the '-fp' - option value exceeds 1024 characters. - -- Extended list of the available screen geometries. - -nxagent-3.5.0-3 - -- Fixed TR08I02572. Upgraded RandR extension to version 1.2. - -- Fixed TR07I02561. The NX agent failed to resize its own window to - fit the desktop size. - -nxagent-3.5.0-2 - -- Fixed TR0502449. Initialized font server path even if font server - connection fails. - -nxagent-3.5.0-1 - -- Opened the 3.5.0 branch based on nxagent-3.4.0-16. - -- Updated copyright to year 2009. - -- Fixed TR0302438. Added a check in function exporting property in - order to handle the case looking up an atom name returns a null - pointer. - -nxagent-3.4.0-16 - -- Updated copyright to year 2011. - -nxagent-3.4.0-15 - -- Added reference to fixed TR11H02405. - -nxagent-3.4.0-14 - -- Reverted fix for TR03H02335 implemented in nxagent-3.4.0-6. The - emulation of right click by Control key + left click introduces - issues for some applications changing the reaction to the left click - depending on the state of Control key. Issue reported in TR03H02335 - affects Apple laptop touchpads having a single button acting as - left button: on those devices the right button can be emulated by - a double-fingered tap (using two fingertips simultaneously). - -nxagent-3.4.0-13 - -- Fixed TR12H02414. Exported property must be split if ChangeProperty - request exceeds 262140 bytes. - -- Reset AllScreens option at reconnection time if full screen mode - have to be automatically turned off. - -nxagent-3.4.0-12 - -- If one of the two full screen modes is active ('one screen' or 'all - screens') both keystrokes Ctrl-Alt-F and Ctrl-Alt-Shift-F change the - mode back to 'windowed'. - -- Fixed TR11H02405. XRenderFreePicture is called only for pictures - that were actually created on the X server side. - -- Ctrl+Alt+f switch fullscreen to all monitors, while Ctrl+Alt+Shift+f - does it to one monitor only. - -- If the fullscreen option is enabled at the startup, session starts - in the fullscreen mode on all monitors. - -- Added a call to XReparentWindow in the nxagentSwitchAllScreens(). - -- Corrected focus and grab when switching to fullscreen on - all monitors. - -- Removed a compile warning e deleted some unused variables. - -- Removed nxagentPointerAndKeyboardGrabbed variable. - -- Use the override redirect attribute to switch to fullscreen to all - monitors instead of send _NET_WM_FULLSCREEN_MONITORS hint to the WM. - -- Added nxagentMinimizeFromFullScreen(), nxagentMaximizeToFullScreen() - and nxagentCreateIconWindow(). - -- Removed check on EnterNotify to grab the keyboard in fullscreen - mode not only if mode is 'NotifyNormal'. - -nxagent-3.4.0-11 - -- Corrected switching between viewport mode and resize mode. - -- Fixed TR04H02340. Keycode is correctly translated in shadow sessions - also if the remote X display is using evdev. - -nxagent-3.4.0-10 - -- Handled XGrabKeyboard() return value. - -- Fixed TR10D01512. NumLock and CapsLock keys are now synchronized - between local and remote. - -nxagent-3.4.0-9 - -- Fixed TR06H02362. No icon was swown in the task bar. - -- Fixed keyboard grab in fullscreen mode. - -- Fixed compiler warnings. - -nxagent-3.4.0-8 - -- Grab the keyboard in fullscreen mode on EnterNotify only if mode is - 'NotifyNormal'. - -- Yield control in the dispatch loop in case we stop the smart sche- - duler timer while waiting for a reply from the remote display. - -nxagent-3.4.0-7 - -- Fixed TR08D01478. The communication with the compiz window manager - by means of the _NET_WM_PING property was not handled properly. - -- Fixed a type mismatch in XKB events on 64 bit platforms. - -- Moved grab/ungrab keyboard from focus in/out event to enter/leave - notify event. - -- Removed nxagentIconWindow because it's not longer used. - -nxagent-3.4.0-6 - -- Fixed TR09F02102. Problem was with pointer buttons map. - -- Fixed TR02H02327. Some KeyRelease events was discarded. - -- Fixed up Num and Caps locks. - -- Fixed TR03H02335. Emulated right mouse button for Mac clients. - -- Added utilities to print info about internal and remote windows. - -- Fixed TR01F01995. Solved a picture resource leak by destroying remo- - te pictures only when their reference counter returns to zero. - -- Fixed TR04H02337. Errors occurred because pictures with no drawable - were handled badly. - -- Implemented handling nxagent's private for gradient pictures and so- - lid fill picture. - -- Fixed BadMatch condition check in function ProcRenderComposite. - -- Fixed nxagentComposite() to handle situations with source picture - drawable pointing to NULL. - -- Implemented render acceleration for requests: CreateSolidFill, - CreateLinearGradient, CreateRadialGradient, CreateConicalGradient. - -- Fixed TR03G02196. Dialogs are shown to the fore when the NX session - is in fullscreen mode. - -- Changed mechanism to switch to fullscreen mode. Now the override - redirect attribute is no longer used and _NET_WM_STATE_FULLSCREEN - hint is sent to the WM. - -nxagent-3.4.0-5 - -- Updated copyright to year 2010. - -nxagent-3.4.0-4 - -- Fixed TR07F02090. Now XDMCP sessions start without problems. - -- Fixed TR08G02259. Corrected window border granularity of rootless - session at reconnection on 64 bit platforms. - -- Fixed TR11G02290. Forcing null timeout with queued events only if - display connection is up. This prevents the flood of session log. - -- Fixed TR10G02287. Now QueryTree's loop is aborted in case of failure - and session log isn't filled anymore with repeated warning messages. - -- Fixed TR01G02154. Corrected window placement when switching between - fullscreen and windowed mode. - -- Fixed TR09G02276. Now the agent does not receive unwanted characters - while interacting with the local window manager. - -- Implemented FR02G02174. Added ability to do large screen pans in - viewport mode through key combination Ctrl+Alt+Shift+Arrow. - -- Corrected parsing of the 'client' option when the client OS is Mac. - -nxagent-3.4.0-3 - -- Fixed TR09G02271. The array containing the font name fields was not - correctly initialized for non-standard font names. - -nxagent-3.4.0-2 - -- Updated copyright to year 2009. - -nxagent-3.4.0-1 - -- Opened the 3.4.0 branch based on nxagent-3.3.0-19. - -- Changed the printed version number. - -nxagent-3.3.0-19 - -- Fixed TR09G02266. A proper error message is printed in the session - log if the shadowing initialization fails because of a mismatch in - the visual class. - -- Added a workaround for X servers that doesn't return 1 among the - available depths. - -nxagent-3.3.0-18 - -- The area to restore from the backing store is limited by the screen - size instead of the visible screen. - -nxagent-3.3.0-17 - -- Fixed TR12F02150. The agent could crash when copying text from VNC - viewer. Fixed by aborting the procedure in case the retrieved pro- - perty has not a valid format. - -nxagent-3.3.0-16 - -- Fixed TR07G02247. Don't try to call XSetWindowColormap() if the - window has no colormap, e.g. if its class is InputOnly. - -nxagent-3.3.0-15 - -- Fixed TR04G02210. Region is cut to the visible screen before re- - storing areas from the backing store. - -- Fixed TR07G02246. Box is shrinked if bounds can't stay in a short - signed integer. - -nxagent-3.3.0-14 - -- Fixed TR03G02206. waitpid() call was missing for the "Fonts replace- - ment" dialog type. - -- Fixed TR03G02195. Added a properties structure compatible with 32 - and 64 bit platform types. - -nxagent-3.3.0-13 - -- Handle the window unmap immediately. Don't add it to the configure - queue. - -nxagent-3.3.0-12 - -- Fixed TR03G02200. Timestamps could be in the future in KeyRelease - events sent to the X clients. - -- Added debug logging of input devices state Logging can be enabled - or disabled via the Ctrl+Alt+x shortcut. State info is dumped every - 5 seconds. - -- Added Ctrl+Alt+y shortcut used to deactivate input devices grab for - debug purposes. - -nxagent-3.3.0-11 - -- Changed the message logging the screen size changes, in order to - show the fullscreen state. - -- Handle the window unmapping in the nxagentConfigureWindow queue. - -nxagent-3.3.0-10 - -- Fixed TR12F02146. Compare the drawable and the bitmap data before - realizing the image update, in order to delay the data clean up that - caused the memcmp() failure. - -- Fixed TR01G02156. Reduce the exposing area by subtracting the ex- - posed region. - -- Fixed a compile warning in Drawable.c. - -- Added detailed logs in the nxagentSynchronizeRegion() function if - the data memory allocation fails. - -nxagent-3.3.0-9 - -- Added /usr/NX/share/base to alternate font paths. This would fix - TR11F02130 if fonts fixed and cursor are installed there. - -- Changed Keyboard initialization and reset. This change should fix - TR11F02129, TR11F02131, TR11F02132. - -nxagent-3.3.0-8 - -- Fixed TR12F02144. Image bits of render glyphs are copied before they - are cleaned. This will avoid a memory corruption. - -- Fixed TR12F02145. When dispatching a MotionNotify event, check if a - top-level window has been entered before trying to show the pulldown - dialog. - -nxagent-3.3.0-7 - -- Added debug code for pointer input. - -nxagent-3.3.0-6 - -- Fixed compile warnings. - -nxagent-3.3.0-5 - -- Disabled verbose logging in Rootless.c. - -nxagent-3.3.0-4 - -- Fix the XKB map load in the case of 64 bit server. - -nxagent-3.3.0-3 - -- Fixed TR10F02119. If the remote X display is using evdev keyboard - then copy maps from remote. - -- Upgraded VERSION to 3.3.0. - -nxagent-3.3.0-2 - -- Fixed TR10F02115. Painting errors occurred when screen areas beyond - the current viewport became viewable in the NX Client for Windows. - -- Using a new struct type nxagentWMHints to avoid type mismatch on - 64 bit platforms. - -- Added debug utilities for pointer input. - -nxagent-3.3.0-1 - -- Opened the 3.3.0 branch based on nxagent-3.2.0-12. - -nxagent-3.2.0-12 - -- Ignore 'resize' option at reconnection if viewport mode is on. - -- Fixed TR08E01814. Added shadow keymap initialization in order to - enable nxcompshad to translate keycodes across different layouts. - -nxagent-3.2.0-11 - -- Fixed TR08F02098. Function splitting font names has to be instruct- - ed to handle the right number of fields. - -nxagent-3.2.0-10 - -- Extended fix for TR07F02091 to include font names having zero in - fields RESOLUTION_X and RESOLUTION_Y. - -nxagent-3.2.0-9 - -- Fixed TR07F02091. Scalable fonts were not correctly listed among - available fonts. - -- Fixed TR06F02080. Use the corrupted area extents as maximum size of - the image data. - -nxagent-3.2.0-8 - -- Fixed TR07F02082. The agent server could be unable to init core - keyboard on 64 bit systems. - -nxagent-3.2.0-7 - -- Imported patch fixing issues from X.Org security advisory, June - 11th, 2008: Multiple vulnerabilities in X server extensions. CVE - IDs: CVE-2008-1377, CVE-2008-1379, CVE-2008-2360, CVE-2008-2361, - CVE-2008-2362. - -nxagent-3.2.0-6 - -- Fixed TR05F02063. Ignore ReparentNotify events for non-rootless - sessions. - -- Fixed TR06F02068. Try to pack images only if format is ZPixmap. - -- Don't require reparent on close of NX window. - -nxagent-3.2.0-5 - -- Fixed TR04F02044. Restored the original MakeRootTile() function in - order to create the root window background pixmap. - -- Fixed TR04F02041. Gnome panels stayed on top of the NX session win- - dow with desktops running Compiz. This fix provides a solution for - the Fullscreen mode. - -- Improved for the shadow session the handling of master session win- - dow resize. - -nxagent-3.2.0-4 - -- Fixed TR10D01535. The agent window is not minimized anymore when - pointer leaves. - -- Changes aimed to avoid possible type mismatch in XDisplay struct - on 64 bit architectures. - -nxagent-3.2.0-3 - -- Fixed a build issue on Solaris. - -nxagent-3.2.0-2 - -- Code clean up. Moved a variable definition to the beginnning of a - block. - -nxagent-3.2.0-1 - -- Opened the 3.2.0 branch based on nxagent-3.1.0-9. - -nxagent-3.1.0-9 - -- Fixed TR03F02025. German umlauts couldn't be pasted into a remote - Windows application. Now also the UTF8_STRING target is available - for ConvertSelection requests. - -- Fixed TR03F02031. Moved SetScreenSaverTimer() call in order to avoid - undesired reset of the auto-disconnect timeout when a screen saver - turns on. - -nxagent-3.1.0-8 - -- Added reference to fixed TR02F02007 and TR07E01762 in the CHANGELOG. - -- Set the GC trap before calling fbPolySegment. - -- Fixed TR09E01863. A flag is set if a resource has been added or fre- - ed and it is checked in FindClientResourcesByType(). - -- Added void entries to nxagentRequestLiteral vector in order to avoid - a wrong string is printed to the output for NoOperation request. - -- Fixed TR11E01948. Now keyboard status is initialized again after - the NX session is reconnected. This avoids CAPS LOCK and NUM LOCK - synchronization problems. - -- Added nxagentXkbCapsTrap and nxagentXkbNumTrap to avoid CAPS LOCK - and NUM LOCK synchronization problems when CAPS LOCK or NUM LOCK is - the first key to be pressed in the NX session. - -- Corrected subSize variable initialization in nxagentRealizeImage(). - -- Fixed various memory leaks. - -- Fixed TR11E01950. Copy and paste via edit menu didn't work for some - applications. - -- Corrected property type in nxagentRequestSelection(). Some external - applications didn't enable their paste button when nxagent was the - owner of the CLIPBOARD selection. - -- Added struct to save values queried by XQueryExtension for XFixes - extension. - -nxagent-3.1.0-7 - -- Imported patch fixing issues from X.Org security advisory, January - 17th, 2008: Multiple vulnerabilities in the X server. CVE IDs: - CVE-2007-5760 CVE-2007-5958 CVE-2007-6427 CVE-2007-6428 - CVE-2007-6429 CVE-2008-0006. - -- Fixed TR02F02007. Handled the case if nxagentCreateDrawableBitmap() - fails to create the pixmap intended to store the bitmap data. - -nxagent-3.1.0-6 - -- Fixed a compile warning in Args.c. - -- The synchronization loop breaks if the drawable is clean when it's - not supposed to be. - -- Fixed TR12E01966. Emacs tooltips were not displayed properly. Added - a check on the event mask before calling miWindowExposures(). - -- Fixed TR01F01982. ConfigureNotify warning is printed in verbose mode - only. - -nxagent-3.1.0-5 - -- Moved some variable definitions placed in ProcGetProperty(). - -nxagent-3.1.0-4 - -- Fixed TR06D01397. The problem was: drag & drop operations between - windows of Java applications didn't work in NX Client for Windows. - -- Implemented FR12E01957. Added a limit to the amount of data that can - be pasted from an NX session into an external application. The new - option - named 'copysize' - can be read from the 'options' file. - -nxagent-3.1.0-3 - -- Fixed TR12E01963. The window tree is revalidated explicitly after - recomputing the root window clip regions. - -nxagent-3.1.0-2 - -- Fixed TR11E01946. Forcing exposures on regions saved in the backing - store could bring to unexpected results. - -- Fixed TR11E01928. Animated cursors were not properly disconnected - and reconnected. - -nxagent-3.1.0-1 - -- Opened the 3.1.0 branch based on nxagent-3.0.0-93. - -nxagent-3.0.0-93 - -- Fixed TR10E01913. Now bell settings are restored after the agent - reconnects. - -nxagent-3.0.0-92 - -- Fixed a compilation error on 64 bit platforms. - -nxagent-3.0.0-91 - -- Checked the window synchronization status before subtracting an ex- - posed area from the corrupted region. - -nxagent-3.0.0-90 - -- Fixed TR11E01932. In case of rootless session displayed by NXWin X - server, synthetic ConfigureNotify events are generated by the X11 - agent. This helps to correct menu navigation in Java 1.6.0. - -- Fixed the handling of 'client' parameter. - -- Fixed bad refreshes in viewport navigation in the case of Windows - client. - -- Fixed TR11E01930. If the defer level is set by means of the command - line, the DeferLevel option is not reset while resuming the session. - -- Fixed TR07E01762. Problem in comparison of font names. - -- Printed the new geometry in the session log when the agent screen is - resized. - -nxagent-3.0.0-89 - -- Fixed TR10E01919. The agent could crash in the routine in charge of - find a replacement for a missing font. - -- Removed an unuseful log message. - -nxagent-3.0.0-88 - -- Fixed TR10D01539. Some XKEYBOARD requests are disabled if the option - 'keyboard' has value 'query'. This locks the initial keyboard map. - Enabling/disabling of XKEYBOARD requests is done at run time. - -- Added -noxkblock command line option enabling the XKEYBOARD requests - even if the option 'keyboard' value is 'query'. - -nxagent-3.0.0-87 - -- Reworked the handling of CT_PIXMAP client clips. Clips are always - converted in regions for internal use, while bitmap are saved for - operations involving the remote X. - -nxagent-3.0.0-86 - -- Fixed TR07E01749. Now using different resolution between shadow - and master session with shadow display option 'As on the server' - doesn't display black borders. - -- Fixed TR09E01852. The GC clips of type CT_PIXMAP are not converted - in regions. This avoids generating regions made up by thousands of - rectangles. Backing store function SetClipmaskRgn is implemented by - a stub doing nothing. - -nxagent-3.0.0-85 - -- Fixed TR08E01841. Exposed are forced to new areas exposed by the - viewport. - -- Fixed TR02E01645. Remote exposures was blocked if the NX client was - running on Linux without window manager. - -- Even if the agent window is fully obscured, synchronization is not - skipped if the Composite extension of the remote display is in use. - -- Fixed TR08E01851. Exposures events have to be internally generated - for regions that can't be restored because the backing pixmap is - corrupted. - -- Fixed TR08E01847. The initial values of store used to save XChangeGC - calls are set to the default GC values. - -- When a drawable becomes synchronized, its outdated bitmap is destro- - yed. - -- If a pixmap is not fully synchronized after a synchronization loop - it is cleared, just like windows. - -- Solved a problem causing some pixmaps to remain among the corrup- - ted resources even if they were synchronized. - -nxagent-3.0.0-84 - -- Renamed Misc.h as Utils.h to solve name clashes on Windows platform. - -nxagent-3.0.0-83 - -- Changes to include correctly declaration of _XDisplay structure on - 64 bit platforms. Further tests are needed to confirm that it fixes - TR08E01824. - -nxagent-3.0.0-82 - -- Fixed TR08E01821. Changed nxagentAddItemBSPixmapList() to check if - the pixmap item has already an entry in the list before adding it. - -- Fixed TR07E01795. Sun Studio main window showed only its grey back- - ground. Changed clipboard events handling to let the agent notify - a failure in converting selection. - -nxagent-3.0.0-81 - -- Based on nxagent-3.0.0-78. - -- The agent options are saved before reopening the display in the - reconnection procedure. If the new initialization fails the backup - values of options are restored. - -- Keyboard device info are saved before the keyboard reset occuring - in the reconnection procedure. If the new initialization of the - keyboard fails, the old values are restored. - -- The initialization procedure of keyboard device returns with error - if it fails to retrieve the keyboard mapping information from the - remote display. - -- The reconnection fails if the default depth of the new display is - different from the previous one. - -- The session can be migrated if the visuals don't match for color - masks swapping. At the moment there are no conversions to line up - the RGB masks, so even if the session can be migrated, incorrect - colors may be shown. - -nxagent-3.0.0-80 - -- The agent options are saved before reopening the display in the - reconnection procedure. If the new initialization fails the backup - values of options are restored. - -- The flag storing that a SIGHUP has been received is reset if the - function reconnecting the session fails. - -nxagent-3.0.0-79 - -- Changed the SIGHUP handler not to ignore the signal if the state - is SESSION_GOING_UP or SESSION_GOING_DOWN. - -- Keyboard device info are saved before the keybord reset occuring - in the reconnection procedure. If the new initialization of the - keyboard fails, the old values are restored. - -- The initialization procedure of keyboard device returns with error - if it fails to retrieve the keyboard mapping information from the - remote display. - -- The reconnection fails if the default depth of the new display is - different from the previous one. - -- The session can be migrated if the visuals don't match for color - masks swapping. At the moment there are no conversions to line up - the RGB masks, so even if the session can be migrated, incorrect - colors may be shown. - -nxagent-3.0.0-78 - -- Fixed TR07E01747. Fixed warnings occuring when compiling for AMD64. - -- Fixed TR07E01753. NoMachine WM icon in the title bar is displayed - correctly. - -- Fixed TR03E01656. If client and server endianess didn't match, glyph - images bits have to be only temporarily swapped. - -- Fixed TR07E01746. Terminate the shadow agent if the option 'shadow' - is empty. - -- Added option '-verbose'. It enables the printing of errors received - by the agent from the remote X server. - -- Warnings related to missing fonts are printed only if verbose mode - is enabled. - -- Disabled a log message related to the use of Composite extension. - -nxagent-3.0.0-77 - -- The pixmap formats are initialized without taking care of which are - supported on the remote display. - -- Removed the check for pixmap format compatibility when migrating the - session to a new display. - -- Fixed TR06E01725. A minimum set of available picture formats is - used to ensure a wide migration from/to different displays. - -- The PictFormat structures used by nxagent are no longer filtered - with the ones available on the real display. - -- The background pixmaps are cleared while reconnecting in order to - make them usable. - -- Fixed TR01E01619. Changed the RandR implementation to return a re- - fresh rate other than zero. - -nxagent-3.0.0-76 - -- Changed the keystroke to force the drawable's synchronization to - CTRL-ALT-J. - -nxagent-3.0.0-75 - -- If the backing store tries to restore areas from a corrupted pixmap, - such areas are subtracted from the saved region, so that exposures - will be sent for them. - -nxagent-3.0.0-74 - -- Don't skip the synchronization when there are more clients ready. - This temporarily solves the synchronization problems observed in - the previous versions if one or more clients kept the agent busy. - -nxagent-3.0.0-73 - -- If the PolyFillRect() uses a FillStippled or a FillOpaqueStippled - fill style and the destination is corrupted, the area affected by - the operation is first synchronized. - -nxagent-3.0.0-72 - -- Fixed the bug affecting the position of the input window when a - session was migrated to a linux X server with no window manager - running. - -- The color used to fill the corrupted backgrounds is converted de- - pending on the depth of remote X server. - -- The PolyFillRect() does not clean the corrupted destination region - if a stipple pixmap is used as mask. This solution is adopted to - reduce the region fragmentation and to solve the text drawing pro- - blems affecting rdesktop. - -nxagent-3.0.0-71 - -- Force a flush of the display buffer if the coalescence timeout is - expired. Set the timeout according to the link type, from 0 to 50 - ms for link MODEM. - -- In nxagentRealizeImage() the width in byte is computed newly if - the image has been scaled. - -- The shadow agent clips the screen updates in tile only if the link - type is MODEM or ISDN. - -- Split the abort conditions in the synchronization loop to check - separately the congestion and the blocking status. - -- Implemented a workaround in order to avoid graphical problems with - render composite operations on Xfree86 remote server. - -nxagent-3.0.0-70 - -- Various adjustments aimed at using the best defer rules depending - on the congestion state. - -- Fixed a problem with icons of message boxes in shadow sessions. - -- Changed the log message printed when the shadow agent can't connect - to the master session. - -- If Composite is in use, don't skip the PutImage and CopyArea opera- - tions even if the agent window is fully obscured. - -nxagent-3.0.0-69 - -- The option -nodamage prevents the shadow agent from using the damage - extension. - -- Changed the scaling feature to set the byte order of the source - image according to the local endianess. - -- Changed the scaling feature in order to handle different ratios for - horizontal and vertical sizes. - -- Force the shadow sessions to be non-persistent. - -- When a pixmap background is synchronized, an expose is sent to its - owners. - -nxagent-3.0.0-68 - -- Changed the type of parameters passed to nxagentRootlessRestack in - order to be compliant with Xlib types on 64 bit platfors. - -- The nxagentCompositeRects() checks for the render operation type to - determine if the corrupted destination region must be cleared. - -nxagent-3.0.0-67 - -- Fixed a condition discarding the expose events received from the X - server. - -nxagent-3.0.0-66 - -- The corrupted resources are removed when a session suspends, and are - reallocated only at reconnection. This is aimed at avoiding synchro- - nization loops when the link is down. - -nxagent-3.0.0-65 - -- Initialize for now the tile size at 64x64 in shadow mode. - -- The height and width of the tiles used for synchronizing drawables - are set without overriding command line option 'tile'. - -- Avoid calling miWindowExposures() for empty regions. - -- Fixed a bug while clearing corrupted regions with window exposures. - -- The corrupted drawable counters are not reset if there are bitmaps - to synchronize. - -nxagent-3.0.0-64 - -- The synchronization bitmap is used only when requesting a full - drawable synchronization, otherwise the frame-buffer is used as - source. - -- Fixed some bugs in the synchronization loop. - -- Removed the remaining debug output. - -nxagent-3.0.0-63 - -- Don't start the synchronization loop if the wakeup handler found - some clients ready. - -- Don't flush the display buffers if the synchronization was inter- - rupted and there are more drawables to synchronize. - -- Changed the backing store functions to not save the obscured areas - which are inside the corrupted region of a window. - -- Added the code to send the XClearArea() commands in shadow mode at - the end of the synchronization loop. In this way large images are - still split in tiles but, on fast links, the final result can made - visible all at once. - -- Modified the corrupted drawable counters to only report the number - of resources needing synchronization. This allows the block hand- - ler to avoid spinning through the synchronization loop if there is - nothing to do. - -- On a window exposure remove the corrupted region of the destinat- - ion window. - -- For testing purposes, the pixmap synchronization loop starts only - if there are corrupted backgrounds. - -nxagent-3.0.0-62 - -- The image scaling is applied only if the destination drawable is the - pixmap shadowing the frame buffer of the master session. - -- The shadow agent exits with a fatal error if it can't connect to the - master session. - -nxagent-3.0.0-61 - -- Forward the SIGCHLD to the NX transport instead of letting the NX - transport forward the signal to us. This allows the agent to set - and replace the signal handler at any time, without having to ta- - ke care of the state of the NX transport. - -- Improved the synchronization loop by implementing a simple round- - robin mechanism between the resources needing synchronization. - -nxagent-3.0.0-60 - -- Use a new set of functions to install, post-install and reset the - signal handlers. - -- Reset the signal handlers to their initial state after a display - failure, as part of the disconnection procedure. - -- Don't set SA_RESTART in the sigaction flags. Make the signal int- - errupt the system call. - -- Terminate all the running dialogs before exiting. - -nxagent-3.0.0-59 - -- Use the value of nxagentCongestion in nxagentUserInput() instead - of calling NXDisplayCongestion(). - -nxagent-3.0.0-58 - -- The clip mask of the scratch GC used by nxagentDeferCopyArea() is - reset before releasing the GC. - -- The MotionNotify event can now break the synchronization loop. - -- In the case of shadow sessions, if synchronization aborts then the - remaining data to synchronize are not stored in a bitmap. - -- If a table rebuild occurs in a loop searching for resources, the - loop restarts from beginning not to use the out of date table. - -nxagent-3.0.0-57 - -- The synchronization bitmap is created only if the corrupted area - of the source drawable is visible. - -- The synchronization loop skips the last synchronizing drawable to - give a chance to the next resources to be synchronized. - -- Removed the session starting infos concerning the mismatching ver- - sions of render and the window manager detection. - -- Split the gliph lists in Render.c only if the symbol SPLIT_GLYPH_- - LISTS is defined. - -- Read again the events in the block handler after the flush. - -- The nxagentCongestion variable is now a value ranging from 0 to 9, - not a boolean flag. - -- Added some experimental code dynamically reducing the size of the - display output buffer when the agent is blocking for write. - -nxagent-3.0.0-56 - -- The synchronization loop is now aborted when a short timeout exp- - ires. If the drawable synchronization cannot be completed, the - remaining data is stored in a bitmap. The synchronization loop is - then restarted using the data from the bitmap, instead of pulling - the latest image from the framebuffer. This allows the agent to - show a complete frame when displaying videos and animations, while - at the same time giving a chance to the clients to update the - screen in background. When an image from the saved bitmap is put - on the remote display, the image is compared with the actual data - in the framebuffer. If the two bitmaps match, the corresponding - region of the drawable is marked as synchronized, otherwise the - drawable remains dirty and will be synchronized at the next loop - using the new data taken from the framebuffer. - -- If the smart schedules is enabled, let the dispatcher decide when - it is time to yield and process the next client. - -nxagent-3.0.0-55 - -- Disable the smart scheduler in the case of shadow sessions. - -- If the smart scheduler is enabled, stop the timer before returning - from the block handler. WaitForSomething() sets a zero timeout if - there are clients with input but doesn't stop the timer. The select - is then interrupted to update the schedule time even if, what the - dispatcher cares, is only the ticks count at the time the client - is scheduled in. - -- Fixed a compilation warning in NXresource.c. - -- The main window of the shadow agent is mapped in nxagentMapDefault- - Windows, like for non shadow agents, if the remote display has no - window manager running. This avoids a flickering effect on the !M - logo having place if the shadow session was displayed from a Wind- - ows client. - -- Some code related to the use of the Composite extension is not built - in the agent being not necessary anymore. - -nxagent-3.0.0-54 - -- Get SmartScheduleStopTimer() from dixstruct.h. - -- Updated the NoMachine icon file. - -nxagent-3.0.0-53 - -- Changed the message 'NXAGENT: Fatal IO error on display' into 'Info: - Disconnected from display'. - -- Fix a problem occurring when the FindClientResourcesByType() needs - to reallocate the resource table. - -- The popup window synchronization breaks if an user input is caught. - -- Implemented FR05E01712. The stderr and stdin are redirected to the - 'clients' file in the session directory. - -- The nxagentRealizeImage function does nothing if the agent is not - connected to the display. - -- Removed the code implementing the redraws of the viewport frame. - Such code is not needed because is't enough for the agent to handle - the expose event received from the X server. - -nxagent-3.0.0-52 - -- Where it is necessary to wrap the function PaintWindowBackground, - the original function pointer is saved and restored afterwards. This - let other code wrapping that function (e.g. the damage extension) to - work correctly. - -- If the agent works in shadow mode, the defer parameters are ignored. - -nxagent-3.0.0-51 - -- Use the smart scheduler on platforms where it is enabled. - -- Check ClientsWithInput in the wakeup handler and update the number - of clients ready if any descriptor is set. - -nxagent-3.0.0-50 - -- Fixed TR05E01714. Changed VisibilityNotify event so that it forces - a refresh on the root window, but only if on the agent Composite is - enabled and its window moves from a VisibilityFullyObscured to ano- - ther state. - -- Grant the availability of core fonts in master sessions also after - the disconnection. This makes possible to start new clients inside - a shadow sessions while the master is down. - -- Changed nxagentGlyphs() to send a single glyph list per request. - -- Major rewrite of the agent dispatch handler. - -- Some name changes to the functions handling the session states. - -nxagent-3.0.0-49 - -- Made the dispatch loop yield control to a different client after a - fair amount of time even if the current client doesn't produce any - output. - -nxagent-3.0.0-48 - -- Modified the message in the suspend dialog to say 'Disconnect' in - place of 'Suspend'. - -- Added macros in Pixels.h to determine the behavior of the lazy en- - coding. - -- Changed the copyright attribution from Medialogic to NoMachine. - -- Reset all options to their defaults before processing the session - arguments. This fixes the problem with the DeferLevel option not - being set at reconnection. - -nxagent-3.0.0-47 - -- Initialized the arguments of NXGetControlParameters(), NXGetShmem- - Parameters() and NXGetUnpackParameters() to end up with valid data - also in the case of a display failure. - -- Converted the coordinates in the X_PolyFill requests to relative - mode. This makes all the requests independent from the origin and - helps the caching by the proxy. - -nxagent-3.0.0-46 - -- Don't print the 'Display failure' message on a SIGTERM. - -- Ensure that the NX transport is shut down after the 'Terminating - session at...' message if the session is killed by the user. - -- Let the agent filter the error output by setting the OsVendorVEr- - rorFProc function pointer. - -- Give the possibility to the agent to redirect the standard error - during a Popen() or a System() by setting the OsVendorStartRedir- - ectErrorFProc and OsVendorEndRedirectErrorFProc function pointers. - -- Fixed a problem in nxagentPolyFillRect() not properly propagating - to the destination. - -- Added nxagentPolyFillRect() and nxagentGlyphs() among the funct- - ions increasing the pixmaps usage counter. - -- Cleaned up some of the FIXME related to the lazy encoding. - -nxagent-3.0.0-45 - -- Use the three distinct functions in nxcompext to query the state - of the display connection. - -- Terminate gracefully on a fatal server error by printing the fol- - lowing in the session log: - - Error: Aborting session with 'Error text...'. - Session: Aborting session at '...'. - Session: Session aborted at '...'. - -- Removed more debug messages from the session log. - -nxagent-3.0.0-44 - -- Guess whether to compress an image with a lossless encoder based - also on the width and height, not only on size. - -- Corrupted pixmaps used as tiles propagate the dirty area when they - are involved in a PolyFillRect() operation. - -- On link settings ADSL to LAN, images are not split in tiles to bet- - ter fill all the available bandwidth. - -- Pixmaps referenced often as source in deferred operations or used - as backgrounds, are now synchronized as long as when the network - congestion level remains 0. - -- Use nxagentPaintWindowBorder() to update the window's border in - the framebuffer. - -- Fixed a problem with the new handling of the X_RenderChangePicture - requests that caused the text to be erroneously clipped. - -nxagent-3.0.0-43 - -- Don't pass the uid of the shared memory segment to the nxcompshad - library if it can't be retrieved from the options. - -- Fixed the new handling of the RenderChangePicture requests to work - on 64 bit platforms. - -nxagent-3.0.0-42 - -- Added support for the 'lossy', 'lossless' and 'adaptive' pack me- - thod literals. These values activate the dynamic selection of the - pack method by the agent. - -- Use the newer constant PACK_NONE instead of NO_PACK. - -nxagent-3.0.0-41 - -- Fixed a bug in the disconnection procedure introduced with the new - handling of the display events. - -- Realize the XRenderChangePicture() request only if a change of the - remote picture's attributes is detected. - -nxagent-3.0.0-40 - -- Dynamically select a lossy or a lossless encoder based on the num- - ber of pixels that appear to be different in the image. - -- Use the new PACK_BITMAP_16M_COLORS image encoding. Handle the case - when the packed image data points at the same data as the original - image. This is useful to save a copy. - -- The PACK_BITMAP_16M_COLORS method is now the default for lossless - encoding. - -- Don't use compression for the alpha channel. This is also intended - to better leverage the stream compression. - -nxagent-3.0.0-39 - -- The nxagentComposite() function doesn't check the source and mask - synchronization status, but defers the XRenderComposite() operation - by checking the defer level only. - -- If the target of an XCompositeText() function is an hidden window, - the operation is prevented. - -- Passing the uid of master X server process to nxcompshad library. - -- Before the call of XRenderAddGlyphs(), call the new library function - XRenderCleanGlyphs() cleaning the padding bytes of data section of - request. - -nxagent-3.0.0-38 - -- Don't warp the cursor if the requesting client is a shadow agent. - -- Changed a call to NXFlushDisplay in order to align to nxcomp version - 3.0.0-15. - -- Updated the NoMachine icon file. - -- Changed Agent.h in order to include NX version of Xlib.h avoiding - missing declarations. - -- If the NXDisplayCongestion notifies an optimum congestion state, - the continuous user input, due to unreleased buttons/keys, doesn't - break the drawable's synchronization. - -- Renamed the option 'block' as 'tile'. - -- Implemented a way to guess if the destination drawable of a copy - area is a popup window. In such a case, the source is synchronized - before doing the copy to avoid ugly effects like text items floating - on an invisible background. - -- In order to reduce the number of clip mask changings, if the clean - region of a corrupted source drawable is formed by a single rectan- - gle, its coordinates are used to change extents and position of the - area involved in the copy area operation. - -- Fixed a crash caused by a reference to a resource table freed by a - table rebuilding. This was happening because during the pixmap re- - connection some new GC resources went beyond the resource table li- - mit, causing a table relocation. As a general rule, a function loop- - ing across a resource table should not add or remove resources. - -nxagent-3.0.0-37 - -- To improve the efficiency of the algorithm deferring the trapezoid - operations, the composite does not propagate the glyphs flag to - the destination. - -- Moved the replacement of XCheckIfEvent() to nx-X11 with the name - XCheckIfEventNoFlush(). - -nxagent-3.0.0-36 - -- Changed nxagentDisplayFlushHandler() according to the new semantic - of the handler. The function is called by nxcomp when new data is - sent to the remote proxy. - -- After the flush handler is called, use NXQueryDisplay() with query - type NXDisplayCongestion to update the congestion flag. - -- Modified the boxes list defragmentation to merge only those rectan- - gles which fully overlap. - -- During the synchronization loop the nxagentDispatchHandler() takes - care of reading the enqueued events, while the nxagentUserInput() - checks only for state changes due to a processed key/button event. - -- Set the display output buffer size according to the link type. - -- Removed the congestion and synchronization callbacks. - -nxagent-3.0.0-35 - -- In order to avoid the lossy encoding of text regions, the nxagent- - GlyphsExtents is computed even if the mask format is not specified. - In this case, the render implementation was not calculating the ex- - tents of composite text operation, whose coordinates are useful only - to build a mask pixmap. - -nxagent-3.0.0-34 - -- Removed message 'Could not init font path element' from the output. - -- Moved initialization of picture support before the call to miDCInit- - ialize in the screen opening procedure. This is because miDCInitial- - ize calls DamageSetup that wraps the picture screen functions. - -- Implemented FR05E01686. Added option 'menu' enabling/disabling the - pulldown menu in the rootless agent. - -- Added a flag to each drawable to record if they have been the dest- - ination of a glyph operation. This is used to skip the deferral of - some operations (e.g. render trapezoids) if they can cause the - drawable to be synchronized using a lossy encoding. - -- The render trapezoids are deferred if the operation falls inside - a dirty region or if the destination drawable does not contain - glyphs. - -- Imported the NXmitrap.c file from render directory. - -- Improved the algorithm queuing multiple writes across a proxy - flush. - -nxagent-3.0.0-33 - -- Read the event queue after each request processed. Doing this - is expensive but it seems to work best. - -- Don't split the big trapezoid requests. Splitting the requests - doesn't seem to provide any benefit with the clients tested. - -- By defining BLOCKS in Handlers.c, Events.c and NXdispatch.c, log - the begin and end of the most sensitive routines. - -nxagent-3.0.0-32 - -- Use NXSetDisplayWriteHandler() to register a callback invoked - by Xlib after some data is written to the display socket. This - callback allows the agent to better determine when it is time - to send the sync requests. - -nxagent-3.0.0-31 - -- The operation of adding glyphs to remote glyphset has been defer- - red, in order to avoid to add unused glyphs. When a composite text - operation looks for a certain glyph, if it has not been added to - the selected glyphset, an XRenderAddglyphs is requested. - -- The forced synchronization timeout is now dependant on link type. - -- Force the mi to process the events just after having processed - any input. - -- Added an experimental 'hard' sync request intended to wait for - the X server to complete an image operation. This also affects - the agent only when the NX transport is not running. - -- Added a synchronization mechanism intended to let the agent de- - tect if the X server is not able to process its input when the - NX transport is not activated. The algorithm uses asynchronous - X_GetInputFocus replies to minimize the impact of latency on - slow connections. A new request is sent at any given amount of - bytes read from our clients. When the number of pending replies - is exceeded, the agent stops accepting additional requests and - waits for the remote until the number of pending replies returns - below the limit. Note that when the NX transport is running, the - algorithm is disabled to not interfere with the proxy's own - token-based flow control. - -- Added the nxagentDispatchHandler() function. It is called by the - dispatcher after a client's request has been processed. - -- Added the nxagentWaitEvents() function. It blocks waiting for - more input with an optional timeout. It handles the case when - the NX transport is not running and is able to recover gracely - from a display failure by returning the error. - -- Replaced most of the code that was relying on NXTransContinue() - to use the new function. - -- Moved the new event-related functions to Events.h and Events.c. - -- Disabled the code raising the splash screen at reconnection. - -- Reverted change done in 3.0.0-8 version, dealing with expose events - not having entries in the queue. They are not collected in a global - region but sent immediately. - -nxagent-3.0.0-30 - -- Let the block handler check if there are events queued after the - flush before entering the select. - -- Changed the dispatch loop to read the incoming events more often. - -- Added the nxagentReadEvents() and nxagentCheckEvents() functions. - Differently from XCheckIfEvent(), nxagentCheckEvents() doesn't - flush the output buffer if no event is available. nxagentReadEv- - ents(), instead, it's like XEventsQueued() but forces the use of - the QueuedAfterReading mode. These functions should be used when- - ever XEventsQueued() and XCheckIfEvent() would be required. - -- The nxagentQueuedEvents() macro uses XQLength() to return the - number of events that have been read and need to be dispatched. - -- The nxagentPendingEvents() function returns true if there is any - event queued. If not, it queries the transport to find if more - events can be read. - -- Ripristinated the code preventing the agent to connect to its own - display. The code was disabled while migrating to the new tree. - -- Removed the dependencies from the NXAGENT_QUERYBSIZE, NXAGENT_NO- - EXPOSEOPTIMIZE and NXAGENT_ONEXIT. Removed the unused code. - -- Removed more unused code in Clipboard.c. - -- The shadow agent calls NXShadowDestroy before exiting. - -- Reverted a change done in 3.0.0-8 dealing with expose events. If the - result of the subtraction is not sent immediately, some duplicated - refresh is shown. - -nxagent-3.0.0-29 - -- The splash screen is removed as soon as the session is started in - the case of shadow session. - -- The rules to verify when the synchronization loop can be stopped - are specified by means of a bitmask passed as parameter to synch- - ronization functions. - -- The glyphsets are no longer reconnected during a session resuming, - but only when they are used. - -- Initialized the timeout parameter in block handlers in case of NULL - value. - -- Added option 'block' to specify the size of image slices sent during - the synchronization. - -- Fixed a memory leak in nxagentParseOptions(). - -nxagent-3.0.0-28 - -- Improved the nxagentGetOptimizedRegionBoxes() function to optimize - the high fragmented rectangle lists. - -- When resizing nxagent window the fictitious resize for all top level - windows, triggering the window tree validation, is not executed if - rootless mode is off. - -- The nxagentInputWindows cannot be resized in rootless mode because - they are not created. - -- Added NXdamage.c to the source files. - -- Changed damage's GCOps functions drawing text. This was needed be- - cause the original functions didn't call agent GCOps if the drawable - was registered for damage events. - -nxagent-3.0.0-27 - -- Fixed TR04E01677. Changed the reconnection procedure to call the - function destroying the NoMachine splash window. It rarely happened - that the splash window was not removed after resuming a session. - -- Ignored the ForceScreenSaver requested by X clients to avoid clashes - with our screen saver handling. - -- Cleanup of code handling the screen saver timeout to remove referen- - ces to the old drawable's synchronization method. - -- Fixed TR04E01664. The session is terminated instead of suspended if - the auto-disconnect timeout expires and the persistence is not allo- - wed. - -- Reverted an optimization in nxagentCheckWindowConfiguration() in - order to avoid inconsistencies in the stacking order. - -- Fixed a segmentation fault in rootless mode. - -nxagent-3.0.0-26 - -- Some fixes to build in the Cygwin environment. - -nxagent-3.0.0-25 - -- Renamed the option 'lazylevel' to 'defer'. - -- Added a flag to windows to know if they have transparent children, - in order to reduce to minimum the put images on windows covered by - their children. - -- Created a generic list of graphic contexts, used when synchronizing - drawables between the nxagent and the remote X server. All the GCs - are created with IncludeInferiors property. This solves problem when - trying to synchronize windows covered by children with transparent - backgrounds. - -- The nxagentUserInput checks if keys are pressed. - -- Fixed some memory leaks. - -- In shadow mode, removed the handling of events of the source display - from the code. They can be handled in the nxcompshad library. - -- In shadow mode, allow the synchronization loop to break in case of - input event. - -- Moved the call to miDCInitialize after the initialization of poin- - ters to screen functions. This was needed to make DAMAGE work pro- - perly. - -- In shadow mode, not breaking the polling if a mouse button is down. - -- In shadow mode, allow events to break the loop sending updates. - -- At reconnection the input window is raised after the root window is - mapped. - -- Fixed an invalid read. The call to the function nxagentSetInstalled- - ColormapWindows() has been moved from nxagentDestroyWindow to Dele- - teWindow. - -nxagent-3.0.0-24 - -- The corrupted drawables are added to dedicated lists of resources - to speed up the synchronization process. - -- The nxagentUserInput checks if a mouse button is pressed. - -- Created the nxagentGetScratchGC which resets the scratch GCs to de- - faults values also on the remote X server. - -- The synchronization cycle is forced when a timeout expires, albeit - the remote display is blocked. - -- Added a parameter to synchronization functions to specify if loops - can break. It's useful to force the synchronization in some circum- - stances. - -- Keystroke CTRL-ALT-R is enabled in shadow mode too. It is used to - switch scaled and non-scaled modes. - -- Some changes to adjust the window position. - -- Moved some macros to Misc.h. - -- Some changes to adjust the behaviour of scaling feature in case of - resize and switch to full screen. - -- Freeing the buffer used for scaling if no needed anymore. - -nxagent-3.0.0-23 - -- Fixed TR02E01648 and TR10D01534. Changed pointer motion events han- - dling. In desktop mode the nxagent creates a InputOnly window that - collects the MotionNotify events. This window is mapped over the - root window. In rootless mode the nxagent creates all windows on - real X server with PointerMotionMask. - -- Not exiting from the block handler with zero timeout if drawables to - be synchronized are pixmaps only. - -- Reduced the margin around the glyph extent from 5 to 3 pixels. - -nxagent-3.0.0-22 - -- Fixed initialization of XImage used for scaling. - -- Changes to fix the position of the shadow main window. - -nxagent-3.0.0-21 - -- Moved the implementation of scaling feature in nxagentRealizeImage. - -- Disabled log message 'Font not found' in Font.c. - -- The synchronization loop is called inside the BlockHandler. Synch- - ronization goes on until the display is not blocked. - -- Exiting the BlockHandler with timeout zero if corrupted drawables - have not been synchronized because of blocked display connection. - -- Changed the synchronization loop to slice the dirty regions. - -- The updates by shadowing nxagents are now sent using the lazy me- - chanics: the remote buffer pixmap is marked as dirty, then synch- - ronized. - -- Traversing the tree to synchonize windows. - -nxagent-3.0.0-20 - -- Fixed a bug in the nxagentGetOptimizedRegionBoxes() function which - was causing a bad merging of boxes. - -- Added a margin of 5 pixels around the glyphs extents before synch- - ronizing them. - -- The synchronization cycle has been reactivated for the first lazy - level, in order to synchronize the window's background. - -- The CopyArea between pixmaps doesn't mark the full destination as - corrupted, but clips the operation with the synchronized area of the - source as happens for the windows. - -- Implemented scaling feature for the shadow agent. To do: run-time - control of this feature by keystrokes and window resize; adapting - the window size to the scaled dimensions. - -- Setting the shadow session scaling ratio equal to the size chosen - from the user divided by the size of the main session. - -- Scaled mouse motion events according with the ratio. - -- Implemented the nxagentScaleImage() function. - -- Updated version number and copyright in the output log. - -- Fixed TR06D01390. When resizing nxagent window, we make a fictitious - resize for all top level windows, in order to trigger the window - tree validation. - -nxagent-3.0.0-19 - -- Force LazyLevel to 0 in case of shadowing session. - -- If shadowing poller returns that nothing is changed and no updates - have to be sent, call WaitForSomething select with 50 ms timeout. - -- The shadow agent doesn't break the sending of updates in case of - mouse motion events. - -- The scratch GC's clip mask was not cleared during a drawable synch- - ronization. Now the GetScratchGC() function is called after changing - the nxagentGCTrap flag. - -- Implemented the function nxagentGetOptimizedRegionBoxes(). It gets - the list of boxes forming a region and operates on it to merge as - much boxes as possible, checking their width and position. - -- Implemented the function nxagentClearRegion(). It does an XClearA- - rea() for each box belonging to a region, using the color returned - by nxagentGetCorruptedRegionColor() as background of target window. - -- Implemented the function nxagentGetCorruptedRegionColor(). It gets - the color of first outer pixel in the bottom right corner of re- - gion. - -- Fixed some memory leaks. - -- Checked and removed some FIXME concerning the lazy encoding. - -- Fixed and added some debug messages in Render.c, GC.c and GCOps.c. - -- Added to the Literals.h file the Render and Shared memory requests. - -nxagent-3.0.0-18 - -- Changes to comply with nxcompshad library. - -nxagent-3.0.0-17 - -- The master agent holds the number of shadow nxagents connected to - itself. The shadow nxagent notify its presence to master nxagent - by setting the _NX_SHADOW property. - -nxagent-3.0.0-16 - -- Rearranged the lazy level rules. All the link types now use the lazy - level 1: the pixmaps are always corrupted, and they becomes synchro- - nized only when they're sources of an operation (i.e. CopyArea, ren- - der). - -- The lazy levels greater than 1 don't synchronize automatically. It's - possible to synchronize with two keystrokes: CTRL+ALT+Z forces the - windows synchronization without take care of the congestion; CTRL+ - ALT+X synchronizes the windows and the background until there is - enough bandwidth. - -- Only the tile, stipples and glyphs are always synchronized. - -- The height of glyphs region has been doubled to obtain a better vi- - sual effect after the synchronization. - -- Fixed a problem causing the background pixmaps to be used also if - they were not fully synchronized. - -- Added a function to convert a PolyPoint in a dirty region. The fun- - ction is now disabled because it is not advisable to use the exten- - ts. - -- The XCopyArea is not requested if the clip region is NIL. - -- The nxagentPutImage does not update the framebuffer when it is - doing a synchronization. - -- Moved all the code handling the drawables synchronization in the - Drawable.c file. - -- As the shared memory pixmaps are never synchronized with the re- - mote X server, now they're marked as dirty when they're created. - -- An XFillRectangles request now marks the rectangles of the desti- - nation drawable as synchronized. - -- Fixed a bug that was causing the CopyArea to propagate wrongly the - corrupted region on the destination drawable when the GC uses a - clip mask. - -- Implemented a test function useful to show on the windows all the - dirty regions as colored rectangles. It is used with the CTRL+ALT+A - keystroke. - -- Before sending the XRenderComposite operations (trapezoids, trian- - gles, TriStrip, TriFan), the drawables involved are synchronized if - they are dirties. - -- Changes to shadow mode. - -- Moved the code splitting the screen shadowing updates to a separate - function. - -- Suspend the sending of updates if input is received from the user. - -- Make use of callback mechanism implemented in the nxshadow library - to suspend screen polling when input is received from the user. - -- Flush the display link when requested by the proxy. - -nxagent-3.0.0-15 - -- Print the following info when the screen is resized: "Info: Resized - screen [] to [x]. - -- Changes to comply with nxshadow library. - -- Fixed the height of screen updates in shadowing mode. - -- Terminate cleanly if shadowing initialization fails. - -- Split shadowing screen updates in smaller rectangles for slow links. - -nxagent-3.0.0-14 - -- Fixed a compilation error in NXrender.c. - -nxagent-3.0.0-13 - -- Changed the LICENSE file to state that the software is only made - available under the version 2 of the GPL. - -- Added file COPYING. - -- Updated the files imported from X.org to the 6.9.0 release. - -nxagent-3.0.0-12 - -- Fixed compilation on Sun platform. - -nxagent-3.0.0-11 - -- Implemented an algorithm adapting colors if the target display have - different depth than the shadowed display. It requires that visuals - are TrueColor and depths are 16 or 24 or 32. - -- Added the option shadowmode. If this option is '0' the shadowing - session doesn't interact with the attached session. - -nxagent-3.0.0-10 - -- Changes to comply with the nxshadow component. - -nxagent-3.0.0-9 - -- Applied changes to files imported from X.org sources. - -- Updated copyright notices to the current year. - -nxagent-3.0.0-8 - -- Imported changes up to nxagent-2.1.0-17. - -- Fixed problem with font path on Solaris 10. - -- Disabled some log messages. - -- If the agent has blocked when trying to write to the display, try to - read other events from the connection. - -- After synchronizing expose events, the result of subtraction is not - sent immediately, but added to a region. Expose events will be for- - warded to clients after exiting from the event loop. - -- Critical output is set when button mouse events are received. - -- Fixed TR12D01584. X11 sessions could not be started on Mandriva Li- - nux 2007 because of a different location of fonts. The font path - used by this distribution is now added to the alternates font paths. - -- Fixed TR11D01550. Modified the collection of visuals when nxagent - opens a display. Now we only use the ones with the same depth than - the default one set in the screen. - -- Modified the reconnection of pict-format structures, to avoid an - error that arises when migrating a session by a Linux machine to - a Windows one. - -- Small changes in handling of expose events. - -- GraphicsExpose are no more forwarded to clients immediately. They - are merged with remote-only exposures and sent later. - -- Invalidated expose queue elements dealing with destroyed windows. - -- Cleaned up code in nxagentSynchronizeExpose(). - -- Fixed TR10D01541. Now when destroing a window if lastClientWindowPtr - point to this window then in nxagentClearClipboard() we put nxagent- - ClearClipboard to NULL and lastClientStage to SelectionStageNone. - -- Fixed a problem with LazyLevel option that wasn't correctly read - from command line. - -- Fixed an arithmetic exception raised when the viewable corrupted - region is empty but not nil. - -- Removed the obsolete 'sss' option. - -- Fixed a warning related to the expose queue. - -- Modified the queue of exposed region to remove some memmov() calls. - -- Remote expose events not having entries in the queue are collected - in a global region and sent later, instead of being sent immediate- - ly. - -- Changed nxagentCheckWindowConfiguration() to prevent unuseful calls - to XQueryTree(). - -- Fixed TR10D01530. Fixed an invalid write in doOpenFont(). - -- Fixed some invalid write/read in nxagentVerifyDefaultFontPath(). - -- Fixed TR10D01518. If needed, a restack is performed on the top level - windows in rootless mode. - -- Fixed TR10D01520. Reviewed session termination and log messages in - the case of indirect XDMCP. - -- In PictureCreateDefaultFormats(), cleaned the PictFormatRec struct - when the format is not supported. - -- Fixed TR09D01498. As it is possible to use multiple paths where to - store the fonts, now the agent concatenates all the existing font - paths used in various XFree/Xorg distributions to obtain a unique - default font path. - -- Fixed TR09D01502. The privates of the real pixmap are initialized - before trying to allocate a virtual pixmap, avoiding the possibility - to access an inconsistent structure in case the allocation fails. - -- Fixed a memory leak due to a missing deallocation of a virtual pix- - map's region. - -- Fixed TR08D01486. Removed a warning in NXrender.c. - -- Implemented FR08D01470. Now in the reconnection phase missing fonts - are replaced by the most similar picked among the available ones. - -- Fixed TR08D01480. A condition inside the nxagentWindowExposures - function was ignoring the possibility that the first region para- - meter could be a null region. - -- Fixed TR06D01409. Now NXCollectGrabPointer() is called with the - owner_events true in ActivatePointerGrab() . - -- Fixed TR03D01317. Increased the time after wich the session termina- - tes. - -- Fixed TR08D01475. In rootless, ConfigureWindow requests are only - forwarded to the X server, even if no window manager has been detec- - ted. - -- Fixed TR04D01367. An XKB event is sent to notify that keyboard map- - ping has changed. - -- Check the number of regions in the list before running nxagentSynch- - ronizeExpose(). - -- Reduced the number of GCs used during the drawable synchronization. - -- Optimized the corrupted region synchronization trying to use the - extents is some circumstances instead of split the full region. - -- Checked and removed some FIXME. - -- Fixed TR05D01384. Xgl server uses less picture formats than nxagent - usually does. Now the PictFormat structures used by nxagent are fil- - tered with the ones available for the real display. - -- Fixed TR06D01410. Function nxagentRestoreAreas have to make use of - a GC with subwindow mode ClipByChildren for preventing from repaint - also children of restored window. Children are restored in a separ- - ate call, if they have backing store on. - -- Fixed TR07D01426. The cursor data were swapped in place if the dis- - play had different bitmap bit order. Let Xlib do this work on a copy - of the image, preventing from messing up the original data. - -- Fixed TR07D01450. Some fonts were missing in the list of available - fonts because the ListFonts pattern used to build this list was too - much generic. To build a full font list two different patterns have - been used. - -- Fixed TR07D01449. Some X clients might affect the X screen saver - functioning modifying the default properties. The SetScreenSaver - request now correctly checks the parameters changes to avoid any - issue. - -- Fixed TR07D01432. X11 sessions could not be started on Debian 'Etch' - because of a different location of fonts. The font path provided by - the Debian Policy is now added to the alternates font paths. - -- Fixed TR07D01437. The auto suspend timer was reset when it should - not. - -- Fixed a conditional jump on uninitialised value. - -- Fixed TR05D01380. Now migrating a session when display have a 16-bit - depth does recover all visuals, avoiding reconnection failure. - -nxagent-3.0.0-7 - -- Fixed problems occurring when the main session is terminated and the - connection is refused to the shadow agent. - -- Fixed include directory order for Solaris. - -nxagent-3.0.0-6 - -- The shadow agent works only in viewport mode. - -- Added nxagentShadowCreateMainWindow function. This function creates a - pixmap and a window for mirroring the display root window. - -- Added NXShadowUpdateBuffer() function in order to create the buffer - for the poller with the same sizes of the root window of the master - agent. - -- Added NXxrandr.c NXxrandr.h and NXxrandrint.h files. - -- If the main agent screen is resized, the shadow agent adapts to the - new size of the root window. - -- Changed option activating mirror to -S. - -- Removed usleep() call when the agent is suspended. - -- Input events are sent to the main session even if it is in sus- - pended state. - -- Updates are made from top to bottom. - -- Added the option IgnoreVisibility. If this option is set, PutImage - is not skipped when the window is fully obscured. - -- Added the option 'shadow' saying the display to attach. - -nxagent-3.0.0-5 - -- Added the mirror mode. It is activated by -M option. - -- Recovered the state of keys when the agent in access mode loses - focus in mirror mode. - -- Changes to work with 16-bit depth display in mirror mode. - -- Changed the Imakefile in order to include NXaccess.h and NXaccess- - Event.h files. - -- The layout keyboard is passed to NXShadowCreate() function in order - to load the right keymap file in mirror mode. - -nxagent-3.0.0-4 - -- Small changes to build on 64 bit x86 platform. - -nxagent-3.0.0-3 - -- Fixes to build on Cygwin platform. - -- Change the order of include directories in Imakefile. - -- Renamed GC.h, Window.h and Pixmap.h to avoid name clashes. - -- Undefined NXAGENT_UPDRADE in Composite.c and NXcomposite* files. - -- Defined ddxBeforeReset() in Init.c. - -nxagent-3.0.0-2 - -- Merged changes to NXdispatch.c, NXdixfonts.c, NXmiwindow.c, NX- - picture.c, NXproperty.c, NXrender.c, NXresource.c, NXwindow.c. - -nxagent-3.0.0-1 - -- Opened the 3.0.0 branch based on nxagent-2.0.0-88. - -nxagent-2.0.0-88 - -- Fixed a memory leak in the code handling the remote font list. - -- Removed some log message. - -nxagent-2.0.0-87 - -- The box size is checked during the region synchronization to avoid a - possible arithmetic exception. - -nxagent-2.0.0-86 - -- Checked the validity of the colormap in nxagentChangeWindowAttri- - butes(). - -nxagent-2.0.0-85 - -- Fixed the bad destination coordinates of shared memory pixmap synch- - ronization in nxagentCopyArea() and nxagentCopyPlane() functions. - -nxagent-2.0.0-84 - -- Discard the Terminate Server key sequence Ctrl-Alt-BackSpace. - -nxagent-2.0.0-83 - -- Added a workaround to prevent the use of an inconsistent client poi- - nter in the nxagentNotifyConvertFailure() function. - -nxagent-2.0.0-82 - -- Fixed the parsing of option 'backingstore'. - -nxagent-2.0.0-81 - -- The agent window visibility on the real X server is used together - with the internal state to decide if graphics operations can be - avoided. - -- When restoring areas, if the backing pixmap is corrupted, an expose - event is sent to the region that can't be restored. - -nxagent-2.0.0-80 - -- The core protocol requests internally used to accomplish a Render - extension request are no longer propagated to the real X server. To - be more precise in this way we can save many XCreatePixmap, XChange- - GC and XSetClipRectangles. - -- Corrected a minimal incoherence in nxagentCopyArea in managing the - creation and deallocation of a region. - -- Fixed a double synchronization of an aged drawable during a put ima- - ge operation, due to a missing check of nxagentSplitTrap value. - -- Added the VisibilityChangeMask bit to the event masks. - -- Improved the algorithm which prevents the server client's resource - duplication. - -nxagent-2.0.0-79 - -- Added the 'lazylevel' option usable in the command line to specify - how much the Agent should be lazy. The default level is 2. Each - level adds the following rules to the previous ones: - - Level 0 The lazy is off. - - Level 1 The put images are skipped if we were out of bandwidth, - unless that the destination drawable has an old corru- - pted region. - - Level 2 No data is put or copied on pixmaps, marking them always - as corrupted and synchronizing them on demand. - - Level 3 The put images over the windows are skipped marking the - destination as corrupted. When a copy area to a window is - requested, the source is synchronized before copying it. - - Level 4 The source drawable is no longer synchronized before a - copy area, but the operation is clipped to the synchro- - nized region. - -- Implemented a dynamic synchronization mechanism, based on user ac- - tivity: if the input devices are not used for a variable amount of - time (depending from the configured link type), the synchronization - starts and goes on until there is enough bandwidth. - -- Minor fixes to the way the copy area propagates the corrupted re- - gion. - -- Whenever a put image is done, a full synchronization is forced on - the destination drawable if it has an old corrupted region. - -- During the overall synchronization a drawable is skipped if its - timestamp is lower than the synchronization interval. - -- Updated the copy plane to skip the operations from a corrupted pix- - map to another pixmap. - -- Fixed the pixmaps synchronization which was not checking the avai- - lable bandwidth. - -- In rootless mode, ConfigureWindow requests are not internally per- - formed for top level windows if a window manager is running. Anyway - they are forwarded to the X server. - -- Enabled the DPMS extension. - -- Fixed the -dpi option. - -nxagent-2.0.0-78 - -- When the remote proxy supports the alpha encoding, the alpha data - is sent compressed. When connected to an old version, the agent - uses the NXSetUnpackAlphaCompat() call. - -- Added support for the RLE pack method. - -nxagent-2.0.0-77 - -- Fixed the check for special keystrokes. State mask for Alt and Meta - keys are inferred from the X server modifier map. - -nxagent-2.0.0-76 - -- Fixed application icon in rootless mode. - -- If SYNC_WHOLE_GLYPH_DRAWABLE is set in Render.c the whole drawables - used in the composite glyphs are synchronized. This is useful to - evaluate the policy we should use to minimize the put images. - -- Code cleanup in Pixmap.c concerning the synchronization functions. - -- Added the nxagentSynchronizeBox() function. - -- Setting a wide band link (ADSL, WAN, LAN) disables Lazy and Strea- - ming options. - -- Now the Lazy option can be switched by the Ctrl+Alt+E keystroke. - -- Set a timestamp on a drawable to verify how much old its data are. - If we didn't update it since two seconds, the put image operations - are not skipped. - -- The image data split in chunks smaller than a threshold is now mo- - ved from the nxagentPutImage() to the nxagentRealizeImage() func- - tion. If a chunk is going to be put on an hidden area of a window, - the operation is skipped. - -- Fixed the value assigned to the id of the alpha visual. Now it is - assigned by XAllocID(). - -- Removed a call to XSetInputFocus() before mapping the default win- - dows. - -- Restored the backup display pointer when failing to reconnect the - display. - -- Fixed some return value in the options parser function. - -- Fixed the parsing of environment variable. - -nxagent-2.0.0-75 - -- Optionally split the long X_RenderTrapezoid requests in multiple - messages to help the compression. - -nxagent-2.0.0-74 - -- Fixed a bug preventing the reconnection of pictures. - -- Fixed the way the agent notify its start up to NX Client. Now the - ownership of agent atom is set before the reconnection of pixmaps. - -nxagent-2.0.0-73 - -- Added a check on the display pointer in nxagentTerminateDisplay() - to ensure that we don't try to force an I/O error if the display - is already down. - -- The image operations now are clipped to the visible area of the - drawable. As this may hamper the caching algorithm, only source - images bigger than 32K are clipped. - -- Code cleanup in Render.c. - -- When setting SKIP_LOUSY_RENDER_OPERATIONS in Render.c the realiza- - tion of some operations is skipped. This is useful to determine - how clients (mis)use the RENDER extension to achieve even worse - performance than they were able to achieve using the core protocol. - -nxagent-2.0.0-72 - -- Ensured that SIGUSR1 and SIGUSR2 are ignored if the NX transport - is not running. - -nxagent-2.0.0-71 - -- Modified the following messages used to track the session state: - - From: "Session: Session starting at..." - To: "Session: Starting session at..." - - From: "Session: Session terminating at..." - To: "Session: Terminating session at..." - -nxagent-2.0.0-70 - -- Removed the obsolete 'Info' messages related to the 'fast' versus - 'slow' copy area and get image modes. The -slow and -fast options - are now ignored as ignored are the keystrokes that allowed switch- - ing between the two modes. - -- Removed more obsolete warnings and commented the logs left around - for test purposes. - -- Removed the code in NXdispatch.c handling the fake get-image. - -- Removed the flags related to the use of the frame-buffer. - -- Major code cleanup in GCOps.c, Window.c, GC.c, Pixmap.c, Screen.c. - -nxagent-2.0.0-69 - -- Added a check to avoid parsing an empty DISPLAY variable. - -- Added parsing of the 'streaming' option. - -- GetTimeInMillis() function is compiled only if DDXTIME is defined, - to avoid double definition errors on Solaris platform. - -- Messages "Suspending session..." and "Session suspended..." are not - printed if the DE_TERMINATE dispatch exception is set. - -- When synchronizing the shared memory pixmaps the image is no longer - put on the framebuffer. - -- Code cleanup in the nxagentSynhronizeRegion() function. - -- Added the 'lazy' option to enable or disable the lazy policy. It is - activated by default. At the moment this is configured at compile - time and can't be changed through a command line or the option file. - -- Fixed the counter of the corrupted backgrounds by checking if the - pixmap was already marked. - -- The option SharedPixmaps is now activated by default. - -- Fixed a problem when synchronizing the shared memory pixmaps with - the operation being erroneously skipped. - -nxagent-2.0.0-68 - -- If we are doing a copy area to a pixmap and the source drawable is - not synchronized, the destination is marked as corrupted and the co- - py area request is not propagated to the X server. As a general rule - the source drawables are now synchronized only when they are copied - to a visible window. - -- The nxagentSynchronizeRegion() function synchronizes the region one - box at a time. This solves the incorrect pictures synchronization. - -- When a new element is added to the list of exposed region, sending - the synchronization request to the X server is postponed to the next - call of nxagentFlushConfigureWindow(). - -nxagent-2.0.0-67 - -- Ensured that NXTransDestroy() is called when getting rid of the NX - transport. - -nxagent-2.0.0-66 - -- The various messages used by the NX server to control the state of - the session have been changed and the NX server will have to be mo- - dified accordingly. - - At the early startup the agent will print the following message: - - "Info: Agent running with pid '...'." - - Followed by: - - "Session: Session starting at '...'." - - The ellipsis here represent the current timestamp, as reported by - the POSIX function ctime(): - - Example: Mon May 22 15:07:11 2006. - - After the connection to the remote display has been established, - the agent will print the following message: - - "Session: Session started at '...'." - - This replaces the old messages: - - "Info: Session started, state is [SESSION_UP]." - - Or: - - "Info: XDMCP session started, state is [SESSION_UP]." - - And: - - "Info: Entering dispatch loop with exception 0x0." - - If the display connection can't be established, due to a network - failure, for example, the agent will exit with a fatal error, for - example: - - "Fatal server error: - Error: Unable to open display 'nx/nx,options=...'." - - This is a special case, as the X server is still initializing and - the agent can't intercept all the possible causes of errors. - - When suspending the session, the agent will print one of the fol- - lowing messages, depending on the reason of the disconnection: - - "Session: Suspending session at '...'." - - Or: - - "Session: Display failure detected at '...'." - "Session: Suspending session at '...'." - - As soon as the disconnection procedure is completed, the agent will - notify the server with the message: - - "Session: Session suspended at '...'." - - This message replaces the old message: - - "Session: Session suspended." - - When entering the reconnection procedure, the agent will print: - - "Session: Resuming session at '...'." - - If the session can be successfully resumed, the agent will print: - - "Session: Session resumed at '...'." - - Otherwise, if the display cannot be opened or if the proxy is not - able to negotiate the session, the agent will return in suspended - mode by printing: - - "Session: Display failure detected at '...'." - "Session: Session suspended at '...'." - - At the time the session be terminated, the agent will print: - - "Session: Session terminating at '...'." - - Followed by: - - "Session: Session terminated at '...'." - - This replaces the old message: - - Info: Exiting dispatch loop with exception 0x2. - - The message 'Session terminated at...' should be the last message - parsed by the NX server. From that moment on the NX server will - wait the agent process to ensure that the cleanup procedures are - completed without errors and that the process successfully termi- - nates with the exit code 0. - -nxagent-2.0.0-65 - -- Many improvements to the block handler and to the drawable synch- - ronization loop. - -- Anyway the synchronization loop is skipped, at the moment, to bet- - ter test the new copy area implementation. Also all the put-image - on pixmaps are skipped, so that the pixmaps are only synchronized - on demand. - -- Small fix in the put image to always use the region already allo- - cated when marking a region as corrupted. - -nxagent-2.0.0-64 - -- The realization of the put image operations now depends on the - state of the link, as reported by the proxy through the synchroni- - zation handler. If the proxy link is aproaching a congestion, the - destination area of the drawable is marked as corrupted and the - operation is skipped. - -- At the moment the synchronization strategy is quite unsophistica- - ted. The drawables are synchronized when a timeout expires in the - block handler. The synchronization loop is aborted as soon as the - link approaches again the congestion and is restarted at the next - timeout. - -- Imported miwindow.c from the DIX layer. The code has been changed - to prevent miSetShape() from trying to destroy a null region. The - bug appears to be related to the backing store but it is unclear - if can also affect the sample server. The region is allocated at - the beginning of the function only if the backing store is set for - the window. Then miSetShape() calls miChangeSaveUnder(), that, in - turn, calls miCheckSubSaveUnder(). The latter can change the back- - ing store attribute of -some- windows, including, apparently, the - window that miSetShape() is processing. miSetShape() then destroys - the region if the backing store is set, but it doesn't verify if - the region was actually allocated. The problem is fixed by simply - adding a check on the pointer. - -nxagent-2.0.0-63 - -- Added the nxagentDisplaySynchronizationHandler() callback. The NX - transport uses the callback to report when it is possible synchro- - nize the pixmaps and the other X objects that are corrupted or in- - complete. - -- Fixed nxagentClearSelection() to correctly validate the selection - owner before clearing the record. - -- Changed the NXGetControlParameters() call to reflect the changes - to the reply. - -nxagent-2.0.0-62 - -- At reconnection the pixmap data is sent to the remote X server only - in two cases: if the pixmap is associated to a picture (glyphs, for - example) or if its depth is 1 (clip masks of GCs). All the other - pixmaps are marked as corrupted and synchronized on demand as soon - as the drawable is used as a source. This code is not enabled by - default and is currently being tested. - -- Implemented a new copy area function synchronizing the corrupted - region of a drawable before using it as a source. - -- Imported resource.c from the DIX. This makes possible to avoid the - duplication of the RT_GC, RT_FONT and RT_PIXMAP resource types. - -- Added the RT_NX_GC resource type and removed the old code dealing - with the reconnection of the GCs used by the GLX extension. - -- Fixed a problem in the synchronization of the window background. - -- Checked and removed some FIXMEs related to the streaming code. - -- Changed nxagentRestoreAreas() to take care of the width of the win- - dow's border. - -- Changed nxagentSaveAreas() to be independent from the window's pos- - ition. - -- Called nxagentMapDefaultWindows() before pixmaps' reconnection. - -- Changed nxagentMapDefaultWindows() to notify the client about the - agent's startup also when running in rootless mode. - -- Added the delete and backspace keystrokes to the routine removing - duplicated keys. - -- Wehn resizing the desktop the clip region of the children windows - is clipped to the new size of the root. This fixes a crash occur- - ring when resizing the desktop to the minimum height. - -nxagent-2.0.0-61 - -- Changed the extraction of alpha channel from images to be endianess - independent. - -nxagent-2.0.0-60 - -- nxagentReleaseSplit() now uses the NXAbortSplit() request to force - the proxy to discard the pending splits. - -- Added the value of the SharedMemory and SharedPixmaps options in - the log, together with the size of the shared memory segment used - by the remote proxy. - -- Fixed the compilation problem affecting the previous version. - -- The location of xkb base directory is checked by calling _NXGetXkb- - BasePath() function. - -- Fixed TR05D01371. nxagentVerifyDefaultFontPath() is called only if - the default font path is not defined on the command line. - -- Removed some log message. - -nxagent-2.0.0-59 - -- Improved the composite text operation to synchronize the regions - affected by the operation instead of the whole drawable. - -- Updated the copy plane to better propagate the corrupted region - to the destination. - -- The background pixmaps are synchronized with a deferred strategy. - Tiles and stipples are still synchronized as soon as the GC needs - to be used. - -- Completed the new copy area implementation. - -- Shared memory pixmaps are not synchronized after a RenderChange- - Picture operation. This needs further testing. - -- Added a nxagentNotifyKeyboardChanges() function that sends a Map- - pingNotify event to clients when the keyboard is reloaded or re- - configured. The SendMappingNotify() function is not used anymore. - This hopefully solves the TR01D01284. - -- Moved the nxagentResetKeyboard() function in Keyboard.c. - -- Checked if the previous sibling of a window is changed before try- - ing to restack it. This saves the redundant window configuration - requests of the previous version. - -nxagent-2.0.0-58 - -- Before composite glyphs operations, only areas intersecting the - glyphs extents are synchronized. - -- When a new split resource is allocated, a copy of the GC used by - the put image operation is created. Such copy will be safely used - by the commit operation even if the original GC is changed or - destroyed. - -nxagent-2.0.0-57 - -- Region saved by the backing store and corrupted region of backing - store pixmaps are emptied at suspend and resume time. This makes - the exposures go to the clients that will redraw their windows. - -- Changed the nxagent root window cursor. The cursor of the parent - window is used instead of the default 'X' cursor. - -nxagent-2.0.0-56 - -- Rewritten the state machine handling the streaming of the images. - -- By calling FatalError(), the normal server shutdown was skipped - and left the X server socket in .X11-unix. This happened also if - for any reason the agent couldn't complete the session startup. - Now the DDX abort routine, if the agent is not exiting because of - an exception, calls nxagentAbortDisplay() which closes down the - well known sockets. - -- Upon a failure of the reconnection procedure, if the alert shown - to the user by leveraging the proxy control channel is not set - to a valid code, the function in will use a default. - -nxagent-2.0.0-55 - -- Added an explicit link flush in the display block handler. The - block handler should now be called by nx-X11 before entering the - select, not only the the agent has entered WaitForReadable() or - WaitForWritable(). - -- Removed the checks on the value of the Streaming option. The way - a drawable is treated only depends from its previous state. - -- Started reimplementing the copy area operation to better propaga- - te the corrupted region to the destination. - -- Shared pixmaps are now synchronized before a copy plane operation. - -- The unpack alpha is discarded before the drawable synchronization. - This fixes the problems with the synchronization of the cursor. A - better way to deal with the condition is to be considered for the - future. - -- Added a check in the nxagentPutImage() function to skip the opera- - tion if the window is fully obscured. - -nxagent-2.0.0-54 - -- Fixed a bug in nxagentPaintWindowBackground(). A region passed as - parameter was modified by this function and this affected subseq- - uent operations involving the region. - -- In rootless mode, the map state of a top level window is uncondit- - ionally reflected in the internal state when receiving a map event - from the real display. - -nxagent-2.0.0-53 - -- Regions are marked as synchronized after an image operation if the - image didn't generate a split. - -- When an image operation takes place on a drawable which is already - being streamed, the resource is marked as invalid and the commits - are discarded. - -- A specific trap is used at the time a drawable is synchronized. - -- Fixed Render.c to use the latest streaming code. - -nxagent-2.0.0-52 - -- Fixed a problem in rootless mode where some windows could have mis- - sed to update the mapped flag after a MapNotify event. - -nxagent-2.0.0-51 - -- Realization of images is skipped, if the link is down, and a small - delay is introduced before returning from the image function. - -- Started implementing a new handler to let the agent include arbit- - rary data in the transport statistics. For now, only the interfa- - ces and the stubs exist, and the handler is not registered to the - proxy. - -nxagent-2.0.0-50 - -- Removed the unused code in nxagentCheckPixmapIntegrity(). - -- Instead of calling nxagentShapeWindow() immediately, windows to be - reshaped are added to the list of windows that have to be configur- - ed at later time. This allows SaveAreas() to work even when windows - change shape, as in the case of the "bouncing cursor" as implement- - ed in some versions of the KDE. - -- Added a missing call to nxagentFlushConfigureWindow() in the recon- - nection procedure. - -nxagent-2.0.0-49 - -- Code cleanup in the lazy encoding. Implemented distinct utilities - to allocate the split resources and manage the corrupted areas. - -- The Render.c file is taken from the previous version because the - updates break the composite code. - -- Renamed the option 'Lazy' to 'Streaming'. - -nxagent-2.0.0-48 - -- Made the image cache use the agent data, instead of allocating and - copying. - -- Fixed a memory leak in the image routines. - -- The image cache is freed at exit. This helps investigating other - eventual leaks. - -nxagent-2.0.0-47 - -- Solved the problem at reconnection with lazy encoding enabled. - -nxagent-2.0.0-46 - -- Solved a bug in the parsing of the pack method that made the agent - select an unavailable id. - -nxagent-2.0.0-45 - -- Ensured that images are explicitly byte swapped before sending to - an X server using a different byte order. In the attempt of saving - an expensive operation, the previous code let the unpack procedure - do the job, but this could fail to work in some special cases. - -- Cleaned the bitmaps used for the core cursors before putting the - image. - -- Left the display error handler installed during all the lifetime - of the session so that other parts of the code don't have to inst- - all it explicitly before entering a critical Xlib routine. - -- Removed more unused code. - -nxagent-2.0.0-44 - -- Fixed the problem with the cursor image being encoded with a lossy - method. The fix is a temporary. The final solution requires changes - to the lazy encoding. - -- Reworked the code dealing with the alpha visual. The color mask is - set based on the endianess of the remote display and is recreated - after a session resume. - -- Removed more unused code. - -nxagent-2.0.0-43 - -- Corrupted regions are now correctly clipped to the visible area of - the drawable. - -- Fixed a problem with the clip mask when calculating the intersect- - ion of the clip region with the destination region. - -- Drawables involved in a composite glyph operation are now synchro- - nized prior to being used. - -- The nxagentRealizeDrawable() function is now called only for draw- - ables that are not already synchronized. - -- Pixmaps are now skipped in the synchronization loop. Synchronizat- - ion of pixmap is to be implemented. - -nxagent-2.0.0-42 - -- Improved the algorithm removing the duplicated keys by trying to - read more events. - -nxagent-2.0.0-41 - -- Made use of the NXFinishSplit() request to speed up the completion - of a pending split. - -- Added an explicit NX transport flush before any operation that may - block waiting for data from the X server. - -- Set the NX flush policy to deferred after reconnection. - -- Solved refresh problems when reconnecting in rootless mode. - -- Modified the routine removing duplicated arrow key events. Now the - routine deals with page down and page up keys as well. - -- Added a check for xkb base directory path, in order to support new - Linux distributions. - -- Disabled backing store support for rootless sessions, as implement- - ation is not very functional, yet. - -nxagent-2.0.0-40 - -- Removed code related to old managing of backing store. - -- Added initialization of backing store by calling miInitializeBack- - ingStore(). - -- Implemented nxagentSaveAreas() and nxagentRestoreAreas() functions. - These functions are based on fb code. Calls to XCopyArea() have been - added in their implementation to make them be effective also on the - real X server. - -- Instead of calling nxagentConfigureWindow() in ClipNotify() and - PositionWindow(), windows to be configured or mapped are added to a - list, together with a mask storing operation that have to be done. - Windows in the list will be configured or mapped later by calling - nxagentFlushConfigureWindow(). This avoids that windows were mapped - or configured before saving areas in the backing store pixmaps. - -- The function nxagentFlushConfigureWindow() is called before resto- - ring areas on the X server in nxagentRestoreAreas() and at the end - of ConfigureWindow and MapWindow in the DIX layer. - -- Blocked the NoExpose events at the proxy side. - -- Fixed an error in nxagentCompareRegions(). - -nxagent-2.0.0-39 - -- Ensured that the display errors are detected while waiting for a - split operation to complete. - -- Removed more unused code. - -nxagent-2.0.0-38 - -- Changed nxagentSetCursorPosition() to avoid warping the cursor if - the requesting client is NULL or the serverClient. - -- Added a specific trap to avoid compressing an image associated to - a RENDER cursor using a lossy encoding. - -nxagent-2.0.0-37 - -- Added a check in nxagentPaintWindowBackground() to avoid calling of - XClearArea() if the window is not realized. - -- Modified nxagentAtomNames in Atoms.c to include CLIPBOARD and TIME- - STAMP atoms, avoiding further calls to XInternAtom in Clipboard.c. - -- Solved TR04D01356. Auto repeat mode setting is no more propagated to - the X server keyboard. - -- Cleaned up the code in the routine removing duplicated arrow key - events. - -nxagent-2.0.0-36 - -- Added the Literals.h file. For now it just contains a table used - to translate a request opcode to the name of the X request, to be - used for test purposes. - -nxagent-2.0.0-35 - -- Major code rewrite in nxagentPutSubImage(). Removed support for the - deprecated image encodings. Ensured that padding bytes are cleaned - before trying to locate the image in the nxcompext cache. Avoided - to store the image in the cache if it is coming from a XVideo or - GLX operation. - -- Added support for the new RGB image encoder. This allows the agent - to use the simplest encoding by still separating the alpha channel - from the image data. - -- Added the missing check in nxagentRedirectWindow() verifying that - use of the composite extension is enabled. - -- Updated to use the new NXCleanImage() function. - -- Removed more debugging output. - -nxagent-2.0.0-34 - -- Updated to use the 'what' parameter in NXFlushDisplay(). - -- Removed the duplicated arrow key events from the event queue. - -- Solved the TR04D01355. The X11 agent now tries to locate the - fonts.dir file in the misc directory, to verify the validity of - the font path. - -- Added a check in nxagentChangeClip to avoid creating a new clip - mask if the old clip mask matches the former. - -- Use the 'fixed' font to replace fonts that are not found a the - display reconnection. This should overcome one the most common - sources of troubles when migrating the session to a different - display, and constitute the base for improving the algorithm - trying to match a substitute font. - -- Implemented the FR04D01360. Now the user can enable/disable the - streaming of the images by using the option 'streaming'. - -- Implemented the FR04D01358. The backing-store can be enabled or - disabled by using the option 'backingstore'. - -- Forced the reconnection routine to call the IOError handler in - the case the display cannot be opened. - -nxagent-2.0.0-33 - -- The GetImage requests in 'slow' mode are now served by retrieving - the content of the drawable from the frame buffer. - -- Replaced a call to XQueryExtension() by one to XRenderQueryExten- - sion(). This function caches previous QueryExtension requests. This - partially implements FR01D01275. - -- At reconnection, the keyboard is reset only if the keyboard option - has been changed. - -- Fixed the fonts reconnection procedure. Now the remote fonts list - is refilled before fonts reconnection and after failed fonts - reconnection, so as to store the correct list of available fonts. - -- Added a check in nxagentLoadQueryFont to look up selected font in - the list of available fonts. This check avoid filling FontStruct - with invalid data. - -- Added TIMESTAMP to handled selection targets. - -nxagent-2.0.0-32 - -- Implemented FR03D01323. Added the 'clipboard' option to enable or - disable copy and paste operations from the user's desktop to the NX - session or vice versa. This option can take four values: - - client The content copied on the client can be pasted inside the - NX session. - - server The content copied inside the NX session can be pasted - on the client. - - both The copy & paste operations are allowed both between the - client and the NX session and viceversa. - - none The copy&paste operations between the client and the NX - session are never allowed. - -nxagent-2.0.0-31 - -- Implemented FR03D01337. Now the X11 agent is able to read the op- - tions from different places according to the following order: the - DISPLAY variable, the options file, the command line. - -- Implemented FR03D01347. Added 'composite' to parsed options. - -- Always activate shared memory support in the remote X server proxy. - -- Modified nxagentCopyArea for the case the source is a shared memory - pixmap. The pixmap on the X server is not synchronized, but the con- - tent of the shared pixmap mantained by the agent is placed directly - on the destination drawable. This allows to skip the following Copy- - Area operation. - -nxagent-2.0.0-30 - -- Added the missing flush of the Xlib buffer at the beginning of - the block handler. - -nxagent-2.0.0-29 - -- Changes in the block and wakeup handlers to queue multiple reads - and flush the link on demand. - -- Removed the unused code in Control.h and Control.c. Renamed the - files as Client.h and Client.c. - -- Added support for the '-nocomposite' command line option. - -nxagent-2.0.0-28 - -- Moved the composite code to Composite.h and Composite.c. - -- Redirected the top-level windows when running in rootless mode. - -nxagent-2.0.0-27 - -- When the composite extension is supported by the remote display, - the agent window is redirected to the off-screen memory of the - X server. - -- Imported Xcomposite.c, Xcomposite.h and xcompositeint.h from the - 3.0.0 branch to be able to activate the off-screen redirection of - the top level windows. - -- Added Composite to the list of agent options. The default is to - use the composite extension, when available. - -nxagent-2.0.0-26 - -- Avoided to suspend the clients on excess of karma or after a get - input focus request. - -- Images are now split only when the agent is in congestion state. - -- Moved all the image related functions from GCOps.h and GCOps.c to - Image.h and Image.c. - -- Removed the unused includes in GCOps.c and Image.c. - -- Added the karma delay field to the NXGetControlParameters() call. - -- Renamed placeholder.xpm as nxmissing.xpm. Renamed the Icon.h file - as Icons.h. Added there a define to point at nxmissing.xpm in the - include. - -nxagent-2.0.0-25 - -- Implemented the FR03D01334. Option keyboard is now a synonym of - option kbtype. - -nxagent-2.0.0-24 - -- Ensured that the split procedure is completed before executing a - render operation that required a synchronization of a shared mem- - ory pixmap. - -- Added the appropriate checks to avoid synchronizing the same sha- - red memory pixmap multiple times. - -nxagent-2.0.0-23 - -- Imported changes to NXrender.c and NXshm.c in the files for the - 3.0.0 port. - -nxagent-2.0.0-22 - -- Implemented FR03D01331. Options shpix and shmem enable/disable the - use of shared pixmaps and shared memory extension. - -- Implented handling of value "query" for nxagentKbtype. This value - is passed by the NX client for MacOSX. If value of nxagentKbtype is - "query" or NULL we init keyboard by core protocol functions reading - the keyvoard mapping of the X server. The property _XKB_RULES_NAMES - is always set on the root window with default values of model and - layout. - -- Fixed TR11C01223. When the XDM connection can't be established the - agent creates an alert to notify the user that XDM session failed - to start. - -- Changed Clipboard.c to fix invalid read errors in nxagentGetClip- - boardWindow() function. - -- Implemented FR11C01218. Modified Font.c introducing the new function - nxagentLoadQueryFont, this function loads the font_struct struct - locally instead of sending a QueryFont request. - -- Modified nxagentListRemoteFontsfunction to fill nxagentFontList - struct with all remote fonts, avoiding further calls to XListFonts. - -- Added two functions, nxagentFreeRemoteFontList and nxagentFreeFont, - used in disconnect phase to empty the nxagentFontList struct and - the cached FontStruct elements, respectively. - -nxagent-2.0.0-21 - -- Updated to include the remote proxy version in the NXGetControl- - Parameter reply. - -- Updated to use the NXDisplayFlush() and NXSetDisplayPolicy() int- - erfaces. - -nxagent-2.0.0-20 - -- NXInitDisplay() and NXResetDisplay() are called at the time we - open or close the display, to let nxcompext set up its internal - structures. - -nxagent-2.0.0-19 - -- Activated the streaming of the images even in the case of a link - type LAN. - -- In NXmiexpose.c, if the number of rectangles in an exposed region - exceeds 4, we let a predicate function decide if it is better to - send the window extents, rather than the rectangles in the region. - -- Added the NXAGENT_SERVER define in the Imakefile. It will be used - in future to mark all the modifications made to files we imported - from other layers. - -- Removed the warnings from NXmiexpose.c. - -nxagent-2.0.0-18 - -- Imported NXmiexpose.c in the agent code. - -- Removed NXmiwindow.c from the agent code. We now use the original - miwindow.c - -- Removed the static qualifier from the _NXFontPath definition. - -- Started implementing the new lazy encoding mechanism. For each of - the drawables, the agent will create a "corrupted" region and will - try to synchronize the drawable when there is bandwidth available. - This is a work in progress. - -- Implemented the function nxagentFbOnShadowDisplay. This is a test - facility which opens a window on the display showing the content - of the agent's framebuffer. - -nxagent-2.0.0-17 - -- The image streaming procedure is now activated also when using a - link of type LAN. - -- Removed the call to NXTransDestroy() in nxagentCloseDisplay. The - NX transport is now implicitly shut down by either NXForceDisplay- - Error() or XCloseDisplay(). - -- Updated to comply with the new NX function prototypes introduced - in nxcomp-2.0.0-31. - -nxagent-2.0.0-16 - -- Fixed a bug in the nxagentModifyPixmapHeader function that was - causing some glyphs to be displayed incorrectly. - -- Implemented the test function nxagentPixmapOnShadowDisplay, useful - to display a pixmap on the real screen to check its consistency. - -nxagent-2.0.0-15 - -- Ensured that, before restarting a client after a no-split, all the - pending image commits are executed. - -- Installed the display error predicate function before trying to - open the display even at session startup. This prevents the agent - from disappearing silently if a failure occurs before the display - initialization is completed. - -- Moved the initialization of the callback functions in Display.c. - -- Added some interfaces to manipulate the callbacks and the error - handlers and verify the state of the display flags. - -nxagent-2.0.0-14 - -- Implemented stub versions of the nxagentDisplayCongestionHandler() - and nxagentDisplayBlockHandler() callbacks. See nx-X11-2.0.0-17. - -- Added the nxagentDisplayErrorPredicate() function. In combination - with changes implemented in nx-X11-2.0.0-16, this allows the agent - to abort a blocking operation and shutdown the display in a timely - fashion if a signal or any other error condition is received insi- - de Xlib. - -- Modified nxagentWaitSplitEvent() to use XIfEvent() as we can trust - the proxy to either send the event or give up the proxy connection. - The function will also give up when an error condition is raised, - like for example a session termination requested by the user. - -- Removed any remaining reference to the unused display buffer and - image cleanup functions. - -- Fixed exposures problems when reconnecting. - -- Solved TR05C00896. The problem was due to window manager utilizing - zero-thick-lines drawing requests. These drawing operations are now - performed by calling fbPolySegment() instead of miPolySegment(), - which doesn't handle the zero-thick-lines drawing case. - -nxagent-2.0.0-13 - -- Improved the management of the expose events. We now create the - fake window used to keep the agent synchronized with the X server - only once, instead of creating and configuring a different window - for each generated region. - -- A warning is printed if the changes requested for the fake window - don't match the changes reported in the subsequent ConfigureNotify - event. - -- Imported previous changes in NXevents.c into the 3.0.0 port. - -nxagent-2.0.0-12 - -- Activated the image streaming also during the reconnection. This - makes possible to leverage the remote disk cache. - -- Ensured that all clients are restarted when the session is suspen- - ded. This is required because the proxy is gone but we may have - some client still waiting for the completion of a split procedure. - -- Skipped the reset of the keyboard device if the display breaks at - the time it is being reconnected. - -- As the reset of the keyboard may have failed before we were able - to set a valid DeviceIntPtr, also added a check in ProcessPointer- - Event(), in NXevents.c to verify that the state of the display is - valid before accessing any of the device members. This is to be - better investigated. - -nxagent-2.0.0-11 - -- Solved TR02D01298. The clip region associated to the current glyph - was not updated because the serial number of the virtual pixmap - pointed by the picture was not incremented. - -- Imported the NXmiglyph.c file from render directory. - -- Removed the patch added in the release 1.3.2-6 temporary fixing this - problem. - -nxagent-2.0.0-10 - -- Various improvements the wakeup procedures. - -- Implemented the FR10C01110. Now, the X11 agent manages both the - PRIMARY and CLIPBOARD selections. It is possible copy and paste text - also by using Ctrl+C and Ctrl-V. - -- Modified NXdispatch.c in order to correctly include header files. - -- More cosmetic changes and code cleanup. - -- Imported changes into the files for the 3.0.0 port. - -nxagent-2.0.0-9 - -- Rewritten the procedures suspending and resuming the clients in - Control.c. This solves a problem with clients that were restarted - at wrong time and should ensure that multiple events for the same - client are correctly handled. - -- Removed the calls to NXSetUnpackGeometry() setting the parameters - for the client 0. The geometry is now set only at the right time, - just before trying to unpack the image. - -- Removed the sample code using the NXTransChannel() interface. - -nxagent-2.0.0-8 - -- Added test code showing how to open a new NX channel by using the - NXTransChannel() interface. - -- Streaming of images is not attempted in the case of link LAN. - -- Added preliminary code to the tell the proxy to flush the link if - the agent is idle. - -- Imported changes from nx-X11-2.0.0-14 in NXdixfonts.c. - -nxagent-2.0.0-7 - -- Modified exposures managing: agent synchronizes both with remote X - server and remote window manager for every generated region. Synch- - ronization is reached sending a ConfigureWindow request for a fake - window created on purpose. This way the exposures for the resulting - region coming from calculating the difference between local region - and the remote region are sent to clients in order to avoid duplica- - ted refreshes. - -- Improved new algorithm for managing exposures in order to work pro- - perly also in rootless mode: added privates to windows in order to - get information about mapping of windows on remote X server and vi- - sibility state too. This way local exposures are replaced by remote - ones if windows are mapped only for agent or windows are not fully - visible. This solves TR08C00971. - -- Window attributes values about backing store and save-under are re- - spectively set to NotUseful and False when creating a window on re- - mote X server and ignored when a client requests to change these - attributes. - -- Removed a no more needed function call to generate exposures when - resizing windows. - -nxagent-2.0.0-6 - -- Updated the NoMachine copyright notices. - -nxagent-2.0.0-5 - -- Added handling of font reconnection failure. In case of failure in - reconnecting some font, the agent adds the font server connection - forwarded by nxcomp to the font path of the X server. - -- Fixed TR09C01022. Moved the handling of the session states into - main cycle. The session states are not more handled into SIGHUP and - IOError handlers but into nxagentHandleConnectionStates() called in - nxagentWakeupHandler(). - -- In ResizeChildrenWinSize(), privates storing window geometry are - updated even if the call to PositionWindow() is skipped. This have - to be done because the window is moved by the X server accordingly - with window gravity. This prevent some window positioning error on - the real display evidenced with OpenOffice and GNOME. - -nxagent-2.0.0-4 - -- Solved TR12C01234. In some conditions Alt-F4 keystroke made the user - unable to open the Gnome Menu panel. This was due to the agent dis- - carding KeyRelease events for Alt-F4 and Alt-F2. - -- Undefined TEST and DEBUG in Dialog.c - -- Changed the NXAGENT_VERSION define from 1.5.0 to 2.0.0 - -- Caching and streaming of images is now disabled when dispatching - requests from the GLX and XVideo extensions. - -- Added the NXxvdisp.c and NXglxext.c files. These files are needed - to intercept calls to the XVideo and GLX extensions. Only files - in the main directory are imported. Files in the X directory, used - for the 3.0.0 port, for now are empty. - -- Added the nxagentXvTrap and nxagentGlxTrap flags. These flags are - set when dispatching requests from the XVideo and GLX extensions. - -- Added the GL and Xext include directories to the Imakefile to be - able to compile the NXxvdisp.c and NXglxext.c sources. - -- Modified the NXrender.c and NXshm.c files to set the nxagentGCTrap - nxagentRenderTrap and nxagentShmTrap even when dispatching requests - from swapped clients. Files for the 3.0.0 port are not updated. - -nxagent-2.0.0-3 - -- Solved a problem in the export of WM_SIZE_HINTS properties in root- - less mode on 64 bit machines. - -- Modified Render.c in order to correctly process Xrender header fi- - les on 64 bit machines. - -- Made changes in order to compile the agent in the Cygwin environ- - ment. - -- Renamed the files Time.* to Millis.* - -- Specified the relative path of some included header files. - -- In the Imakefile added a new include paths order related to the - Cygwin environment to avoid name clashes. - -- Disabled the MIT-SHM extension in the Cygwin environment. - -- Fixed TR11C01186. Added -timeout item to the usage message. - -- Fixed TR08C00945. Scrolling a document in Firefox caused image left- - overs with animated banners. Set the right window gravity on windows - created in the real X server. Let X move children for us accordingly - with window gravity attribute, without dix interferences. - -- Removed logs related to parsing of the options file. - -- Modified dialogs in order to show the name of the session in the - caption. - -nxagent-2.0.0-2 - -- Imported changes up to nxagent-1.5.0-112. - -- Fixed TR12C01241. The failure condition returned by the XQueryTree - function is managed in order to avoid the subsequent errors. - -- Fixed the TR11C01165. X11 sessions could not be started on Ubuntu - 5.10 because of the different location of fonts. Now we check the - existence of the fonts directory pointed by the default XF86 and - X.org font path and, if the directory does not exist, we use the - alternate font path used on Ubuntu. - -- Set the default value of DeviceControl option to False before resu- - ming a session. - -- Added a warning message printed if reset of keyboard fails at recon- - nection. - -- Fixed TR11C01185. Solved by checking if there are windows iconized - when a window is destroyed. - -- Fixed TR11C01164. The xkbcomp process used LD_LIBRARY_PATH as it was - a child of the agent. Added a call to NXUnsetLibraryPath() in Init.c - in order to remove LD_LIBRARY_PATH before executing a child process. - -- Check if there are windows iconized before terminating a rootless - session. - -- Modified CHANGELOG to include reference to fixed TRs TR08C00967 and - TR08C00969. Removed some typo. - -- Fixed TR11C01194. The agent crashed if launched with -kb option. - -- Fixed TR10C01042. The keyboard didn't work if the session migrated - from Apple X server to another platform and viceversa. This has been - solved by initializing the keyboard device whenever the session is - resumed. This feature can be disabled by the new option -nokbreset. - -- Fixed some compilation error arising if TEST was enabled in the file - Keyboard.c. - -- Fixed TR11C01167. During the disconnection the font structures poin- - ted by the font cache were freed leaving inconsistent data in the - corresponding privates. Now they are nullified and the GCs are che- - cked to guarantee a correct font handling in the suspended state. - -nxagent-2.0.0-1 - -- Opened the 2.0.0 branch based on the 1.6.0-11. - -nxagent-1.6.0-11 - -- Updated the NX.original copies of files in X directory. - -- Merged the NX changes: - - - From dix/extension.c to NXextension.c. - - From dix/dixfonts.c to NXdixfonts.c. - - From dix/glyphcurs.c to NXglyphcurs.c. - -- Export of CARDINAL properties are expanded to 64 bit units on 64 - bit machines. - -- Solved a segmentation fault when handling configure notify events - in rootless mode on 64 bit machines. - -- Merged the NX changes from dix/property in X/NXproperty.c. - -- Correctly allocated the local variable used in the call to NXGet- - CollectedInputFocus to be of 64 bit on 64 bit machine. - -- Defined symbolic constants XlibWindow in order to propertly handle - export property on 64 bit machine. - -- Moved the XlibAtom define from Atoms.h to Agent.h. - -- Modified export properties of type Window and Atom in order to han- - dle correctly Window and Atom types on 64 bit machines. - -- Removed some invalid read in Atom handling code when compiled for 64 - bit, due to mismatched size of Atom type between Xlib and Xserver - code. - -- Modified some header files in order to properly see the correct pro- - totypes of some Xlib structures on 64 bit machines. - -- The variable currentDispatch is always defined. - -- The dispatch current time is updated, this way the initial timeout - can elapse and the splash window is removed. - -nxagent-1.6.0-10 - -- Imported changes from nxagent-1.5.0-103. - -- Removed some redundant redeclarations. - -- Merged the NX changes from randr/randr.c to NXrandr.c. - -- Removed some warnings in NXrandr.c. - -- Removed NXAGENT_FORCEBACK and NXAGENT_INTERNALBS code. - -- Added ddxInitGlobals function in order to compile with the new X.org - tree. - -- Converted nxagentSynchronizeShmPixmap from macro to function to - solve a graphical render problem caused by the variable's scope. - -nxagent-1.6.0-9 - -- Imported changes from nxagent-1.5.0-102 - -- Fixed TR10C01124. Function nxagentSetPictureFilter() filled the log - with a debug message. - -- Removed a debug message in Events.c. - -- Run function nxagentSetTopLevelEventMask() only in rootless mode. - -- In the Java application IntelliJ the dropdown menus was shown in a - wrong position when the main window was moved or minimized. The - problem is solved for KDE desktop environment. - -- Fixed TR08C00967, TR08C00969, TR08C00941. Our incomplete implementa- - tion of the MIT-SHM X11 extension was a problem for some applica- - tions using the Shared Memory Pixmaps. Now the extension support has - been completed, so the nxagent can handle the Shared Memory Pixmaps - requests. Introduced some changes in the render implementation to - synchronize the content of the Shared Memory Pixmaps with the X ser- - ver before performing the ChangePicture and Composite operations. - -nxagent-1.6.0-8 - -- Fixed TR09C01028. The problem was the GC foreground was not updated - on the X server. This was due to the private fields was not copied - from a GC to another in the function nxagentCopyGC(). Added macro - nxagentCopyGCPriv in GC.h. - -- Solved TR11C01162. Removed the dialog shown by nxcomp/nxagent when - the resume of a session is happening over a slow link. - -nxagent-1.6.0-7 - -- Imported changes up to nxagent-1.5.0-100. - -- Fixed some compilation errors. - -- Fixed a typo in nxagentChangeClip() declaration. - -- Fixed TR10C01040. After the session resume the applications using - OpenGL were not correctly resumed because some GCs were not recon- - nected. Now we save these GCs in a safe vector, so we can't lose - them. - -- Improved font reconnection procedure in order to take advantage of - new font channel provided by nxcomp. If resuming session fails be- - cause missing fonts, the font channel provided by nxcomp is added - to font paths of X server. After reconnection succeded the font - channel is removed from font paths. - -- In the Java application IntelliJ the dropdown menus remained opened - and shown in a wrong position when the main window was moved or - minimized. This problem has been solved by sending a sinthetic event - to client. This solves partially TR09C01012. - -- In the same application the caret was not shown in the text window. - Solved the problem by setting nxagentGCTrap before calling a MI - function in every GC operations. - -- Merged the NX changes: - - - From render/glyph.c to NXglyph.c. - - From Xext/shm.c to NXshm.c. - - From render/render.c to NXrender.c. - - From mi/miwindow.c to NXmiwindow.c - - From render/glyphstr.h to NXglyphstr.h. - - From render/picturestr.h to NXpicturestr.h. - - From render/picture.c to NXpicture.c. - - From dix/dispatch.c to NXdispatch.c. - - From dix/events.c to NXevents.c. - -- Changed picturestr.h glyphstr.h to remove some formatting changes - compared to the original files. - -- Disabled Xinerama extension in order to fix a type conflict in NX- - dispatch.c. - -- The current directory has been moved in front of the include dire- - ctory list. - -- Removed NXAGENT_FORCEBACK code in files imported from DIX. - -- Changed NXshm.c NXrandr.c NXproperty.c NXpicture.c NXglyphcurs.c - NXglyph.c NXextension.c NXrender.c NXdixfonts.c NXdispatch.c NXmi- - window.c to remove some formatting changes compared to the original - files. - -- Added copyright notice to file NXrandr.c. - -- All files, except those from mi and dix, compile fine in the new - tree. Problems remain with different size of Atoms and other XID - objects. - -- More compilation fixes for the new tree. - -- Merged the NX changes from dix/window.c to NXwindow.c. - -- Changed NXwindow.c and NXevents.c to remove some formatting chan- - ges compared to the original files. - -- More compilation fixes aimed at porting the agent to the new tree. - -- Started porting the agent to the 6.8.99.16 X.org tree. - -- Lot of compilation fixes aimed at building in the new environment. - -- Files imported from the X.org tree's dix and mi will have to be - recreated in the nxagent/X directory. The new files will be inclu- - ded and built from the nxagent/X director if the NXAGENT_UPGRADE - symbol is defined (as it is the case when building in the 2.0.0 - nx-X11 tree), otherwise the usual NX* files in the nxagent's dir- - ectory will be compiled. - -- Fixed TR09C01021. SIGHUP it was not received from the proxy. The - handler of SIGHUP must be installed also in the case of not persi- - stent sessions. - -- In non persistent case: if session is normally running, SIGHUP sig- - nal is dealt like SIGTERM, otherwise it is passed to the proxy. - -- Fixed TR09C01027. Changed function nxagentHandleConfigureNotify() - in order to get changes of the staking order in a rootless session - even if no window manager is running. - -- Fixed TR09C01025. The problem was XView application could be unable - to respond to user's input. Modified the Event Mask for non top le- - vel windows reparented by the root window. Set the input member of - XWMHints to communicate the window manager the keyboard focus model - used by the application. - -- Fixed TR09C01026. Added 'fast' and 'slow' to the set of accepted - command line parameters. 'fast', 'slow' and 'geometry' command line - parameters have precedence regarding the options file. - -- Fixed TR08C00968. There was a problem in the implementation of the - render extension. - -- Fixed TR09C01016. In rootless mode when the session was resumed, - the cursor was shown with a wrong shape. - -- Fixed TR09C01011. Allowed clients to monitor the root window for - structure redirect, button press and resize redirect events in root- - less mode. This is a quick hack to make the java bean shell work - flawlessy with the agent. - -- Solved TR08C00961. Improved the algorithm updating the sprite win- - dow. Now it is updated based upon crossing and motion event. Since - on some X server, like Windows and MacOsX X servers, the only cros- - sing event is not a reliable method to trace the sprite window chan- - ges. - -- Fixed TR08C00966. Solved the problem on Windows when a rootless - session is suspended and some of the application windows are - minimized. - -- Fixed TR08C00960. Updated the internal screen dimension in rootless - sessions at reconnection. - -- Fixed TR09C01005. The problem was that the 'render' option on the - command line was overridden by the one provided in the options file. - -- Implemented the HandleEmptySplitEvent function that synchronizes all - the drawables after the depletion of the split store, when the lazy - option is activated. - -- Some changes in order to avoid duplicated refreshes when display- - ing Mandrake's kde menu. - -- Changed level of some logs from WARNING into TEST in Window.c and - in Rootless.c. - -- Fixed TR08C00958. Changed the log message printed when the user re- - quest to resume the session. - -nxagent-1.6.0-6 - -- When reconnecting, try to estimate the shift on the main window due - to WM reparenting. - -- In the handling of configure events, if a WM is running save the po- - sition of the main window only if event is synthetic. - -nxagent-1.6.0-5 - -- Command line option -noshmem disables shared memory extension in the - agent. - -- Changed level of some logs from WARNING into TEST. - -nxagent-1.6.0-4 - -- Some changes in order to improve handling of expose events in root- - less. The GetInputFocus request is not sent after reconfiguring a - top level window: window manager intervention could give race condi- - tions. The request is placed in WindowsRestructured() in order to be - sure it is sent after any event that could generate expose. - -- Zero lenght change property are now imported in rootless mode. - -- Corrected few typos. - -- Replaced the function usleep with NXTransContinue when NX transport - is running. - -- Changed the session state to GOING_DOWN as soon as the reconnection - is failed. - -nxagent-1.6.0-3 - -- Updated rootless toplevel window map when a window is reparented to - the root window. - -- Renoved duplicated entry in rootless toplevel window map. - -nxagent-1.6.0-2 - -- Removed TEST and DEBUG in Color.c. - -- Removed a compilation error in Atoms.c if DEBUG is enabled. - -- Removed invalid read at server reset in rootless mode, now the a- - toms description are duplicate before that we cache them. - -- Now the local atom in the atom cache are reset when exiting from - the dispatch loop. - -nxagent-1.6.0-1 - -- Opened the 1.6.0 branch based on nxagent-1.5.0-87. - -nxagent-1.5.0-87 - -- Corrected the enable-disable lazy encoding dialog in order to show - the correct keystroke Ctrl-Alt-E. - -nxagent-1.5.0-86 - -- Reset agent position at reconnection when the new size of display - doesn't match the old size and fullscreen is on. - -- Inserted a comment about handling of expose events. - -nxagent-1.5.0-85 - -- If fullscreen and resize options are true when reconnecting, geo- - metry option is ignored and the root window is resized to the en- - tire screen. - -- Read the position of the main window at startup from geometry op- - tions. - -nxagent-1.5.0-84 - -- Changed the keystroke Ctrl-Alt-L to toggle the image encoding on - and off to the new combination Ctrl-Alt-E. - -- Enabled the keystroke Ctrl-Alt-M to minimize the root window also - in window mode. - -nxagent-1.5.0-83 - -- Replaced the call to XIfEvent() with something less efficient but - safer, based on XCheckIfEvent(). The previous version might never - return if an I/O Error was encountered waiting for the event. The - new version fails gracefully, and returns after having restarted - the client. - -nxagent-1.5.0-82 - -- Removed some debug logs. - -nxagent-1.5.0-81 - -- Forced window mode if X server geometry has changed at reconnection. - -nxagent-1.5.0-80 - -- Reset resize desktop at startup flag before reconnection. - -nxagent-1.5.0-79 - -- Removed race condition in the parsing order of the options parame- - ter, now the geometry parameters are set in screen initialization. - -nxagent-1.5.0-78 - -- Disabled auto-resize and viewport mode dialog in case of rootless - session. - -- Removed no more used -backingstore option from usage messages. - -- Modified -bs command line option: now the default value "when_re- - quested" is always set. - -- Fixed wrong size of root window when switching from full screen to - window mode and viewport navigation mode is enabled. - -- Added option that solved a minimize bug in LeaveNotify when the - root window is in full screen and the user is using viewport navi- - gation mode. - -- Forwarded HUP signal to NX transport, when session state is up and - running. - -nxagent-1.5.0-77 - -- Do PutImage in every case. Don't check if the drawable is synchro- - nized. - -- Do CopyArea, CopyPlane, Composite in every case, don't check whether - the source is dirty. - -nxagent-1.5.0-76 - -- Terminate rootless session 15 seconds after the last mapped window - has been destroyed. - -nxagent-1.5.0-75 - -- Ctrl-Alt-T shows suspend/terminate dialog also in rootless mode. - -- Sleeps 50 ms in the block handler if the session state is down. - -- In rootless mode, the focus window is changed following FocusIn - events received from the real X server, also in the case no win- - dow manager has been detected. - -nxagent-1.5.0-74 - -- Changed the alerts names to comply with nxcomp-1.5.0-57. - -- Moved loading of placeholder from startup to the first time it is - needed. - -- Corrected a typo in the CHANGELOG. - -nxagent-1.5.0-73 - -- Ignored put image on not synchronized drawables, when the image - doesn't cover the entire surface. - -- Added parsing of render parameter in option file. - -- Ignored I/O Error when session is suspended. - -- Managed I/O Error at reconnection. - -nxagent-1.5.0-72 - -- Fixed offset of the default window at reconnection and after switch- - ing from fullscreen in window mode. - -- Suppressed the -lazy command line option. - -- Made some slightly changes in GCOps.c and Pixmap.c in order to com- - ply with the new 'Lazy' option. - -- Avoided to do CopyArea, CopyPlane and Composite operations when the - source drawable is dirty. - -- Rootless disconnect dialog has changed. This dialog is launched - after some time the last window has been closed. - -- Ignored geometry changes at reconnection if resize at startup is - not set. - -- Removed reset of the offset of the root window in viewport mode at - reconnection. - -- Fixed some refreshes problems in viewport mode and in desktop resize - mode. - -- Fixed a memory leak in nxagentWindowExposures(). - -- Added predicate to nxagentDispatchEvents. - -- Implemented framework in order to wait for a free resource entry, - when calling the asynchronous Collect* functions. - -nxagent-1.5.0-71 - -- Added keystroke Ctrl+Alt+L switching lazy encoding option. - -- Disabled viewport movement in resize mode. - -- Changed agent geometry at screen resize. - -- Changed agent geometry at initialization. - -nxagent-1.5.0-70 - -- Restored the set of blocked signal after the dialog pid just laun- - ched has been stored. - -- Removed an already fixed FIXME. - -- Updated the copyright message. - -nxagent-1.5.0-69 - -- Started working at the integration of the lazy encoding functiona- - lity. Made the agent draw the placeholder if the image is split and - never suspend the client. There is no provision for synchronizing - the drawables yet. - -- Made the lazy encoding configurable by the new 'Lazy' option. - -- Updated to include the changes in the NXStartSplit() and NXCommit- - Split() requests. - -- This version requires nxcomp-1.5.0-55 and nxcompext-1.5.0-16. - -nxagent-1.5.0-68 - -- Fixed reconnection of iconified windows. - -- Ignored the X server's scratch pixmap at reconnection. - -- The desktop gets automatically resized at reconnection if the desk- - top resize option is enabled. - -- Added the resize option in nxagentProcessOptionsFile() to allow the - user to change the geometry of both the root and the default window - at reconnection. - -- Fixed max size of the default window at startup when auto-resize - mode is enabled or in the case of a reconnected session. - -- Made some minimal changes in Atoms.c and NXdispatch.c. - -nxagent-1.5.0-67 - -- Changed handling of expose events received from real X server. A re- - gion is composed from expose events by checking the count field. - -- Reimplemented the exposures managing. Now the GetInputFocus request - is sent after a window has been configured or unmapped. We use a - vector to store windows originating expose events while waiting for - the reply to GetInputFocus. - -nxagent-1.5.0-66 - -- Added the DisplayLatency value in the agent options. This is int- - ended to give a hint about the latency of the current display - connection. The value is currently used to determine if the agent - is running across a slow link, and so it's appropriate to display - the begin-reconnection alert. - -nxagent-1.5.0-65 - -- Added the DesktopResize option. It controls the behaviour of the - automatic (RandR) resize of the desktop when dragging the agent's - window border. - -- Automatic resize is again the default. - -- Disabled the test logs in Events.c, GCOps.c Pixmap.c, Handlers.c, - Reconnect.c. - -- More cosmetic changes and code cleanup. - -nxagent-1.5.0-64 - -- Rewritten the image streaming procedure to better leverage the new - infrastructure. The start-split/end-split procedure is always init- - iated by the agent, including when the size of the image is below - the threshold, but the client is only suspended when the split has - taken place in the NX transport. - -nxagent-1.5.0-63 - -- Updated image streaming to use the new NX notification events. - -- Removed the references to the NXSync() operation, not used anymore - by the agent. - -nxagent-1.5.0-62 - -- Fixed wrong position of the root window in case of viewport naviga- - tion mode. - -- Added a field to the client private to trace the client type. - -- Tracked which clients are nxclient dialogs in order to not run the - pulldown dialog on them. - -nxagent-1.5.0-61 - -- Disabled server reset if not needed by XDMCP. - -- Disabled persistence for indirect XDMCP session until the first gre- - eter with the list of host has disappeared. - -- Created a small data structure to contain information about integri- - ty status and placeholder status of a drawable. - -- Modified the call to nxagentRealizeOnePixmap function in order to - avoid errors during the signal handling. - -nxagent-1.5.0-60 - -- Added the XDMCP option. If both Rootless and XDMCP are selected the - session will fail. - -nxagent-1.5.0-59 - -- Limited the permission to reset the agent only to indirect XDMCP - sessions, only one reset is allowed. - -- Fixed max size of the default window when switching from fullscreen - to window mode and auto-resize is disabled. - -nxagent-1.5.0-58 - -- Enabled reset mechanism, in order to make XDMCP session work proper- - ly. - -- Added XSync for window manager detection, after a server reset since - the XInternAtom already used should be cached. - -- Now the pixmap status is always tested on real pixmap. - -- The placeholder is drawn only once per drawable. - -- Implemented nxagentUnmapWindows() in case of failed reconnection if - the session was running in fullscreen mode and NX transport is not - enabled. - -- In nxagentPutSplitImage(), passing leftPad to XCreateImage(). - -- This version avoids sending the XSync() to the remote when a large - amounts of GetInputFocus requests are issued by the same client. - It will require more testing, especially to verify how it works on - old Windows machines. - -- Changed the NXCommitSplit() call to comply with the new interface. - -- The drawable status is now propagated on graphic operations where - the source is using the tile and stipple components on the graphic - context and the tile or stipple are not synchronized. This affects - the following operations: - - - PolyLines - - PolySegment - - PolyRectangle - - PolyArc - - FillPolygon - - PolyFillRect - - PolyFillArc - - PolyText8 - - PolyText16 - -nxagent-1.5.0-57 - -- Removed two XSync() operations at screen initialization. - -- Modified keyboard initialization in order to load the correct rules. - This is choosen according to the vendor string of X-Window system in- - stalled on the local machine. - -- Corrected a few typos. - -- When the NX transport is present, the failed reconnection dialog is - launched on the remote X server by using the NXTransAlert() function. - The same dialog is managed by NXTransDialog() when a session is run - by connecting directly to the display. - -- Removed the function nxagentUnmapAllWindows(). - -nxagent-1.5.0-56 - -- Set the parent window for the pulldown dialog. - -nxagent-1.5.0-55 - -- Added an alert at the time the reconnection procedure begins. The - alert is shown only when the NX transport is present and the link - type is not LAN and is removed at the end of the resume operation. - -- Removed the former code used for testing the alert functionality. - -- Moved the function removing the splash window in Splash.c. - -nxagent-1.5.0-54 - -- Fixed initialization of window privates storing exposed regions. - This solves a bug affecting the refresh of windows introduced in - nxagent-1.5.0-42. - -- Added a STARTING state to nxagent. Until the agent is in this state - the suspension mechanism is not activated. - -nxagent-1.5.0-53 - -- Added the special keystroke Ctrl+Alt+R to enable or disable the - auto-resize mode. - -- A dialog notifies the user when the auto-resize mode is toggled. - -- Added a test alert at startup, to verify that NXTransAlert() is - working as expected. - -nxagent-1.5.0-52 - -- Changed the code to call NXTransDialog() and NXTransExit(). - -nxagent-1.5.0-51 - -- Solved a bug that prevented the clients that had been restarted - to be immediately selected for input. - -- Removed some code that was added for debugging. - -nxagent-1.5.0-50 - -- Fixed a memory leak in nxagentHandleExposeEvent(). - -- Fixed a memory leak in nxagentDestroyWindow(). - -- Now rootless dialog is launched only when last mapped window is - deleted, since we have pulldown window to control the session. - -- Added pulldown dialog to handle NX windows in rootless sessions. - This dialog is activated from a "magic" slice of window under the - top border. - -- Solved a problem with sessions that might fail at reconnection. - -- Now the message text of the dialog launched in case of failed re- - connection explains the reason why the agent cannot be resumed. - -- Implemented function nxagentUnmapAllWindows() to unmap all windows - if nxagent has failed to migrate the session to the new display. - -nxagent-1.5.0-49 - -- Fixed the problems with propagation of the drawable status. - -- Modified nxagentPutSplitImage in order to set the correct height - of the last split image. - -- Code cleaning and optimization in Dialog.c. - -- Solved bug that switched on the full screen state in rootless se- - ssion. - -- Changed the way dialog caption are set in rootless mode. It is set - upon the session name or session id value. - -- Corrected the function nxagentFailedReconnectinDialog(). - -nxagent-1.5.0-48 - -- Solved bug that switched on the full screen state in rootless se- - ssion. - -- Changed the way dialog caption are set in rootless mode. It is set - upon the session name or session id value. - -- Corrected the function nxagentFailedReconnectinDialog(). - -nxagent-1.5.0-47 - -- Now we call NXContinueOnDisplayError() with value 1 just after - having opened the display. This will cause the NX Xlib to return - in the case of an I/O error, instead of quitting the application. - -- Removed the references to Context.h and the related elements. - -- Reflected the changes occurred in NXlib.c regarding NXDisplayErr- - ror() and inverted the logic compared to NXDisplayIsValid(). - -- Added a dialog box to notify the user when nxagent has failed to - migrate the session to the new display. Because the main X agent - connection is unavailable, this dialog uses the auxiliary nxcomp - keyboard channel. - -- Disabled the special keystroke Ctrl+Alt+S if any dialog is already - running. - -- Started implementing lazy synchronization of pixmaps. At the pre- - sent moment the implementation doesn't try to perform any optimi- - zation on the windows' regions that have to be redrawn and neither - it checks the congestion state. After having synchronized a reaso- - nable number of pixmaps, it simply sends to all the affected win- - dows an expose event, mandating the repaint of the whole area. - -- Removed a warning in Atoms.c. - -nxagent-1.5.0-46 - -- Removed the longjmp() at the time an I/O error was encountered on - the display. - -nxagent-1.5.0-45 - -- Removed UNDEFINED status for drawables. - -- Now lazy encoding affects only windows. - -- Changed the block handler to call NXTransFlush() with 'if needed'. - -nxagent-1.5.0-44 - -- After reconnection, stored exposed regions are reset and the manag- - ing of duplicate expose events is restarted. - -- Detection of window manager has been moved to the start of screen - initialization. Screen dimensions and fullscreen option are over- - ridden if no window manager is detected. - -- Added a call to XSync() in switching fullscreen function in order - to synchronize it with the network behaviour. - -- Started adding provision for deferred writes in the NX transport. - When the flush policy will be set accordingly, X data accumulated - by the proxy will be written to the network under the control of - the block and wakeup handlers. - -- Fixed a bug in nxagentCopyArea(). In some cases, pixmap drawables - was erroneusly supposed to be windows. This produced invalid reads - when trying to access to fields of WindowRec structure. - -nxagent-1.5.0-43 - -- In the code managing the property notify events, NXCollectProperty - is not called if the window is not found in the tree mantained by - the agent. - -- Changed managing of screen resize in order to avoid repeated resize - of desktop. The agent sleeps one second, then all configure event - are read from the queue and the server connection. The desktop re- - size is performed after the last read configure event. - -- Changed nxagentImportProperty() in order to use NXCollectProperty - instead of XGetWindowProperty. This avoids many round-trips in root- - less mode. - -- Fixed Invalid write problem in nxagentRRSetScreenConfig(). - -nxagent-1.5.0-42 - -- Modyfied test of NXSetUnpackGeometry for visuals, so now the compa- - rison between visuals is based on their IDs and not on the memory - area allocated for their visual structure. - -- Modified exposure managing in order to avoid duplicated refreshes. - Now only exposed regions not formerly managed yet are sent to the - clients. - -nxagent-1.5.0-41 - -- Modified nxagentCloseScreen() in order to free the frame buffer. - -- Added information of the integrity of the windows. Now the integrity - has became a drawable property that will expand in every drawable to - drawable operation. - -nxagent-1.5.0-40 - -- Splitting of images now happens only if the display is a valid con- - nection. - -- The isItTimeToYield flag is now set in the dispatcher only when the - client has been actually suspended because of a karma, a sync, or - a split operation. - -nxagent-1.5.0-39 - -- Improved the handling of the PutImage request to offer provision - for splitting images coming from orders generated by extensions. - -- Fixed a problem with clients being unexpectedly restarted instead - of waiting for the end of split. - -nxagent-1.5.0-38 - -- Added a persistent dialog when agent is running in rootless mode. - -- Modified the policy of management of nxclient dialogs. - -- Fixed memory leak problem in nxagentPutSplitImage(). - -- Modified printing of some debug messages to avoid passing a null - pointer to fprintf(). - -nxagent-1.5.0-37 - -- Implemented initial support for streaming the packed images in the - handling of the MIT-SHM extension. - -nxagent-1.5.0-36 - -- Updated the pixmap status when a placeholder is copied on the pix- - map and when the pixmap is the target of a RENDER composite opera- - tion. - -- Solved the TR05C00900. The NX transport was forced to be set when- - ever the display name contained the nx prefix. - -- Implemented the FRSA052393. Removed the compression filters applied - by nxagent to cursor pixmaps. - -- Modified RANDR implementation to make the user able to resize the - desktop by simply dragging the agent window's border. Screen resize - is made after a small timeout, to give time to the last configure - event to come from the server and avoid multiple re-configurations - of the screen. - -nxagent-1.5.0-35 - -- Added the current screen size to the set of sizes returned by the - RANDR extension. - -nxagent-1.5.0-34 - -- Corrected the placeholder xpm image. - -- Added a client dialog to notify the user that nxagent is running in - fast or in slow mode after pressing Ctrl + Alt + S. - -- Modified RANDR implementation to give a set of screen sizes. Im- - plemented functions actually performing screen resize on a RANDR - request. Now toggling to fullscreen make the desktop cover the en- - tire screen area. - -nxagent-1.5.0-33 - -- Added an auto-disconnect feature similar to the one present in the - Windows Terminal Server. The feature is modeled on the built-in X - server's screen-saver. If the agent doesn't receive any input from - the user in a given timeout, it will either terminate the session, - if no client is connected to the display, or will suspend it, so - that applications will be left running. - -- The default is to disable the auto-disconnect option. The feature - is activated by specifying a "-timeout s" parameter on the command - line, with s being the timeout in seconds. The minimum allowed ti- - meout is 60 seconds. - -- The waitpid() call now only checks the agent's own children. - -- Moved the longjmp() context declaration to a new Context.h file to - avoid clash with redefinitions by the PNG headers. - -- Few other cosmetic changes. - -nxagent-1.5.0-32 - -- Added a check on the type of the connection to avoid cleaning the - images when not needed. - -nxagent-1.5.0-31 - -- Modified the placeholder frames, now it has a left top black border - and a bottom right grey one. - -- Modified fbShmPutImage() in order to set the correct size for the - temporary pixmap. - -- Modified nxagentForceExposure() and nxagentHandleExposeEvent() in - order to clip exposed regions to the window size region of the root - window. - -- Added a new placeholder xpm image. - -- Corrected few typos. - -- Added function to synchronize GC tiles and stipples whenever those - pixmaps have been realized. - -nxagent-1.5.0-30 - -- Hidden viewport windows to clients in QueryTree request in order - to make work XDMCP properly. - -nxagent-1.5.0-29 - -- Removed some warnings with gcc 3.4. - -- Added desktop -D switch to usage. - -- Paint window background draw on framebuffer only with OpenOffice - client. - -- Now fast copy are and fast getimage are no more set according to - the link type, their default value has been set to true. - -nxagent-1.5.0-28 - -- Modified nxagentUpdateViewportFrame() in order to solve a refresh - problem. Windows composing the external frame must be always on top - to be sure that agent sends expose events for every window. - -- In rootless mode agent doesn't export anymore the properties when - disconnected from the X server. - -- Changed the way agent check if the connection with the X server - is available. Instead of using a state machine it uses the display - flag. - -- Removed the SIGTERM handling function in persistent code. We don't - need anymore those function since agent is no more sleeping when - disconnected. - -- Implemented nxagentFreePropertyList() function in order to empty the - list of exported properties when the rootless agent is disconnected. - -- Added special keystroke Ctrl + Alt + S toggling between fast and - slow mode for GetImage and CopyArea. - -- Added missing handling of down arrow key in Keystroke.c. - -- Modified nxagentForceExposure() in order to intersect exposed re- - gions with the clip region of the root window. This prevents window - functions from painting outside the frame buffer. - -- Added the field usesFrameBuffer in struct nxagentPrivClient. Modifi- - ed GC funtion and DoGetImage() in order to write in the frame buffer - only if usesFrameBuffer is True. - -- Removed code performing PutImage in the frame buffer, as it is use- - less at the moment. - -- Modified ProcChangeProperty() to check WM_NAME property. - -- Added a piece of code in nxagentOpenScreen() checking for and remo- - ving duplicated visuals. - -- Added the Dialog.c Dialog.h files. Unified all calls to NXDialog, - and blocked SIGCHLD before calling in order not to get the signal - before the child pid has been stored. - -- Modified the algorithm that disconnect the running session in - order to avoid the opening of a new dialog box for closing or - suspending the nxagent. - -nxagent-1.5.0-27 - -- Changed the disconnect/reconnect procedure in order to have a pro- - per default colormap vector when session is suspended, solving a - segmentation fault in create window function. - -- Corrected few errors in slow copy area mechanism. - -- Modified screen initialization in order to allocate memory for the - internal frame buffer. - -- Modified some GC functions for writing to and reading from the frame - buffer. - -- Modified nxagentCreateWindow() for initializing the window in the - frame buffer. - -- Modified nxagentCreateColormap() in order to use the default visual - if a matching one is not found. - -- Modified function DoGetImage() in order to call nxagentGetImage() in - place of nxagentGetDefaultImage() if fast option is on. - -- Added nxagentCheckWindowIntegrity() function verifying the matching - between the internal frame buffer and the X server for a window. - -nxagent-1.5.0-26 - -- Added the property "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR" to the list - of exported property in rootless mode, in order to let clients use - the system tray. - -- Modified import of WM_STATE properties in rootless mode in order - to better handle null resources. - -- Enhanced the slow CopyArea mechanism in case of one part of the - image is out of the X server screen or out of nxagent screen. - -- Changed type for variables width and height of default window - from 'unsigned int' to 'int'. - -nxagent-1.5.0-25 - -- Added a new signal handler for SIGCHLD. The transport is set to - forward the signal (by means of a new NX_SIGNAL_FORWARD action). - This allows the agent to wait for its own children. - -nxagent-1.5.0-24 - -- Set up the RANDR extension. When querying the configuration, the - clients get 3 sizes, the first being the current size, the second - being the maximum size of the remote display, the third being the - minimum size (arbitrarily set to 100x100 pixels). Screen sizes in - millimeters are calculated based on the size reported for the real - display. - - An example of xrandr -q output is below: - - SZ: Pixels Physical Refresh - *0 800 x 600 ( 270mm x 203mm ) - 1 100 x 100 ( 33mm x 33mm ) - 2 1400 x 1050 ( 474mm x 356mm ) - Current rotation - normal - Current reflection - none - Rotations possible - normal - Reflections possible - none - - As you can note, reflections and rotation is not possible. - -- Set up the GLX extension. This provides basic support with GLX op- - erations being translated into core X protocol primitives. - -- Moved initialization of GLX and RANDR to the Extensions.c file. - -- Removed the references to the unused mfb library. Modified Screen.c - to allocate the right privates for the fb code. - -- Modified the Xserver Imakefile to link nxagent with FbPostFbLibs - and avoid including mfb/libmfb.a. - -nxagent-1.5.0-23 - -- Fixed an incorrect buffer length calculation when retrieving a re- - mote property. - -- Added a check to avoid the use of a NULL pointer when changing the - window cursor. - -- Implemented a function to lookup the remote pixmaps. - -- Changed the RENDER initialization messages. - -- Corrected a few typos in symbol names. - -nxagent-1.5.0-22 - -- Added the nxagentNeedConnectionChange() macro. - -- Small optimizations in the block and wakeup handlers. - -nxagent-1.5.0-21 - -- NXCollectGrabPointer() is called by passing nxagentDefaultClient(). - This is a macro that checks the validity of requestingClient and, - if the pointer is NULL, defaults to NXNumberOfConnections - 1. - -nxagent-1.5.0-20 - -- Replaced all calls to XGrabPointer with the asynchronous version - provided by nxcompext. - -- In DeactivatePointerGrab() function, mouse button state is set to - up if the window entered by the pointer is the root window and the - agent is in rootless mode. This change is needed because the sub- - sequent KeyRelease event could be not received by the agent (for - example if the focus had left the window), so that agent could be - unable to update the mouse button state. - -- In rootless mode, grabs exported to X in ActivatePointerGrab() are - always made asynchronous. The synchronous behaviour is implemented - by the agent, so that requiring a further synchronous grab down to - the real X server is of little use and potentially harmful. - -- Modified function XYToWindow() in order to manage the case that - mouse pointer is located on the title bar of a top level window in - rootless mode. - -- Reflected name changes to NXImageCache variables. - -nxagent-1.5.0-19 - -- Changed the implementation of the SIGHUP handler to forward the sig- - nal to the proxy only when appropriate. This allows nxagent to close - the NX connection without having to go through an I/O error on the - display. - -- Modified nxagentBreakXConnection() to check if the NX transport is - running and thus use NXTransDestroy(). Using a simple shutdown() may - not work, for example if NX is using the memory to memory transport. - -- Added the -D option, to let users specify that agent must be run in - desktop mode. This is presently the default. - -nxagent-1.5.0-18 - -- Set the PropertyChange mask on input/output window in rootless mode - in order to get the PropertyNotify events. - -nxagent-1.5.0-17 - -- Cleaned of the reconnection routines, removed the NXAGENT_RECONNECT - macro. - -- Now the SIGHUP handler forwards the signal also to the NX transport. - -- Moved the NXTransDestroy() call in the closure of the display, so - we can avoid going through the I/O error handler. - -- Removed an invalid free in the function that closes the display. - -- Commented out more code in Display.c to avoid the segfault on exit. - -- In rootless mode, now function XYToWindow() starts search from the - last window originated an EnterNotify event. In this way, we can - prevent shaded windows from getting mouse events. - -- The variable to disable the smart scheduler is set at its definition - instead of setting it in the Dispatch function. This avoids the call - to SmartScheduleInit. - -- Changed implementation of cursor visualization in rootless mode. We - made the cursor attributes changes go transparently to the X server - while in desktop mode we ignore any client request to change the cu- - rsor on the X side, and we just set the cursor on the default window - any time the pointer cross a window border. - -- Expanded the range of properties exported on the remote Xserver, - this way we export properties whose atom name starts with "WM_" and - "_NET_". - -- In Rootless mode PropertyChangeMask is added to top level window in - order to get PropertyNotify Events. - -- First implementation in rootless mode of nxagentImportProperty fun- - ction with which after reception of PropertyNotify Events, all chan- - ging properties coming from external clients such as Window Manager - will be imported in agent windows. - -- Changed the GetEventMask function in order to handle the InputOnly - windows that need to be notified of property changes in rootless - mode. - -nxagent-1.5.0-16 - -- Implemented the -B command line switch, to let nxagent impersonate - a "pure" proxy on the NX server side (that is without X connections - having to be managed by the nxagent's dispatcher). Such a "nxagent - -B" is going to replace the corresponding nxproxy process that in - previous version of NX server was run with the same options. - -- When running nxagent in 'bind' mode the X port where the the proxy - has to listen for connection must be specified after the -B option. - The other NX options must be passed in the DISPLAY environment. - - Example: - - nxagent -B :9 - -- The initialization procedure will check that the display included - on the command line matches the one specified in the NX display - options. - - For example, given the command: - - nxagent -B :9 - - The NX options must be something like: - - DISPLAY=nx/nx,link=modem:9 - - This allows users to find out which display the agent is impersona- - ting by running a 'ps' and inspecting the command line. - -- Fixed a bug preventing the proxy's ClientMessage to reach the right - function when activating rootless mode. - -- Removed unused function nomachineLogo. - -- Code cleaning and soem optimizations in Rootless.c. - -- We want to import all properties changed by external clients to our - internal windows. But we must ignore property notify generated by - our own requests. For this purpose we implement a list to record - every change property that we dispatch. This way when processing - a property notify we can distinguish between the notify generated - by our request and those generated by an 'outside client'. - -- In rootless mode, optimized window configurations mantaining inter- - nal stacking order. - -- Fixed focus troubles in rootless mode. Now focus window is set fol- - lowing FocusIn events. - -- In rootless mode, now fake KeyRelease events on FocusOut are sent - only if keys having down state are modifiers. This prevents from - sending key events to a wrong client. - -- Removed unused function nxagentRootlessNextSibling in Rootless.c. - -- Removed unused function nxagentRootlessStackingOrder in Rootless.c. - -- Fixed compilation error if TEST log is enabled in Events.c. - -- Changed Options variables to comply with NX naming rules. - -- Some additional cosmetic changes. - -nxagent-1.5.0-15 - -- Modified functions nxagentPutImage and DoGetImage for XYPixmap fo- - rmat. - -- Completed implementation of shared memory extension. - -- Implemented a mechanism that prevents monitoring of SubStructure- - Redirect ResizeRedirect and ButtonPress events by any clients simu- - lating the presence of a window manager running inside the agent. - -- Added debug functions in order to check the status of syncroniza- - tion between the pixmaps residing on the X server and the local - framebuffer ones. - -- Changed the policy used when realizing all the pixmaps in 'lazy en- - coding' mode so that the agent now switches to 'eager' policy. - -- Fixed the routine handling the pixmaps realization: pixmaps with - an invalid id are not processed anymore. - -- Solved a bug in the routine taking care of clearing the NoMachine - logo: the state of the background was set to 'pixel' without de- - stroying an eventual backround pixmap. - -- Solved a bug in the 'MakeRootTile' function: the value returned by - 'AddResource' was not interpreted in the correct way causing the - function to bail out without drawing the NoMachine logo and set- - ting the background state to Pixmap. - -- Renamed PlaceHolder.c to Lazy.c and PlaceHolder.h to Lazy.h. - -- Inserted a test feature that cleans the framebuffer pixmaps when - they are created. - -nxagent-1.5.0-14 - -- Changed some reconnection messages. - -- Now the disconnect procedure is called also after an IO Error is - received. - -- The rootless agent now doesn't filter anymore keystrokes combina- - tion related to desktop feature, like viewport navigation the full- - screen state and minimization. - -- In rootless mode, internal stacking order is updated by comparing - the stack of top level windows mantained by the X server with the - one mantained by the agent. A global configuration of windows is - performed from top to bottom through the stack. - -- In rootless mode, map state of top level windows is kept up to date - by managing map and unmap events. - -- In rootless mode, enter events are managed to keep track of top - level window position. It is very useful for managing differences - among window manager behaviours. It should be reimplemented follo- - wing the advice given in ICCCM 4.1.5. - -- In rootless mode, requests of configure top level windows are di- - rectly forwarded to the real X server. Internal configuration is up- - dated when configure events are managed by the agent. In order to - mantain internal stacking order up to date, a query tree request is - performed on the real root window. - -- Added viewport navigation by Ctrl + Alt + keypad arrows. - -- Fixed wrong internal configuration of agent top level windows, while - agent runs in rootless mode with metacity window manager. - -- Fixed segmentation fault in nxagent running in rootless mode with - OpenOffice. - -- Fixed wrong internal stacking order of drop down menus of firefox - with nxagent in rootless mode. - -nxagent-1.5.0-13 - -- Fixed compilation problem on solaris. - -- Modified the modify pixmap header function. Previously this function - has been modified in order to solve a glyph problem, enlarging both - the pixmaps dimensions by four. Corrected the misbehaviour that - modify the pixmaps dimension even if the caller doesn't want to - change it. - -nxagent-1.5.0-12 - -- Fixed erroneous behaviour of Root Window in fullscreen mode caused by - wrong value of XSpan and YSpan. - -- Fixed wrong clients' position at Reconnection in Rootless mode, - setting offset and WinGravity fields in XsizeHints structure. - -- Fixed segmentation fault on closing windows that stay always on top. - -- Moved the handling of configure notify events in the appropriate - functions, and cleaned it. - -- In rootless mode, internal stacking order of top level windows is - mantained up to date by monitoring events from window manager top - level windows. - -- Modify the creation of screen at reconnection for detecting an - eventual failure. - -- Removed export of window properties on the X server in desktop mode. - -- Changed the events mask for client's window set on the X server. - We don't use anymore the window mask choosen by clients. In rootless - mode for a top level window we use the default event mask and for a - child only the exposure mask. - -nxagent-1.5.0-11 - -- Restored default event mask at reconnection. - -- Fixed abnormal behaviour in rootless mode if application windows are - close to the lower and right bounds of the screen. This trouble was - due to the wrong size of the agent root window. - -- Fixed abnormal behaviour in rootless mode for mouse button events if - the application window is not fully contained in the screen. - -- In rootless mode, exposed region are extended a few to take in ac- - count border width offsets caused by window managers. - -- In rootless mode, grab pointer requests from clients are forwarded - to X server. This makes application able to close their pop up win- - dows on a pointer event. - -- Fixed wrong position of the agent root window after resize of main - window. - -- Changed the size of viewport frame windows in order to avoid re- - freshing problems. - -nxagent-1.5.0-10 - -- Handled the Client messages on rootless mode. - -- Initializations of event masks have been moved in a unique group of - functions. - -- Disabled the SmartScheduler in dispatcher as it seems to affect the - responsiveness of nxagent. - -- Modified the block and wakeup handlers. We could have left data to - write to our display connection when entering in WaitForSomething() - so we now flush everything before entering the select() and let the - proxy do all the buffering. - -- Fixed the wakeup handler to match the correct prototype. - -- Few cosmetic changes. - -- Inserted a test feature that cleans the framebuffer pixmaps when - they are created. - -- Adjusted pixmap status information in almost every gc operations. - -- Removed a warning for usleep not defined on Suse 9.0. - -- Adjusted pixmap status information in copy plane operations. - -- Throwed fatal error if on lazy encoding the place holder pixmap - couldn't be loaded. - -- Removed the static path to xpm file in place holder initialization. - -- Removed useless signal handler initialization multiple times. - -- Refined validation of atoms in the atom cache code. - -- Corrected few errors in atom cache initialization. - -- Added a primitive atom cache that mantain the map between internal - and external atoms. - -- Window properties export began on the X server side in rootless - mode, this way nxagent open the communication between local clients - and the window manager on the X server. - -nxagent-1.5.0-9 - -- Fixed wrong position of the main window in case of maximizing in - window mode. - -- Set the correct scan line lenght for XYPixmap created in PutImage - and GetImage. - -- Removed a segmentation fault in GetDefaultImage. The problem arose - because the XYPixmap created with a data storage taking in account - of only some planes instead of all the depths planes. Despite XPut- - Pixel was treating the image as a complete XYPixmap of that depth. - -- Removed MapWindow Error at reconnection caused by wrong value of - IconWindow. - -- Now nxagent_WM_START is intialized as soon as the Atoms are - queried. - -- Removed Geometry restrictions. - -- Changed the configuration of the agent window in window mode. - -- The agent window is correctly reconnected even if is resized. - -nxagent-1.5.0-8 - -- Updated copyright notices. - -- Removed a segmentation fault in font cache cleaning routine. The - problem arise when the session is disconnected and the font struct - are not allocated. - -- Used the return mask of XParseGeometry to correctly set only the - parameters that are involved. - -- Unified the initialization of all the geometry related parameters. - -- Updated the offset of the four viewport frames windows at recon- - nection. - -- Changed the way the geometry parameter is used. Now the first time a - session is started it set the internal dimension of the agent root - window, afterwards it only affects the dimension of the external - window on the X server. - -- Corrected splash screen offset at reconnection in fullscreen mode. - -- Agent can be launched in fullscreen mode and his geometry can differ - from the X server geometry. - -- Now Width and Height options are used to store geometry of the - default window even on fullscreen mode, and to restore the correct - dimension when switching back to window mode from fullscreen - we added two more options. - -- Removed an error in the move viewport procedure that didn't upgrade - the offset of the internal root window when the external root win- - dow was maximized. - -- Unified the initialization of all the geometry related parameters. - -- The window manager detection procedure is now started whenever there - is an attempt to minimize the fullscreen window or to pass to window - mode. - -- Function's optimization for detecting if WM is running. - -- Switching to window mode has been disabled when the window manager - is not running. - -nxagent-1.5.0-7 - -- Now background pixel is not reset at reconnection. - -- Now geometry is parsed also as a command line parameter. - -- Fixed wrong offset of the root window after a reconnection in case - of window mode. - -- Fixed wrong geometry of the nxagent window after a reconnection - in case of window mode. - -- Fixed wrong position of the main window after a reconnection in - case of fullscreen mode. - -- Fixed refreshing windows problems in viewport navigation. Four in- - visible windows are created around the agent window to automatica- - lly generate exposure when the viewport frame is moved or a windows - come out from the non visibile part of the agent window. - -- We need to store the GC records in a list that will be freed in case - the reconnection succed and will be restored in case of failure. We - have to do this because we cannot destroy the GC records in the - disconnect or reconnect procedure, because this way we couldn't - recover from a disconnection or a reconnection failure. - -- Rewritten the reconnection procedure. Since we cannot be sure - that the reconnection will succed we cannot destroy the display - structure, so we postpone the closing of the previous display - with the creation of the new connection. - -nxagent-1.5.0-6 - -- Adjusted usage list in order to show the R parameter for rootless - mode. - -- Added handling of display parameter to option file. - Corrected few typos error, in option file parsing. - -nxagent-1.5.0-5 - -- Removed error that prevented the realization of cursor in eager - mode. - -nxagent-1.5.0-4 - -- Fixed abnormal behaviour of termination dialog, after the keystroke - Ctrl + Alt + T. - -- Fixed segmentation fault in function parsing option file. - -- Fixed various errors on eager encodings. - -- Added lazy command line switch in order to switch lazy encoding - on. - -- Code cleaning. - -- Implemented a signal to switch between two pixmap - realization policies. - -- Corrected an error while defining pixmaps status. - -- Implemented a debug feature, consisting in a method that pushes - the synchronized realization of all the pixmaps. - -- Began implementation of place holders in replacing of images while - they are being loaded. - -- Performed some changes on spreading of pixmaps status information - on copy area. - -- Began implementation of lazy encoding. - -- Changed version to 1.5.0. - -nxagent-1.5.0-3 - -- Removed the option -nogetimage (FRSA052305). - -- Code cleaning in Font.c. - -- Removed NXAGENT_FONTMATCH macro. - -- Removed NXAGENT_FONTCACHE macro. - -- Handled the ReparentNotify event we get when in rootless mode - ours window are reparented from the window manager. Inserted - fake windows to take account of this new parents. - -- Removed the redirection of client message in rootless mode, and - the configuration of the WM_PROTOCOLS properties on all the top - level windows. - -- Removed parent ID from the windows private structure. - -- Implemented screen operation ReparentWindow. - -- Redirect all client message of type WM_PROTOCOLS and value WM_DELETE- - _WINDOW to internal clients in rootless mode. - -- Set the WM_PROTOCOLS property on all the top level window. - -nxagent-1.5.0-2 - -- Changed viewport navigation, in order to make it works in fullscreen - mode. - -- Changed special keystrokes used for closing session and minimizing - fullscreen window. - -- Removed the message 'NX was unable to negotiate a cache - for this session' (FRSA052296). - -- Fixed a minor bug. It made metacity produced a warning when the agent - started up. - -- Code cleaning. - -- Implemented dynamic handling of the main window's size in the X11 - agent (FRSA052264). - -- Implemented dynamic navigation of the main window's viewport in the - X11 agent (FRSA052265). Users can navigate the viewport while keys - Ctrl + Alt are pressed, either by arrows keys or dragging it by the - pointer. - -- Implemented dynamic handling of the full-screen attribute in the - X11 agent. - -- First implementation of dynamic handling of the full-screen - attribute (FRSA052263). - -- Now the X connection descriptor is not closed when disconnected, - because the transport layer still has reference to it. So we want - it busy till we don't close the display, so we shutdown it instead - of closing it. - -- Removed replys when disconnected. - -- Added the X connection number to the set of enabled input devices, at - reconnection. - -- Rewritten the disconnect/reconnect layout. - -- Now in the suspend status nxagent doesn't sleep. - -- Implementing toggle fullscreen special keys. - -nxagent-1.5.0-1 - -- Opened the 1.5.0 branch. - -nxagent-1.4.1-7 - -- Imported changes from nxagent-1.4.0-64 version. - -nxagent-1.4.1-6 - -- Implemented a GC cache for reconnecting pixmap. - -nxagent-1.4.1-5 - -- Handled the situation of disconnect when the pointer has been grabbed. - We disconnect and reconnect the "grabbing" cursor and after reconnection - we fake a button release in order to let client know that the pointer - button has in effect been released. - -- Code cleanup. - -nxagent-1.4.1-4 - -- Imported changes from nxagent-1.4.0-63 version. - -nxagent-1.4.1-3 - -- Imported changes from nxagent-1.4.0-62 version. - -nxagent-1.4.1-2 - -- Cleaned code in the GC reconnection area. - Scratchs GC are now reconnected before of the pixmaps. - -nxagent-1.4.1-1 - -- Opened the 1.4.1 branch. - -nxagent-1.4.0-65 - -- Cosmetic changes to the diagnostic output. - -nxagent-1.4.0-64 - -- Changed the RENDER version advertised to X clients to be the lowest - value between the version of RENDER of nxagent and of the remote X - server. - -- Disabled fast copy area and fast get image flags, if RENDER extension - is not available. - -- At the screen initialization, if we don't have window manager we - grab keyboard to let nxagent get keyboard events. - -- Completely rewritted the handling of KeyPress events, now we moved - all the test for 'special' keybindings in file keystroke.c. Added the - combination MOD1/2-CTRL-SHIFT- for terminate/suspend the session, - we used the combination MOD1/2 in order to let it work even on MacOS - where Alt(MOD1) doesn't seem to be set. - -- Ignored visibility notify events on the icon windows, that were - messing up the agent visibility state. - -- Changed nxagent reaction on VisibilityNotify event. It fixed the - problem with refresh session under Mac OS X with NXDarwin. - -nxagent-1.4.0-63 - -- Reset the congestion state at transport initialization. - -nxagent-1.4.0-62 - -- Fixed the disconnection and reconnection of window that have attached - an animated cursor. - -nxagent-1.4.0-61 - -- Removed the XInputExtension initialization in order to use the more - general mi extension initialization enabled on new mi version. - -- Removed some useless test and logging info on copy area function. - -nxagent-1.4.0-60 - -- Changed the implementation of CopyArea and CopyPlane. - If both drawables are on framebuffer we send NoExpose to clients, - otherwise we use the mi function HandleExposure to calculate the - region to be exposed instead of let mi redo all the copy operation. - -nxagent-1.4.0-59 - -- Disabled use of caching and cleaning of images, if NX transport is - not used. - -nxagent-1.4.0-58 - -- Added timeout on convert selection operation. If timeout has not - expired and is there a pending operation any new request is dropped - and the client notified, until timeout expiration. - -- Corrected a bug that prevented to correctly store last convert se- - lection request time. - -nxagent-1.4.0-57 - -- The Xinput extension is now initialized at startup. This is of - little use because nxagent only needs to support the core pointer - and keyboard. Anyway this allows nxagent to get rid of the warn- - ings printed by some X clients on recent Linux versions when the - extension is not found. - -nxagent-1.4.0-56 - -- Fixed value returned by ConvertSelection. It was the cause of - possible slowndowns during KDE sessions. - -nxagent-1.4.0-55 - -- Agent icon now is loaded from a binary- - embedded Xpm image, if any attempt to - load the default Xpm file from the image - directory or from the path fails. - Removed code used in the old logo drawing - function. - -nxagent-1.4.0-54 - -- Enabled code for sending to client graphics - exposures. Redirecting the ones coming from - remote X server, only if agent window is not - fully visible, and calculating ourselves failure - in CopyArea/Plane and notifying clients. - The only drawback is that we can have double - refresh effect if agent window is covered. - -NOTE: Partially enabled MIT-SHM extension has - been developed but has not been included - in stable release. Included in version - nxagent-1.4.0-53-DAR1. - -nxagent-1.4.0-53 - -- Implemented a reliable technic to detect - if is there any window manager running on - the X server. - -nxagent-1.4.0-52 - -- Fixed a bug that prevented to correctly - notify the client of a successfull convert - selection. - -nxagent-1.4.0-51 - -- Removed a logging error in render initialization. - -nxagent-1.4.0-50 - -- Now we take the ownership of the selection - on "NX_CUT_BUFFER_SERVER" twice, in order - to solve bug in communication with nxclient - to let him see our main window and know that - agent established connection with X server. - -nxagent-1.4.0-49 - -- Fixed the colormask layout of the visual - used to put images on the real X server when - the drawable has an alpha channel, according - to the endianess of the X server. - -nxagent-1.4.0-48 - -- Moved up the render compatibility limit, - due to the inclusion of the support for render - cursor missing on the 0.2 version. - -nxagent-1.4.0-47 - -- Changing artsd forwarding port from display - + 8000 to display + 7000 - -- Stoping key release event if key press was - catched before. For Alt-F2/F4 combination. - -- Preserved the alpha data on drawables that - are not used by picture but have a depth of 32. - -nxagent-1.4.0-46 - -- Rewritten all the code regarding to the - acceleration for the Render creation of the - cursor, and removed the acceleration for - the animated cursor. - -nxagent-1.4.0-45 - -- The two RENDER operations creating cursors and - animated cursors have been accelerated by for- - warding the original operation to the X server. - -nxagent-1.4.0-44 - -- Fixed a problem in the clipboard procedure. - Now when we get a request of the selection - from an internal client we have to, if the - owner is on the X server, forward the request - to X, otherwise we have to pass the request - to our internal client. - But for a problem in this procedure we passed, - in some situation, the request to the internal - client even if the owner was on the other side. - -- Fixed a segmentation problem in the render - extension by removing composite trapezoid - operation on window. - -nxagent-1.4.0-43 - -- Added some pointer sanity check in the discon- - nect procedure. The problem was arising because - we were executing the code twice when after - began a voluntar disconnection the X connect- - ion was broken for a network failure. - -- Changed directory where nxagent gets the icon. - -- Fixed missing implementation of rendering - trapezoids. - -- Fixed bug in render extension when the nxagent - create cursor diffrent then 32 bits format. - -nxagent-1.4.0-42 - -- Solved segmentation fault, caused by a longjmp - on a stack context not previously saved. - -nxagent-1.4.0-41 - -- Added an exposures of the window in a resize - operation. - -nxagent-1.4.0-40 - -- Implemented a timeout on the opening of the X - display, if we get it we reject all well known - sockets. - -nxagent-1.4.0-39 - -- Corrected minor error on events handling. - -nxagent-1.4.0-38 - -- Removed in the resize window code some exposure - that generated useless traffic. - -- Option geometry is no more parsed in the option - file. - -nxagent-1.4.0-37 - -- When session is suspended and we get TERM signal - nxagent just exit instead of just breaking out of - dispatch loop because we get a terminate exception. - Cleared display variable after having closed the - connection with the X server. - -nxagent-1.4.0-36 - -- Refined some details in the ICC with nxclient. - -nxagent-1.4.0-35 - -- Implemented a new method to comunicate to nxclient, - the raise of the agent root window, taking the ownership - of the selection "A-{MD5 of session}". - Used the same selection to let nxclient comunicate to agent - by changing the property on the same string, when the user - choose by the administrator to terminate or suspend the - session. - -nxagent-1.4.0-34 - -- Key sequence to Suspend/Terminate session (Alt-F4). - -- Key sequence to Minimize session in fullscreen mode (Alt-F2). - -- Check if WM is started, for Alt-F2 sequence. - -- Corrected calculation geometry of exposed region - sent to client after reconnection. - This solve a serious memory leak of nxagent. - -- Fixed a bug in validate GC code that passed - a wrong pointer of tile to framebuffer. - -nxagent-1.4.0-33 - -- Changed the reconnection state machine in order - to let agent exit if has got the TERM signal. - -nxagent-1.4.0-32 - -- Fixed memory leak in option parser that wasted - memory if more than one occurence of 'option' - argument would have been parsed. - -- Removed a invalid read in Keyboard initialization. - Now kbtype option value is copyed instead that - referenced. - -- The X connection number is recorded only after - having cheched for display being successfully opened. - -nxagent-1.4.0-31 - -- Fixed memory leak problem caused by region not - beeing destroyed previously. - -- Fixed a memory leak in keyboard initialization. - -- Fixed a bug in the function that parse the option file, - we were reading the options in the format NAME=VALUE and - were passing it to the argument parser in the format - {NAME, VALUE}, without the prepending '-' in front of NAME. - -nxagent-1.4.0-30 - -- Readded option persistent in order to let nxagent - works with older nxserver that are still launching - nxagent with the persistent option. - -nxagent-1.4.0-29 - -- Corrected the message of the client dialog - asking if user want to suspend or terminate the - session. - -- Chenged the default value for persistence of session - in nxagent to true. Change the persistent option to - nopersistent in order to disable it. - -nxagent-1.4.0-28 - -- Added check on screen initialization of possible - memory allocation failure. - -- Changed the parsing policies of the option file. - Now we are just considering kbtype and geometry - options. - -- Removed testing code that forced rootless mode - when geometry is 100X100. - -- Correctly initialized and mapped the icon window - on fullscreen mode. - -nxagent-1.4.0-27 - -- Fixed lost memory problem caused by second - initialization of screen privates. Screen - privates is already initialized by miScreenInit - function. - -nxagent-1.4.0-26 - -- Added option command line option. This parameter - is used to show complete path to option file. - -- Added parser of the option file. - -- Now default value for fast copy area and fast - getimage is true. - -nxagent-1.4.0-25 - -- Done some cleanup to the initialization of the - defaults drawables at reconnection, and removed - a memory leak in the reopening of the Display. - -nxagent-1.4.0-24 - -- Changed the version number, printed at startup. - -- Removed a memory leak in the font reconnection stage. - -nxagent-1.4.0-23 - -- Removed a bug that messed up the render status info - if reconnected to a display with no render support. - Anyway nxserver should prevent agent to trying reconn- - ecting to such display. - -nxagent-1.4.0-22 - -- Enhanced the reconnection error reporting function. - -nxagent-1.4.0-21 - -- Get the ownership of selection NX_CUT_BUFFER_SERVER at reconnection - in order to let client knows that agent windows has started - successfully. - -nxagent-1.4.0-20 - -- Now we draw splash logo at reconnection. And destroy it and show - all other windows when reconnection has done all in once. We draw - it on default window instead that on root window, and we map root - window when reconnection has finished. - -nxagent-1.4.0-19 - -- Removed the old Xconnection descriptor and added the new one - to the device set, instead of resetting the entire enabled - device set, at reconnection. - -nxagent-1.4.0-18 - -- Reset the enabled devices set of descriptors, and properly - add to this set the the Xconnection descriptor. - -NOTE: This solves all the known solaris reconnection problems. - (The problem appear only on solaris because on this machine - the Xconnection descriptor is changing at reconnection.) - -nxagent-1.4.0-17 - -- Restored the previously owned primary selection, at reconnection. - Removed the handling of the return value of XSetSelectionOwner, - man page doesn't specify any return value. - -nxagent-1.4.0-16 - -- Added compatibility with older windows clients(Xserver) - that send a WM_DELETE_WINDOW client message WM_DELETE_WINDOW - to all top level window and so agent show more than one - NXDialog asking for confirmation, instead of sending just the - message to top level window that are visible and haven't set - the override redirect option. - -nxagent-1.4.0-15 - -- Ignored unmatched DirectColor visuals at reconnection - on a different display not providing it. - -nxagent-1.4.0-14 - -- Moved the render query extension in display - initialization from screen initialization. - -- Changed reconnection policy to disallow reconnect a - session that is using render to a server not providing it. - -nxagent-1.4.0-13 - -- Unified the screen opening function. - -- Changed the reconnection requirements - policy about geometry of X server. - Now agent doesn't accept changes of X server - root window size only if in fullscreen mode. - -nxagent-1.4.0-12 - -- Improved failure notification messagges in Display and - font code. - -nxagent-1.4.0-11 - -- Now visuals are properly recreated, in order to reconnect - to another X server. - -- Updated render formats at reconnection. - -nxagent-1.4.0-10 - -- Removed a serious memory leak at reconnection. - -nxagent-1.4.0-9 - -- Added after window reconnection the redisplay of the current - cursor. Done some general cleanup at cursor reconnection code. - -nxagent-1.4.0-8 - -- Unified tha atom creation at reconnect. - -nxagent-1.4.0-7 - -- Dix layer when creating a GC use a default real pixmap as - stipple but agent need a virtual one. This can cause - segmentation fault to agent if is there any apps that use the - default GC stipple created by dix, without changing it. - -nxagent-1.4.0-6 - -- Imported 1.4.0-1-DAR6 from the 1.4.0 development branch. - -- Handled reconnection of window's cursor still not - reconnected at window reconnection. (This because that cursor - is no more a server[nxagent] resource). - -- Set the last image client variable at reconnection in order - to use the visual cache indexed for client number. - Without this we could get a segmentation fault. - -- Handled properly the reconnection of animated cursor. - Modified the procedure of animated cursor creation - in order to empty some unused fields. - -- Removed a 4 bytes memory leak at reconnection. - -- Synced new tree with nxagent-1.3.2-23. - -- Finished the unify of PutImage at reconnection. - Added a Reconnection Trap in order to let screen functions - (like PutImage) knows that are working at reconnection time - and can behave differently. - -- Unified the code for the normal PutImage and the one's used at - reconnection. But the code that calculate the split is still - doubled. - -nxagent-1.4.0-5 - -- Imported 1.3.2-23 from the 1.3.2 development branch, and dropped - the previous 1.4.0 versions. - -nxagent-1.3.2-23 - -- Pixel hints are set according to the display's depth. Added the - defaults to be used on 16 bits. - -nxagent-1.3.2-22 - -- The pixel hint on Solaris is by default 0xffffff. The value can be - overridden by using the -hint option followed by the hex represen- - tation of the color, as in -hint 0xaabbcc. - -nxagent-1.3.2-21 - -- Asynchronous GetImages are now disabled. If fast GetImage mode is - enabled, agent will always try to guess the pixel to be used for - the solid pattern, based, at its best, on the geometry of the pro- - vided area. This behaviour can be overridden by passing the -slow - parameter on the command line. Slow mode is also the default when - selecting WAN or LAN link settings. - -- Code cleanup in preparation of the final release. - -nxagent-1.3.2-20 - -- New code uses sigaction to set the SIGHUP handler in persistent - mode. Contrarily to signal(), the sigaction call doesn't seem to - reset the handler to SIG_DFL after the signal has been caught. - This problem seems to be specific of Solaris. - -- Client messages of type WM_PROTOCOLS are now handled even when - a window manager is not detected at agent startup. - -- Removed handling of GraphicsExposure coming fron the real server. - Agent will still generate events in the MI. Code dealing with the - remote events needs to be better tuned as it seems to cause some - troubles with double refreshes. - -nxagent-1.3.2-19 - -- Starting from this version agent doens't use NXSync and NXKarma - messages to manage bandwidth arbitration among clients but makes - efficient use of the congestion notification messages introduced - in 1.3.1. A new handler has been added to manage the congestion - state. The handler will block, if needed, waiting for the decon- - gestion notification coming from proxy. - -nxagent-1.3.2-18 - -- Rewritten the block handlers to check the event queue more often. - The new code seems to greatly enhance responsiveness, especially - on fast links. - -- Now agent will handle the expose events coming from the remote - display inside the event dispatcher. - -- Created a new function collecting the expose events. Function is - optimized to add all the expose events for the same window to a - single region. Region is passed to the mi when the last event - has been processed. - -- Still dealing with GetImage from OpenOffice. Now we try to match - the geometry of the incoming requests with known geometry of most - of its graphic elements. It seem to work on Fedora. - -nxagent-1.3.2-17 - -- Added swapping of image data in nxagentGetImage() when connecting - to a display having a different image byte order than the agent - server. - -- Added a new nxagentImageReformat() function in GCOps.c. - -- Now agent will not try to pack images having a data size smaller - than 768 bytes. The previous threshold was set to 64. The Mandrake - vesion of KDE seems to send lot of such small images. Compressed - through JPEG, these images obtain a very poor ratio of nearly 1:1. - -- Added a function translating and sending the GraphicsExposures - events received from the remote server to the agent's clients. - -- Renamed the functions providing the ad-hoc handling of remote X - events. - -nxagent-1.3.2-16 - -- Implemented a cache for the alpha channel data. With clients - making heavy use of the alpha blending, the new cache is able to - cut by nearly 30% the traffic incoming to proxy, offering compara- - ble savings in CPU performance. While proxy is usually able to - cache almost all the alpha traffic, when caching is not enabled - (f.e. when link setting is WAN or LAN) this data is sent uncomp- - ressed by the agent. Tests running common desktop environments - showed that alpha channel could weight up to 2 times the corres- - ponding data generated by the packed images. - -- Fixed the compilation warnings in NXrender.c. - -nxagent-1.3.2-15 - -- Rewritten handling of GetImage from dispatcher down to GCOps. If - the fast GetImage mode is enabled agent will use the asynchronous - calls provided by nxcompext to get data from the real server. Data - collected from the last get image performed is preserved and the - upper left pixel is used to guess a solid background. - -- Added a nxagentGetBackgroundImage() function to apply a similar - mechanism when the nxagent window isn't fully visible. Previously - a solid white background was returned. The new handling seems to - correctly match the window background in most cases. - -- Fixed a problem passing the bytes per line value when creating a - XYPixmap image. The previously calculated value didn't take into - account the depth of the image. - -- Now image's bytes per line, length and visual are calculated by - using a few utility functions added to GCOps.c. - -- Added declaration of the nxagentVisibility related variables to - Window.h. - -nxagent-1.3.2-14 - -- On Fedora xbcomp configuration fails when agent is run nested. - This causes keyboard to ignore most AltGr keys. Strangely enough - this behaviour has been observed only with KDE while GNOME does - not seem to be affected. Reason is to be investigated. - -- Auto-repeat mode of the agent's keyboard device is now always - disabled. Agent will leverage auto-repeated keystrokes genera- - ted on the real server even when propagating device configura- - tion changes. - -- The info output telling if agent will propagate the changes to - devices' setting is now printed after having initialized the - screen. The purpose would be to verify if agent is running in - fullscreen mode and there is no WM on the real display. In this - case we should forcibly propagate device configuration changes. - Unfortunately, due to the way intern atoms are collected, this - is not going to work on platforms where sessions are likely to - run on an existing X server. - -nxagent-1.3.2-13 - -- Fixed a problem with XYPixmaps being used in PutImage with the - wrong left pad. This is a step forward in the solution of the - corrupted masks displayed by Mozilla when showing some animated - GIFs. - -- By selecting 'fast' mode nxagent will now skip real XGetImage - operations on windows. This becomes the default in the case of - MODEM, ISDN and ADSL links. In theory X clients should never do - that. In practice a few naive programs and libraries (like, sur- - prisingly enough, a famous Linux office automation suite) do, - mainly to compose images with the window's backgound. Why don't - they compose content into a Pixmap? - -- Improved the implementation of CompositeGlyphs. It now uses a - single call to XRenderCompositeText instead of splitting the - output in multiple RENDER requests. - -- In previous versions file NXmiwindow.o was not linked into the - resulting nxagent. This solves the problem of missing repaints - in CDE and other Xt applications. Be sure you upgrade nx-X11 - to version nx-X11-1.3.2-2. - -- Added a warning when the change keyboard control or the change - pointer control functions are called. - -nxagent-1.3.2-12 - -- Added bit-swapping of glyphs having depth 1 when agent has a - different bitmap-bit-order than the X server. - -- The KeyRelease event's timestamp calculation, accounting for - differences in time between the local and the remote machine, - will now use the timestamp taken from the last KeyPress. Using - the timestamp of the last event was sometimes causing time to - go backward with the result that server could remain grabbed. - This solves the long-standing "mouse stop responding" problem. - -- Fixed a problem handling the alpha channeled visual introduced - while experimenting with the new server endianess layout. - -nxagent-1.3.2-11 - -- Added the Reset option to options repository. By default agent - will skip server reset when the last client disconnects. This is - equivalent to passing the -noreset option to a standard XFree86 - server. To restore the original behaviour the new -reset option - can be used on the command line. - -- Moved the SharedMemory and DeviceControl options to the options - repository. - -- A basic session, still leveraging all the default facilities, can - now be run as: nxagent -name NX -geometry 800x600+10+100 :1. The - -fp unix/:7100 option can be added to enable access to the X font - server. - -- Fixed a "unused variable" warning in Cursor.c. - -nxagent-1.3.2-10 - -- Rootless mode. Some cleanup in initialization. - -- Rootless mode. Working at the configure-window errors. - -nxagent-1.3.2-9 - -- Removed limitations when running nxagent nested inside another - nxagent server. Now both render extension and packing of images - are enabled. - -- The nxagent X server now inherits its endianess from the host - architecture, instead of assuming the same endianess of the con- - necting client. This fixes the remaining problems running ses- - sions nested inside another nxagent server. - -- Removed any reference to ReformatImage(). - -nxagent-1.3.2-8 - -- Changed the way the agent server handles images internally. - The inherited Xnest code used to set the server's image order - to the same order of the remote X display. This caused agent - to create images in the internal frame-buffer with a different - endianess in respect to images got from X clients. - -- The new image handling code seems to solve all the known image - endianess problems, for example cursors created on big-endian - displays with a wrong shape or glyphs being showed flipped when - retrieving the image data from the virtual frame-buffer. - -- As an added bonus the new code seems to double the performance - of the SPARC Solaris server when accessing i386 clients. - -- Commented out all the existing calls to ReformatImage(). Code - needs now extensive testing to see if any of the calls must be - actually restored. - -- Replaced calls to index() with strchr(). - -nxagent-1.3.2-7 - -- Solved a potential memory error when accessing a client or a - window pointer in clipboard management code after the resources - had been destroyed. Added a nxagentClearClipboard() function to - be called before a client or a window is destroyed to get rid - of any reference to the disposed resources. - -- Auto-repeated keystrokes generated by agent from inside the - virtual keyboard device are now ignored. Agent will correctly - honor auto-repeated keystrokes generated by the real X server. - This is actually the expected behaviour. The former implemen- - tation triggered an annoying bug, with keystrokes being inad- - vertedly auto-repeated in the case of high latency on the - network link. - -- Agent will now ignore the pointer settings changes generated - inside the remote session. The original behaviour was to reset - the pointer values (for example acceleration) to the X factory - settings at session startup. Agent will now inherit whatever - values are set on the real X display. - -- Added a -noignore parameter. When passed, agent will propagate - to the real X server any change to keyboard and pointer control - settings operated by its own X clients. - -nxagent-1.3.2-6 - -- Fixed problem with glyphs being drawn clipped in the virtual - frame buffer. This is not yet the final solution but it seems - to work in all the circumstances where problem was observed - in the past. Problem seems to be caused by scratch pixmaps - being requested with a width and height smaller than actually - required. Note anyway that pixmap's buffer seems to be never - accessed beyond its boundary. This probably means that memory - for the pixmap is originally allocated using the right size. - -- Moved backing-store selection to options repository. Now by - default the backing-store mode is set to WhenRequested. This - means that, in most cases, there is no need to pass the -bs - option on the command line. - -- Code cleanup in Render.c, NXrender.c, NXglyph.c. - -nxagent-1.3.2-5 - -- Fixed initialization of all the supported depths. Previous - versions correctly initialized the various depths but still - failed to advertise the support of any other depth than the - default depth supported by the remote X server. - -- Persistent mode. We now correctly propagate the pixmap ID of - the parent to the virtual pixmap at reconnection. This fixes - the reconnection errors when render extension is enabled. - -- Persistent mode. Solved the refresh problems at reconnection. - Problems were generated by the lack of window parent's ID at - the time session was reconnected. - -- Changed the agent's behaviour at the time the close button is - pressed. If agent is running in persistent mode a new dialog - is showed with the option to suspend the session. - -nxagent-1.3.2-4 - -- Persistent mode. At the time the proxy connection is reset the - per-client unpack geometry information is cleared. This makes - agent find out that a new unpack geometry is needed as soon as - the display is reconnected. - -- Persistent mode. Lot of logging added in order to trace use of - resources as long as they are recreated. The current version - fails to correctly restore the picture information when render - is enabled. - -nxagent-1.3.2-3 - -- Finally fixed all the problems with missing initialization of - pixmap formats. The screen info is now correctly set up even - when the remote display doesn't support all the target depths. - Many thanks to Michael L Torrie who helped me to reproduce the - problem and come to a solution. - -- Moved initialization of depths, default drawables and pixmap - formats to their own functions in Display.c. - -nxagent-1.3.2-2 - -- Fixed the nxagentDestroyPixmap() function to correctly take into - account the reference counter of the virtual pixmaps. This solves - the crashes observed when running some GTK clients like xchat. - -- Added a function Pixmap.c to forcibly destroy the pixmaps created - in the virtual framebuffer when the parent pixmap is destroyed. - -- This version contains some verbose output intended to better test - the new behaviour. The output will be removed in future versions. - -nxagent-1.3.2-1 - -- More cleanup in Pixmap.c. - -- Rewritten nxagentCreatePixmap(). Corrected an error where the - bitsPerPixel field was set to the pixmap's depth instead of the - result of BitsPerPixel(depth). This finally solves the problem - of text being incorrectly rendered in the virtual framebuffer. - -- Corrected the X error returned at the end of session when trying - to free a pixmap with an invalid id. - -- Opened the 1.3.2 branch. - -nxagent-1.3.1-32 - -- Cleanup of Pixmap.h/Pixmap.c. Renamed macros according to the - nxagent naming conventions. - -nxagent-1.3.1-31 - -- When running in fullscreen mode, grab and ungrab of pointer and - keyboard is performed in new functions, placed in Events.c. - -- The event loop now checks if the enter/leave notify carries a - NotifyInferior detail and, in this case, doesn't perform the grab. - This saves half the amount of grabs (and the related roundtrips) - performed by the previous version. - -- Ungrab of pointer is now performed whenever the cursor leaves the - fullscreen window. In previous version only the keyboard was - explicitly ungrabbed. - -- Added a warning in the event loop when receiving a MappingNotify. - This event is presently unhandled and seems to be reported, as a - consequence of the selected event mask, only by some X servers. - -nxagent-1.3.1-30 - -- Reverted the patch introduced in Pixmap.c. The whole issue is - being investigated in its ramifications up to the virtual frame - buffer. - -nxagent-1.3.1-29 - -- Fixed a problem in the nxagentDestroyPixmap function where the - reference counter of pixmaps could be decremented twice. This - could lead to agent trying to free the pixmaps more than once. - -- On Solaris there is no description for pc105 keyboard model. As - a workaround we consider pc104 to be the closest approximation. - -nxagent-1.3.1-28 - -- Fixed a bug in the create window procedure. With some clients, - like Maelstrom and xmame, the creation of the main window was - failing due to the wrong colormap and visual attributes used - by agent on the real X server. - -- In fullscreen mode the keyboard is now grabbed at the time we - receive an EnterNotify event. This fixes a problem at startup - observed on some Debian based distributions where agent didn't - receive the keyboard focus until user had minimized and then - brought to front the agent's window. The grab is now correctly - performed by using the timestamp of the remote X server ins- - tead of our local timestamp. - -- In NXdixfonts.c strings corresponding to names of fonts and - font aliases cached by nxagent were missing the terminating - zero. - -- In function InitClientPrivates fixed the missing initializa- - tion of the is_ignored member of the ClientPriv structure. - -- Added the Persistent option to Options repository. The flag is - intended to replace the old nxagentEnableReconnect variable. - -nxagent-1.3.1-27 - -- Fixed a memory allocation problem in Keyboard.c. A string was - allocated in the heap without making enough room for the trail- - ing zero. - -nxagent-1.3.1-26 - -- Added further run-time checks to verify that pixmaps are not - created with bad bit-per-plane settings. This problem seems to - be caused by lack of support by nxagent of some combinations - of depth and visual when the render extension is enabled. If - this is the case, hide the render extension to new clients and - force any subsequent render operation to return a BadRequest - error. This required including extension.c from dix. A new - NXextension.c file is added to the distribution. - -- A problem was reported by Valgrind about reading the first 4 - bytes just after the block allocated in fbCreatePixmap from - nxagentCreatePixmap. A quick fix was added to pixmap.c from - dix so that AllocatePixmap adds 4 additinal bytes to each - buffer. - -nxagent-1.3.1-25 - -- Fixed a memory corruption error. The original AllocateGlyphSet - from render/glyph.c could be called instead of the NX counter- - part defined in NXglyph.c. This could lead to the missing - allocation of the trailing remote glyphset id field. - -- Added initialization of an otherwise usused string in function - nxagentPropagateArtsdProperties(). The whole string is probably - to be removed in future versions. - -- Moved the flag used to avoid reentrancy in GCOps to a separate - Trap header and source. - -- Further cleanup. Removed the zombie file NXglyphcurs.h. - -- Added missing initialization of the picture pointer in private - window's data in nxagentCreateWindow. - -nxagent-1.3.1-24 - -- Added the missing timeout when calling WaitForSomething() at - startup. The bug caused the splash to remain on screen until - a further event was received. - -- Fixed a BadAtom error on Windows during initialization. Error - was caused by a bad attempt to change the NX_AGENT_SIGNATURE. - -- Hunting the 0 bits-per-plane drawable bug in nxagentValidateGC. - Added tracing output and additional checks. GC validation is - skipped if it is not possible to recover an appropriate value. - -- Ensured that nxagentDisplayName is set before calling the post - initialization procedure. - -nxagent-1.3.1-23 - -- When session is run nested inside another NX X agent, all the - optimizations regarding remote expose events on fully visible - windows are disabled. This solves the refresh problems encoun- - tered when covering the nested session with a window from the - local X server. - -- Reusing NX_AGENT_SIGNATURE atom to detect nested operation. - Atom is created internally to the agent server at startup, - before any atom on the real display. - -- Fixed construction of caption used for dialog boxes spawn by - agent. The previous algorithm failed to identify the correct - string in parameter -name passed on the command line. - -nxagent-1.3.1-22 - -- Ensured that state of keyboard modifiers is initialized with - values from the real X server when the first key stroke is - pressed by the user. - -- Fixed the X_SetInputFocus errors generated at session startup. - -- Rootless mode. Ensured that remote expose events are always - reported by the remote proxy. This is a temporary fix looking - forward for better handling of visibility events. - -nxagent-1.3.1-21 - -- Saved a GetWindowAttributes and a GetGeometry in the function - drawing the splash screen. - -- Better handling of splash at startup. Removed the flickering on - Windows without recurring to another atom. This is achieved by - optimizing drawing and delaying mapping of the main windows. - -- Modified the magic values activating rootless mode to 100x100. - -- Removed modifications introduced in 1.3.1-20. - -nxagent-1.3.1-20 - -- Working on eliminating the splash screen flickering on Windows - and Darwin. Checked if the NX_SPLASH atom has been created by - the NX X server. If this is the case, we let the NX X server - show the splash screen on our behalf. - -nxagent-1.3.1-19 - -- Improved the initialization phase by removing a GetProperty, an - InternAtom and two GetInputFocus round-trips. - -- Added appropriate masking of the state bits reported by the - XkbStateNotifyMask event. - -- Added a simple mechanism during the itialization phase to trace - the use of X server replies. - -nxagent-1.3.1-18 - -- Made some order in functions loading the NX icon. - -- Removed some more zombie files from agent distribution. Now only - the files imported from DIX and MI have name prepended with NX. - -nxagent-1.3.1-17 - -- Moved names and values of intern atoms created by agent in their - specific header and source. - -- We temporarily force rootless mode if user provides a geometry - of 801x601. This is intended to simplify testing. Note that if - rootless is selected, we'll anyway disregard any geometry set - by the user, assuming the geometry of the real display. - -nxagent-1.3.1-16 - -- We are checking now whether NX_IDENTITY intern atom is created - before NX_SPLASH. We want NX X servers to show the splash on our - behalf, so if NX_SPLASH is already interned, than we just skip - the splash procedure. - -nxagent-1.3.1-15 - -- Rootless mode. Fixed a segfault handling ConfigureNotify events - on top-level windows. - -- Moved handling of ClientMessages coming from proxy in a separate - function. - -nxagent-1.3.1-14 - -- Rewritten the code dealing with key modifier changes. Now we - use XKB events instead of synchronous XkbGetIndicatorState() - calls. - -- Moved activation of keyboard and pointer events to Events.c. - -- Removed pointer motion optimizations as a better logic, taking - in account the selected link speed, is already implemented in - proxy. - -nxagent-1.3.1-13 - -- Renamed the -reconnect option as -persistent. - -- Rootless mode. Agent's root windows are not mapped at startup. - -- Removed the zombie file glyphcurs.c from agent distribution. - -nxagent-1.3.1-12 - -- Corrected a typo in the new CopyArea code in GCOps.c where: - - if (srcx > nxagentWidth) srcx = nxagentWidth; - if (srcy > nxagentHeight) srcx = nxagentHeight; - - had to be: - - if (srcx > nxagentWidth) srcx = nxagentWidth; - if (srcy > nxagentHeight) srcy = nxagentHeight; - -- Added handling of the fullscreen command line parameter to the - options repository. - -- Added agent geometry parameters to the options repository. - -nxagent-1.3.1-11 - -- Rootless mode. Added handling of configuration events reported - for the top-level windows. - -- Rootless mode. Children of the root window get the event mask - selected when the window is created. This makes the keyboard - work at least with xterm and other simple clients. There are - still problems with the pointer events. - -- Created new Splash.h and Splash.c sources file to contain the - few splash screen procedures that were previously sparsed in - multiple files. - -- Added traces in all the window creation procedures and in the - initialization routines called at startup. - -- Renamed some source files to make simpler to identify what is - imported from DIX and what actually pertains to agent. - -nxagent-1.3.1-10 - -- Added the missing RestackWindow screen operation. This solves - problems of incorrect stacking order observed in menus when - using the drop shadow feature in the latest KDE versions. - -nxagent-1.3.1-9 - -- The new standard for checking previous inclusion of headers is - by verifying definition of _Filename_H_ where Filename is the - base name of the file, for example __Options_H__ in the case - of "Options.h". This is intended to be a step in reducing the - number of defines in code prefixed with NXAGENT. - -- Updated NX copyright to year 2004. Placed copyright statement - regarding NXAGENT and NX modifications to the Xnest software - at the beginning of the file. Checked again if credit is given - to all the existing copyright owners. - -nxagent-1.3.1-8 - -- Added a new Options repository to store the values currently - dispersed all over around. The new macros nxagentOption(option) - and nxagentChangeOption(option, value) should be used from now - on to access the important values affecting agent's operations. - -- General cleanup of code. Removed the remaining references to - the Xnest legacy code. - -nxagent-1.3.1-7 - -- Some steps forward toward rootless agent. Now all the top level - windows are correctly created. Drawing to the real screen seems - to work without problems. It is still not possible to get events - in the event loop and the remote WM is interfering with the WM - on the local display. - -- More cleanup of code. Some changes to parts added since 1.3.1-5. - -nxagent-1.3.1-6 - -- A drawable with 0 bpp can somehow arrive to the fb layer. The - problem needs to be better investigated. In the meanwhile a - quick check is added to correctly identify the ill condition. - -- Small fix to allow Num/Caps lock synchronization also on the - windows platform. This is still to be considered beta quality. - -- New options -slow and -fast added to agent. When "fast mode" is - not set, agent will query the remote X server to get real content - of drawables. When fast mode is enabled, agent will save the - round-trip by just clearing the drawable to its background. The - default mode is "slow", thus agent will always query the remote - server. When "fast mode" is explicitly set or when NX transport - is detected and the link is one of MODEM, ISDN and ADSL, agent - will default to "fast mode". This behaviour can be overridden by - system administrators by setting the key AGENT_EXTRA_OPTIONS_X - to "-slow" in node configuration. - -nxagent-1.3.1-5 - -- Created framework for rootless agent. Added a -rootless option. - -- Slowly going toward a better organization of nxagent internals. - Renamed some files and moved things around. Changed some comments - in Screen.c to be more explainatory. - -nxagent-1.3.1-4 - -- Changed default keyboard model to "pc102" (was "pc101") to correct - problems with "<" and ">" keys on the German keyboards and, poten- - tially on other layouts. - -- Added new parameter -kbtype to handle both geometry and layout in - a single form, for example pc102/pl. Parameter -keyboard is still - supported for backward compatibility. - -- Synchronization of Num and Caps lock status is now done comparing - the real keyboard and the internal state at the time nxagent gets - the focus. If state doesn't match, a fake keyboard event is sent. - -nxagent-1.3.1-3 - -- Fixed a further problem on CopyArea between windows and pixmaps. - -nxagent-1.3.1-2 - -- Implemented CopyArea on framebuffer when copying from windows to - pixmaps. Added the -slow command line switch to let nxagent get - the real content of the window from the X server. This requires - an expensive round-trip so it is disabled by default. - -nxagent-1.3.1-1 - -- Opened the 1.3.1 branch. - -nxagent-1.3.0-32 - -- Fixed a bug on 16 bpp displays using render extension. Now only - images which are used by render pictures and which have depth 32 - are created with a different visual color mask. This saves a big - amount of SetUnpackColormap requests. - -nxagent-1.3.0-31 - -- Fixed a bug in nxagentComposite routine. The macro nxgentPicturePriv - was used without checking for a null pointer argument. - -nxagent-1.3.0-30 - -- Limitations on bandwidth introduced whenever the agent's window - is covered are now disabled by default. They can be enabled by - specifying the -limit option on the command line. The -nolimit - option is left for compatibility with the previous versions. - This handy feature caused complaints in the past from users who - instruct window managers to not move the window having focus on - top of the stacking order. - -nxagent-1.3.0-29 - -- Removed the warnings issued at compile time. - -nxagent-1.3.0-28 - -- Replaced the corrupted file nxagent.xpm with the original version. - -nxagent-1.3.0-27 - -- Hopefully fixed all the remained memory leaks. Most problems were - due to agent's render extension not freeing resources on X server. - -- Added support for big-endian X server display on render extension. - Glyphs are reformatted according with the destination order. - -- Added per client information for SetUnpackGeometry, now the unpack - routines should have the correct information for the color mask at - the end of the split process. - - -nxagent-1.3.0-26 - -- Changed the message printed in the log when leaving the dispatch - loop from 'Error' to 'Info'. - -- Moved initialization of _NXFlushSize to nxcompext in order to set - value at the time NXGetControlParameters() is called. - -nxagent-1.3.0-25 - -- Content of selection is now acquired using a single round-trip. - If content exceeds 262144 bytes, it is truncated at that size. - This works in most situations, at least with text, that, by the - way, is the only target supported at the moment. An improvement - would be to modify the state machine in a way that the remaining - data part is got using a second round-trip. This is not difficult - to do and can be considered for future releases. - -- In handling of clipborad we had to disable check on multiple - convert selection requests from the same client. There is a bug - in the algorithm that prevents the counter to be reset at the - appropriate time. This is to be investigated. - -nxagent-1.3.0-24 - -- Added asynchronous handling of GetProperty requests and replies - using the NXCollectProperty and NXGetCollectedProperty requests - and the NXCollectPropertyNotify event in NXclipboard.c and in - Event.c. Implementation is not complete yet and can sometimes - cause X clients to misbehave. - -- Function xnestBitBlitHelper() now always returns NullRegion. - Handling of graphical expose events should be rewritten so that - regions are always generated internally to nxagent. Returning a - null region without checking our event queue, anyway, saves a - flush of the display buffer and doesn't seem to affect the - functionalities. - -- This version comprises modifications to Events.c, GCOps.c, - NXClipboard.c, NXwindow.c and Window.c where I found XSync() - messages (or code used to just send XSync() messages) outside - any #ifdef ..._DEBUG. - -nxagent-1.3.0-16 - -- A dialog is showed at startup if proxy was not able to load a - persistent cache. - -- Reflected changes introduced in NXGetControlParameters() to add - more detailed information about the compression settings. - -- Fixed a potential bug with the name of the agent's display at the - time a dialog had to be showed. String was allocated with only 6 - characters. This could lead to dialogs not being showed using - display ports greater than 9999. - -- NX.h is now included by NXControl.h. Removed #include directives - from other files. diff --git a/nxcomp/CHANGELOG b/nxcomp/CHANGELOG deleted file mode 100644 index b0323d4a7..000000000 --- a/nxcomp/CHANGELOG +++ /dev/null @@ -1,3778 +0,0 @@ -ChangeLog: - -nxcomp-3.5.0-2 - -- Fixed TR11H02398. Solved a race condition when creating channels. - -nxcomp-3.5.0-1 - -- Opened the 3.5.0 branch based on nxcomp-3.4.0-7. - -- Updated copyright to year 2011. - -nxcomp-3.4.0-7 - -- Fixed TR03H02334. Modified the UNIX domain socket checks on MacOSX - to be compliant with the standard introduced in OSX 10.6.3. - -nxcomp-3.4.0-6 - -- Solved compilation problems on Solaris. - -nxcomp-3.4.0-5 - -- Solved compilation problems on GCC 4.4. - -nxcomp-3.4.0-4 - -- Added reference to fixed TR02H02325. - -nxcomp-3.4.0-3 - -- Updated copyright to year 2010. - -nxcomp-3.4.0-2 - -- Fixed TR03G02204. Changed the parsing of X authority entries in - order to handle the case where the hostname includes white spaces. - -- Fixed TR02H02325. Bug in PNG decompression on 16bpp displays. - -nxcomp-3.4.0-1 - -- Opened the 3.4.0 branch based on nxcomp-3.3.0-4. - -- Changed version number. - -- Updated copyright to year 2009. - -nxcomp-3.3.0-4 - -- Check if the variable storing the ping time exceeded the maximum - integer value. - -- Recover incorrect sequence number when the proxy is not connected - to an agent. - -nxcomp-3.3.0-3 - -- Removed a condition in ClientChannel that caused a loss in event - sequence numbers. - -nxcomp-3.3.0-2 - -- Updated VERSION. - -nxcomp-3.3.0-1 - -- Opened the 3.3.0 branch based on nxcomp-3.2.0-7. - -nxcomp-3.2.0-7 - -- Solved a compilation problem on GCC 4.3. - -nxcomp-3.2.0-6 - -- Changes considering that unsetenv() returns void on Mac OS X. - -nxcomp-3.2.0-5 - -- Fixed TR03F02024. Assume the launchd unix socket as X socket. - -- Changed the authorization cookie retrieval when using the launchd - socket on MacOSX, in order to wait for the X server start. - -nxcomp-3.2.0-4 - -- Fixed TR03F02026. Unset environment variable LD_LIBRARY_PATH before - calling the exec function running nxclient. - -nxcomp-3.2.0-3 - -- Fix addMsTimestamp() and subMsTimestamp(). Remove the check for - a valid input in diffTimestamp() and diffUsTimestamp(). - -nxcomp-3.2.0-2 - -- Fixed TR12E01973. Now the correct number of bits are used for the - number of points in a X_FillPoly request. - -nxcomp-3.2.0-1 - -- Opened the 3.2.0 branch based on nxcomp-3.1.0-6. - -nxcomp-3.1.0-6 - -- Always use a timeout of 50 ms to update the congestion counter. - -nxcomp-3.1.0-5 - -- Solve the possible deadlock caused by both proxies running out of - tokens at the same time. - -- In ServerProxy::handleCheckDrop() copy the list since the function - can delete the elements. - -nxcomp-3.1.0-4 - -- Classes ProxyReadBuffer and ServerReadBuffer returned an invalid - number of characters to read in the case of a readable() failure. - -- Connections to proxy versions newer than 3.0.0 were not accepted. - -- Reading options from file could fail if options contained spaces - or other characters interrupting the fscanf()'s matching of input. - -- The proxy link could not be flushed if a ping request was replied - after the end of the read loop. - -nxcomp-3.1.0-3 - -- Fixed a compilation warning on GCC 2.95. - -nxcomp-3.1.0-2 - -- Solved TR09E01852. Modified the encoding of the number of rects - in the XSetClipRectangles request. - -nxcomp-3.1.0-1 - -- Opened the 3.1.0 branch based on nxcomp-3.0.0-46. - -nxcomp-3.0.0-46 - -- Fixed TR09E01865 and TR08E01831. Assume the old behavior of compr- - essing the CUPS, SMB, HTTP and Font channels when connected to an - old proxy version. - -nxcomp-3.0.0-45 - -- Retry the fork() 30 times, but only on Cygwin (Sob!). - -nxcomp-3.0.0-44 - -- In the case of an error, try again to fork() after a second, for - a maximum of 5 times. This seems to constitute a valid workaround - to the intermittent fork() failures observed on Windows. - -- Fixed NXTransDestroy() to show the 'broken connection' dialog in - the case of a link failure on the client. - -- Handled the 'terminating' and 'terminated' messages as new proxy - stages. - -- Force all the directories and files created by the library to be - readable only by the user. - -- Don't complain if the shared memory segment can't be initialized - on Windows. - -nxcomp-3.0.0-43 - -- Prevent the reallocation of the read buffer in the proxy and the - agent transport if the buffer was borrowed by an upper layer. - -- Let the house-keeping process remove the cache directories that - are empty and have not be used since more than 30 days. - -- Added the missing destruction of the ZLIB stream used for image - decompression at proxy shutdown. - -nxcomp-3.0.0-42 - -- In handleFastWriteReply(), moved the initialization of the 'next' - pointer inside the '#ifndef __sun' block. This should fix the re- - maining encoding problems on SPARCs. - -nxcomp-3.0.0-41 - -- VMWare virtual machines can have the system timer deadly broken. - In the case of timeout, try to send a ping regardless we are the - client or the server proxy to force a write by the remote. - -- Removed the messages 'Info: Using image cache parameters...' and - 'Info: Using image streaming parameters...' from the session log - if the image cache is not enabled. - -nxcomp-3.0.0-40 - -- Removed the messages 'Info: Shutting down the NX transport' and - 'Info: End of NX transport requested by...' at the session tear - down. - -- Removed the remaining log output. - -nxcomp-3.0.0-39 - -- Don't reset the timer on proxy shutdown. - -nxcomp-3.0.0-38 - -- Don't reinstall the signal handler if the signal was enabled and - the NXTransSignal() action is NX_SIGNAL_FORWARD. - -nxcomp-3.0.0-37 - -- Return a congestion level 9 if the agent channel is in congestion - state. - -- Set the idle timeout (used to update the congestion state) based - on the link type. The timeout is 0 ms with link LAN and 50 ms in - the case of MODEM, with the other values in the between. - -nxcomp-3.0.0-36 - -- Changed the encoding of the RenderCompositeGlyphs requests. Use - a separate cache for X and Y. Send a single bit for offset X and - offset Y if they match the source coordinates. - -- Always use the memcpy() in the handleFastWrite*() on Sun, as the - alternative code doesn't work on SPARC if the buffer is not word - aligned. - -nxcomp-3.0.0-35 - -- Ensure a smooth transition between different congestion states. - If the current congestion counter is greater than the previous, - ramp up the value quickly by taking the current counter. If the - new congestion counter is less than the previous, ramp down the - reported value slowly by calculating the average of the last 8 - updates. Reset the congestion counter to 0 if no token reply is - pending and the proxy is idle until a timeout. - -nxcomp-3.0.0-34 - -- Calculate the current congestion as the average of the last 3 - frames sent. - -nxcomp-3.0.0-33 - -- When sending a X_RenderCompositeGlyph update, send a single bit - if the source X and Y match the values in cache. - -- Save the check on the bytes readable from the proxy descriptor - after the select. - -nxcomp-3.0.0-32 - -- Send the X_GetImage replies uncompressed to better leverage the - stream compression. - -- Before entering in congestion state, force a read to see whether - the remote proxy aborted the connection. - -nxcomp-3.0.0-31 - -- Try to avoid using memcpy() in the channels' handleFastWrite*(). - -- Changed the copyright notices at the beginning of the files that - were referring to NXPROXY to refer to NXCOMP. - -nxcomp-3.0.0-30 - -- Set the agent and proxy descriptors as ready, when appropriate, - also in the case of an interrupt. - -nxcomp-3.0.0-29 - -- On the X server side, read more events from the X server just be- - fore and just after having written some data. On the X client si- - de, apply the same to the proxy link. - -- X11 channels originate a congestion control code as soon as the- - re is some data left from the previous write. - -nxcomp-3.0.0-28 - -- Displaced automatically the "channel unresponsive" and "no data - received from remote" dialogs if the error condition is ceased. - -- Rewritten the channel drain procedure. - -- Tried a different approach to the channel congestion handling. - The X11 channels are not drained after a blocking write but only - if a further write is requested and the channel is still in con- - gestion state. Benchmarks show that this is still sub-optimal, - compared to sending the congestion code immediately also for X11 - channels. See the next version. - -nxcomp-3.0.0-27 - -- Ignored the agent option 'defer'. - -- Dropped support for the 1.4.0 versions. - -- More fixes to support the 1.5.0. - -nxcomp-3.0.0-26 - -- The channel read buffer can inherit the data to be encoded from - the caller, instead of taking it from the transport. This is le- - veraged by the agent channel to save the copy. - -- Ignored the agent option 'clients'. - -- Removed the deprecated code checking the CPU limits. - -- Removed the counters that were duplicated in the Statistics and - the Control classes. - -nxcomp-3.0.0-25 - -- Improved the effectiveness of the caching of the RenderComposite- - Glyphs by using a differential encoding for the length, delta x - and delta y of the first string. - -- Better handle the compatibility between different formats of the - cache files. - -nxcomp-3.0.0-24 - -- Fixed the compatibility problem with the 1.5.0 versions. - -- Removed the constants NXDisplayReadable, NXDisplayFlushable and - NXDisplayCongestion. Now nxcompext has three distinct functions. - -nxcomp-3.0.0-23 - -- Removed support for Rdp, Tight and Hextile packed images decod- - ing since they have been made obsolete by the new NX server. - -- Use the value 0 for the action is_hit and 1 for is_added. This - increases the frequency of zeroes in the encode buffer, giving - better compression. - -- Changed the copyright attribution from Medialogic to NoMachine. - -nxcomp-3.0.0-22 - -- Implemented an alternate encoding reducing the size of the int - caches to 16 elements and transmitting the values in blocks of - 4 bits. Although this encoding reduces the effectiveness of - the differential compression, it allows better compression of - the final stream, resulting in a 10% to 20% gain in all condi- - tions. The new encoding is experimental, as it would make the - 3.0.0 incompatible with all the previous NX versions. Use this - package as a reference for future implementations. - -nxcomp-3.0.0-21 - -- Encode the first two coordinates of a FillPoly message by using - a differential encoding, thus the origin of the polygon is not - included in the checksum. This is aimed to work in combination - with the agent converting all the FillPoly requests to the rela- - tive coordinate mode. - -- Add the coordinate mode to the checksum of the PolyPoint and Po- - lyLine messages so that it doesn't need to be encoded separately. - -- Disable the streaming for all messages. This saves the encoding - of a boolean for each message that could potentially be streamed. - -- Don't try to match the block size when encoding a value based on - an IntCache. This saves the additional bool in 90% of the cases. - -- Removed support for the former RDP and RFB session types. - -- Due to the above changes, this version is incompatible with the - previous 3.0.0 releases. - -nxcomp-3.0.0-20 - -- Added support for the 'lossy', 'lossless' and 'adaptive' pack me- - thod literals. These values activate the dynamic selection of the - pack method by the agent. - -- Made the 'adaptive' pack method the default for all link types. - -- The default stream compression level is now 6 for link type ISDN, - 4 for ADSL and 1 for WAN. The default data compression level is - always 1, except for LAN that is 0. - -nxcomp-3.0.0-19 - -- Print in the session log the X11 display that the proxy is imper- - sonating or where it is forwarding the connections. - -nxcomp-3.0.0-18 - -- Implemented decoding of the PACK_BITMAP_16M_COLORS pack method. - This is a very simple encoder removing the 4th byte in 32 bits- - per-plane images. This encoder is intended to better leverage - the stream compression on low bandwidth links. - -- Removed the code cleaning the padding bytes in RenderAddGlyphs - and RenderCompositeGlyphs as the operation is now performed in - Xrender. - -- Removed the "Info: Synchronizing local and remote caches." and - "Info: Using remote server '...'." lines from the session log. - -nxcomp-3.0.0-17 - -- Determine the CPU endianess at compile time only on Linux and - Cygwin. - -nxcomp-3.0.0-16 - -- Optimized the memory allocation of the ReadBuffer classes. The - buffers from the Transport classes are used, when possible, to - avoid the copy. - -nxcomp-3.0.0-15 - -- Reworked the code dealing with the channel congestion control - messages for increased efficiency. - -- Removed the pending_ flag from the proxy and channel class mem- - bers. If needed, the classes will query the transport buffers - to see whether there is data pending. - -- Removed the additional parameter from NXTransFlush(). - -- The proxy doesn't issue anymore a sync control message on a X - reply. Anyway it will respond to the request for compatibility - with older versions. - -- Removed the dynamic selection of the encoding method for the - X_QueryColors request and X_ListFonts, X_QueryColors, X_Query- - Font replies. Now all of them use the differential encoding to - better leverage the stream compression. - -- Fixed to build on SUNs where we don't have endian.h. - -nxcomp-3.0.0-14 - -- When handling partial proxy messages, don't try to determine how - many bytes still need to be read if the ZLIB stream compression - is enabled. - -- If a message can't be located, the ReadBuffer class checks if it - is possible to consume the data already in the transport buffer. - -- Optimize the MD5 routines by determining the CPU endianess at - compile time. - -- Force Drawable and GContext to be CARD32 in NXproto.h. - -nxcomp-3.0.0-13 - -- Changed the semantic of the NXDisplayFlushHandler callback. The - function is called when new data is sent to the remote proxy or, - with a 0 length, upon receiving a new token reply, so that the - agent can update its congestion state. - -- Added the NXTransCongestion() function. It returns a value bet- - ween 0 and 9 indicating the congestion level based on the tokens - remaining. A value of 9 means that the link is congested and no - further data can be sent. - -- Removed the congestion and synchronization callbacks. They are - superseded by the new NXTransCongestion() implementation. - -nxcomp-3.0.0-12 - -- Send the token replies at the end of the encode loop instead of - flushing the buffer immediately. - -- Fixed TR05E01687. Correctly detect CTRL-ALT-SHIFT-ESC keystrokes. - -- Renamed the option 'block' as 'tile'. - -- Ignored the option 'menu', targeting the X11 agent. - -nxcomp-3.0.0-11 - -- Removed the 'interactive' attribute from generic channels. We now - use the 'prioritized' attribute which yields the same result. - -- Simplified the channels' read loop by always reading only once. - -- The channels flush the link as soon as the token is exceeded even - if the flush policy is set to deferred. - -- Reserved more cache memory for the images when running a shadow - session. - -nxcomp-3.0.0-10 - -- Added the NXDisplayWriteHandler callback definition. - -- Removed the code that forced the proxy to retain in the cache the - images referenced at session startup. - -- Disabled the persistent image cache since this is not supported - by the current agent. This will save the overhead caused by the - image house-keeping process. - -nxcomp-3.0.0-9 - -- Fixed a cast problem in GetBytesReadable(). - -nxcomp-3.0.0-8 - -- Added the NXTransTime() utility. It return the time in milliseconds - elapsed since the last call to the same function. Useful for bench- - marking the Xlib layer. - -- Ignored the option 'block' targeting the X11 agent. - -nxcomp-3.0.0-7 - -- Ignored the options 'shadow', 'shadowmode' targeting the X11 agent. - -- Added the session type 'shadow'. - -nxcomp-3.0.0-6 - -- Fixed TR08D01484. Fixed a bug in the cleanup of the RenderAddGlyphs - messages. We clean up only the glyphs with depth 8, width greater - than 1 and pixmap byte pad 4. - -- Added file COPYING. - -nxcomp-3.0.0-5 - -- Updated the copyright notices to the current year. - -nxcomp-3.0.0-4 - -- Imported changes up to nxcomp-2.1.0-6. - -- Fixed TR12D01563. Changed the configure script to always build the - library with the -fPIC option. This is related to the way SELinux - works. - -- Fixed the dependency from local endianess for 16-bit color RDP un- - packing functions. This caused wrong colors to be displayed when the - proxy and the X server were running on two separate machines having - different endianess. - -- Fixed TR10D01523. The Channel::handleDrain() method now accounts - for the fact that agent connections can't be drained. - -- Changed the Tight and Hextile decoding functions to use the X ser- - ver's byte order. - -nxcomp-3.0.0-3 - -- Changed the main loop to handle the 3.0.0 version. - -nxcomp-3.0.0-2 - -- Updated the file VERSION. - -nxcomp-3.0.0-1 - -- Opened the 3.0.0 branch based on nxcomp-2.0.0-81. - -nxcomp-2.0.0-81 - -- Fixed the dependency from local endianess for JPEG and PNG decomp- - ression functions. This caused wrong colors to be displayed when - the proxy and the X server were running on two separate machines - having different endianess. - -- Fixed the number of entries in the handleColormap() function. - -nxcomp-2.0.0-80 - -- Fixed TR06D01404. Removed the warning issued when calling the - AgentTransport::drain() method. - -nxcomp-2.0.0-79 - -- Updated copyright to year 2006. - -nxcomp-2.0.0-78 - -- Fixed a bug in the cleanup of the RenderAddGlyphs messages. - -- Minor improvements to the encoding of the RenderCompositeGlyphs - and RenderComposite requests. - -- Added 'client' to the list of the ignored options. - -nxcomp-2.0.0-77 - -- Added cleanup of the padding bytes in the RenderCompositeGlyphs - and RenderAddGlyphs requests. - -nxcomp-2.0.0-76 - -- Before adding the frame's bytes to the tokens, the frame length - is normalized based on the stream compression ratio of the last - frame sent. This avoids entering the drain loop too early when - the data is highly compressible. - -- Moved the render messages' private data in a union to reduce the - footprint of the render store. - -nxcomp-2.0.0-75 - -- The action performed on the remote message store and the affected - position are encoded as a single value. This saves approximately - 1 bit per each message. - -- Created more Compat classes to handle the backward compatibility - with the 1.4.0 and 1.5.0 versions. - -nxcomp-2.0.0-74 - -- Added support for the RLE pack method and made it the default if - the selected link type is LAN. - -- Removed the legacy support for the 'render' option provided at X - server side. - -- When defining LAME in ClientChannel.h, the channel has the chance - of suppressing more opcodes by the handleTaintLameRequest() call. - This is for test purposes. - -nxcomp-2.0.0-73 - -- The X_NXSetUnpackColormap and X_NXSetUnpackAlpha now carry their - data in compressed form. The alpha data is compressed using the - ZLIB RLE encoding, while the colormap data is compressed using - the default ZLIB deflate. - -- Thanks to the above changes, ZLIB data compression of all messa- - ges which do not have a specific encoding is turned off, so that - we can make better use of the final stream compression. - -- Created new message structures to handle the compatibility with - the old proxy versions. When connected to an old proxy version - the agent should use the NXSetUnpackColormapCompat() and NXSet- - UnpackAlpha() interfaces. - -nxcomp-2.0.0-72 - -- Solved a compatibility problem with the 1.X.X versions due to the - new render encodings. - -nxcomp-2.0.0-71 - -- Improvements to X_RenderSetPictureClipRectangles. - -- Fixed handleUnpack() to pass the correct byte order parameter to - to the unpack alpha function. - -- Added the --parent parameter to the client even in pulldown mode. - -- Fixed a deallocation bug in StaticCompressor. - -nxcomp-2.0.0-70 - -- Added compression of X_RenderSetPictureFilter, X_RenderSetPicture- - Transform, X_RenderTrapezoids and X_RenderTriangles. - -nxcomp-2.0.0-69 - -- Changed the format of the persistent cache to accommodate the new - encoding of the render opcodes. Caches from the 1.4.0 and 1.5.0 - should be still loaded and saved correctly when connected to and - old version of the library. - -- Improved the encoding of the X_CreatePixmap, X_ChangeGC, X_Render- - CompositeGlyphs, X_RenderComposite, X_RenderCreateGlyphSet, X_Rend- - erFreePicture and X_RenderCreatePicture messages. Added new classes - to handle the backward compatibility. - -- Made the static compression and decompression code reside in the - same class. - -nxcomp-2.0.0-68 - -- Improved the encoding of the X_RenderCreateGlyphSet and X_Render- - FreeGlyphSet requests. - -nxcomp-2.0.0-67 - -- Modified the following session messages: - - From: "Session: Session starting at..." - To: "Session: Starting session at..." - - From: "Session: Session terminating at..." - To: "Session: Terminating session at..." - -- Improved the encoding of the requests creating or freeing an XID. - This affects X_CreateGC, X_CreateWindow, X_CreatePixmap, X_Render- - CreatePicture, X_FreeGC, X_DestroyWindow, X_FreePixmap, X_Render- - FreePicture. - -- Added 'streaming' and 'backingstore' to the list of options used - by agents. - -- Modified the info messages to print the ZLIB compression paramet- - ers to be more compact and only use two lines. - -nxcomp-2.0.0-66 - -- When part of an agent, the proxy will wait for the NXTransDestroy() - function to initiate the shutdown. - -nxcomp-2.0.0-65 - -- Starting from this version the NX client can control the behaviour - of the client proxy by monitoring the messages marked as "Session". - - At the early initialization the proxy will print: - - "Session: Session starting at '...'. - - The ellipsis here represent the current timestamp, as reported by - the POSIX function ctime(): - - Once the session is running, the proxy will print: - - "Session: Session started at '...'. - - At the time the session is being shut down, the proxy will print: - - "Session: Session terminating at '...'. - - Followed by: - - Session: Session terminated at '...'. - - The message "Info: Starting X protocol compression." is removed, - replaced by the message 'Session started at...' with the same - meaning. - - Once the message 'Session: Session terminated at..." is read from - the output, the client can optionally wait for the proxy process - to complete and terminate with an exit code 0. - -- The "Session" messages are not printed when the proxy is running - on the NX server side, as part of an agent. - -nxcomp-2.0.0-64 - -- Reduced the default token limit from 32 to 24. The synchronizat- - ion callback is triggered by the tokens going below half the li- - mit. - -nxcomp-2.0.0-63 - -- Added -I/usr/include/c++ to makedepend. - -nxcomp-2.0.0-62 - -- The house-keeping process is now started upon the initialization, - if the memory cache is enabled, and, on the X server side, when - the remote actually requested access to the image cache. - -nxcomp-2.0.0-61 - -- Added a NX_HANDLER_SYNCHRONIZATION callback to NXTransHandler(). - The handler is called when the agent can use the available band- - width to synchronize X objects that are corrupted or incomplete. - - The reason can be: - - NX_SYNCHRONIZATION_BEGIN: The synchronizationis is allowed. - - NX_SYNCHRONIZATION_END: The synchronizationis must stop. - - The reason can be determined by agents by using the NXBeginSynch- - ronization and NXEndSynchronization values defined in NXvars.h. - -- Bytes from 14 to 24 in the X_NXGetControlParameters reply report, - respectively, the frame timeout, the ping timeout, the preferred - image split mode and the split size threshold. - -nxcomp-2.0.0-60 - -- The following messages used by the NX client and server have been - changed. The NX client and server should be modified accordingly. - - From: "Info: Shutting down the link and exiting." - To: "Info: Shutting down the NX transport." - - From: "Info: End of session requested by remote proxy." - To: "Info: End of NX transport requested by remote" - - From: "Info: End of session requested by agent termination." - To: "Info: End of NX transport requested by agent." - - From: "Info: End of session requested by signal '...'." - To: "Info: End of NX transport requested by signal '...'." - - From: "Info: Shutting down the link and exiting." - To: "Info: Shutting down the NX transport." - - From: "Info: Waiting for cleanup timeout to complete." - To: "Info: Waiting the cleanup timeout to complete." - - From: "Info: Waiting for watchdog process to complete." - To: "Info: Waiting the watchdog process to complete." - -nxcomp-2.0.0-59 - -- Added more debug information regarding the timing of packets sent - and received. - -- Added the possibility to redirect the log output to a file that can - be later shared with nxssh running in "binder" mode. This is useful - when testing the forwarding of the SSHD connection by nxssh to the - agent. Activated by defining BINDER in Loop.cpp. - -nxcomp-2.0.0-58 - -- Fixed the unpack alpha procedure to only rely on the image's byte - order. - -- Solved the X_PutImage encoding problem introduced in the 2.0.0-56 - version and restored the compatibility with the 1.5.0 version. - -nxcomp-2.0.0-57 - -- Added a NXTransFile() function. It returns the name of the files - used by the proxy for the current session. - - The type parameter can be: - - NX_FILE_SESSION: Usually the file 'session' in the user's session - directory. - - NX_FILE_ERRORS: The file used for the diagnostic output. Usually - the file 'errors' in the session directory. - - NX_FILE_OPTIONS: The file containing the NX options, if any. - - NX_FILE_STATS: The file used for the statistics output. - - The returned string is allocated in static memory. The caller must - copy the string upon returning from the function, without freeing - the pointer. - -- Fixed the PANIC in the handling of the abort split messages. - -- The encode and decode routines may write one byte past the nominal - end of the encode buffer. This additional byte is now included in - the payload. This is actually a bug, but harmless. - -nxcomp-2.0.0-56 - -- Added the X_NXAbortSplit request. It can be used to interrupt the - streaming of all the messages currently in the split store for - the specified resource. Depending if the split store did or did - not contain split messages, the client will receive an immediate - end-split or no-split notification. - -- Removed the split modes NXSplitModeEager and NXSplitModeLazy. The - available modes are now NXSplitModeSync and NXSplitModeAsync. The - mode NXSplitModeAsync replaces the two old modes and is now the - default. Similarly to NXSplitModeEager, it makes the proxy split - only messages that exceed a size threshold, but the threshold is - generally smaller than in the previous versions. - - #define NXSplitModeDefault 0 - #define NXSplitModeAsync 1 - #define NXSplitModeSync 2 - -- Renamed X_NXSplit to X_NXSplitData, X_NXAbortSplit to X_NXSplitEv- - ent. - -- The proxy now enters a drain loop, when in congestion state, and - waits until the decongestion. Also the X channels are drained if - blocked. - -- The select is restarted immediately if only the proxy is selected - and the data read doesn't make a complete message. - -- The size of the shared memory segment used by the X server proxy - is now negotiated at startup and the selected value is printed in - the session log. - -- Added the option 'encrypted'. It tells the local proxy if it is - running as part of a program providing encryption of the point to - point communication. This is useful to determine if the proxy can - block waiting for data or needs to yield to the client to let it - handle the remote connection. - -nxcomp-2.0.0-55 - -- Fixed handleRestart() to correctly send the end-split event only - after the split sequence has been closed by the client. - -- Fixed a possible memory error in the Keeper class occurring if the - image caches were erased while in the middle of a loop. - -nxcomp-2.0.0-54 - -- Added a '--parent' option when running the client in dialog mode. - This is the process id that needs to be signaled in the case the - user chooses to do so. - -nxcomp-2.0.0-53 - -- Solved a bug in the abort split procedure. The procedure assumed - that the split had to be at the head of the list. This may not be - the case if the split was loaded from disk asynchronously, after - a different split with the same checksum was recomposed. - -- By defining STRICT in Loop.cpp, the number of available tokens is - set to 1. This can be used to trigger the congestion more often - than it would possible when testing the software with the default - settings. - -- Added more debug output to the procedures handling the streaming - of the images. - -- Reset the channel's split pending and congestion flags in the fin- - ish procedure. Not doing so caused some additional loops at chan- - nel shutdown. - -- Fixed a bug on Cygwin that prevented the log files to be succes- - sfully reopened when the size limit was exceeded. - -- Failures to write to the agent transport are reported sooner when - the channel is finished. This saves a few more loops at session - shutdown. - -nxcomp-2.0.0-52 - -- Started implementing a new handler to let the agent include arbit- - rary data in the transport statistics. The parameter, in this case, - is a pointer to a pointer to a null terminated string. The pointer - is set at the time the handler is registered. The pointed string - will have to be filled by the agent with its statistics data. For - now, only the interfaces and the stubs exist. - -- Disabled the timestamp cache as it still causes rounding problems - when calculating the current bitrate. - -nxcomp-2.0.0-51 - -- Removed SelectPackMethod(), not used anymore, from Pack.c. - -nxcomp-2.0.0-50 - -- Added the X_NXFinishSplit request. It forces the proxy to comple- - tely transfer all the split messages for the given resource, and - then notify the agent. - -- Fixed the statistics to not account the split bits to the control - token. - -nxcomp-2.0.0-49 - -- Fixed a bug that caused the split timeout to be reset even if a - different channel had splits to send. - -- Removed an error condition that arose when a split operation was - requested by a different channel than the first to connect. The - reason is that an auxiliary channel (like the one created by the - server to store the keyboard configuration) can be the first to - open a connection to the X server, then can come the agent, that - is actually using the NX opcodes. The proxy will now simply print - a debug message. - -- Removed a further error condition that was assumed by the proxy - if a pending flush was detected while no channel was selected for - output. This can actually happen if the channel was dropped and, - in the meanwhile, the user requested the proxy statistics. - -nxcomp-2.0.0-48 - -- Added a 'type' parameter to NXTransFlush(). The new NX_FLUSH_IDLE - type should be used by agents when they have finished handling all - their clients and are going to wait for more input. This is the - case, for example, of the X agent returning from WaitForSomething() - after having set a small timeout to find out if there are clients - ready, or the case of a RDP agent finding that there are no opcodes - to read from the RDP server. The 'idle' flush should be requested - also when the X11 agent is waiting for a split to complete. When - the flag is used, the proxy uses the available bandwidth to encode - more low-priority data, like the payload of images being streamed. - -nxcomp-2.0.0-47 - -- Added a new RGB image encoder. For now the encoder uses a static - Z stream to compress the image data in the destination buffer and - allows the agent to use the simplest encoding by still separating - the alpha channel from the image data. The new encoder can be the - the base for implementing color reduction by dithering or a color- - mapped translation of the image similar to PNG, but without the - PNG overhead and with the colormap being sent to the client using - the NXSetUnpackColormap() opcode. - -- Put the routines implementing static deflating and inflating of - a ZLIB buffer from the Compressor and Decompressor classes to Z.h - and Z.cpp, so that they can be reused by the new RGB encoder. - -nxcomp-2.0.0-46 - -- Fixed a segfault arising when trying to start a child without the - NX transport. - -nxcomp-2.0.0-45 - -- Undefined the MATCH directive. - -nxcomp-2.0.0-44 - -- Changed the encoding of the X_CreatePixmap, X_CreateGC, X_Render- - CreatePicture, X_CreateWindow, RenderCreateGlyphSet.cpp. The Xid - of the drawable is included in the checksum of the X_CreateGC and - X_CreatePixmap message. This leverages the way GC and Pixmaps are - allocated in the X agent to obtain better compression. - -- Removed the code handling the reset of the proxy connection. This - functionality was unused since when the persistence is handled by - the agent. - -- Added a specific section in the statistics output for the render - extension. - -nxcomp-2.0.0-43 - -- Fixed a bug that could have caused the sending of multiple 'end - split' messages for the same split sequence. - -- Added handling of the option 'strict'. - -nxcomp-2.0.0-42 - -- Added a missing channel switch directive when encoding abort split - messages at the server side. This could cause a decoding error on - the client. - -nxcomp-2.0.0-41 - -- Ensured that the link is flushed immediately on the X server side - when important keyboard or mouse activity is detected in input. - -- Implemented a timestamp cache to avoid calling gettimeofday() when - it is enough to use the last timestamp gotten from the system. The - cache can be disabled by undefining CACHE_TIMESTAMP in Timestamp.h. - -nxcomp-2.0.0-40 - -- Added the karma delay field to the X_NXGetControlParameters reply. - -- Solved a bug with the decoding of split messages likely to happen - only when using link type LAN. - -nxcomp-2.0.0-39 - -- Implemented separate flow control for the generic channels and the - image streaming data. - -- Improved the split procedure to load a message from the disk cache - if found after it was originally discarded because locked. - -nxcomp-2.0.0-38 - -- Renamed the 'shmem' option as 'shseg'. The 'shmem' option becomes - specific to the agent and will be used together with 'shpix' option - to indicate if, respectively, the shared memory extension and the - use of the shared pixmaps must be enabled in the agent server. The - new option will be instead used by the proxy to determine the size - of the memory segment shared between the proxy and the X server. - -- Added the 'shmem', 'shpix', 'keyboard' and 'clipboard' to the list - of ignored options. The 'keyboard' option should become a synonym - of 'kbtype'. The 'clipboard' option will tell the NX agent if the - clipboard support should be disabled for security reasons. - -nxcomp-2.0.0-37 - -- Ensured that, when running a raw session, the persistent cache is - loaded and saved only once in the session lifetime. - -- Added the 'product' keyword to the list of recognized options. The - option is ignored by the proxy, but can be used by the client or - server to facilitate the support. - -nxcomp-2.0.0-36 - -- Added the remote version number in the X_NXGetControlParameters - reply. - -- Solved a bug related to the removal of the split stores. - -- Removed the unused code dealing with the flush timeouts. - -nxcomp-2.0.0-35 - -- Added an alert to notify the user about the failure of the XDMCP - session. - -nxcomp-2.0.0-34 - -- The active channels and the agent resources are now stored in a - list container. - -- Added the X_NXFreeSplit request. The request is currently unused - because the split store is freed automatically when it becomes - empty, but can be useful in future if we want to implement other - otpimizations. - -nxcomp-2.0.0-33 - -- There is now a split store for each agent resource. This allows - the proxy to divide the bandwidth among the agent resources. - -- A simple round-robin load-balancing is implemented, dividing the - bandwidth equally among all the split stores. - -- If there is a previous request being streamed for the same res- - ource, cached messages are appended to the split store and then - committed in the original order. This makes possible to stream - the colormap and the alpha channel data even if the split invol- - ves multiple PutImage or PutPackedImage operations in a single - start-split/end-split sequence. - -- Implemented the commit store class. Made the commit store expand - the message in the final buffer, instead of leveraging the mes- - sage store. - -- Channels having a drop command pending are checked before trying - to load or save the cache. This prevents a potential problem with - the protocol violation error that could be reported by the client - side proxy. - -- The current bitrate is now calculated at the time the transport - actually writes the data to the network, not at the time the data - is appended to the transport by the upper layers. The reason is - that the data can be compressed by the stream compressor and so - we can calculate the real bitrate only after having flushed the - ZLIB stream. This fixes the wrong numbers that could be reported - by the statistics in the previous versions. - -nxcomp-2.0.0-32 - -- More progress in the implementation of the new image streaming. - This version has been tested to work when connecting to an 1.5.0 - server. Due to the significant changes in the way the streaming - works in the newer versions, split is never activated by a 2.0.0 - server connecting to a 1.5.0 client. - -- Fixed the NXTransClose() function to check if the fd matches the - NX agent connection. - -- Fixed the includes in Socket.h to compile on Solaris and MacOSX. - -nxcomp-2.0.0-31 - -- Changed the NX transport functions that didn't require a NX fd - parameter to include one. The value can be NX_FD_ANY to signify - any running NX transport. - -nxcomp-2.0.0-30 - -- More progress in the new implementation of image streaming. - -- This version is apparently compatible with the 1.5.0 client but - needs further testing. - -nxcomp-2.0.0-29 - -- Implemented the NXTransHandler() interface and made the proxy - use the callback, when it is installed, instead of the notifi- - cation events. - -- Modified the agent transport to report an EOF condition as soon - as the channel is dropped, instead of reporting the error only - after the proxy shutdown. This allows the agent to handle its - clients while the proxy is handling the grace timeout. - -- Added a test facility to verify if the client and server caches - match at shutdown. - -- More advances in the new implementation of streaming. - -nxcomp-2.0.0-28 - -- Made the session shutdown faster, normally below 1 second. The - grace time is now 500 ms once all channels have been dropped. - -nxcomp-2.0.0-27 - -- The house-keeping process will now run a number of iterations - (currently 100) and then will exit. The proxy will check the - exit code and, if it was requested by the child, will restart - it. This is intended to keep the memory consumption low, as I - noted that after a big number of iterations the performance of - the allocator start to degrade quickly. - -nxcomp-2.0.0-26 - -- Started implementing the NXTransHandler() interface to let the X - application hook a callback and be notified by the proxy when an - event occurs. At the moment only congestion events are supported. - The interface makes possible for the caller to provide a generic - parameter. This parameter is passed back to the handler function. - The parameter is expected to be the Xlib display pointer, given - that the proxy doesn't have access to the Xlib structures. - -- Moved all the internal variables shared between Xlib, nxcompext - and the X server in nxcomp. Declarations and function prototypes - moved to NXvars.h. - -- Removed the NXGetCleanupParameters() and NXGetImageParameters() - interfaces and the remaining references to the unused display - buffer and image cleanup functions. - -- In this version the images streaming functionality is disabled. - Because of that, expect compatibility problems when connecting - to a different nxcomp version. - -nxcomp-2.0.0-25 - -- Forced the end of the session earlier if a shutdown has been re- - quested by the local side but the remote proxy is not responding. - -nxcomp-2.0.0-24 - -- Changed the loop deleting the file items in Keeper to pick the - first element instead of looping through the iterator. - -- More problems with the libstdc++ allocators. During the tests, I - found that the Keeper class can leak industrial amounts of memory. - Valgrind says that the objects that are not freed are the File - items we allocate in collect(). As this looked suspicious, I log- - ged the constructors and destructors and can say that everything - is OK on our side. Unfortunately, by removing the spleeps used - to let the program work silently in background, one can find that - the memory occupation still grows by a MB every few seconds. This - is less a problem on Windows, where the memory occupation remains - almost constant. See the comment on __USE_MALLOC below. - -- Increased the maximum size of a message that the proxy is allo- - wed to cache to 4MB. This makes possible to cache many replies - (like the X_QueryFont replies) that often exceeded the previous - limit. - -nxcomp-2.0.0-23 - -- Fixed a compatibility problem with the 1.5.0 that arose when - encoding an image with caching and streaming temporarily disa- - bled. - -- Removed the __USE_MALLOC define in Types.h because this is what - the g++ developers want. I'll try to avoid flames and will not - comment on this. - -- Added a --with-use-malloc configure option. This option should - be used when building the release packages on GCC versions that - support it. - -- Started fixing the commit procedure to be able to deal with the - alpha channel. - -nxcomp-2.0.0-22 - -- Prevented channels from being dropped while in the middle of a - read loop. - -- Added a small utility ensuring that the SIGCHLD we receive in - the main loop can be always identified as pertaining to an our - child. - -- Increased the space available for the control messages at the - beginning of the encode buffer and ensured that there is always - enough space for adding a token message, in the case this is - required by the flush procedure. - -- Made all cache files readable only by the user. - -nxcomp-2.0.0-21 - -- Solved a bug in the streaming of images that caused the agent's - clients to never resume when connected to an old proxy version. - -nxcomp-2.0.0-20 - -- Disabled again streaming of the alpha channel data. By enabling - it, the agent randomly fails to repaint the exposed regions. The - reason is to be investigated. - -nxcomp-2.0.0-19 - -- Implemented the split mode NXSplitModeSync. When this mode is - selected, the proxy will not send data for the split at the head - of the list until the remote peer has confirmed that the message - is not available in the image cache. This is going to be useful - in combination with the lazy encoding. - -- Improved the error detection in the case of failure when saving - a recomposed split on disk. - -- Added X_NXSetUnpackAlpha to the set of requests that is possible - to stream. - -nxcomp-2.0.0-18 - -- Enabled the 2.0.0 features that were disabled for test purposes. - -- Changed the LICENSE file to state that the software is only made - available under the version 2 of the GPL. - -nxcomp-2.0.0-17 - -- Introduced a new channel of type 'slave'. Opening a slave channel - should let the proxy fork a new NX client instance (or whatever - is in the NX_SLAVE environment) and pass to it the channel's desc- - riptors. This client instance should authenticate the peer, for - example using the proxy cookie (see how this is implemented in - nxsensor) and then negotiate the service to be used on the channel. - This can be used to implement forwarding of arbitrary ports or ad- - ditional services, like a simple file transfer protocol. For now - the implementation is incomplete. Opening a slave channel will - result in the remote proxy just dropping the channel connection. - -- The proxy is forcibly flushed at the end of each loop. This is a - temporary fix until the agents are updated to flush the proxy link - on demand. - -- Added a new alert to be used in the case the RDP session is closed - and replaced with a new session using the same Windows account. - -- Added a forward declaration of class RenderMinorExtensionStore in - file RenderExtension.h to compile using gcc 4.0.X. - -- Added removal of all .orig file when running a 'make clean'. - -- The code uses again the 2.0.0 style shutdown (the one waiting for - the watchdog process to terminate). - -nxcomp-2.0.0-16 - -- Added the NXTransChannel() interface to allow agents to create - new channels connected to the port that will be forwarded by the - remote proxy. The function returns 1 on success, 0 if the NX - transport is not running, or -1 in the case of error. On success, - the descriptor provided by the caller can be used for all the - subsequent I/O, including selecting the descriptor to check if - I/O is possible. The type parameter not only tells to the proxy - the remote port where the channel has to be connected, but gives - a hint about the type of data that will be carried by the channel, - so that the proxy can optimize the compression and schedule the - traffic on the slow link. - - The type can be: - - NX_CHANNEL_X: The channel will carry X traffic and it - will be connected to the remote X display. - - NX_CHANNEL_CUPS: The channel will carry CUPS/IPP protocol. - - NX_CHANNEL_SMB: The channel will carry SMB/CIFS protocol. - - NX_CHANNEL_MEDIA: The channel will transport audio or other - multimedia data. - - NX_CHANNEL_HTTP: The channel will carry HTTP protocol. - - NX_CHANNEL_FONT: The channel will forward a X font server - connection. - - Only the proxy running at the NX server/X client side will be - able to create a X, CUPS, SMB, MEDIA and HTTP channel. A proxy - running at the NX client/X server side can create font server - connections. The channel creation will also fail if the remote - end was not set up to forward the connection. - - To create a new channel the agent will have to set up a socket- - pair and pass to the proxy one of the socket descriptors. - - Example: - - #include - #include - - int fds[2]; - - if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) - { - ... - } - else - { - // - // Use fds[0] locally and let the - // proxy use fds[1]. - // - - if (NXTransChannel(fds[1], NX_CHANNEL_X) <= 0) - { - ... - } - - // - // The agent can now use fds[0] in - // read(), write() and select() - // system calls. - // - - ... - } - - Note that all the I/O on the descriptor should be non-blocking, - to give a chance to the NX transport to run in the background - and handle the data that will be fed to the agent's side of the - socketpair. This will happen automatically, as long as the agent - uses the XSelect() version of the select() function (as it is - normal whenever performing Xlib I/O). In all the other cases, - like presumably in the agent's main loop, the agent will have - to loop through NXTransPrepare(), NXTransSelect() and NXTrans- - Execute() functions explicitly, adding to the sets the descript- - ors that are awaited by the agent. Please check the implementa- - tion of _XSelect() in nx-X11/lib/X11/XlibInt.c for an example. - -nxcomp-2.0.0-15 - -- Some changes aimed at finding a workaround to the unreliability - of the font server connections. The X server seems to be really - picky about the network latency, so we try to read immediately - from the channel just being created, instead of waiting for a - new loop. Additionally the proxy will keep reading from the font - server connections even after the maximum length of the frame - is exceeded, in the hope that it will be able to send a complete - message in a single frame. - -- updated the various internal consistency tests run when the TEST - or INFO flags are enabled. - -nxcomp-2.0.0-14 - -- It seems that the closure of the socket sometimes takes several - seconds, on Windows, after the connection is broken, with the - result that the alert can be shown long after the user has gone - after the failed session. We now skip the closure of the proxy - link on Windows if we are about to exit. - -- The code uses the 1.5.0 style shutdown (the one waiting for the - term signal in the main process) to be able to test the library - with the old server. To activate the new shutdown procedure be - sure the define SHUTDOWN_COMPATIBLE_1_5_0 is unset. - -nxcomp-2.0.0-13 - -- Ensured that static members in channels are reset at the time a - new proxy is created. - -- Adjusted the token parameters for link modes other than modem. - -nxcomp-2.0.0-12 - -- Handled compatibility with 1.X.X versions not sending the count - field in the token. - -- The proxy link is now flushed automatically if the agent has not - set the deferred flush mode. - -nxcomp-2.0.0-11 - -- Significant modifications to allow the proxy to keep data in the - encode buffer across multiple loops, until the data is flushed - because an explicit request by the agent or. Besides maximizing - the amount of data sent in a single frame, this makes it possi- - ble to move any packet coalescence strategy in the agent, while - still using an 'immediate' flush policy. - -- Modified the procedure handling the proxy congestion. Each token - now carries a counter which represents the multiple of TokenBytes - data bytes that need to be confirmed by the remote end. The ser- - ver side proxy will need to reply by including the value of the - counter. When sending a new token, the tokens are decremented by - the counter and the client side proxy enters in congestion when - the available tokens becomes zero or negative. - -nxcomp-2.0.0-10 - -- Implemented specific encoding of the X_NXSetCacheParameters - request. - -- Handled the compatibility with older versions not supporting the - new request. In this case the request is handled at the local si- - de, preventing the X requests to be cached or split, even without - the cooperation of the remote side. - -nxcomp-2.0.0-9 - -- Modified the shutdown procedure to not rely on the TERM signal - when the proxy needs to wait for the server to complete. We will - now print the following message in the session log: - - Info: Watchdog running with pid 'n'. - Info: Waiting for watchdog process to complete. - - The NX server will have to kill the process with the given pid - to mandate the proxy shutdown. This solves the TR11C01192. - -- Added the X_NXSetCacheParameters request. It tells to the proxy - how to handle caching of X requests, namely if requests should - be stored in the memory cache, split in smaller data chunks and, - in the case of images, saved on disk in the persistent image - cache. The request affects all the X messages until the proxy - is further configured. - -- Enabling and disabling loading and saving of persistent images - due to a X_NXSetCacheParameters is still to be implemented. - -- Implemented font channel compatibility with older versions. If - the font port is queried and the remote proxy doesn't support - the tunneling of font server connections, an empty string is - returned. - -- The option 'resize', used by agents, is now silently ignored. - This solves the TR10C01061. - -- Added the missing reference to TR08C000981. - -nxcomp-2.0.0-8 - -- Discarded the first idea of setting the font path implicitly in - the X server side proxy, by means of a multi-pass operation and - added the NXGetFontParameters() request and reply. If the proxy - has been configured accordingly, the request returns the X font - path that can be set by the agent to tunnel the font server con- - nections through the NX link. - -- Changed the parsing of the font server port to be able to handle - the defaults. - -nxcomp-2.0.0-7 - -- More work on tunneling of font server connections. - -- The synchronization requests are now replied at the same time - as a new request is received, by checking if the channel has - already gone past the awaited sequence number. This avoids the - delay caused by the previous versions in the case the expected - reply had been handled asynchronously, inside the write loop. - -nxcomp-2.0.0-6 - -- The display is again passed to the client using the -display - parameter. - -- The option 'type' is now ignored at X server side. Support at - the X server side had been left for compatibility with older - versions of the proxy. - -- Added direct support for more session types, namely 'unix-cde', - 'unix-xdm', 'unix-console', 'unix-default'. The 'unix-console' - and 'unix-default', similarly to 'unix-application', will now - trigger the 'raw' mode. - -nxcomp-2.0.0-5 - -- Renamed Png.h and Png.cpp to Pgn.h and Pgn.cpp to avoid name - clashes on Windows. - -- The distclean target now removes the autom4te.cache directory. - -nxcomp-2.0.0-4 - -- Added the 'kill=n' option to let the proxy add the process to - the list of daemons that must be terminated at session shutdown. - Multiple 'kill=n' options can be specified. The proxy will send - to each process a SIGTERM signal before exiting. - -- Removed the code that forcibly disabled the RENDER extension on - Solaris. Eventual compatibility problems will be now handled in - the NX agent. - -- The path to the client executable is now assumed to be in the - NX_CLIENT environment. If the variable is not set, the proxy - will guess the location based on the target platform. This is - part of the FR11C01215. - -nxcomp-2.0.0-3 - -- More code cleanup. Protocol step 5 and cache step 2 are assumed - by default. This allows us to remove the various channel caches - that are not used anymore. - -- Removed the outdated encodeBegin() and encodeEnd() methods. - -nxcomp-2.0.0-2 - -- Added compatibility with the 1.5.0 and 1.4.0 versions. Protocol - version older than the 1.4.0 will cause the proxy to drop the - connection. - -- Rewritten the version negotiatiation logic to better handle the - compatibility between the local and the remote version. - -- Removed the conditional code handling the compatibility with - the protocol encodings from 1 to 4. - -- Small adjustments to the session negotiation procedure to give - more hints in the case of errors. A dialog is now issued if the - remote proxy drops the connection due to a probable authentica- - tion failure or when the remote proxy version is not compatible - with our version. - -nxcomp-2.0.0-1 - -- Opened the 2.0.0 branch based on nxcomp-1.5.0-80. - -nxcomp-1.5.0-80 - -- Fixed a bug that prevented the Unix socket to be created in the - right directory. This affected the ability of the server to run - NX sessions without the agent encoding. - -nxcomp-1.5.0-79 - -- Solved a bug in the 15 to 16 bpp conversion for RDP sessions. - -- Corrected a typo in the PANIC message of Unpack16To24 function. - -- Optimized the 16 bpp RDP decompression routine. - -nxcomp-1.5.0-78 - -- Implemented the FR11C01215. The following environment variables - are checked to determine the location of the relevant NX direct- - ories: - - $NX_ROOT The root NX directory is the place where the session - directory and the cache files are created. This is - usually overridden by passing the 'root=' option. By - default, the root NX directory is assumed to be the - directory '.nx' in the user's home. - - $NX_SYSTEM The directory where NX programs and libraries reside. - If not set, the value is assumed to be '/usr/NX'. - Programs, libraries and data files are respectedly - searched in the 'bin', 'lib' and 'share' subdirecto- - ries. - - $NX_HOME The NX user's home directory. If $NX_ROOT is not set - or invalid, the user's NX directory is created here. - - $NX_TEMP The directory where the X11 Unix Domain Sockets and - all temporary files are to be created. - - $NX_CLIENT The full path to the nxclient executable. If the va- - riable is not set, the nxclient executable will be - run assuming that the program is in the system path. - This can be useful on platforms like Windows and the - Mac where nxclient is located in a different direct- - ory compared to the other programs, to make easier - for the user to execute the program from the shell. - - Other environment variables: - - $HOME The variable is checked in the case $NX_HOME is not - set, null or invalid. - - $TEMP The variable is checked whenever the $NX_TEMP direct- - ory is not set, null or invalid. - - $PATH The path where all executables are searched, except - nxclient. If $NX_CLIENT is not set, also the client - executable is searched in the system path. - - $XAUTHORITY - This is the file containing the X11 authorization - cookies. If not set, the file is assumed to be in - the user's home (either $NX_HOME or $HOME). - - $LD_LIBRARY_PATH - System-wide library search order. This should be set - by the program invoking the proxy. - -- Extended the usage message to document the relevant environment. - -- Made the WaitChild() function interruptible. This allows the user - to terminate the connection procedure immediately, by sending a - signal to the proxy process while an abort dialog is shown in the - foreground. This is part of the solution to the TR11C01216. - -- Implementation of the FR11C01215 is not yet complete. The client - program and the nxauth/xauth are still searched using the previ- - ous logic. In particular, the NX_CLIENT variable is ignored. - -nxcomp-1.5.0-77 - -- Corrected the typo in the alert dealing with VNC authentication - failures. This solves the TR11C01199. - -nxcomp-1.5.0-76 - -- Added the missing initialization in the client and server proxy - constructors. - -nxcomp-1.5.0-75 - -- Starting from this version the build procedure will automatically - create a DLL on Windows. - -- Disabled exceptions in the compiled code. - -- Disabled run-time type information to further reduce the size of - the executable. - -- Compiling with GCC 4.0.0 and -fno-exceptions produces a warning - in some files, due to control apparently reaching the end of a - non void function. This is bogus and has been confirmed to be a - GCC 4.0.0 bug solved in more recent versions. - -nxcomp-1.5.0-74 - -- Imported changes from nxcomp-1.6.0-4. - -- Solved a compilation error on Solaris and MacOSX platforms. - -- The 'font' option now accepts either a numeric value (for a TCP - port) or a 'unix/:port' or 'tcp/:port' specification. In the case - of Unix ports, we assume that a port specification "unix/:7100" - corresponds to the "/tmp/.font-unix/fs7100" socket and a port like - "unix/:-1" corresponds to "/tmp/.font-unix/fs-1". - -- An absolute file path is also accepted as a valid socket. This is - useful to test the forwarding of the font server connection, for - example by running a normal X client and pointing the socket to - the X server. - -- Protocol step 7 is now only assumed when connecting to a remote - proxy version 1.6.0 or later. - -nxcomp-1.5.0-73 - -- Use the include files from nx-X11 if the nx-X11/include directory - is found. The previous configure checked the presence of nx-X11/ - exports/include, that might not be built at the time this library - is compiled. - -nxcomp-1.5.0-72 - -- Fixed a problem on AMD64 due to the size of the area pointed by - the argument of NXTransReadable(). The ioctl() requires a pointer - to an int, at least on Linux. The original _X11TransBytesReadable() - function simply calls the ioctl() by passing the pointer that is - provided. Returning the value assuming a pointer to a long crashes - some applications, among them xterm. Now NXTransReadable() follows - the same schema of the ioctl() call and stores the result assuming - a pointer to an int. - -nxcomp-1.5.0-71 - -- Ensured that the NX trasport is destroyed on NXTransExit() even if - the parent has overridden our signal handlers. - -- Added attribute 'noreturn' to NXTransExit(). - -- Small change to the shutdown procedure to send the "Waiting for a - further signal" just after the watchdog is started. - -nxcomp-1.5.0-70 - -- Added the definition of protocol step 7. The new protocol step is - implicitly assumed when activating the font server channel, so that - NX clients and servers may decide what to do by verifying the patch - version of the peer software. This makes possible to activate the - feature without stepping up the 1.5.0 version of the software. - -nxcomp-1.5.0-69 - -- Added the -fPIC GCC flag when compiling on AMD64 architectures. - -- Small changes to configure.in to have specific CFLAGS. - -- Created a new configure using autoconf 2.59. - -- Added the 'mask=n' option to determine how channel ids are distri- - buted between client ans server. By default, channels whose ids are - multiple of 8 (starting from 0) are reserved for the client side. - All other channels can be allocated at the NX server side. - -- A check is missing on the protocol supported by the remote side, - so it is likely that mixing this version with older 1.5.0 will not - work. - -- The release has the debug logs enabled. - -nxcomp-1.5.0-68 - -- Added provision for opening new channels on both client and server - side. This required small changes to the way channel ids are mapped - and retrieved, so that both sides now support bidirectional mapping - of file descriptors to channels. - -- Made the code handling allocation of new generic channels to reside - in the base Proxy class. - -nxcomp-1.5.0-67 - -- Renamed the 'embedded keyboard' channels as 'aux' channel. - -- Renamed 'samba' channels as 'smb'. - -- The 'samba' and 'smb' options can now be used interchangeably. The - same applies to the 'keybd' and 'aux' options, used to set up the - auxiliary X channel. - -- Added a new font channel. The channel is used to forward X font - server connections from the X server on the NX client to the remote - NX server. The channel is not yet functional and requires change to - the channel allocation mechanism. - -- Added a common interface to create new listening sockets. This is - currently used for additional services, but not for the X display - sockets. - -- Simplified the interface used to accept new connections to channels - being forwarded. - -- Removed the -V option as nxproxy is not using dlopen() anymore. - -- Removed the inclusion of ClientChannel.h in Proxy.cpp that caused - test symbols to be reverted to undefined. - -nxcomp-1.5.0-66 - -- Made failures setting the IPTOS_LOWDELAY on the proxy socket to - cause a warning, instead of an error. - -- Made the clean target delete the Cygwin specific libraries. - -- Updated the configure and Message.h to deal with GCC 4. Solves the - TR08C000981. - -nxcomp-1.5.0-65 - -- Removed the warning issued on parsing the agent option 'rootless'. - Solves the TR08C00959. - -- MacOSX 10.4 defines socklen_t. Made the definition conditional so - that we can still support older versions. Solves the TR07C00926. - -- Updated the ChangeLog to include references to the solved TRs. - -nxcomp-1.5.0-64 - -- Imported the 1.6.0 changes in the maintenance 1.5.0. - -- Removed a wrong assertion that might cause the session to fail - when the software was compiled with TEST enabled in Proxy.cpp. - -- The nxclient dialog process is signaled with SIGKILL on Windows, - as the SIGTERM is ignored. This solves the TR07C00929. - -- Ensured the JPEG error flag is always set before jumping out of - the Jpeg decompression. - -- Skipped errors encontered setting the TCP_NODELAY flag on Mac. - Solves TR08C00940. - -- Few cosmetic changes. - -nxcomp-1.5.0-63 - -- Ensured that the parent is checked often in the keeper process, - so that, in the case of a premature death, the child is exited - earlier. - -nxcomp-1.5.0-62 - -- Some performance tuning of the LAN and WAN link modes. - -nxcomp-1.5.0-61 - -- Fixed the problems arisen with loading or saving the image files - on Windows by forcing the streams to be opened in binary mode. - These problems have been triggered by the recent Cygwin upgrade. - -- Removed the logs that had be left enabled for test purposes. - -nxcomp-1.5.0-60 - -- Made all errors encountered while unpacking an image just print - a warning in the session log. Such errors are not fatal but the - client monitors the state of the session at startup, so that by - marking image decompression errors as such may cause the session - to be aborted. - -- Marked as warnings also errors encountered by trying to load an - image from disk. - -nxcomp-1.5.0-59 - -- When detected, the CTRL+ALT+SHIFT+ESC sequence is removed from - the event stream. - -- Also modified the message in the session log to issue a warning, - instead of an error. - -nxcomp-1.5.0-58 - -- Added a setjmp() before yielding the control to the JPEG library. - This makes possible to recover from the JPEG decompression errors - that were previously fatal. - -- In the commit split request, the client id is now encoded by the - client channel beside the propagate flag. The client id is igno- - red by the decoding party. As in the old protocol versions, the - committing client is taken from the client id that was originally - sent together with the packed image. - -- Fixed the compilation problem when defining OPCODES in Misc.cpp. - -- Skipped the synchronous flush of the proxy link when connecting - to a previous NX version. - -- Ensured that the new alerts are only requested when connected to - a compatible proxy. - -- Ignored the option 'fullscreen', targeting the agents. - -nxcomp-1.5.0-57 - -- Added more alerts and changed the name of those dealing with the - resume of a session. - -- Added the MIXED define. When set, the proxy will let all logs go - to the standard error. This is useful to interleave the Xlib log - output with the proxy output in a single file. - -- Added a new alert to report an I/O error at agent reconnection. - This is one of those alert that can't be actually shown, but are - included to offer a consistent view to the agent implementation. - -nxcomp-1.5.0-56 - -- Added the split mode NXSplitModeSync. By selecting this mode, - the proxy will try to empty the split store immediately, until - all messages marked in such mode will be synchronized. The im- - plementation is left to future versions. - - #define NXSplitModeSync 3 - -- Added the messages specific to RDP and VNC sessions in NXalert.h. - Included are also a few alerts related to changes to the color - depth and desktop geometry that may be eventually mandated by the - remote server. - -- Corrected a typo in NXalert.h - -nxcomp-1.5.0-55 - -- Added the 'mode' field in the X_NXStartSplit request. It determi- - nes the strategy that the proxy will adopt to handle the image. - If set to 'eager', the proxy will only split the messages whose - size exceeds the split threshold (the threshold can be found in - the X_NXGetControlParameters reply). If mode is set to lazy, the - proxy will split any image that it is not able to find in its - cache. - - The opcode and the two available modes are defined in NXproto.h, - currently: - - #define NXSplitModeDefault 0 - #define NXSplitModeEager 1 - #define NXSplitModeLazy 2 - -- All requests related to image streaming now carry a 'resource' id. - The id is currently ignored by the proxy in the case of X_NXCom- - mitSplit requests. - -- Added a new NXSetSplitMode() request. It determines the strategy - that the proxy will adopt to stream the images. If set to 'eager' - the proxy will only split the messages whose size exceeds the - split threshold, otherwise it will split all the images, regard- - less their size. This is in preparation of the lazy encoding in - agent. - -- Slightly decreased the startup timeout compared to the value it - had in the 1.4.0. This timeout is used to retain the images used - during session startup in the persistent cache. - -nxcomp-1.5.0-54 - -- Modified the text of the begin-reconnection alert to mention the - speed of the connection detected by the agent. - -nxcomp-1.5.0-53 - -- Reworked the handling of the abort-split events issued by the re- - remote proxy so that we now finalize the procedure and restart the - client asynchronously, in the middle of the write loop. - -nxcomp-1.5.0-52 - -- Rewritten the internal interface to the notification events. There - are now five different split notification events: - - NXNoSplitNotify The operation didn't cause any actual split. - The client can be immediately restarted. - - NXStartSplitNotify A split is ongoing. The client should be - suspended until the end of the split. - - NXCommitSplitNotify A complete request has been recomposed. The - client can commit the given request to the - X server. - - NXEndSplitNotify The split operation was duly completed. The - client can be restarted. - - NXEmptySplitNotify No more split operation are pending. The - agent can use this information to implement - specific strategies, requiring for example - that all messages have been recomposed at - the remote end. This can include updating - the drawables that were not synchronized - because of the lazy encoding. - -- Removed the X_NXSync and X_NXKarma operations, not used anymore by - the NX agents. - -- Increasing or decreasing a timeout makes it respectively equal to - the base timeout or to the base timeout / 4. - -nxcomp-1.5.0-51 - -- Improved the mechanism by which synchronization replies are sent - to the X client proxy. - -- Using the leftPad field as passed by the nxagent 1.5.0-58 doesn't - seem to work with the MIT-SHM. The workaround is to disable the - MIT-SHM operation in the case of 1 bpp images. - -- Removed the limitation on the size of the shared memory segment - that had been introduced for test purposes. - -nxcomp-1.5.0-50 - -- Solved compilation problem when --with-info was not given. - -nxcomp-1.5.0-49 - -- Improved support for color matching from 15 and 16 bpp to 24 and - 32 bpp in RDP sessions. - -- Solved TR05C00910. This was about "shadows" that might appear in - RDP sessions when small elements like tooltips were drawn. - -nxcomp-1.5.0-48 - -- Added a 'commit' field in X_NXCommitSplit request. When zero, the - X server side proxy will unlock the message in the message store, - without actually committing the image to the X server. The new - field required changes to the encoding. This means that this ver- - sion is not compatible with older 1.5.0 nxcomp releases. - -- Added a new control message. This is used by NXTransFlush() to for- - ce a roundtrip between the proxies and speed-up the handling of - the synchronous replies. - -nxcomp-1.5.0-47 - -- Made the timeouts dynamic, based on the user input and the current - bitrate. - -- Set the available tokens to 8. This allows for 16 KB to be sent on - a modem before having to wait for a reply. - -- Added provision for removing a dialog on the remote end. This can - be used, for example, to get rid of a message that was displayed - by the agent at the beginning of a lengthy operation. - -- Fixed a fault that arose when trying to run the proxy on a display - whose name began with the 'nx' string. - -- Running a client or server session on a display host beginning with - 'nx' should be now possible. - -- Flush is now always immediate when there is already data queued in - the TCP socket. - -nxcomp-1.5.0-46 - -- Created the NXalert.h header from Alert.h to share the alert codes - with the agents. The new NXTransAlert() interface can be used to - start an alert on the remote side. - -- Created the NXTransParse*() and NXTransCleanup() wrappers. - -- Temporarily using the single-dash style when passing parameters to - nxclient until the double-dash style is fixed. - -nxcomp-1.5.0-45 - -- Motion events are now flushed at the time the X server channel is - sending the token reply. - -- Renamed NXDialog() to NXTransDialog() and added a window ID parame- - ter, to be used by the agent when starting the "pulldown" dialogs. - -- Also renamed the other NX utility functions. - -nxcomp-1.5.0-44 - -- Solved a bug that prevented auxiliary X connections from working - with the agent. - -- Added the missing check on the proxy pointer in HandleTimer() as - it may be actually called before the proxy is created. - -nxcomp-1.5.0-43 - -- Started tuning the performance. For now, the available tokens are - set to an improbable value of 10000. - -nxcomp-1.5.0-42 - -- Disabled the X server side remote expose events for test purposes. - This is intended uncover the display problems introduced by the - new handling of exposures in the X11 agent. - -- Fixed some timestamp related functions to avoid rounding problems. - -- Moved the timestamps of split, frame and flush from the Control - to the Proxy class. - -- Made the X server side proxy to skip updating the counters related - to token management. - -- Made also the X server side use deferred flushes. - -- Modified handleFrame() to manage both pings and data frames and - send the token before the actual write operation. - -- Cleaned the pseudo-files used to load the control parameters. - -- Cleaned up the FIXME's in the lower layers. More FIXME's remain in - the frontend classes. - -- Added a further counter to the statistics tracking the number of - network writes performed on the proxy link. - -nxcomp-1.5.0-41 - -- Now the watchdog process doesn't kill the parent. The termination - event is determined by monitoring the child. This is advisable to - avoid interfering with the signal handling in agent. - -- The house-keeping process is not started if differential compres- - sion (and thus caching of images) is disabled. - -- Wait for the watchdog to terminate before starting the house-keep- - ing process. - -- Fixed the problem of gray stripes in white areas when using 15bpp - RDP compression. This solves the TR06C00916. - -- Added a log in Message.cpp to tell when an image is removed from - the memory cache. - -- Removed most of the logs. Only left the logs directly related to - the deferred flushes. - -- Removed a warning due to a missing definition in NX.h. - -nxcomp-1.5.0-40 - -- Added the signal '12' to the set of blocked signal on Cygwin. This - is what is delivered to the application when it tries to create a - shared memory segment when the cygserver is not running. The call - later returns "Operation not implemented", only useful if you have - survived to the signal. - -- Modified the configure script to not link against cygipc. - -- Improved error handling in the negotiation phase. - -- Reset the last signal received when aborting a connection attempt. - Not doing that might cause a warning. - -nxcomp-1.5.0-39 - -- Both channels and proxy can now deal with incomplete messages by - waiting for the full data to become available. This is not going - to work when the transport is connected to an agent that is run- - ning in-process, so the timeout must be really small. - -- Made the main loop more compact by letting a single function read - from proxy and channels. The same change applies to writing to - descriptors that are reported to be ready. - -- Optimized the loop to report as ready the agent descriptors that - have become available after the proxy execution phase. - -- Now the proxy will try to asynchronously read from its descriptor - after having read from the channel. - -- Unified the routine setting the routines setting the read and write - descriptors and the timeouts. - -- Unified the routine handling the channel events. - -- Reintroduced the last ping timestamp to avoid sending more than a - single ping every PingTimeout milliseconds. - -- The cleanup procedure now waits for the watchdog and house-keeping - processes to terminate. - -- Reverted the change occurred in 1.5.0-35 about the byte-ordering - problem in decompression of PNG and JPEG images. - -- More coding about deferred flushes. - -- Relevant debug logs are enabled in the main loop, in the proxy and - in the channel classes, so use only for testing. - -nxcomp-1.5.0-38 - -- Started the implementation of deferred writes based on the new NX - transport. - -- Solved a problem with the statistics file affecting the Windows - platform. Basically it seems that Cygwin or the stdc++ library - don't deal correctly with files that are reopened just after - having unlinked them. - -- Implemented support for 15 bpp RDP bitmaps. - -- Added "rdpcolors" and "rdpcache" to the list of parameters that - are ignored in ParseEnviromentOptions(). - -- This version has lot of logs enabled and some forced cleanups in - the case of unexpected conditions. Avoid to use it for long-last- - ing test sessions. - -nxcomp-1.5.0-37 - -- Now splitting of images is fully disabled when running with link - LAN. Previously the split was not executed by the proxy, but the - agent was configured to send the start/end sequence. - -- Added the check protecting the proxy from token underflow. In the - previous code the check was left out to verify the conditions un- - der which this event might be encountered. - -- NXTransWrite() and NXTransWriteVector() allocate a context before - calling handleRead(), so they can correctly return in the case of - a cleanup. - -nxcomp-1.5.0-36 - -- Modified the channel write loop to interleave abort split events - between the writes to the X server socket. - -nxcomp-1.5.0-35 - -- Solved a byte-ordering problem in decompression of PNG and JPEG - images. - -- Changed the handleToken() interface to make explicit if a token - must be issued because of a ping. - -- Small fix to prevent a warning in Jpeg.cpp when TEST is enabled. - -nxcomp-1.5.0-34 - -- Solved a few problems introduced by the rewrite of the read loops - in channels. - -- Added definition of NXCollectInputFocusNotify. - -nxcomp-1.5.0-33 - -- Implemented a new control flow system based on tokens exchanged bet- - ween the proxies. When the clint side runs out of tokens it stops - sending data until a new token is returned. Tokens are sent whenever - the data written to the socket exceeds the amount of data set for a - scheduled write, so the proxy is free to send a number of smaller - frames before running out of tokens. - -- The reason the new system is introduced is because the old method - had two outstanding problems: - - - It worked very well when the proxies were directly connected, - but couldn't reliably detect a link congestion when tunneled - over SSH. - - - In the attempt of reducing the data queued to the TCP layer, it - didn't leverage all the available bandwidth. - -- Moved the final check on the state of the session at the end of - execution stage, instead of the beginning. The signals sent by the - user to request the statistics could be reset before the proxy had - entered the right procedure. - -- Added the session type 'unix-rootless', to be used for single apps - run with the agent in rootless mode. - -nxcomp-1.5.0-32 - -- Modified the main loop to skip the select when I/O is possible on - any of the agent descriptors or the proxy link. - -- Now the house-keeping process is allocated in the heap instead of - the stack. - -nxcomp-1.5.0-31 - -- The server channel now performs asynchronous reads from the display - by interleaving them with data decoded from the remote proxy. - -- Improved the handling of the memory-to-memory transport. - -nxcomp-1.5.0-30 - -- Redesigned the handling of the congestion events to work more re- - liably and to report the events to the remote peer earlier. - -- Increased the size of the shared memory segment when the MIT-SHM - extension is activated. - -- Solved a bug that prevented the ping timeout to work as expected. - -- Ensured that, when entering the main select(), neither the chan- - nels or the proxy have pending messages in the read buffers. - -- There is now only a single case where we can have pending messa- - ges, namely in the handling of the MIT-SHM events. - -- Solved a bug introduced by the 1.5.0-29 that made the proxy en- - ter the select with a null timeout. - -- Renamed LINK_TYPE_AUTO to LINK_TYPE_NONE in NXproto.h. - -nxcomp-1.5.0-29 - -- Now encoding data from the agent descriptors happens in the same - context as data is written to the buffer. - -- Optimized the handling of the congestion events to avoid running - further unneeded loops. - -- Added timer handling utilities. - -nxcomp-1.5.0-28 - -- Added code providing information about the reason of the failure - encountered connecting to the local X server. This greatly helps - when troubleshooting X authorization problems. - -- On connection failure a warning message is printed in the session - log. - -- Removed the warning that was previously printed when the MIT-SHM - extension failed to be initialized on Windows. Shared memory has - problems on Cygwin and it currently doesn't work in NXWin. - -- Reworked the message printed in the case of link failure. - -nxcomp-1.5.0-27 - -- Solved a bug in the connection procedure introduced by 1.5.0-25. - -nxcomp-1.5.0-26 - -- Transformed the errors printed on failure of the fork() creating - the children into warnings. This can happen quite often on Win- - dows, due to well known Cygwin problems. See also the ChangeLog - entry for nxcomp 1.4.0-28. This patch closes the TRSL052278 but - it's obviously not a long-term solution. - -- Set the sticky bit when creating the '/tmp/.X11-unix' directory. - -- Modified the Makefile.in to remove the *.out.* files generated by - Valgrind. - -- Updated the README files. - -nxcomp-1.5.0-25 - -- Changed the directory where the client for the Mac is searched if - it is not found in the system path. - -- Modified Auth.cpp to use nxauth also on the Mac. - -- Reworked the procedure showing the alert dialog when a timeout is - encountered in the initial connection. - -- Removed the experimental code from the official 1.5.0 branch. - -nxcomp-1.5.0-24 - -- Implemented more experimental classes. - -nxcomp-1.5.0-23 - -- Added the NX_SIGNAL_FORWARD action to NXTransSignal(). This can - be used to let the proxy call the original signal handler of the - agent after having blocked the signal. - -nxcomp-1.5.0-22 - -- Ensured that we always have a context, even before creating the - transport. - -- Suppressed the error message printed when passing the -h option. - -- Added the experimental code that is currently under development. - -nxcomp-1.5.0-21 - -- Enabled the fake X cookie authentication. This requires checking - the remote proxy version to verify that the server supports the - new authorization mechanism. - -- It's worth noting that the X client side proxy doesn't care which - cookie is sent over the connection. The problem is that clients - connecting to 1.4.0 servers don't have a method to force the ser- - ver to use the fake cookie. This means that we have to solve the - problem by letting the proxy check the remote version so that it - can omit to replace the cookie when connecting to older servers. - -nxcomp-1.5.0-20 - -- Added the NXTransCongestion() function. It returns true if proxy - is in congestion state. - -- Removed an incorrect warning that was printed when calling force() - for the memory-to-memory transport. The agent could actually re- - quire multiple loops to read all data queued for it. - -nxcomp-1.5.0-19 - -- Small optimization in NXTransReadable() to run a new NXTransConti- - nue() loop only after at least RetryTimeout milliseconds are pas- - sed since the last call and still no data is available. This cuts - the number of unneeded loops to 1/4th of the total, probably more, - on faster machines. - -- Added NXCollectGrabPointerNotify to NXproto.h. - -nxcomp-1.5.0-18 - -- Minor changes to NXTransContinue(). - -nxcomp-1.5.0-17 - -- Moved respawning of a new nxclient instance in the cleanup procedu- - re. This ensures that the respawn is executed whatever is the rea- - son of the session shutdown. - -- Added a method to force closure of a given channel in proxy. - -- Removed code handling the special case triggered on Windows by the - presence of a NX_SESSION variable in the environment. - -nxcomp-1.5.0-16 - -- Added the NXTransSignal() function to let agents tell to the proxy - how to handle the standard POSIX signals. Given the SIGINT signal, - for example, the caller can specify any of the following actions. - - NX_SIGNAL_ENABLE: A signal handler will have to be installed by - the library, so that it can be intercepted by - the proxy. - - NX_SIGNAL_DISABLE: The signal will be handled by the caller and, - eventually, forwarded to the proxy by calling - NXTransSignal() explicitly. - - NX_SIGNAL_RAISE: The signal must be handled now, as if it had - been delivered by the operating system. This - function can be called by the agent with the - purpose of propagating a signal to the proxy. - - As a rule of thumb, agents should let the proxy handle SIGUSR1 and - SIGUSR2, used for producing the NX protocol statistics, and SIGHUP, - used for disconnecting the NX transport. - -- The following signals are blocked by default upon creation of the - NX transport: - - SIGCHLD These signals should be always put under the control - SIGUSR1 of the proxy. If agents are intercepting them, agents - SIGUSR2 should later call NXTransSignal(..., NX_SIGNAL_RAISE) - SIGHUP to forward the signal to the proxy. - - SIGINT These signals should be intercepted by agents. Agents - SIGTERM should ensure that NXTransDestroy() is called before - exiting, to give the proxy a chance to shut down the - NX transport. - - SIGPIPE This signal is blocked by the proxy, but not used to - implement any functionality. It can be handled by the - NX agent without affecting the proxy. - - SIGALRM This is not blocked by the proxy, but could be used - in future. - - SIGVTALRM These signals are not used and should not be used in - SIGWINCH future versions of the library. - SIGIO - SIGTSTP - SIGTTIN - SIGTTOU - -- By calling NXTransSignal(..., NX_SIGNAL_DISABLE) nxcomp will res- - tore the signal handler that was saved at the time the proxy hand- - ler was installed. This means that you should call the function - just after the XOpenDisplay() or any other function used to init- - ialize the NX transport. - -nxcomp-1.5.0-15 - -- In NXTransContinue(), if the transport is gone, return immediately, - that is without having to wait until the NXTransSelect() timeout. - -- Ensure that NXTransCreate() has a jump context, just in the case - a subsequent operation would cause a cleanup. - -nxcomp-1.5.0-14 - -- Solved a problem with requests left in the agent's buffer when run- - ning the NX transport. The agent could have enqueued data to our - side and checked the available events but requests could not be - written to the proxy because proxy might not have had a chance to - enter a new select. We found that this behaviour was triggered by - _XEventsQueued, so now a new loop is forced when agent is calling - _X11TransDataReadable. The procedure can be optimized, by avoiding - an expensive loop when no critical I/O is pending. - -- Added a few additional logs to ClientChannel and ServerChannel. - -nxcomp-1.5.0-13 - -- Added the code handling the special cases of an user not specifying - a proxy cookie or the case of the X authorization file not contain- - ing a value matching the display. In the first case we'll forward - the same cookie that was feeded to the proxy, in the second case we - will forward to the X server a random generated cookie, similarly to - what SSH does in this same condition. - -- Rewritten the command line parser. Removed all the command line - options parsed on behalf of nxproxy except: - - -C Specify that nxproxy has to run on the "X client" - side, listening for connections and impersonating - an X server.\n\ - - -S Specify that nxproxy has to run in "X server" mode, - thus forwarding the connections to daemons running - on the client.\n\ - - -V n.n.n Request nxproxy to load the given nxcomp version. - This option is only present on Solaris and Linux. - - -v Print version information. - - host:port Put at the end, specifies the host and port of the - listening proxy. - - value=name Set the NX option to the provided value. - - Multiple NX options can be specified in the DISPLAY environment or - on the command line, by using the nx/nx,name=value notation. - -- The above information is printed on the console when incurring in - a parse error, together with a list of the available option=value - parameters. - -- Renamed the 'log' option to 'errors'. This makes sense as the de- - fault name for the log file is actually 'errors'. - -- Now the "Established X server connection" message is printed to - the session log only after the X connection has passed the X auth- - entication phase. This means that the NX client should become able - to show the details of the session log whenever the session fails - due to a cookie problem. - -- When selecting the additional services without specifying a port, - the client proxy will now automatically forward the connections to - the corresponding well-known ports of the CUPS, SMB and HTTP servi- - ces. Embedded X keyboard connections will be automatically forward- - ed to the same display port used to connect to the X server. The - user will still have to specify the port to be used for the media - connections as we don't have a suitable well-known port. - -- Starting from this version, connections to the keybd port will cre- - ate real X connection channels. This is required to let connections - leverage the fake authorization cookie. - -- By testing the forwarding of keybd connections I found that, when - letting X clients connect to the port, it is required to provide - the X cookie for the unix display. Adding only the TCP cookie will - not work. For example, by creating a cookie as in: - - xauth add localhost:2009 MIT-MAGIC-COOKIE-1 6f...f4 - - And running: - - xterm xterm -display localhost:2009 - - You will get the following error: - - Xlib: connection to "localhost:2009.0" refused by server - Xlib: No protocol specified - - Adding also the unix cookie will fix it: - - xauth add localhost/unix:2009 MIT-MAGIC-COOKIE-1 6f...f4 - - This seems to be a Xlib problem, with Xlib trying to get the cookie - for the UDS port even if the TCP port was requested by the user. - -- Fixed a bug that prevented the nxclient dialog to be displayed when - the session was abruptedly shut down. - -- Fixed the compilation error on Apple MacOSX due to the sa_restorer - field in sigaction. As long as this field is present on Linux we - will keep following the safer route and will set it explicitly to - NULL. - -- Included what needs to be included in Process.cpp to compile with - older gcc. - -nxcomp-1.5.0-12 - -- Implemented a replacement for the popen() and pclose() that do not - rely on a shell to run the command. They were required on Windows, - where we don't ship a suitable shell in the install. - -- Removed code forcing the PATH to include the bin directory on - Windows. - -nxcomp-1.5.0-11 - -- Forced Auth.cpp on Windows to have the directory containing the - nxauth executable in the PATH. This is just for testing, until - nxclient is fixed. - -- Fixed compilation errors on Cygwin and Sun. - -- Removed the NX_FORCE_* stubs. - -nxcomp-1.5.0-10 - -- Modified the memory management policies in ReadBuffer to fit all - the available bytes in a single buffer allocation. - -- The locateMessage() methods now give hints on the amount of data - that has to be read. - -- The read loop in channel now doesn't yield in the case of prio- - ritized messages. This is experimental. - -- Removed the check on isTimeToYield() between encodings of multi- - ple messages. This is aimed at reducing the risk of leaving pen- - ding messages in channels. - -- Modified the channels' read loop to always read all the available - data. - -- Disabled the log output that was selected when compiling with the - configure option --with-info. This leaves space for other log out- - put to be selected for more up-to-date scopes. - -- Implemented the NXTransReadVector() and the NXTransWriteVector() - functions to replace READV() and WRITEV(). - -- Implemented memory-to-memory communication between the agent and - the NX proxy by making use of the NXTransAgent() interface in the - nx-X11/lib/X11/Xtranssock.c file. - -- Added a check in NXTransSelect() for the EBADF and, on Solaris, - the EINVAL errors. It can happen in the X11 code that a descript- - or has become invalid before it is removed from the managed set - -- Rewritten the signal handling functions to restore the old actions - and masks when the NX transport is destroyed. - -- Added a NXTransAgent() function to let agents tell the proxy which - descriptor must be used for the controlling connection. Setting a - controlling connection has the effect of disabling further X client - connections and makes the proxy terminate when the channel is shut - down. - -- Solved a problem with setting the initial timeout in the select(). - -- Modified the Makefile.in to not include -Wno-deprecated when compi- - ling C programs. - -nxcomp-1.5.0-9 - -- Fixed a problem that prevented the 1.5.0-8 to work on the NX server - side. - -- This version has NX_FORCE_NULL_LISTEN_OPTION and NX_FORCE_NEW_SES- - SION_OPTION undefined, so it should work in a way that is compati- - ble with the old nxcomp. - -nxcomp-1.5.0-8 - -- The new code comes with a preliminary integration of nxcomp with - SSH. It is now possible to create the NX transport by just calling - the "switch" command as in the following example: - - NX> 299 Switching connection to: NX options: ... - -- Other possible forms for the NX switch command are: - - NX> 299 Switching connection to: NX mode: ... - - NX> 299 Switching connection to: NX mode: ... options: ... - - Or just: - - NX> 299 Switching connection to: NX - - The "mode" parameter is there to provide a way to run both enc- - rypted and unencrypted connections. Possible values are "encrypt- - ed", "unencrypted" or "default", the latter being an alias for - "encrypted". Unfortunately I was not able to test unencrypted - connections, so this may or may not work. - -- The top-level process can create the NX transport layer by calling - NXTransCreate(). The user has to set up a socket pair and pass the - higher descriptor to nxcomp. nxcomp will later monitor its end, by - reading and writing NX-encoded traffic. The user has to call the - NXTransExecute() function as often as it is possible, by letting - first NXTransPrepare() combine the sets of NX descriptors with the - descriptors that are used inside its process. A custom NXTransSel- - ect() is provided to optionally replace the original select(). This - function saves the original error code and the number of selected - descriptors upon exit, so the user can call it, restore the original - values as they were returned by the select() and run the rest of - the loop unmodified. - -- Future versions of the library should provide appropriate methods - for passing data to and from the proxy by means of a memcpy(), so - that it will be possible to remove the even minimal TCP overhead. - -- Note that integration is far from complete. More work is required - especially to manage the shutdown cleanly, in a way that gives to - SSH a chance to free its resources, and on adding facilities for - handling SSH and NX signals in a single function. - -- Rewritten the initialization procedure to make possible to run the - proxy in-process in an arbitrary connection manager, like SSH or a - HTTP utility. The same functionality can be used to embed nxcomp in - the NX agents, so that nxcomp has not to run in a separate process. - -- A new state-machine handles the advances through the connection - stages until the remote proxy (or the forwarder process ) is auth- - enticated, options have been negotiated and the session is started. - -- The option "session" is now used to pass the name of the session - file to the proxy. The parameter was previously used to pass the - literal name of the session, as set by the user, and was ignored - by the proxy. By default the session log is the standard error of - the process. It is anyway required to set the option when running - inside SSH, otherwise output will go to the same file as the SSH - output. In the NX client this would be the 'sshlog' file. - -- This version can be easily crafted to test the new integration by - setting the following define: - - NX_FORCE_NULL_LISTEN_OPTION - - This makes possible to test the nxcomp/nxssh integration by using - any production 1.4.0 client. To run this version you are required - to use nxproxy 1.5.0-4 and nxssh-1.5.0-6. - -- New functions handling enabling and disabling signals, based on - sigprocmask(). - -- Improved error reporting when failures are encountered while ne- - gotiating the session. - -nxcomp-1.5.0-7 - -- Caches are saved with a version identifier 1.4.0 so that they are - not discarded after upgrading the software to the 1.5.0. - -- Made values of T_* enumerations to be all lower case. - -- Updated copyright to year 2005. - -- Started working on an interface for running nxcomp in-process, as - a additional transport layer of nxssh or nxagent. - -nxcomp-1.5.0-6 - -- Modified the configure script and the makefiles to not include the - -Wstrict-prototypes and -Wmissing-prototypes compilation flags. The - -Wnested-externs and -Wmissing-declarations flags are not included - when using GCC 3. - -- Removed the initial newline from string "NXPROXY - Version" printed - at program startup. - -- Made X authentication compatible with 1.4.0 clients. This is a tem- - porary solution while code is updated to handle the new X authori- - zation scheme. - -nxcomp-1.5.0-5 - -- Added an Auth class to handle the X authentication. The NX server - should now use the same proxie cookie that is passed by the client - at session startup. The X server side proxy will forward the autho- - rization credentials by replacing the fake cookie with the real co- - okie, as it is read from the auth file using the xauth utility. The - implementation is based on the corresponding code found in the SSH - client and comes with the same limitations: only MIT-MAGIC-COOKIE-1 - cookies are checked and the authorization file is read only once, - at the time the instance is initialized. If the auth file changes - along the life of the session, the old cookie will still be used. - This works with X servers because of an undocumented "feature". - See also nx-X11. - -nxcomp-1.5.0-4 - -- Adjusted for alarm(0) returning an inconsistent value in ConnectTo- - Remote(). - -- Small changes to Types.h, Jpeg.cpp and Png.cpp to compile with gcc - 3.4.2. - -- Cosmetic changes to the ChangeLog file. - -nxcomp-1.5.0-3 - -- Removed test code from ServerChannel.cpp. - -- Small cosmetic change in Loop.cpp. - -- Tested for compatibility against 1.4.1-8. - -nxcomp-1.5.0-2 - -- Changed VERSION file according to TRCL052336. - -nxcomp-1.5.0-1 - -- Opened the 1.5.0 branch based on 1.4.1-9. - -nxcomp-1.4.1-9 - -- Implemented methods PACK_RDP_PLAIN_64K_COLORS and PACK_RDP_PLAIN_- - 16M_COLORS. It seems that 16 bpp plain bitmaps can be seldom recei- - ved. This doesn't seem to be the case of 24 bpp bitmaps. - -nxcomp-1.4.1-8 - -- The new code enables use of 16 bpp and 32 bpp RDP bitmaps. This re- - quired modifications to the following files: - - Misc.h - Misc.cpp - Loop.cpp - Control.cpp - ServerChannel.cpp - Unpack.h - Unpack.cpp - -- Lots of cosmetic changes compared to the original code in 1.4.1-7. - -- Merged the 1.4.0 and the 1.4.1 branches by importing changes up to - the 1.4.1-7. - -nxcomp-1.4.0-30 - -- Modified the function checking the Unix socket where X connections - will be forwarded. The function will not fail if the socket itself - doesn't exist yet. This solves the TRCL042203. - -- Moved the code checking for the CTRL+ALT+SHIFT+ESC sequence to a - separate function. The implementation will now look for a different - sequence on the MacOS/X platform. This should solve the TRCL042182. - -nxcomp-1.4.0-29 - -- Solved a bug that could cause proxy to stop reading data from the - X channels due to an incorrect calculation of the bytes queued on - the proxy link. The bug only affected Linux kernels of the 2.0/2.2 - series. - -- Fixed a problem in the proxy class that could let the select time- - out to become zero. - -nxcomp-1.4.0-28 - -- Prevented the main proxy process from quitting when the fork() of - any of the children fails. This can actually happen on Windows due - to conflicts in reallocating any of the Cygwin DLLs. - -- Reworked handling of the priority flag in channels when dealing - with the X_InternAtoms and X_AllocColor requests to reduce the time - of session startup. Priority is never set in case of X_InternAtom - requests and replies as we assume that most clients use the appro- - priate Xlib function to pipeline multiple requests in a single net- - work operation. - -- The timeout after which proxy will abort the peer connection is - still 120 seconds. An alert dialog will be shown earlier, after 30 - seconds instead of 60. - -nxcomp-1.4.0-27 - -- Removed the code setting priority on channels on ButtonPress and - Button release events. It seems preferrable to delay the flush and - pack more events in a single frame. This makes possible to get the - ButtonRelease together with the ButtonPress. - -- Fixed error detection in SetNoDelay() where a positive result - could produce a 'not supported' message in debug mode. - -nxcomp-1.4.0-26 - -- Reworked the check aimed at detecting the clock drifts. The previ- - ous code, introduced in 1.3.2-2, had the undesired side-effect of - resetting the proxy timeout. This could cause the proxy to never - detect that the other end had been killed. - -- The default behaviour of proxy is now to terminate the session at - the time an error is encountered. This includes network failures. - -- Added a new dialog to be shown to the user whenever the session - is terminated abnormally. - -nxcomp-1.4.0-25 - -- Fixed a bug in handling of suppression of errors generated by - committing the image splits. Other errors, unrelated to the commit - of split, could be suppressed. This might cause the hangup of the - session when the suppressed error was matching a reply. - -nxcomp-1.4.0-24 - -- When killing the proxy process -9 the watchdog could remain alive. - This caused the SSH link to keep the stderr open, with the effect - that former proxy message were not flushed to the session log. - Now the watchdog checks every second if the parent is dead, so - that file descriptors can be closed as soon as possible. - -- SetupDisplaySocket() tried to force the connections to the X - server on the UNIX port whenever the display was set to localhost. - This patch was intended to fix a bug in nxclient, using the TCP - port even when the display was set to a UNIX socket. This beha- - viour caused problems when running nxclient on a remote host by - means of a ssh -X. Proxy will now adhere to the display setting. - -nxcomp-1.4.0-23 - -- Added the possibility to respawn nxclient at the end of session. - This is an useful feature when powering thin-clients where NX - is the only application made available. - -- This configuration applies system-wide to the local client ins- - tallation. By default it is disabled. It can be enabled by the - by creating a 'noexit' file in the directory '/usr/NX/share', - or at compile time, by setting ENABLE_RESTART_ON_SHUTDOWN to 1. - -- Note that the solution is not perfect yet, as there are cases - where session could die without going through HandleShutdown(), - for example if a decoding error is raised in the communication - with the remote peer and the subsequent restore of the proxy - link fails to succeed. - -nxcomp-1.4.0-22 - -- Corrected typos in Timestamp.h and Loop.cpp. - -nxcomp-1.4.0-21 - -- Tuned the handling of RenderCompositeGlyphs. Now compression of - RENDER shows an average ratio of 8:1. This is a steady increase - compared to the 5:1 of the 1.3.2 version. The overall advantage - when running clients displaying a large amount of text is 30%. - -nxcomp-1.4.0-20 - -- Added a new message store for the CreatePixmap request. - -- Fixed handleCopy() to only send the data part past the offset. - This fix can save a significant amount of traffic, especially - when sending many small images whose size doesn't reach the - threshold set for compressing them. - -nxcomp-1.4.0-19 - -- Added tuning of all the RENDER requests. RenderCompositeGlyphs - will require further work. - -- Completed porting of the RENDER requests to the new templates. - -nxcomp-1.4.0-18 - -- Tuned the handling of RenderCreatePicture and RenderFreePicture. - -- Created a new template system for writing new message encoders. - -- Renamed getBits() in EncodeBuffer with diffBits(). The getBits() - method now returns the bits actually allocated in the buffer and - can be called multiple times. - -nxcomp-1.4.0-17 - -- Provided specific encoding of the remaining RENDER requests and - added compression of RenderCreateGlyphSet. - -nxcomp-1.4.0-16 - -- Code underwent through 7 different patch versions but seems to - be stable now. It still needs to provide specific encoding for - RenderCreatePicture RenderChangePicture and RenderFreePicture. - Code will likely include incompatible changes at any new version - until the new encoding will stabilize, so be sure that you use - the same nxcomp version at both sides. - -- Created the infrastructure for compressing extension messages - based on the minor opcode. A new class, MinorMessageStore, has - to be inherited by stores requiring specific compression, so - that all the encoding methods of the parent can be redirected - to it. The RENDER extension is now compressed using this new - class. - -- Managed to maintain the compatibility with caches created by the - 1.3.X version. Caches will be saved using the old format if the - remote version is not a 1.4.x. When restoring a cache created - by the 1.3.x with both proxies being the newest version, RENDER - mesages will be discarded without having to discard the whole - cache. - -- Added a member to the message class to store the identity size. - This field is now used instead of the default data offset to - manage the message data, that is the part of message after the - identity. - -- Removed the warnings printed in the session log when passing the - 'kbtype' and the 'geometry' options to the proxy. These options - are actually used by agents. - -nxcomp-1.4.0-15 - -- Started implementation of the new framework for handling enco- - ding of X extensions. - -- Renamed the overloaded methods handleEncode() and handleDecode() - to handleEncodeCached(), handleEncodeIdentity() and handleDecode- - Cached(), handleDecodeIdentity(). - -- Updated the copyright notice to year 2004. - -nxcomp-1.4.0-14 - -- Added the new channel for HTTP connections. This channel can be - used to let applications running on the NX server get access to - data and applications made available by a HTTP daemon running at - the client side. - - This channel is not used at the moment by nxclient. It can be - activated by passing http=1 to the NX server side proxy and the - value http=80 to the NX client side. - -nxcomp-1.4.0-13 - -- Quick patch to run on MacOS/X where inet_addr("127.0.0.1") - alone seems to fail to return a valid interface. - -nxcomp-1.4.0-12 - -- Few cosmetic changes to logging. - -- Removed the debug output. - -nxcomp-1.4.0-11 - -- Removed code used for simulating the new forwarding function- - ality without client and server support. - -nxcomp-1.4.0-10 - -- Implemented authentication of the forwarder to the listening - proxy. If a session cookie is required, the forwarder must - provide the cookie upon connection. - - An authentication phase at the time the forwarder connects - to the NX client side is strongly suggested because it is usu- - ally this side that sends the authorization cookie. Without - such a forwarder authentication, the local peer would reveal - the cookie to the first process connecting to the port. - -- If no cookie is specified in the switch command, the forward- - er is required to skip the authentication phase. This can be - useful when running the programs on the command line. - -- The implementation required appropriate changes to session - negotiation in nxssh. This version requires nxssh-1.4.0-8. - -nxcomp-1.4.0-9 - -- Fixed the startup procedure to correctly negotiate the cookie - when the X server side proxy is listening for a forwarder. - -- When listening for a local forwarder (that is when the listen - option is enabled at X server side), proxy will listen for the - forwarder on the localhost interface. - -- This version has ports and and other parameters hardcoded for - testing purposes and is not intended for normal use. - -nxcomp-1.4.0-8 - -- Slightly modified the text of FAILED_PROXY_CONNECTION alert. - -nxcomp-1.4.0-7 - -- Added provision for leaving a running dialog showing an OK box - if proxy is exiting abnormally. This seems to fail to yield the - expected results as, at the present moment, client checks if - parent has exited. - -- Added a Binder class invoked when calling proxy with -B option. - It would serve as a replacement of the modifications I'm doing - in nxssh. The class is just a framework and the implementation - is unfinished. - -nxcomp-1.4.0-6 - -- Added a line in the session log if the connection procedure is - aborted due to a signal. - -- Fixed ParseHostOption() to let it take in account the proxy - port offset when passing 'host:port' as the last parameter at - X server side. - -nxcomp-1.4.0-5 - -- Lowered the default port offsets used for CUPS and SMB services - to 2000 and 3000. Arbitrary ports can be used by passing the ser- - vice's port at proxy startup. By default, anyway, the port is at - the same offset of the proxied display. Considering that the NX - server uses to start the first session at display 1000, we must - lower some of the defaults to avoid interference with the normal - X sessions run on the server. - - Session at display ":1000" will have: - - . Forwarding of CUPS connections at 3000. - - . Forwarding of SMB connections at 4000. - - . The listening proxy (at NX server side) at 5000. This - port is not used when enabling SSH tunneling - - . The proxied X display (NX agent or proxy) at 7000. - - . Forwarding of multimedia channels at 8000. - - . Forwarding of embedded keyboard connections at 9000. - -- Turned off the log output. - -nxcomp-1.4.0-4 - -- Managed to get the X client side proxy connect to the remote - peer. This means that some parameters that were implicitly - assumed based on the proxied port simulating the X display - must be now specified in the NX display string. - -- The 'port' parameter now specifies the remote TCP port where - the local proxy will connect to the remote peer. In previous - versions this parameter also affected the proxied port. This - was mainly a side effect, as the remote peer was always con- - tacted at port 4000 plus the proxied display offset. - -- Added the 'listen' parameter to tell to the proxy that is go- - ing to accept the peer connection on which port it will be - contacted. By default, similarly to the previous version, the - proxy will listen at the proxied display offset. - -- A check has been added in order to disallow passing both the - 'accept' and the 'connect' parameter at the same time. A simi- - lar check affects the 'listen' parameter. - -- Renamed the previously unused 'sync' channel as 'cups'. - -nxcomp-1.4.0-3 - -- Preserved the ability of version 1.3.2 to load caches generated - by this version. - -nxcomp-1.4.0-2 - -- Small fixes to compile under Solaris 8. - -nxcomp-1.4.0-1 - -- Opened the 1.4.0 branch. - -nxcomp-1.3.2-4 - -- Fixed a problem with shmget(). Code in ServerChannel checked - the return value for being greater then 0, while 0 can actual- - ly be a valid segment. - -- When memory cache is disabled, nxcomp will explicitly set the - appropriate control variables dealing with loading and saving - of the persistent cache. This can be considered a cosmetic - change as nxcomp will disable NX delta compression if memory - cache is not available and this has an implicit effect on the - ability to load and save such a cache. - -nxcomp-1.3.2-3 - -- Removed inclusion of zlib.h in Png.cpp. Conflicting symbols - with zlib.h from nx-X11 could cause compilation to fail. - -nxcomp-1.3.2-2 - -- Added a function to take into account the clock drifts at the - time we check the ping from the remote proxy. This can be - caused by the user changing the system time or by small adjust- - ments introduced by the operating system making the clock go - backward. Such events could cause the proxy link to be shut - down and reconnected. - -- Reduced the length of lines printed in statistics when showing - the details of X protocol's opcodes. This is intended to help - nxclient to keep the whole statistics in the 'details' window, - so that users don't have to use the scrollbars. - -nxcomp-1.3.2-1 - -- Opened the 1.3.2 branch. - -nxcomp-1.3.1-5 - -- It seems that Solaris can return an EINVAL error selecting a - shutdown descriptor even before we actually close the socket. - We now ignore the condition on Solaris. This is definitely a - Solaris bug. - -nxcomp-1.3.1-4 - -- Increased the timeout after which proxy will abort the peer - connection to 120 seconds. An alert dialog will now be shown - after 60 seconds, instead of the 30 seconds being the default - in the previous version. Some users reported the timeout to - be too short in the case of temporary network failures. - -nxcomp-1.3.1-3 - -- Some optimizations in the cache house-keeping process. Now it - runs at lower system priority in respect to the parent. Any 2 - iterations through directories and images, it also sleeps for - a tiny amount of time. This further decreases the system load. - -- Removed the underline characters and added a colon in the - title of this ChangeLog to fully comply with format used in - the release notices. - -nxcomp-1.3.1-2 - -- Fixed a crash when running both client and server on the SPARC - Solaris. An optimization used to avoid byte-swapping when both - hosts have the same endianess doesn't work on SPARC if buffer - is not aligned to word boundary. A better version of the code - should check the CPU, not the OS, as this probably applies to - other processors. - -nxcomp-1.3.1-1 - -- Opened the 1.3.1 branch. - -nxcomp-1.3.0-50 - -- Disabled the processor limit in X client side proxy. In previous - versions the processor load limit was set to an idle time ratio - of 2. This was likely to cause an unwanted slowdown on very old - hardware or when running the server as guest OS inside a VMWare - virtual machine. - -nxcomp-1.3.0-49 - -- Last minute update on proxy shutdown bug on Cygwin. A stack - trace reveals that faillure happens in the static destructor of - the BlockCacheSet class. It seems that problem appeared just - after having upgraded to the latest version of Cygwin DLL. Now - the destructor is skipped at shutdown. - -nxcomp-1.3.0-48 - -- Further fix to overcome the shutdown problem on Windows. - -nxcomp-1.3.0-47 - -- Used T_files::value_type() in Keeper.cpp. The form without the - explicit constructor fails to compile with GCC 2.91 on RH 6.2. - -- Fixed '==' -> '=' in configure.in to build under RH 6.2 and - probably other platforms. - -nxcomp-1.3.0-46 - -- The cleanup procedure now skips deletion of the IO streams - under Windows. This is intended to overcome a strange segfault - occurring at random time, at the time proxy is being shutdown. - -nxcomp-1.3.0-45 - -- Newer versions of the stdlibc++ do not seem to be able to deal - with NULL strings or non printable characters. This caused the - standard error stream to get sometimes corrupted in the case - TEST and DEBUG logs were enabled in Loop.cpp. - -nxcomp-1.3.0-44 - -- Disabled TEST and DEBUG logs in ServerChannel. - -nxcomp-1.3.0-43 - -- Fixed a crash when unpacking an image in server proxy in the - case the unpack state for the given channel had not been - previously created. - -nxcomp-1.3.0-42 - -- Small modification to setSchedule() to not account previous - data accumulated in the encode buffer. The new code seems to - allow better use of the available bandwidth. - -nxcomp-1.3.0-41 - -- Further fix in Tight decompression. Content of the main write - buffer was not removed before flushing the unpacked data to - the X server link. - -nxcomp-1.3.0-40 - -- Removed the code marked as FIXME in Loop and ServerChannel. - Code was used in previous version to override any pack method - other than NO_PACK and to disable initialization of the shared - memory. - -nxcomp-1.3.0-39 - -- Solved the problem with unpacking of RDP text on big-endian - architectures. The width field in PutPackedImage was put as - 16 bits and extracted as 32 bits at decoding side. - -- Moved the code checking if any of the children has exited in a - specific function. This function is now called any time signals - are newly enabled. This works even on Solaris. - -- Enabled use of shared memory with Tight image decompression. - -- Added event NXCollectPropertyNotify to NXproto.h. - -nxcomp-1.3.0-38 - -- Message locks are now checked before splitting a message. - -nxcomp-1.3.0-37 - -- Added a further counter to yield encoding data if the amount - of output bytes to be written to channels exceeds a threshold. - -- Modified proxy to write data immediately if the encoding loop - was interrupted. - -nxcomp-1.3.0-36 - -- Further fix required by Tight decompression. By handling mul- - tiple writes in the Tight class we may flush the main write - buffer in the wrong order. If Tight decompression is enabled, - the buffer is now flushed before decoding the packed image. - -- A SIGCHLD is raised any time signals are newly enabled. This - allows the main loop to wait() the pid of children that had - exited while signals were disabled. - -nxcomp-1.3.0-35 - -- Fixed Tight decompression by handling multiple writes to the - channel's transport inside the decompression function. - -- Made Tight decompressor in ServerChannel a pointer instead of - an instance of the class. Class is allocated the first time it - is referenced. - -- Rewritten handleUnpack() in ServerChannel to use a switch() - on the pack method instead of multiple if(). - -nxcomp-1.3.0-34 - -- Disabled RENDER extension when running X agent sessions on - the Solaris client. Problems seem to be caused by incompati- - bilities in the implementation of RENDER on the Sun X server - shipped by default. We did not test NX with the XFree86 X - server, but it seems that, when using the Sun X server, even - plain X clients don't make full use of the extension. - -nxcomp-1.3.0-33 - -- Added 4 new fields to the X_NXGetControlParameters reply. - A dialog should be shown by agent if proxy was not able to - negotiate a persistent cache or if a cache was selected but - not loaded because incompatible or corrupted. - -- Fixed a bug on Solaris where socket() must be recreated if - the first connect() fails. Not a problem. The strange thing - is that if you reuse the socket(), the subsequent connect() - is successful and the program fails as soon as you try to - write to it. - -nxcomp-1.3.0-32 - -- Added request X_NXFreeUnpack to free the resources allocated - by the remote proxy to unpack images for the given agent's - client - -- Added an alert at X server side if proxies were not able to - negotiate a persistent cache or if a cache was selected but - not loaded at X server side (that means that probably cache - was not compatible or corrupted). The alert is not enabled - at the moment. Before enabling it, we need to find a way to - deal with full-screen mode. - -- Tuning of MIT-SHM parameters. - -nxcomp-1.3.0-31 - -- Modified the following requests to carry the id of the - agent's client: - - - X_NXSetUnpackGeometry - - X_NXSetUnpackColormap - - X_NXSetUnpackAlpha - - X_NXPutPackedImage - - Now each agent's client has its own record pointing to the - geometry, colormap and alpha channel that will be used to - unpack the image. Code is not finished yet so it is advisable - that agents' writers keep using client id 0. Note also that - the final solution will require some changes to the way split - notifications are sent to agent that I plan to implement in - the next versions. - -- The X_NXSetUnpackGeometry request has now a message store. - This should reduce the overhead to the minimum even in the - case of dumb agents not checking if the current geometry - matches the image to be unpacked. - -nxcomp-1.3.0-30 - -- Improved handling of short-circuited replies at X client - side. Request opcodes are now pushed in the sequence queue - to determine if a reply is expected. In this case tainting - of reply is skipped to preserve the sequence ordering of - any event or error that could have generated by the reply. - This seems to solve all the problems reported by people - running a NX session in virtual desktop mode nested in an - existing session being run in single application mode. - -- Modified the cleanup procedure to print the 'Waiting for' - message in the session log only at the time all X channels - have been actually shut down. This message can be used by - the NX server to find out the appropriate time to close - the session. - -- Added the selected session type to the 'Using pack method' - message printed at startup. - -- Added the option to close down the proxy link and perform - a clean shutdown of the session, re-read the whole session - configuration or restart the proxy link when a SIGHUP is - delivered to the proxy process. The default behaviour is - to close down the session. The new default (the old one was - to restart the link) is a required feature to let users run - full sessions using single application mode f.e. in a LTSP - environment. I noted that when the controlling terminal of - the X session is closed, a SIGHUP is delivered to the X - server side proxy (probably it is delivered to all the con- - nected clients, and, thus for NX, only to the proxy). This - signal can be used to terminate the whole session. - -nxcomp-1.3.0-29 - -- Changed defaults to disable image masks when running proxy - in single application mode. The new configuration requires - changes in NX server and in NX X11 library. Users should - experience much better image quality when using NX on slow - links. This comes at the cost of slightly worse compression - ratios. - -nxcomp-1.3.0-28 - -- Opcode of request was not rewritten by server channel when - using link LAN. This caused problems with taint of replies. - -nxcomp-1.3.0-27 - -- Modified the split store and the split procedures in client - channel to always return the client id in the notification - events. The new field is added to event at byte offset 28 - to preserve compatibility with previous agent releases. The - modification permits to agent to match the commit of alpha - channel with the original image, if requests are split by - proxy. - -- Temporarily set the timeout used to poll MIT-SHM completion - events coming from X server to 0. More testing is required. - -- Fixed an inconsistent message generated in statistics due to - a division by 0. - -nxcomp-1.3.0-26 - -- Modified pending timeout from 1 to 0 milliseconds. This means - that both channels and proxy are now immediately restarted to - let them consume all data left in their read buffer. - -- When querying the X server for MIT-SHM support, size of name - in X_QueryExtension request was sent as 32 bits instead of 16. - This caused request to fail on big endian architectures. - -- Modified the MIT-SHM initialization procedure to always send - all the 3 protocol requests also in the case of early failures. - -nxcomp-1.3.0-25 - -- Implemented handling of the new X_NXSetUnpackAlpha message. - Performances are very satisfactory. Using most of the current - GNOME and KDE applications, caching reaches 90% of the total - messages. - -- Modified the persistent cache management routines to handle - backward compatibility with proxy versions prior of 1.3.0. - -- It has been made possible to send both X_NXSetUnpackColormap - and X_NXSetUnpackAlpha messages with 0 entries to temporarily - disable use of the colormap or the alpha channel and free the - resources allocated by the server channel class. - -- Added function UnpackAlpha() to Unpack.cpp. - -nxcomp-1.3.0-24 - -- Using WriteBuffer::registerPointer() to track growing of the - write buffer in handleFastWrite() functions. This problem - existed even in 1.2.2 but never shown up because we didn't - have to use the pointer after data had been written to the - write buffer. Now, instead, we have to post-process the write - buffer to copy data to the shared segment. - -- Optimized memory allocations running with link LAN to save a - memcpy() any time new data is allocated in the scratch buffer. - -- When running with link LAN the scratch buffer is now used only - when: - - - A further allocation would case growing of the write buffer - (and, thus, a memcpy() of the previous content). - - - When data to added is bigger than the write threshold. - - In previous versions the scratch buffer was used any time the - total amount of data to be written (write buffer + scratch - buffer) exceeded the scheduled write threshold. This caused - small writes to be appended even when a single write could - be obtained without reallocating the buffer. - -- Preliminary support for transporting the alpha channel in a - separate message in case of 32 bits displays using the RENDER - extension. - -nxcomp-1.3.0-23 - -- Modified the mask used to open the shared memory segment on - OS/X to 0777. We have to better investigate why the previous - 0600 mask doesn't work even if the user running the proxy is - the same user running the X server. - -nxcomp-1.3.0-22 - -- Implemented MIT-SHM support on LAN connections. - -- More MIT-SHM bug fixes. - -nxcomp-1.3.0-21 - -- Better use of the shared segment through an improved - algorithm leveraging the offset field of the X_ShmPutImage - request. The new algorithm greatly reduces the amount of - polls the proxy needs to perform to find if the completion - event has arrived. - -- Implemented MIT-SHM support for X_PutImage requests. - -- Implemented option shmem=value. Use of this option is anyway - discouraged. Proxy will allocate the shared memory segment - based on the size of the in-memory cache set by the user. - Use of MIT-SHM is disabled when user did set a memory cache - smaller than 2MB (for example on the embedded client). - -- Rewritten post-processing of images in server channel loop. - -- Improved error handling to ensure we intercept all MIT-SHM - X errors before they reach the NX agent. - -- Solved a problem that was causing channels to not reflect - shared memory support flags set in control. - -nxcomp-1.3.0-20 - -- Solved a compatibility problem when mixing proxy versions - 1.2.2 and 1.3.0. - -nxcomp-1.3.0-18 - -- Rewritten interfaces to shared memory initialization in - client and server channel. - -- Server channel checks for the completion event until a - timeout before reusing the shared memory segment. - -- Flush flag was not cleared after the write buffer had been - flushed in handleWrite() of both client and server channels. - This could lead to multiple fragmented writes, affecting - the performances. - -- Added -lcygipc to linking on Windows platform. - -- Added a check on GCC version to see if -Wnested-externs - -Wmissing-declarations are valid options. - -nxcomp-1.3.0-17 - -- Implemented initial support for MIT-SHM extension in the - network path between the X server proxy and the real X - server. Presently it works only for X_NXPutPackedImages. - -- Modified configure.in to compile under FreeBSD. - -- Small changes to sources due to FreeBSD support. - -nxcomp-1.3.0-16 - -- Fixed caching of RENDER extension on MacOS/X and Solaris. - -- Under Solaris an explicit call to EnableSignal() is needed - at the end of the signal handler as raising a signal seems - to reset the previous settings. - -- Can't find a way to get bytes queued for write on Solaris as - both FIONWRITE and TIOCOUTQ don't seem to be available. This - means that NX server on Solaris is only able to detect con- - gestions on proxy link at the time a write fails with error - EAGAIN. - -- Starting from this version, render extension messages are not - automatically discarded from cache when running agent based X - sessions. This is in preparation of render support introduced - in this release. - -nxcomp-1.3.0-15 - -- Changed default to force writes if X channels exceed buffer - limits. This change was suggested by benchmarks performed on - Win32. - -- Wrapped IO on cache files in functions performing better error - checking. - -- General cleanup in handling of socket options for MacOS/X and - Solaris. - -nxcomp-1.3.0-14 - -- Corrupted persistent caches were not deleted in case loading - of any of the message stores failed. To run further sessions - on the same host, user had to delete the cache file manually. - -- Improved error handling in JPEG decompression. Now connection - is reset in case of failure. - -- Before performing JPEG or PNG decompression, image is better - checked to verify if loading from disk failed. - -- Improved error handling in case of failure loading persistent - cache from disk. On MacOS/X istream -> fail() doesn't seem to - work properly. This needs further investigation. - -- The default installation path of nxclient is searched under - MacOS/X at the time nxclient is invoked in dialog mode. - -nxcomp-1.3.0-13 - -- Fixed a (further) compilation problem under Solaris. Now static - libraries are first searched under /usr/sfw/lib (in case Sun - would decide to include them in future releases). - -nxcomp-1.3.0-12 - -- Fixed parsing of command line when passing option -V. - -- Correctly detected ENOPROTOOPT when setting TCP_NODELAY socket - option on MacOS/X and Solaris. - -nxcomp-1.3.0-11 - -- Given option in configure to specify what needs to be built - statically: - - --with-static-png enable static linking of PNG library - --with-static-jpeg enable static linking of JPEG library - --with-static-z enable static linking of Z library - -nxcomp-1.3.0-10 - -- Fixed a problem in saving of persistent cache on big-endian - machines. - -nxcomp-1.3.0-9 - -- Testing with different settings to check if it's possible to - increase the performances under Windows. - -- Solved a problem in parsing of options that prevented proxy - to connect to a remote session running at port offset 0. - -- Fixed two warnings compiling on Solaris. - -- Changed configure.in to first check for nx-X11 includes - and libraries. Added "/usr/openwin/bin/makedepend" to path - searched for the executable. - -nxcomp-1.3.0-8 - -- Small cleanup in configure.in and files modified by Gregorz - Kryza to add support for Solaris. - -- A new configure script has been generated using autoconf-2.57-3. - -nxcomp-1.3.0-7 - -- Added support for detection of Solaris in configure script. - Now Makefile.in uses ranlib instead of ar. - -- Small changes in source and header files to support Solaris. - -nxcomp-1.3.0-4 - -- Corrected a bug that could cause priority on proxy and channels - to be not taken in account at the time proxy tries to determine - if it's time to flush the proxy link. - -- Better implementation of abort split notification by X server - proxy to its remote peer. The new implementation doesn't - need to set a timeout and permits notifications to be received - earlier. - -- Improved support for 'tainting' XSync() messages coming from - X clients in single application mode. Now a X_GetInputFocus - is sent to the real X server any n such messages received by - proxy. - -- Included support for 15 bpp displays. It seems that handling - them as 16 bpp it's OK. diff --git a/nxcomp/README b/nxcomp/README deleted file mode 100644 index f35cce6b5..000000000 --- a/nxcomp/README +++ /dev/null @@ -1,21 +0,0 @@ -README ------- - -Building --------- - -1. To compile: - - > tar zxvf nxcomp-X.Y.Z-N.tar.gz - > cd nxcomp - > ./configure - > make - - You'll have to run gmake under Solaris. - -2. The 'make install' target is not currently supported - in the Makefile, but it should be simple to fix. - -You need at least nxproxy and nxagent packages to enjoy this code. Check the -NoMachine website at http://www.nomachine.com to get the latest release. - diff --git a/nxcomp/README-IPAQ b/nxcomp/README-IPAQ deleted file mode 100644 index f9418635c..000000000 --- a/nxcomp/README-IPAQ +++ /dev/null @@ -1,21 +0,0 @@ -README-IPAQ ------------ - -1. Install a cross-compiler for ARM. You can find detailed - informations at: - - http://www.ailis.de/~k/knowledge/crosscompiling/toolchain.php - - There are also binaries needed to install the cross-compiler. - -2. Configure and compile libXcomp using: - - $ ./configure --with-ipaq - $ make - - After compilation type: - - $ arm-linux-strip libXcomp.* - -3. Remember that you also need nxproxy to actually run your NX X - session. diff --git a/nxcompext/CHANGELOG b/nxcompext/CHANGELOG deleted file mode 100644 index 941e9b411..000000000 --- a/nxcompext/CHANGELOG +++ /dev/null @@ -1,806 +0,0 @@ -ChangeLog: - -nxcompext-3.5.0-1 - -- Opened the 3.5.0 branch based on nxcompext-3.4.0-1. - -- Updated copyright to year 2011. - -nxcompext-3.4.0-1 - -- Opened the 3.4.0 branch based on nxcompext-3.3.0-4. - -- Updated version number. - -- Updated copyright to year 2009. - -nxcompext-3.3.0-4 - -- Fixed TR03G02199. The color palette allocated for encoding an image - having 256 colors or less was not freed. - -nxcompext-3.3.0-3 - -- Now setting the correct event serial number when sending collect - notifies back. - -nxcompext-3.3.0-2 - -- Updated VERSION. - -nxcompext-3.3.0-1 - -- Opened the 3.3.0 branch based on nxcompext-3.2.0-1. - -nxcompext-3.2.0-1 - -- Opened the 3.2.0 branch based on nxcompext-3.1.0-2. - -nxcompext-3.1.0-2 - -- Updated file VERSION to match the current release version. - -nxcompext-3.1.0-1 - -- Opened the 3.1.0 branch based on nxcompext-3.0.0-18. - -nxcompext-3.0.0-18 - -- Removed the remaining debug output. - -nxcompext-3.0.0-17 - -- Changed the copyright notices at the beginning of the files that - were referring to NXPROXY to refer to NXCOMPEXT. - -nxcompext-3.0.0-16 - -- Handle the reply failure in NXGetShmemParameters(). - -nxcompext-3.0.0-15 - -- Separated the functionalities made available by NXQueryDisplay() - in three distinct functions: - - NXDisplayReadable() Query the number of bytes readable from - the display connection. - - NXDisplayFlushable() Query the number of the outstanding bytes - to flush to the display connection. - - NXDisplayCongestion() Return a value between 0 and 9 indicating - the congestion level of the NX transport. - -- Renamed NXQueryDisplayError() to NXDisplayError(). - -nxcompext-3.0.0-14 - -- Removed support for Rdp, Tight and Hextile packed images encod- - ing since they have been made obsolete by the new NX server. - -- Changed the copyright attribution from Medialogic to NoMachine. - -nxcompext-3.0.0-13 - -- Allocate 1024 additional bytes for the Jpeg compression, instead - of 512, to avoid failures on very tiny images. - -- Removed support for the special *PNG_JPEG* pack method. - -nxcompext-3.0.0-12 - -- Implemented the NXEncodeBitmap() method. This is a very simple - encoder removing the 4th byte in 32 bits-per-plane images. For - the other pixmap depths it simply returns a pointer to the orig- - inal image data, saving the copy. This encoding is intended to - better leverage the stream compression on low bandwidth links. - -- Removed the quality parameter from the RGB/RLE encoding function. - -nxcompext-3.0.0-11 - -- Removed the additional parameter in the call to NXTransFlush(). - -nxcompext-3.0.0-10 - -- Moved the _NXRDPGlyph and _NXRDPText declarations from NXlib.h - to NXproto.h to force fields to be CARD32. - -- Fixed a typo in NXSetDisplayBuffer() that could cause a double - free. - -- Fixed a compilation error with old GCC versions. - -- Removed the warning issued on AMD64 when compiling with the logs - enabled. - -nxcompext-3.0.0-9 - -- Added the NXDisplayCongestion query type to NXQueryDisplay(). It - returns a value between 0 and 9, with 9 meaning that the link is - congested and no further data can be sent. - -- Added the NXSetDisplayBuffer() function. It allows the caller to - set the display output buffer size at runtime. - -- Removed the congestion and synchronization callbacks. - -nxcompext-3.0.0-8 - -- Removed the warnings issued when purging the collected data at - display reset. - -nxcompext-3.0.0-7 - -- Added the NXSetDisplayWriteHandler() interface. The function - registers a callback that will be invoked every time more data - is written to the display socket. - -nxcompext-3.0.0-6 - -- Made NXQueryDisplay() take into account the bytes in the display - buffer when queried for the bytes flushable. - -nxcompext-3.0.0-5 - -- Added file COPYING. - -nxcompext-3.0.0-4 - -- Updated copyright notices to the current year. - -nxcompext-3.0.0-3 - -- Imported changes up to nxcompext-2.1.0-4. - -- Fixed TR12D01564. Changed configure script to build library with - -fPIC option. - -- Added 256 byte to the size of Jpeg destination buffer. - -nxcompext-3.0.0-2 - -- Updated the file VERSION. - -nxcompext-3.0.0-1 - -- Opened the 3.0.0 branch based on nxcompext-2.0.0-33. - -nxcompext-2.0.0-33 - -- Placed the inclusion of jpeglib.h after the X includes to fix a - possible compilation error. - -nxcompext-2.0.0-32 - -- Avoid to copy the data to the scratch buffer and yield the task - of padding the output to _XSend() in the NXPutPackedImage(), NX- - SetUnpackAlpha() and NXSetUnpackColormap() requests. - -- Added support for the RLE pack method. - -nxcompext-2.0.0-31 - -- The X_NXSetUnpackColormap and X_NXSetUnpackAlpha now carry their - data in compressed form. The alpha data is compressed using the - ZLIB RLE encoding, while the colormap data is compressed using - the default ZLIB deflate. - -- Created new message structures to handle the compatibility with - the old proxy versions. When connected to an old proxy version - the agent should use the NXSetUnpackColormapCompat() and NXSet- - UnpackAlpha() interfaces. - -nxcompext-2.0.0-30 - -- Removed the unfriendly warning printed if a client tried to reset - the library multiple times. - -nxcompext-2.0.0-29 - -- Made possible to compile even if makedepend is not found. - -nxcompext-2.0.0-28 - -- Added the NXSetDisplaySynchronizationHandler() interface. The NX - transport will use the callback to report when the agent can use - the available bandwidth to synchronize the X objects that are - corrupted or incomplete. - -- Bytes from 14 to 24 in the NXGetControlParameters() reply report, - respectively, the frame timeout, the ping timeout, the preferred - image split mode and the split size threshold. - -nxcompext-2.0.0-27 - -- Changed the image cleanup functions and the Png and Jpeg encoders - to be independent from the host endianess. - -- Enabled again the image cleanup on big endian machines. - -nxcompext-2.0.0-26 - -- Added the NXAbortSplit() request. - -- Added information about the size of the shared memory segment used - by the remote proxy in the NXGetShmemParameters() reply. - -nxcompext-2.0.0-25 - -- Renamed the NXGetSplitResource() and NXGetUnpackResource() utili- - ties to NXAllocSplit() and NXAllocUnpack(). They can be called - with a NXAnyResource parameter to get the first available id or - requre a specific resource. From this version the resource must - be explicitly reserved. NXFreeUnpack() and NXFreeSplit() check - if the resource was allocated and don't do anything if it is not - the case. NXAllocSplit() and NXAllocUnpack() return NXNoResource - if the resource can't be reserved. - -nxcompext-2.0.0-24 - -- NXFlushDisplay() now verifies whether the XlibDisplayWriting flag - is set before flushing the display buffer. in this case, it only - flushes the NX link. - -nxcompext-2.0.0-23 - -- Implemented a move-to-front strategy for the image cache, to mi- - nimize the number of lookups. - -- Fixed the problems imtroduced by the new cache implementation by - modifying the memory allocation routines in Jpeg.c and Pgn.c. - -- Temporarily fixed the cleanup problems on big-endian machines by - skipping the operation. - -- Added a NXSetDisplayStatisticsHandler() to let the agent include - arbitrary data in the transport statistics. The parameter is a - pointer to a pointer to a null terminated string. The pointer is - set at the time the handler is registered. The pointed string can - be filled by the agent with its statistics data. - -nxcompext-2.0.0-22 - -- The NXCacheFindImage() returns a pointer to the checksum, if the - image is found. - -- The image cache uses the data passed to NXCacheAddImage() instead - of making a copy. - -- The Z stream used by the RGB encoder is allocated at initializat- - ion and freed at reset. - -nxcompext-2.0.0-21 - -- Removed the reliance on the local byte order in the image cleanup - functions. - -nxcompext-2.0.0-20 - -- Added the NXFinishSplit() request. It forces the proxy to comple- - tely transfer all the split messages for the given resource, and - then notify the agent. - -nxcompext-2.0.0-19 - -- Enabled again the cleanup of images. - -- Updated to comply with the new NXTransFlush() interface. - -nxcompext-2.0.0-18 - -- Moved all the declarations in Rgb.c at the beginning of the block - to avoid the possible compilation errors with old compilers. - -nxcompext-2.0.0-17 - -- Added a new RGB image encoder. For now the encoder uses a static - Z stream to compress the image data in the destination buffer and - allows the agent to use the simplest encoding by still separating - the alpha channel from the image data. The new encoder can be the - the base for implementing color reduction by dithering or a color- - mapped translation of the image similar to PNG, but without the - PNG overhead and with the colormap being sent to the client using - the NXSetUnpackColormap() opcode. - -- Created a new NXCleanImage() function that takes a XImage pointer - and uses either the CleanXYImage() or the CleanZImage() routines - to cleanup the padding bits. - -nxcompext-2.0.0-16 - -- Added a parameter to NXFlushDisplay() to specify what needs to be - flushed. The parameter can be one the following values, defined - in NXvars.h: - - NXFlushBuffer Only the Xlib buffer is to be flushed. - - NXFlushLink Flush both the Xlib buffer and any pending - data encoded by the NX transport. - - NXFlushIdle Inform the NX transport that the agent is - idle. This will let the NX transport encode - more low-priority data, and then flush the - link. - -- Ensured that the padding bytes are cleaned when creating a new - PNG image. It seems that some images are still missed. This is - to be investigated. - -nxcompext-2.0.0-15 - -- Ensured that the packed image cache is recreated only on a size - change. - -nxcompext-2.0.0-14 - -- Updated to get the karma delay field from the X_NXGetControlPara- - meters reply. - -nxcompext-2.0.0-13 - -- Added the NXSetDisplayPolicy() and NXSetDisplayFlushHandler() in- - terfaces. The second function registers a callback that will be - invoked by the NX transport when the number of bytes encoded by - the proxy exceeds the threshold set for the scheduled write. - -- Added the NXFlushDisplay() and NXQueryDisplay() interfaces. They - are used to hide the corresponding NX transport functions to the - application. NXQueryDisplay() can be called with the NXDisplay- - Flushable or NXDisplayReadable parameters, to get, repectively, - the number of bytes that are queued to the NX transport and the - number of bytes that is possible to read. - -- Included the remote proxy version in the NXGetControlParameter() - reply. - -nxcompext-2.0.0-12 - -- Added the NXGetSplitResource() and NXGetUnpackResource utilities. - These can be used by the client to find out the first unused id - available for a split or unpack operation. - -- Added the NXFreeSplit() request function. It makes the resource - available for the next operation and tells the proxy to destroy - all the storage associated to the split. - -- Renamed the NXNumberOfConnections constant to NXNumberOfResources. - -nxcompext-2.0.0-11 - -- Changed NXForceDisplayError() to also shut down the NX transport - by calling NXTransClose(). - -- Updated to comply with the new NX function prototypes introduced - in nxcomp-2.0.0-31. - -nxcompext-2.0.0-10 - -- NXQueryDisplayError() now checks the predicate function only if - the I/O error was not encountered already. - -nxcompext-2.0.0-9 - -- Added the NXSetDisplayErrorPredicate(), NXSetDisplayBlockHand- - ler(), NXSetDisplayCongestionHandler(), NXSetLostSequenceHand- - ler() interfaces to let the user set the values used internal- - ly. All functions return the previous handler. See ChangeLog - in nx-X11-2.0.0-16 and nx-X11-2.0.0-17. - -- Moved all the internal variables shared between Xlib, nxcompext - and the X server in nxcomp. Declarations and function prototypes - moved to NXvars.h. - -- Some name changes. In particular the NXContinueOnDisplayError() - function iss renamed NXHandleDisplayError() and NXDisplayError() - is now renamed NXQueryDisplayError(). To verify if the display - is valid, NXQueryDisplayError() will now call the _NXDisplayEr- - rorPredicate function, or, if the predicate function is not set, - will simply check the value of the XlibDisplayIOError flag. - -- Removed the NXGetCleanupParameters() and NXGetImageParameters() - interfaces and the remaining references to the unused display - buffer and image cleanup functions. - -- Updated the NoMachine copyright notice to year 2006. - -nxcompext-2.0.0-8 - -- Removed the unused screen parameter from XSetUnpackGeometry(). - -- NXSetUnpackGeometry() now fails if no visual is provided. - -nxcompext-2.0.0-7 - -- Changed the LICENSE file to state that the software is only made - available under the version 2 of the GPL. - -- Removed the misplaced DXPC copyright notices from the license. - They were copied from NXCOMP but they don't apply in any way to - NXCOMPEXT. - -nxcompext-2.0.0-6 - -- Added the NXSetCacheParameters() request. It tells to the local - proxy how to handle the X requests, namely if the next requests - have to be stored in the memory cache, split in smal data chunks, - and in the case of images, saved on disk in the persistent image - cache. The request will affect all X messages, including plain - and packed images. It can be used to tell the proxy to discard - images coming from some selected operations, like GLX or XVideo. - -nxcompext-2.0.0-5 - -- Added the NXGetFontParameters() request and reply. If the proxy - has been configured accordingly, the request returns the X font - path that can be set by the agent to tunnel the font server con- - nections through the NX link. - -nxcompext-2.0.0-4 - -- Initial work on font server tunneling. - -nxcompext-2.0.0-3 - -- Renamed the NXSetExposeEvents request to NXSetExposeParameters. - -nxcompext-2.0.0-2 - -- Modified the configure and the makefiles to support the Cygwin - environment. - -- Renamed Png.h to Pgn.h to avoid name clashes on Windows. - -- The distclean target now removes the autom4te.cache directory. - -nxcompext-2.0.0-1 - -- Opened the 2.0.0 branch based on nxcompext-1.5.0-20. - -nxcompext-1.5.0-20 - -- Removed the code installing a SIGSEGV handler before trying to - clean an image in NXCleanImageInPlace(). - -nxcompext-1.5.0-19 - -- Added the NXUnsetLibraryPath() function to specify the behaviour - of the Popen() in the X server. If the _NXUnsetLibraryPath flag - is set, the Popen() will remove the LD_LIBRARY_PATH variable from - the environment before running the child process. This will cause - the X server to run the process (for example the keyboard initia- - lization utilities) by using the native system libraries, instead - of the libraries shipped with the NX environment. - -nxcompext-1.5.0-18 - -- Moved the declarations of _NXEnable* and related structures from - Xlibint.h to NXlibint.h. - -- Use the include files from nx-X11 if the nx-X11/include directory - is found. The previous configure checked the presence of nx-X11/ - exports/include, that might not be built at the time this library - is compiled. - -nxcompext-1.5.0-17 - -- Added the -fPIC GCC flag when compiling on AMD64 architectures. - -- Removed all warnings when compiling with GCC4. - -- Small changes to configure.in to have specific CFLAGS. - -- Created a new configure using autoconf 2.59. - -nxcompext-1.5.0-16 - -- Added the 'mode' field in the NXStartSplit() request. It determi- - nes the strategy that the proxy will adopt to handle the image. - If set to 'eager', the proxy will only split the messages whose - size exceeds the split threshold (the threshold can be found in - the NXGetControlParameters() reply). If mode is set to lazy, the - proxy will split any image that it is not able to find in its - cache. - - The opcode and the two available modes are defined in NXproto.h, - currently: - - #define NXSplitModeDefault 0 - #define NXSplitModeEager 1 - #define NXSplitModeLazy 2 - -- All requests related to image streaming now carry a 'resource' id. - The id is currently ignored by the proxy in the case of NXCommit- - Split() requests. - -nxcompext-1.5.0-15 - -- Removed the NXSync() and NXKarma() operations, not used anymore - by the NX agents. - -- Updated to comply with changes occurred in the numbering of the - notification events and in the interface to the image streaming - functions. - -nxcompext-1.5.0-14 - -- Accounted for the missing xoffset field in clean-up of XYPixmaps. - -nxcompext-1.5.0-13 - -- Added a 'commit' field in NXCommitSplit(). When zero, the remote - proxy will remove the message from the split store, without send- - ing the recomposed image to the X server. - -nxcompext-1.5.0-12 - -- Added the NXContinueOnDisplayError() function to specify the be- - haviour of the Xlib I/O error handler. If the flag is set to true, - Xlib will simply return, instead of quitting the program. This - leaves to the application the responsibility of checking the sta- - te of the XlibDisplayIOError flag. - -- Changed NXDisplayIsValid() to NXDisplayError() and inverted the - logic. Now the function returns true if the display pointer is - NULL or the XlibDisplayIOError flag is set. - -- Added the NXForceDisplayError() function, to shutdown the display - descriptor and force Xlib to set the I/O error flag. - -nxcompext-1.5.0-11 - -- Added -I../nx-X11/exports/include to CCINCLUDES in Makefile.in. - -nxcompext-1.5.0-10 - -- Added FindLSB() to replace ffs() that may be not present on some - systems. - -- Some cosmetic changes. - -nxcompext-1.5.0-9 - -- Fixed a printf() that prevented the code to compile if TEST was - enabled. - -nxcompext-1.5.0-8 - -- Implemented the NXLib interface for asynchronous handling of the - XGetInputFocus requests and replies. - -nxcompext-1.5.0-7 - -- Removed the _NXFlushSize parameter. New agents run the NX trans- - port in-process, so we don't get any benefit from increasing the - display buffer size. - -nxcompext-1.5.0-6 - -- Added a NXDisplayIsValid() to check that the display is not NULL - and that the descriptor was not shut down after an IOError. The - reason a function is needed for this is that the flags field is - only in Xlibint and it is not visible to Xlib applications. - -nxcompext-1.5.0-5 - -- Added the NXGetCollect*Resource utility functions, returning the - first available small integer resource id that can be used in a - subsequent collect request. - -nxcompext-1.5.0-4 - -- Added the NXNumberOfConnections constant. - -nxcompext-1.5.0-3 - -- Implemented the NXLib interface for the asynchronous handling of - the XGrabPointer requests and replies. - -- Solved an error in image cleaning that prevented the 8 bits-per- - pixel images to be completely cleaned. Due to the bug, only half - of the total lines were cleaned. - -- Removed a bug that prevented the cleaning of XYPixmaps images of - bitmap unit 32 and byte order LSB. - -- Renamed the NXImageCache variables to show they are global. They - are currently used in the nxagent code. - -nxcompext-1.5.0-2 - -- Changed VERSION file. - -nxcompext-1.5.0-1 - -- Opened the 1.5.0 branch. - -nxcompext-1.4.1-1 - -- Removed the configure option --with-static. There are two options - now, --with-static-png and --with-static-jpeg, to offer a greater - degree of control on the resulting library. - -- This version differs from the 1.4.0-3-KRY1 in the way that the con- - figure script is generated by GNU Autoconf 2.57, the same version - used for nxcomp. - -- Opened the 1.4.1 branch. - -nxcompext-1.4.0-3 - -- Updated the VERSION file to reflect the 1.4.0 status. - -nxcompext-1.4.0-2 - -- Imported changes from the latest 1.3.2 development branch. - -- The 1.4.0 branch already had a 1.4.0-1 version. The changes from - the 1.4.0-1 were up to date with the 1.3.2-2 version. - -nxcompext-1.3.2-6 - -- Fixed problem with icons in KDE and Mozilla on SPARC Solaris. The - problem was related to cleaning of one-bit XYPixmaps on big-endian - hosts, where shift of the cleaning mask executed in the wrong di- - rection. - -nxcompext-1.3.2-5 - -- Changes in Clean.c to compile on Solaris. - -nxcompext-1.3.2-4 - -- Fixed a bug in clean image procedures for 1bit XYPixmaps. The bug - caused Mozilla to trash some transparent icons in web pages and - the toolbar. - -- Added cleaning of the padding bytes at the end of the data chunk - inside XImage structure - -- Implemented handling of SIGSEGV during cleanup in case of static - data. - -- Moved image cleanup and masking code in new Clean.c and Mask.c - sources. - -- Corrected few typos in NXCollectImage code. - -nxcompext-1.3.2-2 - -- Imported 1.4.0-1 changes from the 1.4.0 development branch. - -- Modified NXAllocColors to handle errors generated allocating - each requested color. A per-color result code is now returned - to the caller. - -- Code cleanup in Png.h and Png.c. - -nxcompext-1.3.2-1 - -- Opened the 1.3.2 branch. - -nxcompext-1.3.1-2 - -- Removed the underline characters and added a colon in the - title of this ChangeLog to fully comply with format used in - the release notices. - -nxcompext-1.3.1-1 - -- Opened the 1.3.1 branch. - -nxcompext-1.3.0-18 - -- Added the _NXLostSequenceHandler function to let NX agents - suppress the error message and modify the default Xlib - behaviour when out-of-order sequence numbers are received. - Pointer to function is assigned to _NXLostSequenceFunction - in XlibInt.c. - -- Original output buffer size in stock XFree86 is 2048. We try - to reduce context switches and help stream compression by - increasing the maximum size of the buffer 8192. _NXFlushSize - determines when the display buffer is actually flushed. It is - set by default to 4096 in XlibInt.c and set to 0 to use the - maximum available size at the time NXGetControlParameters() - is called. - -nxcompext-1.3.0-17 - -- In handling of asynchronous GetProperty replies a warning - message was printed in session log when a null property was - stored in the state structure. This message is now printed - only if TEST is defined. - -nxcompext-1.3.0-16 - -- Added asynchronous handling of GetProperty request and reply - by means of the NXCollectProperty and NXGetCollectedProperty - requests and the NXCollectPropertyNotify event. - -nxcompext-1.3.0-15 - -- Added 4 new fields to the X_NXGetControlParameters reply. - -nxcompext-1.3.0-14 - -- Added request X_NXFreeUnpack to free the resources allocated - by the remote proxy to unpack images for the given agent's - client - -nxcompext-1.3.0-13 - -- Modified the following requests to carry the id of the - agent's client in the field resource: - - - X_NXSetUnpackGeometry - - X_NXSetUnpackColormap - - X_NXSetUnpackAlpha - - X_NXPutPackedImage - -nxcompext-1.3.0-11 - -- Modified the MIT-SHM initialization procedure to always send - all the 3 protocol requests also in the case of early failures. - -nxcompext-1.3.0-10 - -- Added handling of X_NXSetUnpackAlpha request. - -- It has been made possible to send both X_NXSetUnpackColormap - and X_NXSetUnpackAlpha messages with 0 entries to temporarily - disable use of the colormap or the alpha channel and free the - resources allocated by the remote proxy. - -nxcompext-1.3.0-9 - -- Solved a compatibility problem when mixing proxy versions - 1.2.2 and 1.3.0 due to the missing X_NXGetShmemParameters - request. - -nxcompext-1.3.0-7 - -- Reduced the number of requests needed to setup the shared - segment at X server proxy from 4 to 3. - -- Small changes to the shared memory interface to support - path X agent to X client proxy. - -nxcompext-1.3.0-6 - -- Implemented initial support for MIT-SHM extension in the - network path between the X server proxy and the real X - server. - -- Configure script now checks for the FreeBSD environment. - -- New configure script generated using autoconf-2.57-3. - -- Removed the XFree86 CCDEFINES from Makefile.in. - -nxcompext-1.3.0-5 - -- Cosmetic changes. - -- Started to convert configure.in to the new layout adopted - for nxcomp. - -- Created file CHANGELOG. - -nxcompext-1.3.0-4 - -- More fixes in image clean-up. - -nxcompext-1.3.0-3 - -- Many fixes in image clean-up functions to handle differences - in endianess between client and X server. - -nxcompext-1.3.0-2 - -- Modified configure.in to compile under Solaris. - -nxcompext-1.3.0-1 - -- First 1.3.0 version based on nxcompext-1.2.2-12. - diff --git a/nxcompext/README b/nxcompext/README deleted file mode 100644 index 39648e76b..000000000 --- a/nxcompext/README +++ /dev/null @@ -1,15 +0,0 @@ -README ------- - -1. To compile: - - > tar zxvf nxcompext-X.Y.Z-N.tar.gz - > cd nxcompext - > ./configure - > make - - You'll have to run gmake under Solaris. - -2. The 'make install' target is not currently supported - in the Makefile, but it should be simple to fix. - diff --git a/nxcompshad/CHANGELOG b/nxcompshad/CHANGELOG deleted file mode 100644 index 3472a4afe..000000000 --- a/nxcompshad/CHANGELOG +++ /dev/null @@ -1,404 +0,0 @@ -ChangeLog: - -nxcompshad-3.5.0-2 - -- Fixed TR03G02189. Now key combinations involving the Shift keys - are recognized correctly. - -nxcompshad-3.5.0-1 - -- Opened the 3.5.0 branch based on nxcompshad-3.4.0-3. - -- Updated copyright to year 2011. - -nxcompshad-3.4.0-3 - -- Updated copyright to year 2010. - -nxcompshad-3.4.0-2 - -- Fixed TR08G02256. Now the Shadow session is shown correctly with - MIT-SHM extension disabled. - -- Improved updateShadowFrameBuffer() and ~Poller() functions. - -- Avoided memory leak. - -nxcompshad-3.4.0-1 - -- Opened the 3.4.0 branch based on nxcompshad-3.3.0-3. - -- Updated version number. - -- Updated copyright to year 2009. - -- Improved error messages logging in case of initialization failures. - -nxcompshad-3.3.0-3 - -- Fixed TR01G02158. Keymap initialization could be incorrect because - of a type mismatch on 64 bit platforms. - -nxcompshad-3.3.0-2 - -- Updated VERSION. - -nxcompshad-3.3.0-1 - -- Opened the 3.3.0 branch based on nxcompshad-3.2.0-3. - -nxcompshad-3.2.0-3 - -- Improved keycode translation. - -nxcompshad-3.2.0-2 - -- Solved a problem when sending fake modifier events. - -- Added support for keyboard events handling for the web player. - -- Changed keycodes translation for Solaris keyboard. - -- Corrected a problem for keycodes translation from Solaris keyboard. - -- Fixed TR02F02001. In shadow session the shadower's keyboard layout - could be wrong. Now keycodes are correctly translated if master and - shadow keyboards have different layouts. - -- Added NXShadowGetScreenSize() and NXShadowSetScreenSize() functions, - so that the shadow session can handle correctly the resize of the - master session window. - -- Solved a compilation problem on GCC 4.3. - -nxcompshad-3.2.0-1 - -- Opened the 3.2.0 branch based on nxcompshad-3.1.0-2. - -nxcompshad-3.1.0-2 - -- Updated file VERSION to match the current release version. - -nxcompshad-3.1.0-1 - -- Opened the 3.1.0 branch based on nxcompshad-3.0.0-19. - -nxcompshad-3.0.0-19 - -- Skip initialization of damage extension if it was already disabled. - -nxcompshad-3.0.0-18 - -- The poller destructor checks if the damage extension is in use. - -- Small changes to the function getting the screen content in the case - damage is not in use. - -nxcompshad-3.0.0-17 - -- Cleanup of some log messages. - -nxcompshad-3.0.0-16 - -- Disabled some log message in the functions initializing the poller. - -nxcompshad-3.0.0-15 - -- Before calling XTest functions, it is checked if the connection to - master X server has been initialized. - -nxcompshad-3.0.0-14 - -- After the shm segment is created, its mode is changed and it is - marked for destroying. A check on the number of attaches is done. - -nxcompshad-3.0.0-13 - -- Creating the shm segment even if the uid of master X server can't be - retrieved. - -- Fixed reallocation of update region. - -- Checking if the master X server provides XTest extension. - -nxcompshad-3.0.0-12 - -- Fixed a compiler warning on AMD64 platform. - -- Changed configure script to add -fPIC option. - -- Fixed a mismatch in UpdateManager destructor. - -nxcompshad-3.0.0-11 - -- Fixed the function setting the uid of shm segment. - -- Sync with the master X server before marking the shm segment to be - destroyed. - -nxcompshad-3.0.0-10 - -- Setting the shm segments as readable only by the master X server - process. - -- Mark shm segments to be destroyed when the last process detach. - -- Enabled keycode translation in order to allow keyboards of different - models to work. - -nxcompshad-3.0.0-9 - -- Changed the LICENSE file to state that the software is only made - available under the version 2 of the GPL. - -- Added file COPYING. - -- Changes to translate keycodes between different keyboard types. The - keycodes are translated through the keysym. - -- Changes to convert a Mode_switch key to ISO_Level3_Shift if it is - needed. - -nxcompshad-3.0.0-8 - -- Added interface function NXShadowDisableShm disabling the use of - MIT-SHM extension. - -- Added interface function NXShadowDisableDamage disabling the use of - DAMAGE extension. - -- Added interface function NXShadowSetDisplayUid setting the uid of - shadowed X server - -- Changed the owner of shared memory segments to the uid of the sha- - dowed X server. - -- Fixed logWarning method. - -- Moved the code initializing the use of shared memory to shmInit - method of X11 Poller. - -nxcompshad-3.0.0-7 - -- Removed the class qualifier in the declaration of destroyUpdate- - ManagerRegion(). - -nxcompshad-3.0.0-6 - -- Fixed build errors on 64 bit platforms. - -- Called XTestGrabControl to override possible grabs of the X server. - -nxcompshad-3.0.0-5 - -- Added some stub members to the Poller class. These are intended to - handle keyboard state. - -- Changes in the default polling algorithm to disable the line pri- - ority persistence. - -nxcompshad-3.0.0-4 - -- If a low layer handling of screen changes is available (DAMAGE in - case of X11), polling routine uses it and returns immediately. - -- Creating a Damage notify object if the extension is supported. - -- DamageNotify events are saved in the update region. After all avail- - able events have been handled, the content of screen is retrieved - by ShnGetImage requests. - -- XDamageSubtract and XSync are done before any event handling. - -- Damages are requested as raw rectangles. - -- Added Xdamage and Xrandr to required libraries. - -- Fixed a problem with some lines not refreshed in shadowing mode. - -nxcompshad-3.0.0-3 - -- Added destroyUpdateManagerRegion() method to UpdateManager class. - -- Turned off some log messages. - -- Changed configure.in to remove warnings related to deprecated header - files and options. - -- Changed Makefile.in to remove autom4te.cache dir if the target is - 'distclean'. - -- Removed multi-word file names. - -nxcompshad-3.0.0-2 - -- Changes to get the screen of original display by a ShmGetImage. - -- Exit the polling loop if more than 50 ms have elapsed. - -nxcompshad-3.0.0-1 - -- Created nxcompshad based on nxshadow-3.0.0-7. - -nxshadow-3.0.0-7 - -- Deleted files KeyCursorTmp.cpp, scancodes.h, constant.h. - -- Renamed NXshadow.h to Shadow.h. - -- Merged NXshadowEvent.h with Shadow.h. - -- Fixed configure.in, changed Makefile.in to build Xcompshad library, - rebuilt configure script. - -nxshadow-3.0.0-6 - -- Implemented a callback mechanism to ask the caller program if screen - polling have to be suspended. - -nxshadow-3.0.0-5 - -- Changes to comply with the library name. - -- Fixed a bug in CorePoller that could prevent the update of the last - line of a rectangle. - -nxshadow-3.0.0-4 - -- Removed some parameters of the NXShadowAddUpdaterDisplay() function. - -nxshadow-3.0.0-3 - -- Updated copyright notices to the current year. - -- Code cleanup in KeysCursorTmp.c file. - -nxshadow-3.0.0-2 - -- If master agent uses shared memory extension, the GetImage is rea- - lized by XShmGetImage() function. - -- Added new parameters to NXShadowAddUpdaterDisplay() function, the - depth and bit mask color of the master display. - -nxshadow-3.0.0-1 - -- Opened the nxshadow-3.0.0 branch based on the nxaccess-3.0.0-13. - -- Renamed NXaccess.h NXaccessEvent.h and RegionM.h files as NXshadow.h - NXshadowEvent.h and Regions.h. - -- Modified the Makefile.in file and configure scripts in order to - compile the component. - -nxaccess-3.0.0-13 - -- Fixed X11Poller.cpp pre-processing. - -nxaccess-3.0.0-12 - -- Fixed build problems on Solaris. - -nxaccess-3.0.0-11 - -- Added NXShadowUpdateBuffer() function. This function creates the - buffer for the polling. - -- If the scaline fails, the polling will suspend for 50 ms. - -- Added some functions in order to access data member class. - -nxaccess-3.0.0-10 - -- Used XTEST extension to make the shared display create input events. - -nxaccess-3.0.0-9 - -- Added the mouse events. - -- Now, it's possible to connect to X server display or agent display, - the display's content is captured by GetImage and sent to another - display by PutImage. - -nxaccess-3.0.0-8 - -- Added KeysCursorTmp.cpp file. - -- Solved a problem with the keys, when the window lost focus the Key- - Release events weren't propagated. - -nxaccess-3.0.0-7 - -- Added functions in order to remove issues with some keys combina- - tion. - -nxaccess-3.0.0-6 - -- Added functions to simulate keys Ctrl + Alt + Del in order to run - the Task Manager application. - -- Now nxaccess is able to manage all switches between desktops. - -nxaccess-3.0.0-5 - -- Solved a problem with the cursor shape. After a while, the cursor - shape are no more updated. - -- Now the cursor is updated only when it changes its shape. - -- Removed a dirty lines after screen updates. - -- Removed the unused file Keyboard.cpp. - -- Added the colorCorrect() macro in NXaccess.h. - -- Removed the colorCorrect() function in Updater.cpp. - -nxaccess-3.0.0-4 - -- Renamed some source files and functions conforming them to the name - of component. - -nxaccess-3.0.0-3 - -- Removed the parameter of type Display in all methods of the class - Poller. - -- Print, Break and Pause keys are enabled. - -nxaccess-3.0.0-2 - -- Modified the Makefile.in in order to avoid compiling the executive - file. - -- Removed the unused file Main.cpp. - -- The Windows keys are enabled. - -- Synchronized local and remote states of Num_Lock, Caps_Lock and - Scroll_Lock. - -- Updated the NoMachine copyright notices. - -nxaccess-3.0.0-1 - -- Opened the 3.0.0 branch based on the nxmirror-2.0.0-3. - -nxmirror-2.0.0-3 - -- Added the keyboard events for all layouts. - -- The mouse wheel button is enabled. - -nxmirror-2.0.0-2 - -- Completed implementation of the keyboard events only for italian - layout. - -- Added the mouse events and shape cursor. - -nxmirror-2.0.0-1 - -- Opened the 2.0.0 branch based on the 1.5.0-60. - -- Added CHANGELOG. diff --git a/nxproxy/CHANGELOG b/nxproxy/CHANGELOG deleted file mode 100644 index e5dff2e4f..000000000 --- a/nxproxy/CHANGELOG +++ /dev/null @@ -1,216 +0,0 @@ -ChangeLog: - -nxproxy-3.5.0-1 - -- Opened the 3.5.0 branch based on nxproxy-3.4.0-2. - -- Updated copyright to year 2011. - -nxproxy-3.4.0-2 - -- Updated copyright to year 2009. - -nxproxy-3.4.0-1 - -- Opened the 3.4.0 branch based on nxproxy-3.3.0-2. - -- Changed version number. - -nxproxy-3.3.0-2 - -- Updated VERSION. - -nxproxy-3.3.0-1 - -- Opened the 3.3.0 branch based on nxproxy-3.2.0-1. - -nxproxy-3.2.0-1 - -- Opened the 3.2.0 branch based on nxproxy-3.1.0-2. - -nxproxy-3.1.0-2 - -- Updated version number. - -nxproxy-3.1.0-1 - -- Opened the 3.1.0 branch based on nxproxy-3.0.0-4. - -nxproxy-3.0.0-4 - -- Added file COPYING. - -- Changed the LICENSE file to state that the software is only made - available under the version 2 of the GPL. - -nxproxy-3.0.0-3 - -- Updated the copyright notices to year 2007. - -nxproxy-3.0.0-2 - -- Updated the file VERSION. - -nxproxy-3.0.0-1 - -- Opened the 3.0.0 branch based on nxproxy-2.0.0-2. - -nxproxy-2.0.0-2 - -- Updated copyright to year 2006. - -nxproxy-2.0.0-1 - -- Opened the 2.0.0 branch based on nxproxy-1.5.0-10. - -nxproxy-1.5.0-10 - -- Added the JPEG, PNG and Z libraries to the linker when compiling - on Cygwin. GCC 3.3.x requires that these libraries are explicitly - given while this is not required since GCC 3.4.x. - -- Created a new configure using autoconf 2.59. - -nxproxy-1.5.0-9 - -- Removed provision for dynamically loading a different version of - the nxcomp library. - -nxproxy-1.5.0-8 - -- Updated to reflect the new naming of the NX transport interfaces. - -nxproxy-1.5.0-7 - -- Modified the Makefile.in to remove the *.out.* files generated by - Valgrind when running a 'make clean'. - -- Modified the README files and removed files that were outdated. - -nxproxy-1.5.0-6 - -- Removed the NX_FORCE_IDLE_PROXY stubs. - -nxproxy-1.5.0-5 - -- This version has NX_FORCE_IDLE_PROXY undefined, so it should work - in a way that is compatible with the old nxproxy. - -nxproxy-1.5.0-4 - -- This software is crafted by default to test the new integration - between nxcomp and nxssh. The process will stay idle and will - let nxssh create the proxy. Note that the session log will go to - 'sshlog', not to 'session'. This will have to be fixed in nxcomp - in future versions. - -- Removed the references to the "bind" functionality that is not - used in the current software. - -nxproxy-1.5.0-3 - -- Added a NX_FORCE_IDLE_PROXY. If set, nxproxy will stay idle and - will not try to create a nxcomp proxy. This is used for testing - the new in-process nxcomp functionalities with the development - versions of nxclient and nxssh software. - -nxproxy-1.5.0-2 - -- Small changes to this file. - -nxproxy-1.5.0-1 - -- Opened the 1.5.0 branch. - -nxproxy-1.4.1-1 - -- Opened the 1.4.1 branch. - -nxproxy-1.4.0-3 - -- We were lucky. We found a machine where nxproxy failed exactly - in the same way described by multiple users in their reports. - The error was the same ('dlopen: win32 line 126') and neither - rebasing the Cygwin DLLs or removing all the other Cygwin li- - braries worked. So the problem had necessarily to be in a bug- - gy Cygwin dlopen() implementation. To solve this I had to make - changes to the nxproxy code on Windows, so it links to nxcomp - at compile time in the way specified below. As far as I can - tell, any other way fails. This seems to be another Cygwin bug: - the linker says that everything is OK but then the executable - can't be run. Both the Cygwin's bash and the command.com say - 'Permission denied'. - - LIBS = -L../nxcomp -lstdc++ -Wl,-e,_mainCRTStartup -lXcomp \ - -lcygipc -static -lpng -static -ljpeg -lz - -nxproxy-1.4.0-2 - -- Added a Binder class invoked when calling proxy with -B option. - It would serve as a replacement of the modifications I'm doing - in nxssh. The class is just a framework and the implementation - is unfinished. - -- Solved a potential problem in Main.c with NXExit() being called - after the dlclose(). This was unlikely to happen as proxy never - returns. - -nxproxy-1.4.0-1 - -- Opened the 1.4.0 branch. - -nxproxy-1.3.2-1 - -- Opened the 1.3.2 branch. - -nxproxy-1.3.1-2 - -- Removed the underline characters and added a colon in the - title of this ChangeLog to fully comply with format used in - the release notices. - -nxproxy-1.3.1-1 - -- Opened the 1.3.1 branch. - -nxproxy-1.3.0-7 - -- Added a check on the OS version when running on MacOS/X. - Versions 10.2 and 10.3 differ in the way names are mangled. - -- Fixed error detection on dlsym(). The previous code was not - able to correctly identify missing symbols. - -nxproxy-1.3.0-6 - -- Modified configure.in to compile under FreeBSD. - -nxproxy-1.3.0-5 - -- Fixed a (further) compilation problem under Cygwin. - -nxproxy-1.3.0-4 - -- New nxproxy is able to load libXcomp by dlopen() under - Cygwin. This simplifies both code in Main.c and the - configure.in script. - -- Changed configure.in to not link with -mwindows under - Cygwin. Linking with -mwindows prevented stderr to be - correctly output when running nxproxy on a console. - -nxproxy-1.3.0-3 - -- Changed configure.in to first check for nx-X11 includes - and libraries. Added "/usr/openwin/bin/makedepend" to - path searched for the executable. - -nxproxy-1.3.0-2 - -- Small cleanup in configure.in. A new configure script has - been generated using autoconf-2.57-3. - -nxproxy-1.3.0-1 - -- Updated internal version, so this release tries to load - libXcomp version 1.3.0. diff --git a/nxproxy/README b/nxproxy/README deleted file mode 100644 index 8f95d9f3f..000000000 --- a/nxproxy/README +++ /dev/null @@ -1,14 +0,0 @@ -README ------- - -1. To compile: - - > tar zxvf nxproxy-X.Y.Z-N.tar.gz - > cd nxproxy - > ./configure - > make - - You'll have to run gmake under Solaris. - -2. The 'make install' target is not currently supported - in the Makefile, but it should be simple to fix. diff --git a/nxproxy/README-IPAQ b/nxproxy/README-IPAQ deleted file mode 100644 index 7a8a8a958..000000000 --- a/nxproxy/README-IPAQ +++ /dev/null @@ -1,27 +0,0 @@ -README-IPAQ ------------ - -1. Install a cross-compiler for ARM. You can find detailed - informations at: - - http://www.ailis.de/~k/knowledge/crosscompiling/toolchain.php - - There are also binaries needed to install the cross-compiler. - -2. Configure and compile nxproxy using: - - $ ./configure --with-ipaq - $ make - - After compilation type: - - $ arm-linux-strip nxproxy - -3. You need libXcomp.so to run nxproxy. Be sure you include the - library in your LD_LIBRARY_PATH. For example, you can run: - - > export LD_LIBRARY_PATH $HOME/NX/nxcomp - > nxproxy -S localhost:8 - -4. The package nxscripts contains many examples of NX usage that - you can modify to suit your needs. diff --git a/nxproxy/README-VALGRIND b/nxproxy/README-VALGRIND deleted file mode 100644 index ce4d513a4..000000000 --- a/nxproxy/README-VALGRIND +++ /dev/null @@ -1,39 +0,0 @@ -README-VALGRIND ---------------- - -You can run nxproxy (and nxcomp) under the supervision of valgrind -(a very good memory debugger) by wrapping nxproxy in the following -script: - - -#!/bin/bash - -# Enable core dumps. - -ulimit -c unlimited - -# Set this to directory where nxproxy is located. - -NXPROXY_DIR=~/NX/nxproxy - -# Set this to directory where valgrind is located. - -VALGRIND_DIR=/usr/local/bin - -exec ${VALGRIND_DIR}/valgrind -v --leak-check=yes --leak-resolution=high \ - --show-reachable=yes --show-reachable=yes \ - --suppressions=${NXPROXY_DIR}/nxproxy.supp \ - --num-callers=16 --logfile-fd=2 \ -\ -${NXPROXY_DIR}/nxproxy $1 $2 $3 $4 $5 $6 $7 $8 $9 - - -Run the following commands on your shell, right in the place where -the nxproxy executable is to be placed in your setup: - -$ cat >nxproxy - -$ chmod a+x nxproxy - -Output of valgrind will go on stderr, that is in session file, if -run in NX environment. -- cgit v1.2.3 From ebb2026a7cb5295986397955c1661322fb13963d Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 5 Jul 2016 13:24:16 +0200 Subject: man pages: Greatly improve man pages nxagent.1 and nxproxy.1. --- nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 997 ++++++++++++++++++++++- nxproxy/man/nxproxy.1 | 380 ++++++++- 2 files changed, 1347 insertions(+), 30 deletions(-) (limited to 'nxproxy') diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index f92393893..a97204afe 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -1,37 +1,992 @@ -.TH NXAGENT 1 + +.\" Copyright 1984 - 1991, 1993, 1994, 1998 The Open Group +.\" Copyright 2011 - 2016, Mike Gabriel +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and its +.\" documentation for any purpose is hereby granted without fee, provided that +.\" the above copyright notice appear in all copies and that both that +.\" copyright notice and this permission notice appear in supporting +.\" documentation. +.\" +.\" The above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.ds q \N'34' +.TH NXAGENT 1 3.6.x .SH NAME -nxagent \- NoMachine's NX Agent. +nxagent \- nx-X11 Agent (nested Xserver optimized for remote computing) .SH SYNOPSIS .B nxagent .I "[options]" - .SH DESCRIPTION \fBnxagent\fR is an Xnest-like X server for remote application/desktop access. .PP -\fBnxagent\fR implements a very efficient compression of the X11 protocol. +\fBnxagent\fR implements a very efficient compression of the X11 +protocol, called the NX protocol. +.PP +The NX protocol increases performance when using X applications over high +latency and low bandwidth networks, while providing a local (LAN-like) +usage experience even if connecting from off-site locations (via cable +modem or GSM). +.PP +\fBnxagent\fR can be used standalone as a nested X server (with NX +protocol disabled), but its real benefits are gained when using it over +remote connections via the nxcomp compression library. The counterpart +application on the other end (i.e. the client) is called +\fBnxproxy\fR. .PP -This increases performance when using X applications over high latency and -low bandwidth networks, while providing a local (LAN-like) usage experience -even if connecting from off-site locations (via cable modem or GSM). +When used in proxy <-> agent mode, \fBnxagent\fR adds the feature of +being suspendible. Sessions can be started from one client, suspended and +then resumed from another client. .PP -\fBnxagent\fR is not designed to be used as a standalone application. -It has to be launched on the server side by remote desktop frameworks like FreeNX. +\fBnxagent\fR and \fBnxproxy\fR are utilized by various remote +application/desktop frameworks for providing server-side GUI application +access from remote client systems. +.PP +Currently, nx-X11 Agent is co-maintained by three of these projects: The +Arctica Project, TheQVD and X2Go. .PP -Available clients are -NoMachine's \fBnxclient\fR or the community projects \fBqtnx\fR and \fBremmina\fR -(with NX plugin). + +.SH "STARTING THE SERVER" +The nx-X11 Agent should be run in user space. Other than the system's +local X.org server, \fBnxagent\fR does not require to be run as root. +When bundled with a remote application framework, you normally don't have +to launch \fBnxagent\fR manually. nx-X11 Agent startup is normally +managed by the underlying framework (e.g. Arctica Session Manager, X2Go +Server, etc.). +.PP +When the nx-X11 Agent starts up (e.g. by typing 'nxagent -ac :1' in a +terminal window), it typically launches in "windowed desktop" mode. On +your local X server, there appears a new window being an X server itself. +.PP +However, nx-X11 Agent also supports rootless (or seamless) application +mode and a shadow session mode (similar to what VNC does). +.PP +Example: You can launch a complete desktop session inside this nested X +server now: +.TP 8 +The Debian way... +.PP +.nf + $ export DISPLAY=:1 + $ STARTUP=mate-session /etc/X11/Xsession +.fi +.TP 8 +The Fedora / Gentoo / openSUSE way... +.PP +.nf + ### FIXME / TODO ### +.fi +.PP +However, nx-X11 Agent also supports rootless (or seamless) application +mode and a shadow session mode (similar to what VNC does). .SH OPTIONS -.TP +The nx-X11 agent accepts a range of default X server options as described +below. Those default options have to be provided via the command line. + +Furthermore, the nx-X11 Agent accepts some nx-X11 specific options, +described further below. + +Last but not least, the nx-X11 Agent accepts several more options +provided via the $DISPLAY environment variable, the so-called nx/nx +options. See below for further details. + +.SH STANDARD XSERVER OPTIONS +.TP 8 +.B :\fIdisplaynumber\fP +The X server runs as the given \fIdisplaynumber\fP, which by default is 0. +If multiple X servers are to run simultaneously on a host, each must have +a unique display number. See the DISPLAY +NAMES section of the \fIX\fP(__miscmansuffix__) manual page to learn how to +specify which display number clients should try to use. +.TP 8 +.B \-a \fInumber\fP +sets pointer acceleration (i.e. the ratio of how much is reported to how much +the user actually moved the pointer). +.TP 8 +.B \-ac +disables host-based access control mechanisms. Enables access by any host, +and permits any host to modify the access control list. +Use with extreme caution. +This option exists primarily for running test suites remotely. +.TP 8 +.B \-audit \fIlevel\fP +sets the audit trail level. The default level is 1, meaning only connection +rejections are reported. Level 2 additionally reports all successful +connections and disconnects. Level 4 enables messages from the +SECURITY extension, if present, including generation and revocation of +authorizations and violations of the security policy. +Level 0 turns off the audit trail. +Audit lines are sent as standard error output. +.TP 8 +.B \-auth \fIauthorization-file\fP +specifies a file which contains a collection of authorization records used +to authenticate access. See also the \fIxdm\fP(1) and +\fIXsecurity\fP(__miscmansuffix__) manual pages. +.TP 8 +.B bc +disables certain kinds of error checking, for bug compatibility with +previous releases (e.g., to work around bugs in R2 and R3 xterms and toolkits). +Deprecated. +.TP 8 +.B \-bs +disables backing store support on all screens. +.TP 8 +.B \-br +sets the default root window to solid black instead of the standard root weave +pattern. +.TP 8 +.B \-c +turns off key-click. +.TP 8 +.B c \fIvolume\fP +sets key-click volume (allowable range: 0-100). +.TP 8 +.B \-cc \fIclass\fP +sets the visual class for the root window of color screens. +The class numbers are as specified in the X protocol. +Not obeyed by all servers. +.TP 8 +.B \-co \fIfilename\fP +sets name of RGB color database. The default is +.IR /usr/share/nx/rgb . +.ig +.TP 8 +.B \-config \fIfilename\fP +reads more options from the given file. Options in the file may be separated +by newlines if desired. If a '#' character appears on a line, all characters +between it and the next newline are ignored, providing a simple commenting +facility. The \fB\-config\fP option itself may appear in the file. +.BR NOTE : +This option is disabled when the Xserver is run with an effective uid +different from the user's real uid. +.. +.TP 8 +.B \-core +causes the server to generate a core dump on fatal errors. +.TP 8 +.B \-deferglyphs \fIwhichfonts\fP +specifies the types of fonts for which the server should attempt to use +deferred glyph loading. \fIwhichfonts\fP can be all (all fonts), +none (no fonts), or 16 (16 bit fonts only). +.TP 8 +.B \-dpi \fIresolution\fP +sets the resolution for all screens, in dots per inch. +To be used when the server cannot determine the screen size(s) from the +hardware. +.TP 8 +.B dpms +enables DPMS (display power management services), where supported. The +default state is platform and configuration specific. +.TP 8 +.B \-dpms +disables DPMS (display power management services). The default state +is platform and configuration specific. +.TP 8 +.B \-f \fIvolume\fP +sets feep (bell) volume (allowable range: 0-100). +.TP 8 +.B \-fc \fIcursorFont\fP +sets default cursor font. +.TP 8 +.B \-fn \fIfont\fP +sets the default font. +.TP 8 +.B \-fp \fIfontPath\fP +sets the search path for fonts. This path is a comma separated list +of directories which the X server searches for font databases. +See the FONTS section of this manual page for more information and the default +list. +.TP 8 .B \-help -Lists all others options that are not listed here. +prints a usage message. +.TP 8 +.B \-I +causes all remaining command line arguments to be ignored. +.TP 8 +.B \-maxbigreqsize \fIsize\fP +sets the maxmium big request to +.I size +MB. +.TP 8 +.B \-nolisten \fItrans-type\fP +disables a transport type. For example, TCP/IP connections can be disabled +with +.BR "\-nolisten tcp" . +This option may be issued multiple times to disable listening to different +transport types. +.TP 8 +.B \-noreset +prevents a server reset when the last client connection is closed. This +overrides a previous +.B \-terminate +command line option. +.TP 8 +.B \-p \fIminutes\fP +sets screen-saver pattern cycle time in minutes. +.TP 8 +.B \-pn +permits the server to continue running if it fails to establish all of +its well-known sockets (connection points for clients), but +establishes at least one. This option is set by default. +.TP 8 +.B \-nopn +causes the server to exit if it fails to establish all of its well-known +sockets (connection points for clients). +.TP 8 +.B \-r +turns off auto-repeat. +.TP 8 +.B r +turns on auto-repeat. +.TP 8 +.B \-s \fIminutes\fP +sets screen-saver timeout time in minutes. +.TP 8 +.B \-su +disables save under support on all screens. +.TP 8 +.B \-t \fInumber\fP +sets pointer acceleration threshold in pixels (i.e. after how many pixels +pointer acceleration should take effect). +.TP 8 +.B \-terminate +causes the server to terminate at server reset, instead of continuing to run. +This overrides a previous +.B \-noreset +command line option. +.TP 8 +.B \-to \fIseconds\fP +sets default connection timeout in seconds. +.TP 8 +.B \-tst +disables all testing extensions (e.g., XTEST, XTrap, XTestExtension1, RECORD). +.TP 8 +.B tty\fIxx\fP +ignored, for servers started the ancient way (from init). +.TP 8 +.B v +sets video-off screen-saver preference. +.TP 8 +.B \-v +sets video-on screen-saver preference. +.TP 8 +.B \-wm +forces the default backing-store of all windows to be WhenMapped. This +is a backdoor way of getting backing-store to apply to all windows. +Although all mapped windows will have backing store, the backing store +attribute value reported by the server for a window will be the last +value established by a client. If it has never been set by a client, +the server will report the default value, NotUseful. This behavior is +required by the X protocol, which allows the server to exceed the +client's backing store expectations but does not provide a way to tell +the client that it is doing so. +.TP 8 +.B \-x \fIextension\fP +loads the specified extension at init. +This is a no-op for most implementations. +.TP 8 +.B [+-]xinerama +enables(+) or disables(-) XINERAMA provided via the PanoramiX extension. This is +set to off by default. +.TP 8 +.B [+-]rrxinerama +enables(+) or disables(-) XINERAMA provided via the RandR extension. By +default, this feature is enabled. To disable XINERAMA completely, make +sure to use both options (-xinerama -rrxinerama) on the command line. + +.SH SERVER DEPENDENT OPTIONS +The nx-X11 Xserver (i.e. \fBnxagent\fR) additionally accepts the following options (non-standard options, dependent on Xserver implementation): +.TP 8 +.B \-logo +turns on the X Window System logo display in the screen-saver. +There is currently no way to change this from a client. +.TP 8 +.B nologo +turns off the X Window System logo display in the screen-saver. +There is currently no way to change this from a client. +.TP 8 +.B \-render +.BR default | mono | gray | color +sets the color allocation policy that will be used by the render extension. +.RS 8 +.TP 8 +.I default +selects the default policy defined for the display depth of the X +server. +.TP 8 +.I mono +don't use any color cell. +.TP 8 +.I gray +use a gray map of 13 color cells for the X render extension. +.TP 8 +.I color +use a color cube of at most 4*4*4 colors (that is 64 color cells). +.RE +.TP 8 +.B \-dumbSched +disables smart scheduling on platforms that support the smart scheduler. +.TP +.B \-schedInterval \fIinterval\fP +sets the smart scheduler's scheduling interval to +.I interval +milliseconds. +.SH NXAGENT SPECIFIC OPTIONS +The nx-X11 system adds the following command line arguments: +.TP 8 +.B \-forcenx +force use of NX protocol messages assuming communication through nxproxy +.TP 8 +.B \-timeout \fIint\fP +auto-disconnect timeout in seconds (minimum allowed: 60) +.TP 8 +.B \-norootlessexit +don't exit if there are no clients in rootless mode +.TP 8 +.B \-norender +disable the use of the render extension +.TP 8 +.B \-nocomposite +disable the use of the composite extension +.TP 8 +.B \-nopersistent +disable disconnection/reconnection to the X display on SIGHUP +.TP 8 +.B \-noshmem +disable use of shared memory extension +.TP 8 +.B \-shmem +enable use of shared memory extension +.TP 8 +.B \-noshpix +disable use of shared pixmaps +.TP 8 +.B \-shpix +enable use of shared pixmaps +.TP 8 +.B \-noignore +don't ignore pointer and keyboard configuration changes mandated by clients +.TP 8 +.B \-nokbreset +don't reset keyboard device if the session is resumed +.TP 8 +.B \-noxkblock +always allow applications to change layout through XKEYBOARD +.TP 8 +.B \-tile WxH +size of image tiles (minimum allowed: 32x32) +.TP 8 +.B \-D +enable desktop mode (default) +.TP 8 +.B \-R +enable rootless mode +.TP 8 +.B \-S +enable shadow mode +.TP 8 +.B \-B +enable proxy binding mode +.PP +Other than the command line options, \fBnxagent\fR can be configured at +session startup and at runtime (i.e. when resuming a suspended session) +by so-called nx/nx options. +.PP +As nx/nx options all options supported by nxcomp (see \fBnxproxy\fR man +page) and all nxagent nx/nx options (see below) can be used. +. +When launching an nxcomp based nx-X11 agent session (i.e. proxy <-> +agent), you will normally set the $DISPLAY variable like this: +.PP +.nf + $ export DISPLAY=nx/nx,listen=,options=: + $ nxagent : +.fi +.PP +The value for is some value of a not-yet-used X11 +display (e.g. :50). +.PP +Using an options file is recommended, but you can also put available +nx/nx options (see below) into the DISPLAY variable directly. Note, that +the $DISPLAY variable field is of limited length. +.PP +As you can pick an arbitrary (unused) TCP port or Unix +socket file path. This is the port / socket that you have to connect to +with the \fBnxproxy\fR application. +.PP +Available nx-X11 Agent options (as an addition to nx/nx options supported +by nxcomp already): +.TP 8 +.B options= +read options from file, this text file can contain a single loooong line with comma-separated nx/nx options +.TP 8 +.B rootless= +start \fBnxagent\fR in rootless mode, matches \-R given on the command line, no-op when resuming (default: false) +.TP 8 +.B geometry= +desktop geometry when starting or resuming a session, no-op in rootless mode (default 66% of the underlying X server geometry) +.TP 8 +.B resize= +set resizing support (default: true) +.TP 8 +.B fullscreen= +start or resume a session in fullscreen mode (default: off) +.TP 8 +.B keyboard= +set remote keyboard layout +.TP 8 +.B clipboard= +enable / disable (set to: \fInone\fR) clipboard support, uni-directional (\fIserver\fR or \fIclient\fR) or bi-directional (\fIboth\fR, default setting) support +.TP 8 +.B streaming= +streaming support for images, not fully implemented yet and thus non-functional +.TP 8 +.B backingstore= +disable or enforce backing store support (default: BackingStoreUndefined) +.TP 8 +.B composite= +enable or disable Compsite support in \fBnxagent\fR (default: enabled) +.TP 8 +.B xinerama= +enable or disable XINERAMA support in \fBnxagent\fR (default: enabled) +.TP 8 +.B shmem= +enable using shared memory +.TP 8 +.B shpix= +enable shared pixmaps support +.TP 8 +.B kbtype= +set remote keyboard type +.TP 8 +.B client= +type of connecting operating system (supported: \fIlinux\fR, \fIwindows\fR, \fIsolaris\fR and \fImacosx\fR) +.TP 8 +.B shadow= +start \fBnxagent\fR in shadow mode, matches \-S given on the command line, no-op when resuming (default: false) +.TP 8 +.B shadowuid= +unique identifier for the shadow session +.TP 8 +.B shadowmode= +full access (set to \fI1\fR) or viewing-only (set to \fI0\fR, default) +.TP 8 +.B defer= +defer image updates (enabled for all connection types except LAN), accepts values \fI0\fR, \fI1\fR and \fI2\fR + +The default value can be set via the cmd line (\-defer). The value +provided as nx/nx option is set when resuming a session, thus it +overrides the cmd line default. +.TP 8 +.B tile= +set the tile size in pixels (\fIx\fR) for bitmap data sent over the wire + +The default value can be set via the cmd line (\-tile). The value +provided as nx/nx option is set when resuming a session, thus it +overrides the cmd line default. +.TP 8 +.B menu= +support pulldown menu in nx-X11 Agent session (only available on proxy <-> agent remote sessions) +.TP 8 +.B sleep= +delay X server operations when suspended (provided in msec), set to \fI0\fR to keep nx-X11 Agent session +fully functional when suspended (e.g. useful when mirroring nx-X11 Agent session via VNC) + +.SH XDMCP OPTIONS +X servers that support XDMCP have the following options. +See the \fIX Display Manager Control Protocol\fP specification for more +information. +.TP 8 +.B \-query \fIhostname\fP +enables XDMCP and sends Query packets to the specified +.IR hostname . +.TP 8 +.B \-broadcast +enable XDMCP and broadcasts BroadcastQuery packets to the network. The +first responding display manager will be chosen for the session. +.TP 8 +.B \-multicast [\fIaddress\fP [\fIhop count\fP]] +Enable XDMCP and multicast BroadcastQuery packets to the network. +The first responding display manager is chosen for the session. If an +address is specified, the multicast is sent to that address. If no +address is specified, the multicast is sent to the default XDMCP IPv6 +multicast group. If a hop count is specified, it is used as the maximum +hop count for the multicast. If no hop count is specified, the multicast +is set to a maximum of 1 hop, to prevent the multicast from being routed +beyond the local network. +.TP 8 +.B \-indirect \fIhostname\fP +enables XDMCP and send IndirectQuery packets to the specified +.IR hostname . +.TP 8 +.B \-port \fIport-number\fP +uses the specified \fIport-number\fP for XDMCP packets, instead of the +default. This option must be specified before any \-query, \-broadcast, +\-multicast, or \-indirect options. +.TP 8 +.B \-from \fIlocal-address\fP +specifies the local address to connect from (useful if the connecting host +has multiple network interfaces). The \fIlocal-address\fP may be expressed +in any form acceptable to the host platform's \fIgethostbyname\fP(3) +implementation. +.TP 8 +.B \-once +causes the server to terminate (rather than reset) when the XDMCP session +ends. +.TP 8 +.B \-class \fIdisplay-class\fP +XDMCP has an additional display qualifier used in resource lookup for +display-specific options. This option sets that value, by default it +is "MIT-Unspecified" (not a very useful value). +.TP 8 +.B \-cookie \fIxdm-auth-bits\fP +When testing XDM-AUTHENTICATION-1, a private key is shared between the +server and the manager. This option sets the value of that private +data (not that it is very private, being on the command line!). +.TP 8 +.B \-displayID \fIdisplay-id\fP +Yet another XDMCP specific value, this one allows the display manager to +identify each display so that it can locate the shared key. + +.SH XKEYBOARD OPTIONS +X servers that support the XKEYBOARD (a.k.a. \*qXKB\*q) extension accept the +following options. All layout files specified on the command line must be +located in the XKB base directory or a subdirectory, and specified as the +relative path from the XKB base directory. The default XKB base directory is +.IR /usr/share/X11/xkb . +.TP 8 +.B [+-]kb +enables(+) or disables(-) the XKEYBOARD extension. +.TP 8 +.BR [+-]accessx " [ \fItimeout\fP [ \fItimeout_mask\fP [ \fIfeedback\fP [ \fIoptions_mask\fP ] ] ] ]" +enables(+) or disables(-) AccessX key sequences. +.TP 8 +.B \-xkbdir \fIdirectory\fP +base directory for keyboard layout files. This option is not available +for setuid X servers (i.e., when the X server's real and effective uids +are different). +.TP 8 +.B \-ar1 \fImilliseconds\fP +sets the autorepeat delay (length of time in milliseconds that a key must +be depressed before autorepeat starts). +.TP 8 +.B \-ar2 \fImilliseconds\fP +sets the autorepeat interval (length of time in milliseconds that should +elapse between autorepeat-generated keystrokes). +.TP 8 +.B \-noloadxkb +disables loading of an XKB keymap description on server startup. +.TP 8 +.B \-xkbdb \fIfilename\fP +uses \fIfilename\fP for default keyboard keymaps. +.TP 8 +.B \-xkbmap \fIfilename\fP +loads keyboard description in \fIfilename\fP on server startup. + +.SH SECURITY EXTENSION OPTIONS +X servers that support the SECURITY extension accept the following option: +.TP 8 +.B \-sp \fIfilename\fP +causes the server to attempt to read and interpret filename as a security +policy file with the format described below. The file is read at server +startup and reread at each server reset. +.PP +The syntax of the security policy file is as follows. +Notation: "*" means zero or more occurrences of the preceding element, +and "+" means one or more occurrences. To interpret , ignore +the text after the /; it is used to distinguish between instances of + in the next section. +.PP +.nf + ::= * + + ::= '\en' + + ::= | | | + + ::= # * '\en' + + ::= '\en' + + ::= sitepolicy '\en' + + ::= property '\en' + + ::= + + ::= any | root | + + ::= | + + ::= = + + ::= [ | | ]* + + ::= r | w | d + + ::= a | i | e + + ::= | | + + ::= " * " + + ::= ' * ' + + ::= + -.SH FURTHER READINGS -Information on NX: http://www.nomachine.com + ::= [ ' ' | '\et' ]* + +Character sets: + + ::= any character except '\en' + ::= any character except " + ::= any character except ' + ::= any character except those in +.fi +.PP +The semantics associated with the above syntax are as follows. +.PP +, the first line in the file, specifies the file format +version. If the server does not recognize the version , it +ignores the rest of the file. The version string for the file format +described here is "version-1" . +.PP +Once past the , lines that do not match the above syntax +are ignored. +.PP + lines are ignored. +.PP + lines are currently ignored. They are intended to +specify the site policies used by the XC-QUERY-SECURITY-1 +authorization method. +.PP + lines specify how the server should react to untrusted +client requests that affect the X Window property named . +The rest of this section describes the interpretation of an +. +.PP +For an to apply to a given instance of , + must be on a window that is in the set of windows +specified by . If is any, the rule applies to + on any window. If is root, the rule applies to + only on root windows. +.PP +If is , the following apply. If is a , the rule applies when the window also +has that , regardless of its value. If is a , must also have +the value specified by . In this case, the property must +have type STRING and format 8, and should contain one or more +null-terminated strings. If any of the strings match , the +rule applies. +.PP +The definition of string matching is simple case-sensitive string +comparison with one elaboration: the occurrence of the character '*' in + is a wildcard meaning "any string." A can +contain multiple wildcards anywhere in the string. For example, "x*" +matches strings that begin with x, "*x" matches strings that end with +x, "*x*" matches strings containing x, and "x*y*" matches strings that +start with x and subsequently contain y. +.PP +There may be multiple lines for a given . +The rules are tested in the order that they appear in the file. The +first rule that applies is used. +.PP + specify operations that untrusted clients may attempt, and +the actions that the server should take in response to those operations. +.PP + can be r (read), w (write), or d (delete). The following +table shows how X Protocol property requests map to these operations +in The Open Group server implementation. +.PP +.nf +GetProperty r, or r and d if delete = True +ChangeProperty w +RotateProperties r and w +DeleteProperty d +ListProperties none, untrusted clients can always list all properties +.fi +.PP + can be a (allow), i (ignore), or e (error). Allow means +execute the request as if it had been issued by a trusted client. +Ignore means treat the request as a no-op. In the case of +GetProperty, ignore means return an empty property value if the +property exists, regardless of its actual value. Error means do not +execute the request and return a BadAtom error with the atom set to +the property name. Error is the default action for all properties, +including those not listed in the security policy file. +.PP +An applies to all s that follow it, until the next + is encountered. Thus, irwad means ignore read and write, +allow delete. +.PP +GetProperty and RotateProperties may do multiple operations (r and d, +or r and w). If different actions apply to the operations, the most +severe action is applied to the whole request; there is no partial +request execution. The severity ordering is: allow < ignore < error. +Thus, if the for a property are ired (ignore read, error +delete), and an untrusted client attempts GetProperty on that property +with delete = True, an error is returned, but the property value is +not. Similarly, if any of the properties in a RotateProperties do not +allow both read and write, an error is returned without changing any +property values. +.PP +Here is an example security policy file. +.PP +.ta 3i 4i +.nf +version-1 + +# Allow reading of application resources, but not writing. +property RESOURCE_MANAGER root ar iw +property SCREEN_RESOURCES root ar iw + +# Ignore attempts to use cut buffers. Giving errors causes apps to crash, +# and allowing access may give away too much information. +property CUT_BUFFER0 root irw +property CUT_BUFFER1 root irw +property CUT_BUFFER2 root irw +property CUT_BUFFER3 root irw +property CUT_BUFFER4 root irw +property CUT_BUFFER5 root irw +property CUT_BUFFER6 root irw +property CUT_BUFFER7 root irw + +# If you are using Motif, you probably want these. +property _MOTIF_DEFAULT_BINDINGS root ar iw +property _MOTIF_DRAG_WINDOW root ar iw +property _MOTIF_DRAG_TARGETS any ar iw +property _MOTIF_DRAG_ATOMS any ar iw +property _MOTIF_DRAG_ATOM_PAIRS any ar iw + +# The next two rules let xwininfo -tree work when untrusted. +property WM_NAME any ar + +# Allow read of WM_CLASS, but only for windows with WM_NAME. +# This might be more restrictive than necessary, but demonstrates +# the facility, and is also an attempt to +# say "top level windows only." +property WM_CLASS WM_NAME ar + +# These next three let xlsclients work untrusted. Think carefully +# before including these; giving away the client machine name and command +# may be exposing too much. +property WM_STATE WM_NAME ar +property WM_CLIENT_MACHINE WM_NAME ar +property WM_COMMAND WM_NAME ar + +# To let untrusted clients use the standard colormaps created by +# xstdcmap, include these lines. +property RGB_DEFAULT_MAP root ar +property RGB_BEST_MAP root ar +property RGB_RED_MAP root ar +property RGB_GREEN_MAP root ar +property RGB_BLUE_MAP root ar +property RGB_GRAY_MAP root ar + +# To let untrusted clients use the color management database created +# by xcmsdb, include these lines. +property XDCCC_LINEAR_RGB_CORRECTION root ar +property XDCCC_LINEAR_RGB_MATRICES root ar +property XDCCC_GRAY_SCREENWHITEPOINT root ar +property XDCCC_GRAY_CORRECTION root ar + +# To let untrusted clients use the overlay visuals that many vendors +# support, include this line. +property SERVER_OVERLAY_VISUALS root ar + +# Dumb examples to show other capabilities. + +# oddball property names and explicit specification of error conditions +property "property with spaces" 'property with "' aw er ed + +# Allow deletion of Woo-Hoo if window also has property OhBoy with value +# ending in "son". Reads and writes will cause an error. +property Woo-Hoo OhBoy = "*son" ad + +.fi +.SH "NETWORK CONNECTIONS" +The X server supports client connections via a platform-dependent subset of +the following transport types: TCP\/IP, Unix Domain sockets, DECnet, +and several varieties of SVR4 local connections. See the DISPLAY +NAMES section of the \fIX\fP(__miscmansuffix__) manual page to learn how to +specify which transport type clients should try to use. + +.SH GRANTING ACCESS +The X server implements a platform-dependent subset of the following +authorization protocols: MIT-MAGIC-COOKIE-1, XDM-AUTHORIZATION-1, +XDM-AUTHORIZATION-2, SUN-DES-1, and MIT-KERBEROS-5. See the +\fIXsecurity\fP(__miscmansuffix__) manual page for information on the +operation of these protocols. +.PP +Authorization data required by the above protocols is passed to the +server in a private file named with the \fB\-auth\fP command line +option. Each time the server is about to accept the first connection +after a reset (or when the server is starting), it reads this file. +If this file contains any authorization records, the local host is not +automatically allowed access to the server, and only clients which +send one of the authorization records contained in the file in the +connection setup information will be allowed access. See the +\fIXau\fP manual page for a description of the binary format of this +file. See \fIxauth\fP(1) for maintenance of this file, and distribution +of its contents to remote hosts. +.PP +The X server also uses a host-based access control list for deciding +whether or not to accept connections from clients on a particular machine. +If no other authorization mechanism is being used, +this list initially consists of the host on which the server is running as +well as any machines listed in the file \fI/etc/X\fBn\fI.hosts\fR, where +\fBn\fP is the display number of the server. Each line of the file should +contain either an Internet hostname (e.g. expo.lcs.mit.edu) or a DECnet +hostname in double colon format (e.g. hydra::) or a complete name in the format +\fIfamily\fP:\fIname\fP as described in the \fIxhost\fP(1) manual page. +There should be no leading or trailing spaces on any lines. For example: +.sp +.in +8 +.nf +joesworkstation +corporate.company.com +star:: +inet:bigcpu +local: +.fi +.in -8 +.PP +Users can add or remove hosts from this list and enable or disable access +control using the \fIxhost\fP command from the same machine as the server. +.PP +If the X FireWall Proxy (\fIxfwp\fP) is being used without a sitepolicy, +host-based authorization must be turned on for clients to be able to +connect to the X server via the \fIxfwp\fP. If \fIxfwp\fP is run without +a configuration file and thus no sitepolicy is defined, if \fIxfwp\fP +is using an X server where xhost + has been run to turn off host-based +authorization checks, when a client tries to connect to this X server +via \fIxfwp\fP, the X server will deny the connection. See \fIxfwp\fP(1) +for more information about this proxy. +.PP +The X protocol intrinsically does not have any notion of window operation +permissions or place any restrictions on what a client can do; if a program can +connect to a display, it has full run of the screen. +X servers that support the SECURITY extension fare better because clients +can be designated untrusted via the authorization they use to connect; see +the \fIxauth\fP(1) manual page for details. Restrictions are imposed +on untrusted clients that curtail the mischief they can do. See the SECURITY +extension specification for a complete list of these restrictions. +.PP +Sites that have better +authentication and authorization systems might wish to make +use of the hooks in the libraries and the server to provide additional +security models. +.SH SIGNALS +The X server attaches special meaning to the following signals: +.TP 8 +.I SIGHUP +This signal causes the server to close all existing connections, free all +resources, and restore all defaults. It is sent by the display manager +whenever the main user's main application (usually an \fIxterm\fP or window +manager) exits to force the server to clean up and prepare for the next +user. +.TP 8 +.I SIGTERM +This signal causes the server to exit cleanly. +.TP 8 +.I SIGUSR1 +This signal is used quite differently from either of the above. When the +server starts, it checks to see if it has inherited SIGUSR1 as SIG_IGN +instead of the usual SIG_DFL. In this case, the server sends a SIGUSR1 to +its parent process after it has set up the various connection schemes. +\fIXdm\fP uses this feature to recognize when connecting to the server +is possible. +.SH FONTS +The X server +can obtain fonts from directories and/or from font servers. +The list of directories and font servers +the X server uses when trying to open a font is controlled +by the \fIfont path\fP. +.LP +The default font path is +__default_font_path__ . +.LP +The font path can be set with the \fB\-fp\fP option or by \fIxset\fP(1) +after the server has started. +.SH FILES +.TP 30 +.I /etc/X\fBn\fP.hosts +Initial access control list for display number \fBn\fP +.TP 30 +.IR /usr/share/fonts/X11/misc, + /usr/share/fonts/X11/75dpi, + /usr/share/fonts/X11/100dpi +Bitmap font directories +.TP 30 +.IR /usr/share/fonts/X11/Type1 +Outline font directories +.TP 30 +.I /usr/share/nx/rgb +Color database +.TP 30 +.I /tmp/.X11-unix/X\fBn\fP +Unix domain socket for display number \fBn\fP +.TP 30 +.IR /tmp/rcX\fBn\fP +Kerberos 5 replay cache for display number \fBn\fP +.SH "SEE ALSO" +Protocols: +.I "X Window System Protocol," +.I "NX Compression Protocol," +.I "The X Font Service Protocol," +.I "X Display Manager Control Protocol" +.PP +Fonts: \fIbdftopcf\fP(1), \fImkfontdir\fP(1), \fImkfontscale\fP(1), +\fIxfs\fP(1), \fIxlsfonts\fP(1), \fIxfontsel\fP(1), \fIxfd\fP(1), +.I "X Logical Font Description Conventions" +.PP +Security: \fIXsecurity\fP(__miscmansuffix__), \fIxauth\fP(1), \fIXau\fP(1), +\fIxdm\fP(1), \fIxhost\fP(1), \fIxfwp\fP(1), +.I "Security Extension Specification" +.PP +Starting the server: \fIxdm\fP(1), \fIxinit\fP(1) +.PP +Controlling the server once started: \fIxset\fP(1), \fIxsetroot\fP(1), +\fIxhost\fP(1) +.PP +Server-specific man pages: +\fIXdec\fP(1), \fIXmacII\fP(1), \fIXsun\fP(1), \fIXnest\fP(1), +\fIXvfb\fP(1), \fIXFree86\fP(1), \fIXDarwin\fP(1). +.PP +Server internal documentation: +.I "Definition of the Porting Layer for the X v11 Sample Server" +.SH AUTHORS +The first sample X server was originally written by Susan Angebranndt, +Raymond Drewry, Philip Karlton, and Todd Newman, from Digital Equipment +Corporation, with support from a large cast. It has since been +extensively rewritten by Keith Packard and Bob Scheifler, from MIT. Dave +Wiggins took over post-R5 and made substantial improvements. +.PP +The first implementation of nx-X11 (version 1.x up to 3.5.x) was written +by NoMachine (maintained until 2011). +.PP +The current implementation of nx-X11 is maintained by various projects, +amongst others The Arctica Project, TheQVD (Qindel Group) and X2Go. .PP -Information on FreeNX: http://freenx.berlios.de +This manual page was written by Per Hansen , and +modified by Marcelo Boveto Shima and Mike +Gabriel . In 2016, the original +Xserver.man page shipped with nx-X11 was merged into the \fBnxagent\fR +man page and received a major update by Mike Gabriel +. -.SH AUTHOR -This manual page was written by Per Hansen , -and modified by Marcelo Boveto Shima and -Mike Gabriel . diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index d389d1068..6922c1427 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -5,23 +5,385 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH nxproxy 1 "Nov 2011" "Version 3.5.0" "NX Proxy" +.TH nxproxy 1 "June 2016" "Version 3.6.x" "NX Proxy" .SH NAME nxproxy \- NX Proxy Tool .SH SYNOPSIS 'nh .fi .ad l -\fBnxproxy\fR +\fBnxproxy\fR \fI[] :\fR .SH DESCRIPTION \fBnxproxy\fR is a tool that allows one to tunnel X sessions through -the NX compression libraries. \fBnxproxy\fR is a backend application -utilized by the X2GoClient GUI and some other NX/X2Go clients. -.PP -.SH OPTIONS -For an insight in \fBnxproxy\fR options use \fBnxproxy \-help\fR on the command line. +the NX compression library. \fBnxproxy\fR is a backend application +utilized by various client application (Remmina, X2Go Client, PyHoca-Gui, +Arctica Client, TheQVD Client, etc.). .PP +.SH COMMAND LINE OPTIONS +.TP 8 +.B -C +Specify that nxproxy has to run on the 'X client' side, listening for +connections and impersonating an X server. +.TP 8 +.B -S +Specify that nxproxy has to run in 'X server' mode, thus forwarding the +connections to daemons running on the client. +.TP 8 +.B -h +Print this message. +.TP 8 +.B -v +Print version information. +.TP 8 +.B : +Put at the end, specifies the host and port of the listening proxy. + +.SH NX/NX DISPLAY OPTIONS +Multiple nx/nx options can be specified in the DISPLAY environment or on +the command line, by using the nx/nx,option=value notation. +.TP 8 +.B link= +An indication of the link speed that is going to be used between the +proxies. Usually the compression and the other link parameters depend on +this setting. The value can be either 'modem', 'isdn', 'adsl', 'wan', +'lan', 'local' or a bandwidth specification, like for example '56k', +'1m', '100m', etc. + +.TP 8 +.B type= +Type of session, for example 'windows', 'unix-kde'. 'unix-application', +etc. + +.TP 8 +.B display= +Specify the real display where X connections have to be forwarded by the +proxy running on the client. + +.TP 8 +.B listen= +Local port used for accepting the proxy connection. + +.TP 8 +.B loopback= +Bind to the loopback device only. + +.TP 8 +.B accept= +Name or IP of host that can connect to the proxy. + +.TP 8 +.B connect= +Name or IP of host that the proxy will connect to. + +.TP 8 +.B port= +Remote port used for the connection. + +.TP 8 +.B retry= +Number of connection atempts. + +.TP 8 +.B root= +The root directory for the session. Usually is the C\-* or S\-* in the .nx +directory in the user's home, with '*' being the virtual display. + +.TP 8 +.B session= +Name of the session file. The default is the name 'session' in the +session directory. + +.TP 8 +.B errors= +Name of the log file used by the proxy. The default is the name 'errors' +in the session directory. + +.TP 8 +.B stats= +Name of the file where are written the proxy statistics. The default is a +file 'stats' in the session directory. The proxy replaces the data in the +file whenever it receives a SIGUSR1 or SIGUSR2 signal: + +.I SIGUSR1: +Gives total statistics, i.e. statistics collected since the beginning of +the session. + +.I SIGUSR2: +Gives partial statistics, i.e. statistics collected since the last time +this signal was received. + +.TP 8 +.B cookie= +Use the provided cookie for authenticating to the remote proxy. The same +cookie is used as the fake value used for the X authorization. The fake +cookie is replaced on the X server side with the real cookie to be used +for the display, so that the real cookie doesn't have to travel over the +net. When not using a proxy cookie, any host will be able to connect to +the proxy. See also the 'accept' parameter. + +.TP 8 +.B nodelay= +A boolean indicating if TCP_NODELAY has to be set on the proxy link. Old +Linux kernels had problems with handling TCP_NODELAY on PPP links. + +.TP 8 +.B policy= +Let or not the agent decide when it is the best time to flush the proxy +link. If set to 0, the proxy will flush any encoded data immediately. The +option has only effect on the X client side proxy. + +.TP 8 +.B render= +Enable or disable use of the RENDER extension. + +.TP 8 +.B taint= +Try to suppress trivial sources of X roundtrips by generating the reply +on the X client side. + +.TP 8 +.B delta= +Enable X differential compression. + +.TP 8 +.B data= +Enable or disable the ZLIB data compression. It is possible to specify a +value between 0 and 9. Usually the value is chosen automatically based on +the requested link setting. + +.TP 8 +.B stream= +Enable or disable the ZLIB stream compression. The value, between 0 and +9, is usually determined according to the requested link setting. Not +fully implemented in nx-X11 Agent, yet. + +.TP 8 +.B limit= +Specify a bitrate limit allowed for this session. + +.TP 8 +.B memory= +Trigger memory optimizations used to keep small the size of X buffers. +This is useful on embedded plat- forms, or where memory is scarce. + +.TP 8 +.B cache= +Size of the in-memory X message cache. Setting the value to 0 will +disable the memory cache as well as the NX differential compression. + +.TP 8 +.B images= +Size of the persistent image cache. + +.TP 8 +.B shseg= +Enable the use of the MIT-SHM extension between the \fBnxproxy\fR and the +real X server. A value greater than 1 is assumed to be the size of +requested shared memory segment. By default, the size of the segment is +determined based on the size of the in-memory cache. + +.TP 8 +.B load= +Enable loading a persistent X message cache at the proxy startup. + +.TP 8 +.B save= +Enable saving a persistent X message cache at the end of session. + +.TP 8 +.B cups= +Enable or disable forwarding of CUPS connections, by listening on the +optional port 'n'. + +.TP 8 +.B aux= +Enable or disable forwarding of the auxiliary X channel used for +controlling the keyboard. The 'keybd=' form is accepted for backward +compatibility. + +.TP 8 +.B smb= +Enable or disable forwarding of SMB connections. The 'samba=' form is +accepted for backward compatibility. + +.TP 8 +.B media= +Enable forwarding of audio connections. + +.TP 8 +.B http= +Enable forwarding of HTTP connections. + +.TP 8 +.B font= +Enable forwarding of reversed connections to a font +server running on the NX server. + +.TP 8 +.B file= +Enable forwarding of file transfer connections. + +.TP 8 +.B mask= +Determine the distribution of channel ids between the proxies. By +default, channels whose ids are multiple of 8 (starting from 0) are +reserved for the NX client side. All the other channels can be allocated +by the nx-X11 Agent side. + +.TP 8 +.B timeout=t +Specify the keep-alive timeout used by proxies to determine if there is a +network problem preventing communication with the remote peer. A value of +0 disables the check. + +.TP 8 +.B cleanup=t +Specify the number of seconds the proxy has to wait at session shutdown +before closing all channels. The feature is used by the NX server to +ensure that services are disconnected before shutting down the link. + +.TP 8 +.B pack= +Determine the method used to compress images. + +.TP 8 +.B product= +The product id of the client or server. The value is ignored by the +proxy, but the client or server can provide it to facilitate the support. + +.TP 8 +.B core= +Enable production of core dumps when aborting the proxy connection. + +.TP 8 +.B options= +Specify an additional file containing options that has to be merged with +option read from the command line or the environment. + +.TP 8 +.B kill= +Add the given process to the list of daemons that must be terminated at +session shutdown. Multiple 'kill=' options can be specified. The proxy +will send them a SIGTERM signal just before exiting. + +.TP 8 +.B strict= +Optimize for responsiveness, rather than for the best use of all the +available bandwidth. + +.TP 8 +.B encryption= +Should be set to 1 if the proxy is running as part of a program providing +encryption of the point to point communication. + +.TP 8 +.I These options are interpreted by the nx-NX Agent. They are ignored by the proxy. + + rootless= + geometry= + resize= + fullscreen= + keyboard= + clipboard= + streaming= + backingstore= + composite= + xinerama= + shmem= + shpix= + kbtype= + client= + shadow= + shadowuid= + shadowmode= + defer= + tile= + menu= + sleep= + +.SH NX ENVIRONMENT VARIABLES + +The \fBnxproxy\fR application (and also \fBnxagent\fR when using nxcomp +support) can be influenced by the following environment variables: + + +.TP 8 +.B NX_ROOT +The root NX directory is the place where the session directory and the +cache files are created. This is usually overridden by passing the +'root=' option. By default, the root NX directory is assumed to be the +directory '.nx' in the user's home. + +.TP 8 +.B NX_SYSTEM +The directory where NX programs and libraries reside. If not set, the +value is assumed to be '/usr/NX'. Programs, libraries and data files are +respectedly searched in the 'bin', 'lib' and 'share' subdirectories. + +.TP 8 +.B NX_HOME +The NX user's home directory. If NX_ROOT is not set or invalid, the +user's NX directory is created here. + +.TP 8 +.B NX_TEMP +The directory where the X11 Unix Domain Sockets and all temporary files +are to be created. + +.TP 8 +.B NX_CLIENT +The full path to the executable. If the variable is not set, +the executable will be run assuming that the program is in the +system path. This can be useful on platforms like Windows and the MacOS X +where is located in a different directory compared to the +other programs, to make easier for the user to execute the program from +the shell. + +.SH SHELL ENVIRONMENT VARIABLES + +.TP 8 +.B HOME +The variable is checked in the case NX_HOME is not set, null or invalid. + +.TP 8 +.B TEMP +The variable is checked whenever the NX_TEMP directory is not set, null +or invalid. + +.TP 8 +.B PATH +The path where all executables are searched, except . If +NX_CLIENT is not set, also the client executable is searched in the +system path. + +.TP 8 +.B LD_LIBRARY_PATH +System-wide library search order. This should be set by the program +invoking the proxy. + +.TP 8 +.B DISPLAY +On the X server side, the DISPLAY variable indicates the location of the +X11 server. When nxcomp is used as a transport library, the DISPLAY may +represent a NX transport specification and options can passed in the form +nx/nx,option=value... + +.TP 8 +.B XAUTHORITY +This is the file containing the X11 authorization cookie. If not set, the +file is assumed to be in the user's home (either NX_HOME or HOME). + .SH AUTHOR -This manual has been written by Mike Gabriel for the X2Go project -(http://www.x2go.org). +The \fBnxproxy\fR application has originally been derived from a sofware +project called DXCP. The company NoMachine turned DXCP into nxcomp with +nxproxy as executable around nxcomp. +.PP +The current maintenance of \fBnxproxy\fR (major version 3) is coordinated +between various projects, mainly by The Arctica Project, TheQVD (Qindel +Group) and the X2Go Project. +.PP +This manual has been written by Mike Gabriel + for the X2Go project +(http://www.x2go.org) and later on improved for the Arctica Project +(https://arctica-project.org). -- cgit v1.2.3 From 0369bf5e98bb0b1c032fbd39f5b76f73792a4ff2 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 6 Jul 2016 00:04:05 +0200 Subject: nxproxy.1 man page: Fix a typo + a rendering error. Detected by lintian. --- nxproxy/man/nxproxy.1 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'nxproxy') diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index 6922c1427..044481a11 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -46,9 +46,8 @@ the command line, by using the nx/nx,option=value notation. .B link= An indication of the link speed that is going to be used between the proxies. Usually the compression and the other link parameters depend on -this setting. The value can be either 'modem', 'isdn', 'adsl', 'wan', -'lan', 'local' or a bandwidth specification, like for example '56k', -'1m', '100m', etc. +this setting. The value can be either 'modem', 'isdn', 'adsl', 'wan', 'lan', 'local' +or a bandwidth specification, like for example '56k', '1m', '100m', etc. .TP 8 .B type= @@ -375,7 +374,7 @@ This is the file containing the X11 authorization cookie. If not set, the file is assumed to be in the user's home (either NX_HOME or HOME). .SH AUTHOR -The \fBnxproxy\fR application has originally been derived from a sofware +The \fBnxproxy\fR application has originally been derived from a software project called DXCP. The company NoMachine turned DXCP into nxcomp with nxproxy as executable around nxcomp. .PP -- cgit v1.2.3 From 5cbc93678753a9933b646fbb96ccf8797fef1b93 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 6 Jul 2016 00:40:36 +0200 Subject: nxproxy.1 man page: Another rendering flaw fixed. --- nxproxy/man/nxproxy.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nxproxy') diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index 044481a11..7b950a607 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -310,8 +310,8 @@ support) can be influenced by the following environment variables: .TP 8 .B NX_ROOT The root NX directory is the place where the session directory and the -cache files are created. This is usually overridden by passing the -'root=' option. By default, the root NX directory is assumed to be the +cache files are created. This is usually overridden by passing the 'root=' +option. By default, the root NX directory is assumed to be the directory '.nx' in the user's home. .TP 8 -- cgit v1.2.3 From c7eac1f95626e376b17ccd684b2a4e9402b3c17c Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Mon, 24 Oct 2016 13:27:52 +0200 Subject: Add description of NX_SLAVE_CMD to man and help --- nxcomp/Misc.cpp | 7 +++++++ nxproxy/man/nxproxy.1 | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'nxproxy') diff --git a/nxcomp/Misc.cpp b/nxcomp/Misc.cpp index 71013fc6f..09a0b29d2 100644 --- a/nxcomp/Misc.cpp +++ b/nxcomp/Misc.cpp @@ -357,6 +357,13 @@ tolerancechecks=s\n\ Mac where nxclient is located in a different direct-\n\ ory compared to the other programs, to make easier\n\ for the user to execute the program from the shell.\n\ +\n\ + NX_SLAVE_CMD The full path to the slave channel handler. When the\n\ + slave channel is enabled, the agent will listen on a\n\ + port and forward the connection to the NX_SLAVE_CMD\n\ + program. This can be used to implement agent/proxy\n\ + communication for applications such as serial port and\n\ + USB forwarding.\n\ \n\ Shell environment:\n\ \n\ diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index 7b950a607..3cf95c992 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -339,6 +339,13 @@ where is located in a different directory compared to the other programs, to make easier for the user to execute the program from the shell. +.TP 8 +.B NX_SLAVE_CMD +The full path to the slave channel handler. When the slave channel is +enabled, the agent will listen on a port and forward the connection to +the NX_SLAVE_CMD program. This can be used to implement agent/proxy +communication for applications such as serial port and USB forwarding. + .SH SHELL ENVIRONMENT VARIABLES .TP 8 -- cgit v1.2.3 From 7993d28f1d4cd835980d81993bf53854441a6705 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 3 Nov 2016 23:53:46 +0100 Subject: add .gitignore files --- .gitignore | 13 + nx-X11/.gitignore | 5 + nx-X11/include/.gitignore | 5 + nx-X11/lib/X11/.gitignore | 1 + nx-X11/programs/Xserver/.gitignore | 2 + nx-X11/programs/Xserver/GL/.gitignore | 341 ++++++++++++++++++++++++++ nx-X11/programs/Xserver/composite/.gitignore | 0 nx-X11/programs/Xserver/hw/nxagent/.gitignore | 3 + nx-X11/programs/Xserver/include/.gitignore | 1 + nxcomp/.gitignore | 2 + nxcompext/.gitignore | 2 + nxcompshad/.gitignore | 2 + nxproxy/.gitignore | 2 + 13 files changed, 379 insertions(+) create mode 100644 .gitignore create mode 100644 nx-X11/.gitignore create mode 100644 nx-X11/include/.gitignore create mode 100644 nx-X11/lib/X11/.gitignore create mode 100644 nx-X11/programs/Xserver/.gitignore create mode 100644 nx-X11/programs/Xserver/GL/.gitignore create mode 100644 nx-X11/programs/Xserver/composite/.gitignore create mode 100644 nx-X11/programs/Xserver/hw/nxagent/.gitignore create mode 100644 nx-X11/programs/Xserver/include/.gitignore create mode 100644 nxcomp/.gitignore create mode 100644 nxcompext/.gitignore create mode 100644 nxcompshad/.gitignore create mode 100644 nxproxy/.gitignore (limited to 'nxproxy') diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..325bebed4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +.gitignore +*.o +*.so.* +*.so +*.a +xmakefile +autom4te.cache/ +config.log +config.status +configure +depend.status +*~ +[#]* diff --git a/nx-X11/.gitignore b/nx-X11/.gitignore new file mode 100644 index 000000000..8e0d8bf9d --- /dev/null +++ b/nx-X11/.gitignore @@ -0,0 +1,5 @@ +Makefile +Makefile.bak +xmakefile +exports/ +.build-exports/ diff --git a/nx-X11/include/.gitignore b/nx-X11/include/.gitignore new file mode 100644 index 000000000..16951a0af --- /dev/null +++ b/nx-X11/include/.gitignore @@ -0,0 +1,5 @@ +GL/gl.h +GL/glext.h +GL/glxext.h +GL/osmesa.h +Xpoll.h diff --git a/nx-X11/lib/X11/.gitignore b/nx-X11/lib/X11/.gitignore new file mode 100644 index 000000000..8215e21de --- /dev/null +++ b/nx-X11/lib/X11/.gitignore @@ -0,0 +1 @@ +ks_tables.h \ No newline at end of file diff --git a/nx-X11/programs/Xserver/.gitignore b/nx-X11/programs/Xserver/.gitignore new file mode 100644 index 000000000..ea37aa3ef --- /dev/null +++ b/nx-X11/programs/Xserver/.gitignore @@ -0,0 +1,2 @@ +nxagent +nxagent.bak diff --git a/nx-X11/programs/Xserver/GL/.gitignore b/nx-X11/programs/Xserver/GL/.gitignore new file mode 100644 index 000000000..5231f1978 --- /dev/null +++ b/nx-X11/programs/Xserver/GL/.gitignore @@ -0,0 +1,341 @@ +glx/DONE +glx/glcontextmodes.c +glx/glcontextmodes.h +glx/indirect_size.c +glx/indirect_size.h +mesa/X/DONE +mesa/X/compsize.c +mesa/X/driverfuncs.c +mesa/X/driverfuncs.h +mesa/X/xm_api.c +mesa/X/xm_buffer.c +mesa/X/xm_dd.c +mesa/X/xm_line.c +mesa/X/xm_span.c +mesa/X/xm_tri.c +mesa/array_cache/DONE +mesa/array_cache/ac_context.c +mesa/array_cache/ac_context.h +mesa/array_cache/ac_import.c +mesa/array_cache/acache.h +mesa/main/DONE +mesa/main/accum.c +mesa/main/accum.h +mesa/main/api_arrayelt.c +mesa/main/api_arrayelt.h +mesa/main/api_eval.h +mesa/main/api_loopback.c +mesa/main/api_loopback.h +mesa/main/api_noop.c +mesa/main/api_noop.h +mesa/main/api_validate.c +mesa/main/api_validate.h +mesa/main/attrib.c +mesa/main/attrib.h +mesa/main/blend.c +mesa/main/blend.h +mesa/main/bufferobj.c +mesa/main/bufferobj.h +mesa/main/buffers.c +mesa/main/buffers.h +mesa/main/clip.c +mesa/main/clip.h +mesa/main/colormac.h +mesa/main/colortab.c +mesa/main/colortab.h +mesa/main/config.h +mesa/main/context.c +mesa/main/context.h +mesa/main/convolve.c +mesa/main/convolve.h +mesa/main/dd.h +mesa/main/debug.c +mesa/main/debug.h +mesa/main/depth.c +mesa/main/depth.h +mesa/main/dispatch.c +mesa/main/dlist.c +mesa/main/dlist.h +mesa/main/drawpix.c +mesa/main/drawpix.h +mesa/main/enable.c +mesa/main/enable.h +mesa/main/enums.c +mesa/main/enums.h +mesa/main/eval.c +mesa/main/eval.h +mesa/main/execmem.c +mesa/main/extensions.c +mesa/main/extensions.h +mesa/main/fbobject.c +mesa/main/fbobject.h +mesa/main/feedback.c +mesa/main/feedback.h +mesa/main/fog.c +mesa/main/fog.h +mesa/main/framebuffer.c +mesa/main/framebuffer.h +mesa/main/get.c +mesa/main/get.h +mesa/main/getstring.c +mesa/main/glapi.c +mesa/main/glheader.h +mesa/main/glthread.c +mesa/main/hash.c +mesa/main/hash.h +mesa/main/hint.c +mesa/main/hint.h +mesa/main/histogram.c +mesa/main/histogram.h +mesa/main/image.c +mesa/main/image.h +mesa/main/imports.c +mesa/main/imports.h +mesa/main/light.c +mesa/main/light.h +mesa/main/lines.c +mesa/main/lines.h +mesa/main/macros.h +mesa/main/matrix.c +mesa/main/matrix.h +mesa/main/mm.c +mesa/main/mm.h +mesa/main/mtypes.h +mesa/main/occlude.c +mesa/main/occlude.h +mesa/main/pixel.c +mesa/main/pixel.h +mesa/main/points.c +mesa/main/points.h +mesa/main/polygon.c +mesa/main/polygon.h +mesa/main/rastpos.c +mesa/main/rastpos.h +mesa/main/renderbuffer.c +mesa/main/renderbuffer.h +mesa/main/simple_list.h +mesa/main/state.c +mesa/main/state.h +mesa/main/stencil.c +mesa/main/stencil.h +mesa/main/texcompress.c +mesa/main/texcompress.h +mesa/main/texcompress_fxt1.c +mesa/main/texcompress_s3tc.c +mesa/main/texenvprogram.c +mesa/main/texenvprogram.h +mesa/main/texformat.c +mesa/main/texformat.h +mesa/main/texformat_tmp.h +mesa/main/teximage.c +mesa/main/teximage.h +mesa/main/texobj.c +mesa/main/texobj.h +mesa/main/texrender.c +mesa/main/texrender.h +mesa/main/texstate.c +mesa/main/texstate.h +mesa/main/texstore.c +mesa/main/texstore.h +mesa/main/varray.c +mesa/main/varray.h +mesa/main/version.h +mesa/main/vtxfmt.c +mesa/main/vtxfmt.h +mesa/main/vtxfmt_tmp.h +mesa/math/DONE +mesa/math/m_clip_tmp.h +mesa/math/m_copy_tmp.h +mesa/math/m_debug.h +mesa/math/m_debug_clip.c +mesa/math/m_debug_norm.c +mesa/math/m_debug_util.h +mesa/math/m_debug_xform.c +mesa/math/m_dotprod_tmp.h +mesa/math/m_eval.c +mesa/math/m_eval.h +mesa/math/m_matrix.c +mesa/math/m_matrix.h +mesa/math/m_norm_tmp.h +mesa/math/m_trans_tmp.h +mesa/math/m_translate.c +mesa/math/m_translate.h +mesa/math/m_vector.c +mesa/math/m_vector.h +mesa/math/m_xform.c +mesa/math/m_xform.h +mesa/math/m_xform_tmp.h +mesa/math/mathmod.h +mesa/shader/DONE +mesa/shader/arbfragparse.c +mesa/shader/arbfragparse.h +mesa/shader/arbprogparse.c +mesa/shader/arbprogparse.h +mesa/shader/arbprogram.c +mesa/shader/arbprogram.h +mesa/shader/arbprogram_syn.h +mesa/shader/arbvertparse.c +mesa/shader/arbvertparse.h +mesa/shader/atifragshader.c +mesa/shader/atifragshader.h +mesa/shader/grammar/DONE +mesa/shader/grammar/grammar.c +mesa/shader/grammar/grammar.h +mesa/shader/grammar/grammar_mesa.c +mesa/shader/grammar/grammar_mesa.h +mesa/shader/grammar/grammar_syn.h +mesa/shader/nvfragparse.c +mesa/shader/nvfragparse.h +mesa/shader/nvfragprog.h +mesa/shader/nvprogram.c +mesa/shader/nvprogram.h +mesa/shader/nvvertexec.c +mesa/shader/nvvertexec.h +mesa/shader/nvvertparse.c +mesa/shader/nvvertparse.h +mesa/shader/nvvertprog.h +mesa/shader/program.c +mesa/shader/program.h +mesa/shader/shaderobjects.c +mesa/shader/shaderobjects.h +mesa/shader/shaderobjects_3dlabs.c +mesa/shader/shaderobjects_3dlabs.h +mesa/shader/slang/DONE +mesa/shader/slang/library/slang_common_builtin_gc.h +mesa/shader/slang/library/slang_common_builtin_gc_bin.h +mesa/shader/slang/library/slang_core_gc.h +mesa/shader/slang/library/slang_core_gc_bin.h +mesa/shader/slang/library/slang_fragment_builtin_gc.h +mesa/shader/slang/library/slang_fragment_builtin_gc_bin.h +mesa/shader/slang/library/slang_shader_syn.h +mesa/shader/slang/library/slang_version_syn.h +mesa/shader/slang/library/slang_vertex_builtin_gc.h +mesa/shader/slang/library/slang_vertex_builtin_gc_bin.h +mesa/shader/slang/slang_assemble.c +mesa/shader/slang/slang_assemble.h +mesa/shader/slang/slang_assemble_assignment.c +mesa/shader/slang/slang_assemble_assignment.h +mesa/shader/slang/slang_assemble_conditional.c +mesa/shader/slang/slang_assemble_conditional.h +mesa/shader/slang/slang_assemble_constructor.c +mesa/shader/slang/slang_assemble_constructor.h +mesa/shader/slang/slang_assemble_typeinfo.c +mesa/shader/slang/slang_assemble_typeinfo.h +mesa/shader/slang/slang_compile.c +mesa/shader/slang/slang_compile.h +mesa/shader/slang/slang_execute.c +mesa/shader/slang/slang_execute.h +mesa/shader/slang/slang_preprocess.c +mesa/shader/slang/slang_preprocess.h +mesa/shader/slang/slang_storage.c +mesa/shader/slang/slang_storage.h +mesa/shader/slang/slang_utility.c +mesa/shader/slang/slang_utility.h +mesa/shader/slang/traverse_wrap.h +mesa/swrast/DONE +mesa/swrast/s_aaline.c +mesa/swrast/s_aaline.h +mesa/swrast/s_aalinetemp.h +mesa/swrast/s_aatriangle.c +mesa/swrast/s_aatriangle.h +mesa/swrast/s_aatritemp.h +mesa/swrast/s_accum.c +mesa/swrast/s_accum.h +mesa/swrast/s_alpha.c +mesa/swrast/s_alpha.h +mesa/swrast/s_atifragshader.c +mesa/swrast/s_atifragshader.h +mesa/swrast/s_bitmap.c +mesa/swrast/s_blend.c +mesa/swrast/s_blend.h +mesa/swrast/s_buffers.c +mesa/swrast/s_context.c +mesa/swrast/s_context.h +mesa/swrast/s_copypix.c +mesa/swrast/s_depth.c +mesa/swrast/s_depth.h +mesa/swrast/s_drawpix.c +mesa/swrast/s_drawpix.h +mesa/swrast/s_feedback.c +mesa/swrast/s_feedback.h +mesa/swrast/s_fog.c +mesa/swrast/s_fog.h +mesa/swrast/s_imaging.c +mesa/swrast/s_lines.c +mesa/swrast/s_lines.h +mesa/swrast/s_linetemp.h +mesa/swrast/s_logic.c +mesa/swrast/s_logic.h +mesa/swrast/s_masking.c +mesa/swrast/s_masking.h +mesa/swrast/s_nvfragprog.c +mesa/swrast/s_nvfragprog.h +mesa/swrast/s_pixeltex.c +mesa/swrast/s_pixeltex.h +mesa/swrast/s_points.c +mesa/swrast/s_points.h +mesa/swrast/s_pointtemp.h +mesa/swrast/s_readpix.c +mesa/swrast/s_span.c +mesa/swrast/s_span.h +mesa/swrast/s_spantemp.h +mesa/swrast/s_stencil.c +mesa/swrast/s_stencil.h +mesa/swrast/s_texstore.c +mesa/swrast/s_texture.c +mesa/swrast/s_texture.h +mesa/swrast/s_triangle.c +mesa/swrast/s_triangle.h +mesa/swrast/s_trispan.h +mesa/swrast/s_tritemp.h +mesa/swrast/s_zoom.c +mesa/swrast/s_zoom.h +mesa/swrast/swrast.h +mesa/swrast_setup/DONE +mesa/swrast_setup/ss_context.c +mesa/swrast_setup/ss_context.h +mesa/swrast_setup/ss_triangle.c +mesa/swrast_setup/ss_triangle.h +mesa/swrast_setup/ss_tritmp.h +mesa/swrast_setup/swrast_setup.h +mesa/tnl/DONE +mesa/tnl/t_array_api.c +mesa/tnl/t_array_api.h +mesa/tnl/t_array_import.c +mesa/tnl/t_array_import.h +mesa/tnl/t_context.c +mesa/tnl/t_context.h +mesa/tnl/t_pipeline.c +mesa/tnl/t_pipeline.h +mesa/tnl/t_save_api.c +mesa/tnl/t_save_api.h +mesa/tnl/t_save_loopback.c +mesa/tnl/t_save_playback.c +mesa/tnl/t_vb_arbprogram.c +mesa/tnl/t_vb_arbprogram.h +mesa/tnl/t_vb_arbprogram_sse.c +mesa/tnl/t_vb_cliptmp.h +mesa/tnl/t_vb_cull.c +mesa/tnl/t_vb_fog.c +mesa/tnl/t_vb_light.c +mesa/tnl/t_vb_lighttmp.h +mesa/tnl/t_vb_normals.c +mesa/tnl/t_vb_points.c +mesa/tnl/t_vb_program.c +mesa/tnl/t_vb_render.c +mesa/tnl/t_vb_rendertmp.h +mesa/tnl/t_vb_texgen.c +mesa/tnl/t_vb_texmat.c +mesa/tnl/t_vb_vertex.c +mesa/tnl/t_vertex.c +mesa/tnl/t_vertex.h +mesa/tnl/t_vertex_generic.c +mesa/tnl/t_vertex_sse.c +mesa/tnl/t_vp_build.c +mesa/tnl/t_vp_build.h +mesa/tnl/t_vtx_api.c +mesa/tnl/t_vtx_api.h +mesa/tnl/t_vtx_eval.c +mesa/tnl/t_vtx_exec.c +mesa/tnl/t_vtx_generic.c +mesa/tnl/tnl.h diff --git a/nx-X11/programs/Xserver/composite/.gitignore b/nx-X11/programs/Xserver/composite/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/nx-X11/programs/Xserver/hw/nxagent/.gitignore b/nx-X11/programs/Xserver/hw/nxagent/.gitignore new file mode 100644 index 000000000..256534b63 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/nxagent/.gitignore @@ -0,0 +1,3 @@ +miinitext.c +stubs.c +xpstubs.c diff --git a/nx-X11/programs/Xserver/include/.gitignore b/nx-X11/programs/Xserver/include/.gitignore new file mode 100644 index 000000000..919ccf080 --- /dev/null +++ b/nx-X11/programs/Xserver/include/.gitignore @@ -0,0 +1 @@ +osdep.h diff --git a/nxcomp/.gitignore b/nxcomp/.gitignore new file mode 100644 index 000000000..27a99e5b2 --- /dev/null +++ b/nxcomp/.gitignore @@ -0,0 +1,2 @@ +nxcomp.pc +Makefile diff --git a/nxcompext/.gitignore b/nxcompext/.gitignore new file mode 100644 index 000000000..4dbbba27e --- /dev/null +++ b/nxcompext/.gitignore @@ -0,0 +1,2 @@ +nxcompext.pc +Makefile diff --git a/nxcompshad/.gitignore b/nxcompshad/.gitignore new file mode 100644 index 000000000..f083c6b27 --- /dev/null +++ b/nxcompshad/.gitignore @@ -0,0 +1,2 @@ +nxcompshad.pc +Makefile diff --git a/nxproxy/.gitignore b/nxproxy/.gitignore new file mode 100644 index 000000000..3d98254b2 --- /dev/null +++ b/nxproxy/.gitignore @@ -0,0 +1,2 @@ +Makefile +nxproxy -- cgit v1.2.3 From e1f2902bb1ad29f852f97dc08a3e3e29ad88c384 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 24 Feb 2017 22:22:47 +0000 Subject: release 3.5.99.4 --- ChangeLog | 4065 ++++++++++++---------- VERSION | 2 +- debian/changelog | 7 + nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 2 +- nx-libs.spec | 2 +- nxproxy/man/nxproxy.1 | 2 +- 6 files changed, 2165 insertions(+), 1915 deletions(-) (limited to 'nxproxy') diff --git a/ChangeLog b/ChangeLog index 284c5f690..afcecb41a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,82 +1,326 @@ -2016-12-19 15:03:09 +0100 Mike Gabriel (f2c07b8) +2017-02-24 22:22:47 +0000 Mike Gabriel (73cc94686) - * release 3.5.99.3 (HEAD, 3.6.x) + * release 3.5.99.4 (HEAD -> 3.6.x) -2016-12-14 13:32:23 +0100 Mike Gabriel (8be276d) +2017-02-24 12:23:51 +0100 Mihai Moldovan (31426a3d2) - * Merge branch 'theqvd-fix-loopback-bind' into 3.6.x (origin/HEAD, + * Merge branch 'uli42-fix_#306_#322' into 3.6.x (origin/HEAD, origin/3.6.x) -2016-12-13 12:00:43 +0100 Vadim Troshchinskiy (920f423) +2017-02-19 00:06:54 +0100 Ulrich Sibiller (3d8575c21) + + * dix: fix incomplete commit + +2017-02-20 10:33:52 +0100 Mihai Moldovan (3c322ffbb) + + * Merge branch 'sunweaver-pr/security-acl-naming-change' into 3.6.x + +2017-02-15 09:59:00 +0100 Mike Gabriel (104a3e9e2) + + * Naming change: Security*Access -> Dix*Access + (gh-sunweaver/pr/security-acl-naming-change, + pr/security-acl-naming-change) + +2017-02-20 10:21:01 +0100 Mike Gabriel (c79f2d289) + + * Merge branch + 'sunweaver-pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym' + into 3.6.x + +2017-02-17 12:43:06 +0000 Mike Gabriel (38ac74d6f) + + * Switch from using libNX_X11's deprecated XKeycodeToKeysym() + function to using XGetKeyboardMapping(). + (gh-sunweaver/pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym, + sunweaver-pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym, + pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym) + +2017-02-18 10:24:21 +0100 Mihai Moldovan (73ec915bc) + + * Merge branch 'sunweaver-pr/smart-scheduler-is-not-optional' into + 3.6.x + +2017-02-09 14:05:32 +0100 Mathieu Bérard (6884e6a5b) + + * The smart scheduler is not optional. + (gh-sunweaver/pr/smart-scheduler-is-not-optional, + pr/smart-scheduler-is-not-optional) + +2017-02-10 00:47:32 +0100 Mihai Moldovan (0a7df0770) + + * Merge branch 'sunweaver-pr/use-rpath-for-nxagent' into 3.6.x + +2017-02-08 16:33:40 +0100 Mike Gabriel (99c130f15) + + * Makefile: Fix flawed uninstall-* targets. Spotted by Ionic while + reviewing the nxagent RPATH changeset. Thanks! + (gh-sunweaver/pr/use-rpath-for-nxagent, + pr/use-rpath-for-nxagent) + +2017-02-08 16:31:00 +0100 Mike Gabriel (52760b6e8) + + * debian/patches: Update comment header of + 016_nx-X11_install-location.debian.patch. + +2017-02-04 19:02:16 +0100 Mike Gabriel (a474b9f93) + + * debian/patches: Update 016_nx-X11_install-location.debian.patch. + Adapt path to recent upstream changes. + +2017-02-04 19:00:00 +0100 Mike Gabriel (ba620a054) + + * Load libNX_X11 / faked libX11 via RPATH setting rather than + fidgeting with LD_LIBRARY_PATH in the nxagent wrapper + script. + +2017-02-08 15:03:58 +0100 Mike Gabriel (9d1da072c) + + * Makefile: Allow longer names for variables that we want to allow + distro maintainers to override. + +2017-02-04 18:54:21 +0100 Mike Gabriel (4c4d3dfba) + + * Makefile: Actively set/override USRLIBDIR and SHLIBDIR when calling + Xserver's make process. + +2017-02-04 18:53:25 +0100 Mike Gabriel (4a01be659) + + * debian/rules: Don't manually override SHLIBDIR via the + dh_auto_build call. The default in the main Makefile + should work fine. + +2017-02-04 18:52:56 +0100 Mike Gabriel (0ae1fd5d3) + + * nx-libs.spec: Don't manually override SHLIBDIR via the .spec file. + The default in the main Makefile should work fine. + +2017-02-04 18:52:04 +0100 Mike Gabriel (c45cab1ba) + + * Makefile: Align variable names USRLIBDIR, SHLIBDIR (and NX_DIR) + with nx-X11 internal naming schemes (and use + /usr//nx/X11 rather than /usr//nx-X11). + +2017-02-09 22:01:31 +0100 Mihai Moldovan (0a314adfa) + + * Merge branch 'sunweaver-pr/drop-support-for-ancient-platforms' into + 3.6.x + +2017-02-08 11:06:17 +0100 Mike Gabriel (029bae127) + + * nx-X11/include/Xos_r.h: Drop one _POSIX_REENTRANT_FUNCTIONS macro + block, where offenders AIXV3, AIXV4 and __osf__ are gone + now. (gh-sunweaver/pr/drop-support-for-ancient-platforms, + pr/drop-support-for-ancient-platforms) + +2017-02-04 16:25:13 +0100 Daniel Stone (7dae94814) + + * dix: remove staggeringly broken vendor workarounds + +2016-11-15 22:03:39 +0100 Mike Gabriel (2d45d8d80) + + * drop platform support: unifdef sgi. + +2016-11-15 21:51:55 +0100 Mike Gabriel (c6250a864) + + * drop platform support: unifdef QNX. + +2016-11-15 21:41:57 +0100 Mike Gabriel (754e48ac0) + + * drop platform support: unifdef DGUX. + +2016-11-15 21:32:46 +0100 Mike Gabriel (a9c30796d) + + * drop platform support: unifdef __osf__. + +2016-11-15 21:20:22 +0100 Mike Gabriel (4b178918b) + + * drop platform support: unifdef AIXV3, AIXV4 (and AIXrt, AIX386). + +2016-11-15 20:59:35 +0100 Mike Gabriel (184c5d778) + + * drop platform support: unifdef hpux and __hppa__. + +2016-11-15 19:20:13 +0100 Mike Gabriel (ace255eda) + + * drop platform support: unifdef Lynx. + +2016-11-15 18:41:52 +0100 Mike Gabriel (d12f95241) + + * drop platform support: unifdef __UNIXOS2__. + +2017-02-08 22:34:53 +0100 Mike Gabriel (86a6a340f) + + * Merge branch 'uli42-pr/fix_#293' into 3.6.x + +2017-02-08 21:43:45 +0100 Ulrich Sibiller (3790a28fe) + + * Screen.c: clean up superfluous whitespace + (gh-sunweaver/uli42-pr/fix_#293, uli42-pr/fix_#293) + +2017-02-08 21:13:38 +0100 Ulrich Sibiller (184c07e24) + + * Screen.c: Ensure that an output is unused before destroying it + +2017-02-06 21:57:50 +0100 Mihai Moldovan (083051f66) + + * Merge branch 'sunweaver-pr/fix-DefaultRGBDatabase-path' into 3.6.x + +2017-02-05 19:16:54 +0000 Mike Gabriel (34889920c) + + * nx-X11/config/cf/X11.tmpl: Fix DefaultRGBDatabase path to + $(USRDATADIR)/rgb (not $(LIBDIR)/rgb). + (gh-sunweaver/pr/fix-DefaultRGBDatabase-path, + pr/fix-DefaultRGBDatabase-path) + +2017-02-04 15:41:18 +0100 Mike Gabriel (d6f475f67) + + * debian/copyright{,.in}: Adopt from Debian's upload candidate, being + DEP-5 compliant and up-to-date for 3.5.99.3. + +2017-02-03 14:58:06 +0100 Mike Gabriel (1cd73ccb7) + + * Makefile: Don't create superfluous symlink for libX11.so -> + ../libNX_X11.so. The libNX_X11.so is only required at + build time, so need to use it for faking libX11.so in + nxagent. + +2017-02-03 14:40:19 +0100 Mike Gabriel (b0d28c8a6) + + * debian/changelog: Cosmetic fix, restoring correct version number + for 3.5.99.2 release stanza. + +2017-01-12 10:23:02 +0100 Mike Gabriel (93447eb2b) + + * Merge branch 'opoplawski-symlink' into 3.6.x + (gh-sunweaver/pr/no-extra-mode-freeing-in-nxagentAdjustRandRXinerama) + +2017-01-05 16:43:17 -0700 Orion Poplawski (f92820948) + + * Be consistent with macros (opoplawski-symlink) + +2017-01-05 16:35:34 -0700 Orion Poplawski (c392bc0a8) + + * Use Obsoletes instead of Conflicts. Drop unneeded %{?_isa} + versions + +2017-01-12 10:21:51 +0100 Mike Gabriel (42b136811) + + * Merge branch 'opoplawski-fedora' into 3.6.x + +2017-01-11 15:19:24 -0700 Orion Poplawski (c9ab60e89) + + * Install missing libNX_X11.so.6 symlink - fixes gh-287 + +2017-01-05 16:43:17 -0700 Orion Poplawski (bdcc867e2) + + * Be consistent with macros (opoplawski-fedora) + +2017-01-05 16:35:34 -0700 Orion Poplawski (13f3bdc00) + + * Use Obsoletes instead of Conflicts. Drop unneeded %{?_isa} + versions + +2016-12-22 20:12:53 +0100 Mike Gabriel (7d845e7f4) + + * hw/nxagent/Init.c: Amend artifact in license header. + +2016-12-22 15:30:07 +0100 Mike Gabriel (9c0d52807) + + * helper scripts: Add license headers to files. + +2016-12-20 10:33:48 +0100 Mike Gabriel (b425f071e) + + * nxcomp: Fix artifacts in copyright headers. + +2016-12-20 10:27:07 +0100 Mike Gabriel (8a8ec60cc) + + * nxcompext: Drop folder with .gitignore file. nxcompext has been + moved into nxagent DDX. + +2016-12-20 09:04:11 +0100 Mike Gabriel (02546c560) + + * roll-tarballs.sh: Adapt to recent changes in nx-libs, keep legacy + support for older 3.6.x and 3.5.x releases. + +2016-12-19 15:03:09 +0100 Mike Gabriel (9acd13e50) + + * release 3.5.99.3 (tag: 3.5.99.3, origin/release-builds/3.6.x, + release-builds/3.6.x) + +2016-12-14 13:32:23 +0100 Mike Gabriel (8be276d27) + + * Merge branch 'theqvd-fix-loopback-bind' into 3.6.x + +2016-12-13 12:00:43 +0100 Vadim Troshchinskiy (920f423a5) * Make nxagent only bind to loopback when requested (theqvd-fix-loopback-bind) -2016-12-14 10:57:39 +0100 Mike Gabriel (e466a93) +2016-12-14 10:57:39 +0100 Mike Gabriel (e466a9387) * Merge branch 'theqvd-fix-accept-host-message' into 3.6.x -2016-12-13 12:19:09 +0100 Vadim Troshchinskiy (7718886) +2016-12-13 12:19:09 +0100 Vadim Troshchinskiy (77188865e) * Fix reversed logic in acceptHost setting (theqvd-fix-accept-host-message) -2016-12-10 21:49:10 +0100 Mike Gabriel (2b8f592) +2016-12-10 21:49:10 +0100 Mike Gabriel (2b8f59261) * Merge branch 'uli42-pr/improve_xinerama_debug' into 3.6.x -2016-12-07 21:50:40 +0100 Ulrich Sibiller (6f3fb52) +2016-12-07 21:50:40 +0100 Ulrich Sibiller (6f3fb5248) * Screen.c: more debug output formatting improvements (uli42-pr/improve_xinerama_debug) -2016-12-07 21:17:26 +0100 Ulrich Sibiller (e143098) +2016-12-07 21:17:26 +0100 Ulrich Sibiller (e14309892) * Screen.c: fix uninitalized variable -2016-12-07 21:15:59 +0100 Ulrich Sibiller (ce76009) +2016-12-07 21:15:59 +0100 Ulrich Sibiller (ce76009d2) * Screen.c: fix compile warnings in DEBUG mode -2016-12-07 21:42:03 +0100 Ulrich Sibiller (6882b08) +2016-12-07 21:42:03 +0100 Ulrich Sibiller (6882b08d8) * Screen.c: fix formatting -2016-12-07 20:18:09 +0100 Ulrich Sibiller (c806956) +2016-12-07 20:18:09 +0100 Ulrich Sibiller (c806956c2) * Screen.c: improve debugging output -2016-12-05 10:26:28 +0000 Mike Gabriel (5bdb2fc) +2016-12-05 10:26:28 +0000 Mike Gabriel (5bdb2fcdf) * debian/control: B-D alternatively on libxfont1-dev or libxfont-dev. Fix FTBFS on Debian stretch which has libxfont2-dev as default now. -2016-12-04 21:45:33 +0100 Mike Gabriel (c893ad6) +2016-12-04 21:45:33 +0100 Mike Gabriel (c893ad65c) * Merge branch 'sunweaver-pr/drop-glx-ansic' into 3.6.x -2016-11-02 20:30:07 +0100 Mike Gabriel (4e33fd4) +2016-11-02 20:30:07 +0100 Mike Gabriel (4e33fd4be) * Mesa: Convert some files with MSDOS EOL style to Unix EOL style. (gh-sunweaver/pr/drop-glx-ansic, sunweaver-pr/drop-glx-ansic, pr/drop-glx-ansic) -2016-11-01 21:30:22 +0100 Kristian Høgsberg (4146d1a) +2016-11-01 21:30:22 +0100 Kristian Høgsberg (4146d1aa7) * Drop xf86glx.h, so we can finally drop Xserver/GL/include/ entirely. -2016-10-31 15:06:37 +0100 Kristian Høgsberg (cee997d) +2016-10-31 15:06:37 +0100 Kristian Høgsberg (cee997dac) * Drop glx_ansic.h wrapper and call malloc, realloc, free and str-funcs directly. -2016-12-04 21:14:24 +0100 Mike Gabriel (b38d5b9) +2016-12-04 21:14:24 +0100 Mike Gabriel (b38d5b97d) * Merge branch 'sunweaver-pr/extmod-xfree86loader-cleanup' into 3.6.x -2016-10-29 11:28:02 +0200 Eric Anholt (508d2de) +2016-10-29 11:28:02 +0200 Eric Anholt (508d2deae) * Remove libcwrapper usage from xorg server modules. The libcwrapper is not used in nxagent. @@ -84,3044 +328,3043 @@ sunweaver-pr/extmod-xfree86loader-cleanup, pr/extmod-xfree86loader-cleanup) -2016-12-04 21:09:52 +0100 Mike Gabriel (62f8e50) +2016-12-04 21:09:52 +0100 Mike Gabriel (62f8e50e7) * Merge branch 'uli42-pr/compilation_fixes_and_debug_improvements' into 3.6.x -2016-12-03 23:31:26 +0100 Ulrich Sibiller (b0106e7) +2016-12-03 23:31:26 +0100 Ulrich Sibiller (b0106e75a) * slightly improve rrxinerama debug output -2016-12-03 23:06:32 +0100 Ulrich Sibiller (c5e06d4) +2016-12-03 23:06:32 +0100 Ulrich Sibiller (c5e06d408) * Fix compilation warnings -2016-11-30 08:13:54 +0100 Mike Gabriel (a0a429c) +2016-11-30 08:13:54 +0100 Mike Gabriel (a0a429cc7) * Update auto-generated debian/copyright.in. -2016-11-18 00:07:19 +0100 Mike Gabriel (cb8af80) +2016-11-18 00:07:19 +0100 Mike Gabriel (cb8af80ae) * .gitignore: Don't ignore myself. -2016-11-18 00:06:30 +0100 Mike Gabriel (edeca4a) +2016-11-18 00:06:30 +0100 Mike Gabriel (edeca4aff) * Merge branch 'uli42-pr/gitignore' into 3.6.x -2016-11-03 23:53:46 +0100 Ulrich Sibiller (7993d28) +2016-11-03 23:53:46 +0100 Ulrich Sibiller (7993d28f1) * add .gitignore files -2016-11-17 20:49:53 +0100 Mike Gabriel (1f60704) +2016-11-17 20:49:53 +0100 Mike Gabriel (1f6070437) * Merge branch 'uli42-pr/remove_xlibi18n' into 3.6.x -2016-11-04 00:25:25 +0100 Ulrich Sibiller (de4eca1) +2016-11-04 00:25:25 +0100 Ulrich Sibiller (de4eca171) * LibX11: drop unused xlibi18n -2016-11-15 17:06:18 +0100 Mike Gabriel (cb8bcbe) +2016-11-15 17:06:18 +0100 Mike Gabriel (cb8bcbec8) * Merge branch 'sunweaver-pr/testscripts-file-headers' into 3.6.x -2016-11-07 12:32:09 +0100 Mike Gabriel (00725f1) +2016-11-07 12:32:09 +0100 Mike Gabriel (00725f16a) * testscripts: Use non-NoMachine file headers for our testscripts. (gh-sunweaver/pr/testscripts-file-headers, pr/testscripts-file-headers) -2016-11-15 17:02:11 +0100 Mike Gabriel (91d0672) +2016-11-15 17:02:11 +0100 Mike Gabriel (91d06723b) * New helper script: regenerate-symbol-docs.sh. Plus update symbols usage of libNX_X11 and nxcompext in nxagent, nxcompext and libNX_X11. -2016-11-15 16:42:39 +0100 Mike Gabriel (8c5a1b0) +2016-11-15 16:42:39 +0100 Mike Gabriel (8c5a1b071) * Merge branch 'sunweaver-pr/move-nxcompext-into-Xserver' into 3.6.x -2016-11-09 16:45:47 +0100 Mike Gabriel (9ad0aae) +2016-11-09 16:45:47 +0100 Mike Gabriel (9ad0aae5d) * Xserver/Imakefile: Some whitespace fixes. (gh-sunweaver/pr/move-nxcompext-into-Xserver) -2016-11-03 00:19:26 +0100 Mike Gabriel (80b5de3) +2016-11-03 00:19:26 +0100 Mike Gabriel (80b5de3f5) * nxcompext: Move code into Xserver subtree, as nxcompext requires Xserver includes at build time. -2016-11-03 08:30:49 +0100 Mike Gabriel (cae394b) +2016-11-03 08:30:49 +0100 Mike Gabriel (cae394b45) * Xserver/hw/nxagent/Imakefile: Introduce the NULL variable. -2016-11-08 08:00:44 +0100 Mihai Moldovan (b1d3f2c) +2016-11-08 08:00:44 +0100 Mihai Moldovan (b1d3f2ca5) * Merge branch 'uli42-pr/keyboard_fixes' into arctica-3.6.x -2016-10-27 01:00:23 +0200 Ulrich Sibiller (2f2ade6) +2016-10-27 01:00:23 +0200 Ulrich Sibiller (2f2ade61a) * Keyboard.c: evdev is only existing on Linux -2006-10-02 20:58:33 +0300 Daniel Stone (926e90a) +2006-10-02 20:58:33 +0300 Daniel Stone (926e90abc) * xkb: remove the world's most staggeringly broken vendor workaround -2016-10-26 11:01:57 +0200 Ulrich Sibiller (08ed062) +2016-10-26 11:01:57 +0200 Ulrich Sibiller (08ed062c4) * Keyboard.c: move variable to inner scope -2016-10-26 10:39:37 +0200 Ulrich Sibiller (d37f9f3) +2016-10-26 10:39:37 +0200 Ulrich Sibiller (d37f9f311) * Reconnect.c: simplify code by using strndup -2016-10-25 23:40:13 +0200 Ulrich Sibiller (e52799d) +2016-10-25 23:40:13 +0200 Ulrich Sibiller (e52799d5c) * Keyboard.c: replace malloc/strcpy by str(n)dup -2016-10-25 22:59:35 +0200 Ulrich Sibiller (718c5b9) +2016-10-25 22:59:35 +0200 Ulrich Sibiller (718c5b9f1) * Keyboard.c: more whitespace/formatting fixes -2016-10-25 22:53:39 +0200 Ulrich Sibiller (b5cc3c9) +2016-10-25 22:53:39 +0200 Ulrich Sibiller (b5cc3c94e) * Keyboard.c: improve keyboard file creation -2016-10-25 22:53:07 +0200 Ulrich Sibiller (52848b7) +2016-10-25 22:53:07 +0200 Ulrich Sibiller (52848b785) * Keyboard.c: use NULL instead of 0 -2016-10-25 22:52:43 +0200 Ulrich Sibiller (3ea601b) +2016-10-25 22:52:43 +0200 Ulrich Sibiller (3ea601bcb) * Keyboard.c: remove superfluous whitespace -2016-10-25 21:50:11 +0200 Ulrich Sibiller (2901aca) +2016-10-25 21:50:11 +0200 Ulrich Sibiller (2901aca36) * Keyboard.c: Fix wrong error msg prefix -2016-10-25 21:41:11 +0200 Ulrich Sibiller (2f7f39b) +2016-10-25 21:41:11 +0200 Ulrich Sibiller (2f7f39b49) * Keyboard.c: Fix and simplify keyboard config file handling -2016-10-25 21:40:10 +0200 Ulrich Sibiller (8793e36) +2016-10-25 21:40:10 +0200 Ulrich Sibiller (8793e362b) * Improve DEBUG/TEST output regarding keyboard stuff -2016-10-25 21:39:24 +0200 Ulrich Sibiller (e3ac55b) +2016-10-25 21:39:24 +0200 Ulrich Sibiller (e3ac55bc2) * Drop unused define NXAGENT_KEYMAP_DIR_FILE -2016-11-05 05:20:31 +0000 Mihai Moldovan (7b79e8d) +2016-11-05 05:20:31 +0000 Mihai Moldovan (7b79e8d83) * Makefile: fix up a9b145d4. -2016-11-05 05:18:06 +0000 Mihai Moldovan (c7e0193) +2016-11-05 05:18:06 +0000 Mihai Moldovan (c7e01938d) * nx-X11/lib/X11/Imakefile: essentially revert 5a90a63. -2016-11-04 14:19:07 +0100 Vadim Troshchinskiy (e5091e0) +2016-11-04 14:19:07 +0100 Vadim Troshchinskiy (e5091e002) * Added sample slave agent and test script -2016-11-03 22:51:56 +0100 Mihai Moldovan (53d304e) +2016-11-03 22:51:56 +0100 Mihai Moldovan (53d304ef7) * Merge branch 'sunweaver-pr/drop-fbmmx' into arctica-3.6.x -2016-10-29 14:23:58 +0200 Mike Gabriel (f5c5cb1) +2016-10-29 14:23:58 +0200 Mike Gabriel (f5c5cb10f) * Xserver/fb: Drop fbmmx.[ch] files and code passages wrapped-in by USE_MMX macro. (gh-sunweaver/pr/drop-fbmmx) -2016-10-29 14:23:25 +0200 Mike Gabriel (89e1457) +2016-10-29 14:23:25 +0200 Mike Gabriel (89e1457d1) * Xserver/fb/Imakefile: Introduce NULL variable. -2016-11-03 09:36:23 +0100 Mike Gabriel (d12b775) +2016-11-03 09:36:23 +0100 Mike Gabriel (d12b77543) * Merge branch 'uli42-pr/libX11_xtrans_silence_compiler_warnings' into 3.6.x -2016-11-02 23:57:43 +0100 Ulrich Sibiller (47fab08) +2016-11-02 23:57:43 +0100 Ulrich Sibiller (47fab08aa) * xtrans: fix const warnings for SocketConnectConnInfo -2016-11-02 23:55:23 +0100 Ulrich Sibiller (882c034) +2016-11-02 23:55:23 +0100 Ulrich Sibiller (882c034c3) * xtrans: silence compiler warning regarding is_numeric -2016-11-02 23:37:30 +0100 Ulrich Sibiller (90612d2) +2016-11-02 23:37:30 +0100 Ulrich Sibiller (90612d25c) * libX11 + Xserver: fix missing define warning -2016-11-02 23:36:50 +0100 Ulrich Sibiller (2631603) +2016-11-02 23:36:50 +0100 Ulrich Sibiller (2631603b6) * xtrans: Fix compile warning -2016-11-02 23:14:52 +0100 Ulrich Sibiller (5d06f46) +2016-11-02 23:14:52 +0100 Ulrich Sibiller (5d06f46e5) * xtrans: fix compilation warnings because of missing XTRANS_SEND_FDS -2016-11-02 19:59:23 +0100 Mike Gabriel (8dc0d18) +2016-11-02 19:59:23 +0100 Mike Gabriel (8dc0d18c1) * debian/libnx-x11-6.symbols: Update after upgrade of xtrans library files. -2016-11-02 19:50:24 +0100 Mike Gabriel (107e72b) +2016-11-02 19:50:24 +0100 Mike Gabriel (107e72b03) * Merge branch 'uli42-pr/upgrade_xtrans' into 3.6.x -2016-11-02 11:48:23 +0100 Ulrich Sibiller (6a186b9) +2016-11-02 11:48:23 +0100 Ulrich Sibiller (6a186b921) * Whitespace fixes -2016-10-31 02:29:18 +0100 Ulrich Sibiller (e65b106) +2016-10-31 02:29:18 +0100 Ulrich Sibiller (e65b106a8) * Xtrans: update to Xorg/xtrans upstream (1.3.5+) -2016-10-13 21:53:17 +0200 Ulrich Sibiller (793d587) +2016-10-13 21:53:17 +0200 Ulrich Sibiller (793d587b4) * Remove __UNIXOS2__ references -2016-05-18 12:38:02 -0400 Adam Jackson (603fe25) +2016-05-18 12:38:02 -0400 Adam Jackson (603fe2554) * remove CLTS code -2016-10-13 19:08:37 +0200 Ulrich Sibiller (247e1f7) +2016-10-13 19:08:37 +0200 Ulrich Sibiller (247e1f72e) * use %p in format strings -2016-10-13 00:51:03 +0200 Ulrich Sibiller (c3f43e8) +2016-10-13 00:51:03 +0200 Ulrich Sibiller (c3f43e832) * replace PRMSG by prmsg -2016-10-13 00:35:04 +0200 Ulrich Sibiller (c4b775f) +2016-10-13 00:35:04 +0200 Ulrich Sibiller (c4b775f6d) * align license headers with Xorg/xtrans upstream -2016-10-13 00:31:51 +0200 Ulrich Sibiller (6957b3d) +2016-10-13 00:31:51 +0200 Ulrich Sibiller (6957b3daa) * move helper functions to file end -2008-02-10 19:04:40 -0800 Jeremy Huddleston (f686bc3) +2008-02-10 19:04:40 -0800 Jeremy Huddleston (f686bc3eb) * Fixed #ifdef checks that were using i386 to use __i386__ -2016-10-13 00:16:30 +0200 Ulrich Sibiller (64d5186) +2016-10-13 00:16:30 +0200 Ulrich Sibiller (64d51869f) * whitespace cleanup -2008-08-07 10:32:11 -0400 Adam Jackson (e5b4532) +2008-08-07 10:32:11 -0400 Adam Jackson (e5b4532ab) * Drastically simplify TRANS_OPEN_MAX. -2016-10-12 22:28:41 +0200 Ulrich Sibiller (0ca6e59) +2016-10-12 22:28:41 +0200 Ulrich Sibiller (0ca6e5999) * undef __QNX__ -2016-10-12 22:27:34 +0200 Ulrich Sibiller (4ab02b2) +2016-10-12 22:27:34 +0200 Ulrich Sibiller (4ab02b27c) * undef Lynx -2016-10-12 22:47:36 +0200 Ulrich Sibiller (89cea60) +2016-10-12 22:47:36 +0200 Ulrich Sibiller (89cea600a) * undef AIXV3 -2016-10-12 22:44:21 +0200 Ulrich Sibiller (eb4ee6c) +2016-10-12 22:44:21 +0200 Ulrich Sibiller (eb4ee6c32) * undef hpux -2016-10-12 22:24:09 +0200 Ulrich Sibiller (175a341) +2016-10-12 22:24:09 +0200 Ulrich Sibiller (175a3416e) * undef __UNIXOS2__ -2016-10-12 22:05:26 +0200 Ulrich Sibiller (97d651f) +2016-10-12 22:05:26 +0200 Ulrich Sibiller (97d651fcf) * Remove OS2PIPECONN transport -2016-10-12 21:33:00 +0200 Ulrich Sibiller (0cbc892) +2016-10-12 21:33:00 +0200 Ulrich Sibiller (0cbc89221) * Remove unused TLI ("STREAMSCONN") code -2016-10-12 21:06:36 +0200 Ulrich Sibiller (b5bfd3a) +2016-10-12 21:06:36 +0200 Ulrich Sibiller (b5bfd3a49) * remove DECnet support -2016-11-02 19:38:08 +0100 Mike Gabriel (a9b145d) +2016-11-02 19:38:08 +0100 Mike Gabriel (a9b145d46) * Makefile: Make sure libNX_X11.so.6.2 does not get installed as symlink but as actual file. (Follow-up for 5a90a63). -2016-11-02 17:54:24 +0100 Mike Gabriel (1d1d1fc) +2016-11-02 17:54:24 +0100 Mike Gabriel (1d1d1fc21) * Merge branch 'pr/unused_files' into 3.6.x -2016-10-30 19:05:56 +0100 Ulrich Sibiller (7d88404) +2016-10-30 19:05:56 +0100 Ulrich Sibiller (7d884049b) * remove unused mkks.sh (pr/unused_files) -2016-10-30 19:02:36 +0100 Ulrich Sibiller (bac5ce7) +2016-10-30 19:02:36 +0100 Ulrich Sibiller (bac5ce7b5) * remove unused jump_* files from libX11 -2016-10-30 18:54:04 +0100 Ulrich Sibiller (331497b) +2016-10-30 18:54:04 +0100 Ulrich Sibiller (331497b88) * drop unused xtest1.frags -2016-10-30 18:48:31 +0100 Ulrich Sibiller (6b9ce7d) +2016-10-30 18:48:31 +0100 Ulrich Sibiller (6b9ce7da4) * remove unused fb24_32.h -2016-10-30 18:47:04 +0100 Ulrich Sibiller (a29a2b6) +2016-10-30 18:47:04 +0100 Ulrich Sibiller (a29a2b656) * remove unused registry.h -2016-10-30 18:43:38 +0100 Ulrich Sibiller (89f9212) +2016-10-30 18:43:38 +0100 Ulrich Sibiller (89f9212ef) * remove unused XInput.h -2016-10-30 18:40:10 +0100 Ulrich Sibiller (881979b) +2016-10-30 18:40:10 +0100 Ulrich Sibiller (881979bd1) * Remove unused Xv and XvMC headers -2016-10-30 18:01:11 +0100 Ulrich Sibiller (ba87cf4) +2016-10-30 18:01:11 +0100 Ulrich Sibiller (ba87cf406) * drop unused glu.h -2016-10-30 17:58:59 +0100 Ulrich Sibiller (903d5ce) +2016-10-30 17:58:59 +0100 Ulrich Sibiller (903d5ce8a) * drop ap_keysym.h -2016-10-30 17:55:53 +0100 Ulrich Sibiller (1832ab6) +2016-10-30 17:55:53 +0100 Ulrich Sibiller (1832ab62f) * remove unused registry file -2016-10-30 17:54:46 +0100 Ulrich Sibiller (b7daac2) +2016-10-30 17:54:46 +0100 Ulrich Sibiller (b7daac272) * remove *-def.cpp -2016-10-29 23:26:05 +0200 Ulrich Sibiller (4271b9e) +2016-10-29 23:26:05 +0200 Ulrich Sibiller (4271b9ebd) * nxcomp: remove unused Utils.cpp -2016-10-29 22:52:53 +0200 Ulrich Sibiller (96c9aaf) +2016-10-29 22:52:53 +0200 Ulrich Sibiller (96c9aafd6) * Imake: drop DoLoadableServer, MakeDllModules and IHaveModules -2016-10-29 11:18:41 +0200 Mike Gabriel (8dab7c2) +2016-10-29 11:18:41 +0200 Mike Gabriel (8dab7c21d) * Remove extmod from nx-X11/programs/Xserver/Xext/. -2016-11-02 17:53:15 +0100 Mike Gabriel (6eb8d3e) +2016-11-02 17:53:15 +0100 Mike Gabriel (6eb8d3ec6) * Merge branch 'uli42-pr/add_libX11_links' into 3.6.x -2016-10-28 23:38:17 +0200 Ulrich Sibiller (5a90a63) +2016-10-28 23:38:17 +0200 Ulrich Sibiller (5a90a638f) * libX11/Imakefile: handle libX11 links -2016-10-28 23:37:17 +0200 Ulrich Sibiller (f1d420b) +2016-10-28 23:37:17 +0200 Ulrich Sibiller (f1d420baa) * libX11/Imakefile: add missing dependencies on ks_tables.h -2016-10-31 12:44:52 +0100 Mike Gabriel (4c59a3c) +2016-10-31 12:44:52 +0100 Mike Gabriel (4c59a3c58) * Merge branch 'sunweaver-pr/clean-up-old-vcs-comments' into 3.6.x -2016-10-29 15:30:20 +0200 Mike Gabriel (fcf61d3) +2016-10-29 15:30:20 +0200 Mike Gabriel (fcf61d341) * Imakefile cleanup: Delete all ancient Vcs comments stemming from SVN times of X.org and XFree86. -2016-10-30 23:52:44 +0100 Mike Gabriel (6b3080d) +2016-10-30 23:52:44 +0100 Mike Gabriel (6b3080d54) * Merge branch 'sunweaver-pr/drop-mfb-maskbits-h' into 3.6.x -2016-10-30 21:36:53 +0100 Mike Gabriel (b99c787) +2016-10-30 21:36:53 +0100 Mike Gabriel (b99c78721) * Xserver/Imakefile: Drop references to already removed afb code. (gh-sunweaver/pr/drop-mfb-maskbits-h) -2016-10-30 21:36:03 +0100 Mike Gabriel (65e25bd) +2016-10-30 21:36:03 +0100 Mike Gabriel (65e25bd47) * Xserver/Imakefile: Drop all references to building already removed cfb* implementations. -2016-10-30 20:16:53 +0100 Adam Jackson (cc03502) +2016-10-30 20:16:53 +0100 Adam Jackson (cc0350202) * Death to mfb (removing last remnants from NX code). -2016-10-30 18:31:54 +0100 Adam Jackson (3c0e426) +2016-10-30 18:31:54 +0100 Adam Jackson (3c0e426f0) * Disinfect mi/ of mfb. -2016-10-30 14:32:04 +0100 Mike Gabriel (23c66f4) +2016-10-30 14:32:04 +0100 Mike Gabriel (23c66f400) * Merge branch 'sunweaver-pr/drop-nxlibint-h' into 3.6.x -2016-10-30 13:11:38 +0100 Mike Gabriel (1ddbe39) +2016-10-30 13:11:38 +0100 Mike Gabriel (1ddbe39ad) * nxcompext: Drop (nowadays) no-op file NXlibint.h. (gh-sunweaver/pr/drop-nxlibint-h) -2016-10-30 14:25:57 +0100 Mike Gabriel (23ad270) +2016-10-30 14:25:57 +0100 Mike Gabriel (23ad270b5) * Merge branch 'uli42-misc_fixes' into 3.6.x -2016-10-30 13:46:11 +0100 Ulrich Sibiller (1694701) +2016-10-30 13:46:11 +0100 Ulrich Sibiller (16947012d) * nxagent.keyboard: add quotes -2016-10-30 13:45:33 +0100 Ulrich Sibiller (903cc06) +2016-10-30 13:45:33 +0100 Ulrich Sibiller (903cc0657) * Imakefile: remove references to non-existing subdirs -2016-10-30 02:32:35 +0200 Ulrich Sibiller (162a627) +2016-10-30 02:32:35 +0200 Ulrich Sibiller (162a627c4) * saver.c: fix unused variable warnings -2016-10-29 10:32:51 +0200 Mike Gabriel (a375d17) +2016-10-29 10:32:51 +0200 Mike Gabriel (a375d178f) * Merge branch 'sunweaver-pr/build-includes-robustness' into 3.6.x -2016-10-28 15:19:10 +0200 Mike Gabriel (2f2a5a9) +2016-10-28 15:19:10 +0200 Mike Gabriel (2f2a5a920) * Imake.rules: Make BuildIncludes{,Top}() more robust in case people attempt providing path names instead of file names via srclist. (gh-sunweaver/pr/build-includes-robustness) -2016-10-29 10:30:27 +0200 Mike Gabriel (ecd335f) +2016-10-29 10:30:27 +0200 Mike Gabriel (ecd335fa6) * Merge branch 'uli42-pr/remove_xf86' into 3.6.x -2016-10-28 01:05:03 +0200 Ulrich Sibiller (4aeed7a) +2016-10-28 01:05:03 +0200 Ulrich Sibiller (4aeed7ad9) * remove hw/xfree86 altogether -2016-10-28 00:30:25 +0200 Ulrich Sibiller (6c7f9cd) +2016-10-28 00:30:25 +0200 Ulrich Sibiller (6c7f9cdaa) * remove xf86Version.h and xf86Date.h -2016-10-28 14:51:52 +0200 Mike Gabriel (4cdcd91) +2016-10-28 14:51:52 +0200 Mike Gabriel (4cdcd9145) * debian/patches: Rebase 102_xserver-xext_set-securitypolicy-path.debian.patch. (pr/harmonize-xkb-defaults) -2016-10-28 14:48:25 +0200 Mike Gabriel (c9da511) +2016-10-28 14:48:25 +0200 Mike Gabriel (c9da511cf) * Merge branch 'theqvd-slave-channel' into 3.6.x -2016-10-24 13:27:52 +0200 Vadim Troshchinskiy (c7eac1f) +2016-10-24 13:27:52 +0200 Vadim Troshchinskiy (c7eac1f95) * Add description of NX_SLAVE_CMD to man and help (theqvd-slave-channel) -2016-10-18 09:19:28 +0200 Vadim Troshchinskiy (30af52e) +2016-10-18 09:19:28 +0200 Vadim Troshchinskiy (30af52eb3) * Slave channel implementation -2016-10-28 05:42:02 +0200 Mihai Moldovan (a5de791) +2016-10-28 05:42:02 +0200 Mihai Moldovan (a5de79181) * Merge branch 'uli42-pr/backup_memleak' into arctica-3.6.x -2016-10-25 21:30:15 +0200 Emilio Pozuelo Monfort (8d1126e) +2016-10-25 21:30:15 +0200 Emilio Pozuelo Monfort (8d1126e97) * Plug a memory leak -2016-10-20 22:56:41 +0200 Mike Gabriel (5d4a7e0) +2016-10-20 22:56:41 +0200 Mike Gabriel (5d4a7e071) * debian/rules: Re-enable (+pie) hardening flags again when building .deb packages. -2016-10-20 10:31:24 +0200 Mike Gabriel (61b8d44) +2016-10-20 10:31:24 +0200 Mike Gabriel (61b8d44f1) * Merge branch 'uli42-pr/fix_compile_warnings' into 3.6.x -2016-10-20 00:15:20 +0200 Ulrich Sibiller (50eb5e4) +2016-10-20 00:15:20 +0200 Ulrich Sibiller (50eb5e4a9) * sendexev.c: Fix return of unitialized variable -2011-05-24 18:33:17 +0200 Cyril Brulebois (151e0b1) +2011-05-24 18:33:17 +0200 Cyril Brulebois (151e0b16d) * xfixes: Remove unused variable. -2006-02-14 08:11:41 +0000 Benjamin Herrenschmidt (c266216) +2006-02-14 08:11:41 +0000 Benjamin Herrenschmidt (c26621610) * Remove useless line of code that contained a bug and triggered a gcc warning. This variable will be overriden before being used anyway. (Bugzilla #5595) -2009-01-11 08:25:17 +0100 Julien Cristau (4f99f85) +2009-01-11 08:25:17 +0100 Julien Cristau (4f99f854c) * dix: fix cast from pointer to integer -2014-12-09 09:30:57 -0800 Keith Packard (e3e4062) +2014-12-09 09:30:57 -0800 Keith Packard (e3e4062c3) * dbe: Call to DDX SwapBuffers requires address of int, not unsigned int [CVE-2014-8097 pt. 2] -2016-10-19 21:58:06 +0200 Ulrich Sibiller (01eaab8) +2016-10-19 21:58:06 +0200 Ulrich Sibiller (01eaab831) * LRGB.c: Fix label defined but not used -2016-06-04 17:19:59 +0200 walter harms (ddc5ed4) +2016-06-04 17:19:59 +0200 walter harms (ddc5ed4c9) * Fixes: warning: variable 'req' set but not,used -2016-04-26 16:31:27 +0200 walter harms (21405f6) +2016-04-26 16:31:27 +0200 walter harms (21405f62b) * fix: warning: pointer targets in passing argument 2 of '_XSend' differ in signedness [-Wpointer-sign] -2016-04-26 16:34:11 +0200 walter harms (3f9ebf3) +2016-04-26 16:34:11 +0200 walter harms (3f9ebf33d) * no need to check args for Xfree() -2016-04-26 16:23:46 +0200 walter harms (897b8b2) +2016-04-26 16:23:46 +0200 walter harms (897b8b28b) * remove stray extern -2016-10-16 02:15:13 +0200 Ulrich Sibiller (2c59fbe) +2016-10-16 02:15:13 +0200 Ulrich Sibiller (2c59fbe30) * Fix warnings in XlibInt.c -2016-10-16 00:41:11 +0200 Ulrich Sibiller (0a28292) +2016-10-16 00:41:11 +0200 Ulrich Sibiller (0a28292ec) * xkb.c: fix 'assignment makes integer from pointer without a cast' -2016-10-16 00:19:47 +0200 Ulrich Sibiller (057ddde) +2016-10-16 00:19:47 +0200 Ulrich Sibiller (057ddde08) * xkmread.c: use _X_UNUSED to avoid compiler warning when result is not needed -2016-10-16 00:07:21 +0200 Ulrich Sibiller (33b5911) +2016-10-16 00:07:21 +0200 Ulrich Sibiller (33b5911f2) * xcmisc.c: remove HAVE_STDINT -2016-10-16 00:02:41 +0200 Ulrich Sibiller (c180a21) +2016-10-16 00:02:41 +0200 Ulrich Sibiller (c180a2147) * security.c: fix compiler warnings -2016-10-15 23:01:59 +0200 Ulrich Sibiller (185fbda) +2016-10-15 23:01:59 +0200 Ulrich Sibiller (185fbdaf9) * Loop.cpp: Fix output of SetCore() -2016-10-15 22:02:06 +0200 Ulrich Sibiller (d238db3) +2016-10-15 22:02:06 +0200 Ulrich Sibiller (d238db344) * Window.c: Fix function assignment warning -2016-10-15 21:45:30 +0200 Ulrich Sibiller (81a7c6c) +2016-10-15 21:45:30 +0200 Ulrich Sibiller (81a7c6cf4) * Display.c: remove unused variable -2016-10-15 21:42:54 +0200 Ulrich Sibiller (54b7561) +2016-10-15 21:42:54 +0200 Ulrich Sibiller (54b7561f9) * Colormap.c: add cast to avoid warning -2016-10-15 21:41:03 +0200 Ulrich Sibiller (3c5621c) +2016-10-15 21:41:03 +0200 Ulrich Sibiller (3c5621c37) * Args.c: fix string format warning -2016-10-15 18:21:48 +0200 Ulrich Sibiller (e3c9bc3) +2016-10-15 18:21:48 +0200 Ulrich Sibiller (e3c9bc392) * imLcIm.c: Fix unused variables -2016-10-15 18:03:18 +0200 Ulrich Sibiller (babaf67) +2016-10-15 18:03:18 +0200 Ulrich Sibiller (babaf67c9) * Pending.c: Fix compilation warning -2016-10-15 17:51:11 +0200 Ulrich Sibiller (ae8ec6b) +2016-10-15 17:51:11 +0200 Ulrich Sibiller (ae8ec6b14) * Fix libX11 implicit declaration warnings -2016-10-20 10:08:14 +0200 Mike Gabriel (da01dc8) +2016-10-20 10:08:14 +0200 Mike Gabriel (da01dc8da) * Drop nx-X11/lib/X11/libX11.elist. Not needed for anything nowadays. Probably never was needed in nx-X11. -2016-10-20 09:58:37 +0200 Mike Gabriel (44c76ca) +2016-10-20 09:58:37 +0200 Mike Gabriel (44c76cacf) * debian/libnx-x11-6.symbols: Update symbols list. -2016-10-20 09:52:45 +0200 Mike Gabriel (a559592) +2016-10-20 09:52:45 +0200 Mike Gabriel (a559592dc) * XKeysymDB: ... got removed. -2016-10-19 22:15:01 +0200 Mike Gabriel (70ac75f) +2016-10-19 22:15:01 +0200 Mike Gabriel (70ac75f4a) * Merge branch 'uli42-pr/libX11_further_backports' into 3.6.x -2016-09-25 21:25:25 +0200 Tobias Stoeckmann (70e9d34) +2016-09-25 21:25:25 +0200 Tobias Stoeckmann (70e9d346f) * Validation of server responses in XGetImage() -2016-09-25 21:22:57 +0200 Tobias Stoeckmann (b17557f) +2016-09-25 21:22:57 +0200 Tobias Stoeckmann (b17557f9f) * The validation of server responses avoids out of boundary accesses. -2016-02-06 14:18:32 -0800 Alan Coopersmith (68e3ee6) +2016-02-06 14:18:32 -0800 Alan Coopersmith (68e3ee67c) * xcms: use size_t for pointer offsets passed to strncmp -2016-02-06 13:32:44 -0800 Alan Coopersmith (8d8d5cf) +2016-02-06 13:32:44 -0800 Alan Coopersmith (8d8d5cfd8) * xcms: use unsigned indexes when looping through unsigned values -2016-02-06 13:01:25 -0800 Alan Coopersmith (327d2cc) +2016-02-06 13:01:25 -0800 Alan Coopersmith (327d2cc60) * xcms: use size_t for strlen/sizeof values instead of converting to int & back -2015-03-26 07:52:58 +0100 Dominik Muth (de40477) +2015-03-26 07:52:58 +0100 Dominik Muth (de4047722) * Xlib.h: Fix macros imitating C functions. -2016-01-21 11:54:19 +0100 Olivier Fourdan (a3759f3) +2016-01-21 11:54:19 +0100 Olivier Fourdan (a3759f323) * XKB: fix XkbGetKeyboardByName with Xming server -2015-12-19 18:03:41 -0800 Alan Coopersmith (50192b7) +2015-12-19 18:03:41 -0800 Alan Coopersmith (50192b720) * lcPubWrap: replace malloc(strlen) + strcpy with strdup -2015-12-19 10:21:04 -0800 Alan Coopersmith (7a1fc17) +2015-12-19 10:21:04 -0800 Alan Coopersmith (7a1fc1759) * XlcDL.c: reduce code duplication -2015-12-19 10:19:25 -0800 Alan Coopersmith (c9ebd12) +2015-12-19 10:19:25 -0800 Alan Coopersmith (c9ebd122f) * XlcDL.c: replace strcpy+strcat sequences with snprintf -2015-12-19 10:05:42 -0800 Alan Coopersmith (2874fd1) +2015-12-19 10:05:42 -0800 Alan Coopersmith (2874fd14b) * XDefaultOMIF: Remove comments referring to ancient Sun bug ids -2015-12-19 10:00:22 -0800 Alan Coopersmith (d980be3) +2015-12-19 10:00:22 -0800 Alan Coopersmith (d980be3c2) * XDefaultOMIF: additional code simplification -2015-12-19 09:46:31 -0800 Alan Coopersmith (c00196d) +2015-12-19 09:46:31 -0800 Alan Coopersmith (c00196d2d) * XDefaultOMIF: replace strlen+Xmalloc+strcpy with strdup -2015-12-19 09:20:55 -0800 Alan Coopersmith (f7254c6) +2015-12-19 09:20:55 -0800 Alan Coopersmith (f7254c69f) * Use strdup instead of Xmalloc+strcpy in _XDefaultOpenIM -2015-12-04 22:20:53 -0800 Alan Coopersmith (b912a40) +2015-12-04 22:20:53 -0800 Alan Coopersmith (b912a4042) * Delete #if 0 hunks of code -2015-12-03 23:38:07 -0800 Alan Coopersmith (9dec6c1) +2015-12-03 23:38:07 -0800 Alan Coopersmith (9dec6c18b) * Bug 93183: _XDefaultOpenIM memory leaks in out-of-memory error paths -2015-12-03 23:19:48 -0800 Alan Coopersmith (8d6d95d) +2015-12-03 23:19:48 -0800 Alan Coopersmith (8d6d95d74) * Bug 93184: read_EncodingInfo invalid free -2015-11-28 13:18:11 -0800 Alan Coopersmith (8339e68) +2015-11-28 13:18:11 -0800 Alan Coopersmith (8339e6803) * Remove unused definition of XCONN_CHECK_FREQ -2015-09-27 18:38:32 -0700 Alan Coopersmith (f857c70) +2015-09-27 18:38:32 -0700 Alan Coopersmith (f857c70f8) * Get rid of some extraneous ; at the end of C source lines -2015-07-19 10:22:45 +0200 Thomas Klausner (fc524dd) +2015-07-19 10:22:45 +0200 Thomas Klausner (fc524ddbb) * Do not return() after exit(). -2015-05-18 14:49:01 +0100 Ross Burton (1445735) +2015-05-18 14:49:01 +0100 Ross Burton (1445735ef) * Add missing NULL checks to ICWrap -2015-06-04 20:51:17 -0700 Alan Coopersmith (39dd37d) +2015-06-04 20:51:17 -0700 Alan Coopersmith (39dd37d57) * Replace Xmalloc+memset pairs with Xcalloc calls -2015-06-04 19:07:12 -0700 Bhavi Dhingra (a402ed0) +2015-06-04 19:07:12 -0700 Bhavi Dhingra (a402ed016) * omGeneric.c: Correct the parameter usage of sizeof -2015-05-19 12:30:22 +1000 Peter Hutterer (73f2d66) +2015-05-19 12:30:22 +1000 Peter Hutterer (73f2d66e0) * Fix three "use of uninitialized variable" coverity warnings -2015-05-18 07:55:17 +1000 Peter Hutterer (e144899) +2015-05-18 07:55:17 +1000 Peter Hutterer (e14489988) * Fix potential memory leak -2015-02-03 13:23:50 -0500 Ran Benita (8e3e7bb) +2015-02-03 13:23:50 -0500 Ran Benita (8e3e7bb77) * compose: fix the description of modifiers in compose sequences -2014-07-11 10:34:08 -0700 Alan Coopersmith (0f1fa85) +2014-07-11 10:34:08 -0700 Alan Coopersmith (0f1fa85fe) * Use C99 named initializers to fill in events passed to XSendEvent -2014-07-06 11:13:49 -0700 Alan Coopersmith (f20f91e) +2014-07-06 11:13:49 -0700 Alan Coopersmith (f20f91ee8) * Fix validation of ctrls parameter to XkbGetPerClientControls() -2014-07-06 10:54:57 -0700 Alan Coopersmith (37b8d68) +2014-07-06 10:54:57 -0700 Alan Coopersmith (37b8d6883) * Fix map->num_types check in XkbAddKeyType() -2014-06-07 12:03:17 +0200 walter harms (aa7053b) +2014-06-07 12:03:17 +0200 walter harms (aa7053b3e) * lcDefConv.c: fix use before check -2014-06-07 11:54:34 +0200 walter harms (dd6dc2d) +2014-06-07 11:54:34 +0200 walter harms (dd6dc2ddf) * rm redundant null checks -2014-06-07 15:17:27 +0200 walter harms (a982607) +2014-06-07 15:17:27 +0200 walter harms (a98260726) * libX11: rm redundante NULL checks -2014-06-06 22:53:05 +0200 walter harms (1ff6961) +2014-06-06 22:53:05 +0200 walter harms (1ff696123) * Remove more redundant null checks before Xfree() -2014-06-05 18:37:40 +0200 walter harms (fc26b97) +2014-06-05 18:37:40 +0200 walter harms (fc26b97ea) * Remove redundant null checks before free -2014-06-04 17:12:31 +0200 walter harms (191d157) +2014-06-04 17:12:31 +0200 walter harms (191d1575f) * libX11/lcUTF8.c fix: dereferenced before check -2014-06-04 17:10:20 +0200 walter harms (861fe5a) +2014-06-04 17:10:20 +0200 walter harms (861fe5aee) * libX11/XKBNames.c fix: dereferenced before check -2014-06-04 17:08:12 +0200 walter harms (e7528f5) +2014-06-04 17:08:12 +0200 walter harms (e7528f581) * libX11/lcGenConv.c fix: dereferenced before check -2014-05-09 18:21:05 -0400 Owen W. Taylor (afc7138) +2014-05-09 18:21:05 -0400 Owen W. Taylor (afc7138f9) * Fix XNextRequest() after direct usage of XCB -2014-02-11 13:26:16 +0200 Ran Benita (88d4965) +2014-02-11 13:26:16 +0200 Ran Benita (88d496598) * Remove dead USE_OWN_COMPOSE-protected code -2014-02-06 13:48:08 -0800 Alan Coopersmith (3e8df1a) +2014-02-06 13:48:08 -0800 Alan Coopersmith (3e8df1a2e) * Fix typos in Xrm.c comments -2013-12-26 09:26:13 -0800 Alan Coopersmith (101419b) +2013-12-26 09:26:13 -0800 Alan Coopersmith (101419b10) * _XkbReadGeomOverlay: check for NULL first, then use pointer -2013-12-26 09:22:49 -0800 Alan Coopersmith (1b0df5d) +2013-12-26 09:22:49 -0800 Alan Coopersmith (1b0df5da6) * XkbSelectEventDetails: remove unnecessary assignments -2010-10-07 18:46:08 +0100 Jon TURNEY (4fad46e) +2010-10-07 18:46:08 +0100 Jon TURNEY (4fad46e9c) * Don't try so hard to find a matching font with the given encoding -2013-12-02 21:51:27 -0800 Alan Coopersmith (f45ac4a) +2013-12-02 21:51:27 -0800 Alan Coopersmith (f45ac4ae3) * unifdef -UISC -2013-11-16 20:21:54 -0800 Alan Coopersmith (35dc478) +2013-11-16 20:21:54 -0800 Alan Coopersmith (35dc4784b) * Drop X_LOCALE fallback for OS'es without setlocale() -2013-08-24 17:27:43 -0700 Alan Coopersmith (f04e1a6) +2013-08-24 17:27:43 -0700 Alan Coopersmith (f04e1a6d1) * Bug 68413 - [Bisected]Error in `xterm': realloc(): invalid next size -2013-08-16 21:04:02 -0700 Alan Coopersmith (ba86b7a) +2013-08-16 21:04:02 -0700 Alan Coopersmith (ba86b7a2e) * Stop checking for HAVE_DIX_CONFIG_H on the client side -2013-08-16 18:27:28 -0700 Alan Coopersmith (2824899) +2013-08-16 18:27:28 -0700 Alan Coopersmith (2824899d2) * Rearrange some variable declarations & initializations in XKB -2013-08-11 13:29:33 -0700 Alan Coopersmith (3c5880e) +2013-08-11 13:29:33 -0700 Alan Coopersmith (3c5880e72) * Reindent XKB code to X.Org standard style -2013-08-16 18:14:14 -0700 Alan Coopersmith (3cd8225) +2013-08-16 18:14:14 -0700 Alan Coopersmith (3cd822526) * Fix overflow checks in _XkbReadKeySyms when key_sym_map is already created -2013-08-11 17:02:21 -0700 Alan Coopersmith (c22524d) +2013-08-11 17:02:21 -0700 Alan Coopersmith (c22524d30) * Remove long unused udcInf.c -2013-08-11 00:07:33 -0700 Alan Coopersmith (2625618) +2013-08-11 00:07:33 -0700 Alan Coopersmith (26256188b) * Remove unnecessary casts of pointers to (char *) in calls to Xfree() -2013-08-10 23:57:55 -0700 Alan Coopersmith (d33cf04) +2013-08-10 23:57:55 -0700 Alan Coopersmith (d33cf0446) * Don't cast sizeof() results to unsigned when passing to Xmalloc/Xcalloc -2013-08-10 23:51:08 -0700 Alan Coopersmith (c161df4) +2013-08-10 23:51:08 -0700 Alan Coopersmith (c161df4fe) * Remove even more casts of return values from Xmalloc/Xrealloc -2013-08-10 23:05:13 -0700 Alan Coopersmith (5d6cda4) +2013-08-10 23:05:13 -0700 Alan Coopersmith (5d6cda4f6) * xlibi18n: fix argsize argument to _XlcParsePath -2013-08-10 22:32:42 -0700 Alan Coopersmith (069c1f4) +2013-08-10 22:32:42 -0700 Alan Coopersmith (069c1f4d5) * i18n modules: Fix some const cast warnings -2013-08-10 22:21:54 -0700 Alan Coopersmith (d8358c6) +2013-08-10 22:21:54 -0700 Alan Coopersmith (d8358c6ef) * xlibi18n: Fix a bunch of const cast warnings -2013-08-10 22:18:00 -0700 Alan Coopersmith (e667b90) +2013-08-10 22:18:00 -0700 Alan Coopersmith (e667b9054) * Fix const handling in XSetLocaleModifiers -2013-08-10 21:46:37 -0700 Alan Coopersmith (d2671c2) +2013-08-10 21:46:37 -0700 Alan Coopersmith (d2671c285) * Constify lc_name argument to _XlcLocaleDirName() & _XlcLocaleLibDirName() -2013-08-10 13:37:53 -0700 Alan Coopersmith (22377a7) +2013-08-10 13:37:53 -0700 Alan Coopersmith (22377a799) * init_om: remove unneeded extra copy of string to local buffer -2013-08-10 12:34:53 -0700 Alan Coopersmith (9259131) +2013-08-10 12:34:53 -0700 Alan Coopersmith (92591316d) * Delete unused XKB_INSURE_SIZE macro from XKBlibint.h -2013-08-10 12:19:17 -0700 Alan Coopersmith (be32fbb) +2013-08-10 12:19:17 -0700 Alan Coopersmith (be32fbb31) * miRegionOp(): ensure region size is not updated if realloc fails -2013-08-10 12:19:17 -0700 Alan Coopersmith (ad51fbd) +2013-08-10 12:19:17 -0700 Alan Coopersmith (ad51fbdb4) * miRegionCopy(): handle realloc failure better -2013-08-10 11:27:22 -0700 Alan Coopersmith (105cd47) +2013-08-10 11:27:22 -0700 Alan Coopersmith (105cd4711) * Avoid memory leak/corruption if realloc fails in Xregion.h:MEMCHECK macro -2013-08-10 12:07:51 -0700 Alan Coopersmith (180991c) +2013-08-10 12:07:51 -0700 Alan Coopersmith (180991ce2) * Avoid memory leak/corruption if realloc fails in imLcPrs.c:parseline() -2013-08-10 12:30:39 -0700 Alan Coopersmith (7156a20) +2013-08-10 12:30:39 -0700 Alan Coopersmith (7156a20bc) * lcDB.c: ensure buffer size is updated correctly if realloc fails -2013-08-10 11:07:47 -0700 Alan Coopersmith (0574a55) +2013-08-10 11:07:47 -0700 Alan Coopersmith (0574a55eb) * Avoid memory leak/corruption if realloc fails in XlcDL.c:resolve_object() -2013-08-09 23:33:03 -0700 Alan Coopersmith (a6d9409) +2013-08-09 23:33:03 -0700 Alan Coopersmith (a6d9409b0) * omGeneric.c: convert sprintf calls to snprintf -2013-08-09 23:30:30 -0700 Alan Coopersmith (d03ab1d) +2013-08-09 23:30:30 -0700 Alan Coopersmith (d03ab1de0) * ximcp/imRm.c: convert sprintf calls to snprintf -2013-08-09 23:02:12 -0700 Alan Coopersmith (a1b0fdb) +2013-08-09 23:02:12 -0700 Alan Coopersmith (a1b0fdb2c) * xlibi18n: convert sprintf calls to snprintf -2013-08-09 23:02:12 -0700 Alan Coopersmith (bde3d8b) +2013-08-09 23:02:12 -0700 Alan Coopersmith (bde3d8b14) * lcfile: skip over any null entries in args list -2013-08-09 22:00:09 -0700 Alan Coopersmith (7bca345) +2013-08-09 22:00:09 -0700 Alan Coopersmith (7bca34528) * Fix file leak on malloc error in XlcDL.c:resolve_object() -2012-12-18 15:28:05 +0000 ISHIKAWA,chiaki (ce482d4) +2012-12-18 15:28:05 +0000 ISHIKAWA,chiaki (ce482d4fd) * Fix bogus timestamp generated by XIM -2011-06-16 17:28:39 +0200 Egbert Eich (ed53aca) +2011-06-16 17:28:39 +0200 Egbert Eich (ed53aca1d) * XIM: Fix race on focus change: set 'FABRICATED' only when keyev filters in place. -2013-07-27 01:03:18 -0700 Alan Coopersmith (adcf389) +2013-07-27 01:03:18 -0700 Alan Coopersmith (adcf3894a) * omGeneric: remove space between struct name & member name -2013-07-23 22:11:34 -0700 Alan Coopersmith (6d64c41) +2013-07-23 22:11:34 -0700 Alan Coopersmith (6d64c4164) * XSetModifierMapping: Use Data instead of GetReqExtra -2013-06-09 11:13:42 -0700 Kees Cook (ea82396) +2013-06-09 11:13:42 -0700 Kees Cook (ea8239650) * libX11: check size of GetReqExtra after XFlush -2013-06-25 22:35:29 +0200 Thomas Klausner (39c6e5a) +2013-06-25 22:35:29 +0200 Thomas Klausner (39c6e5aa8) * Tighten out-of-range comparisons. -2013-06-25 18:34:32 +0200 Thomas Klausner (ac3d262) +2013-06-25 18:34:32 +0200 Thomas Klausner (ac3d26251) * Fix out-of-range comparison in _XF86BigfontQueryFont -2013-06-25 18:33:56 +0200 Thomas Klausner (61fdf93) +2013-06-25 18:33:56 +0200 Thomas Klausner (61fdf93ef) * Check for symbol existence with #ifdef, not #if -2013-06-25 18:31:32 +0200 Thomas Klausner (d122d75) +2013-06-25 18:31:32 +0200 Thomas Klausner (d122d7545) * Stop truncating source to destination length if it is larger. -2013-06-24 23:02:05 -0700 Alan Coopersmith (88edf80) +2013-06-24 23:02:05 -0700 Alan Coopersmith (88edf8083) * Require ANSI C89 pre-processor, drop pre-C89 token pasting support -2016-10-08 00:20:48 +0200 Ulrich Sibiller (7f98ab0) +2016-10-08 00:20:48 +0200 Ulrich Sibiller (7f98ab03b) * update Xfuncproto.h -2016-10-07 23:46:05 +0200 Ulrich Sibiller (e2e45b2) +2016-10-07 23:46:05 +0200 Ulrich Sibiller (e2e45b2b3) * Align files with upstream libX11-1.6.0 -2012-12-16 17:44:42 -0800 Alan Coopersmith (878040b) +2012-12-16 17:44:42 -0800 Alan Coopersmith (878040bf0) * Tell clang not to report -Wpadded warnings on public headers we can't fix -2010-09-08 10:44:23 -0400 Adam Jackson (9b5f99c) +2010-09-08 10:44:23 -0400 Adam Jackson (9b5f99c37) * Zero buffer data in BufAlloc() -2011-01-31 14:02:10 +0200 Erkki Seppälä (13fe4d4) +2011-01-31 14:02:10 +0200 Erkki Seppälä (13fe4d475) * GetProp: Zero-initialized error so its resourceID field is initialized -2013-03-01 18:37:37 -0800 Alan Coopersmith (7992a98) +2013-03-01 18:37:37 -0800 Alan Coopersmith (7992a9873) * integer overflow in ReadInFile() in Xrm.c [CVE-2013-1981 7/13] -2011-01-31 14:01:58 +0200 Erkki Seppälä (78b0ca2) +2011-01-31 14:01:58 +0200 Erkki Seppälä (78b0ca2fe) * ximcp/imRmAttr: Handle leaking colormap_ret -2011-02-21 15:56:54 +0100 Samuel Thibault (b00312f) +2011-02-21 15:56:54 +0100 Samuel Thibault (b00312f5d) * Fix status reporting for braille patterns -2016-10-07 22:16:24 +0200 Ulrich Sibiller (a2fded2) +2016-10-07 22:16:24 +0200 Ulrich Sibiller (a2fded2e3) * Revert incomplete "Fix status reporting for braille patterns" -2010-09-03 23:11:53 -0700 Alan Coopersmith (bd43a06) +2010-09-03 23:11:53 -0700 Alan Coopersmith (bd43a0640) * Sun's copyrights are now owned by Oracle -2016-10-07 21:16:39 +0200 Ulrich Sibiller (5dbcf19) +2016-10-07 21:16:39 +0200 Ulrich Sibiller (5dbcf1987) * Assume size_t is always available, since it was defined in C89 -2016-10-07 21:00:20 +0200 Ulrich Sibiller (1078f97) +2016-10-07 21:00:20 +0200 Ulrich Sibiller (1078f9770) * rename xf86bigfstr.h to xf86bigfproto.h -2013-06-02 11:49:54 -0700 Thomas Klausner (e03d8c2) +2013-06-02 11:49:54 -0700 Thomas Klausner (e03d8c215) * cmsMath.c: Add missing stdio header for printf(3) in DEBUG build. -2013-05-17 15:26:21 -0700 Niveditha Rau (26f7239) +2013-05-17 15:26:21 -0700 Niveditha Rau (26f7239a0) * Make sure internal headers include required headers -2013-05-16 23:05:36 -0700 Alan Coopersmith (71fb99c) +2013-05-16 23:05:36 -0700 Alan Coopersmith (71fb99cb4) * Free fs->properties in XF86BigfontQueryFont overflow error path -2013-05-23 20:39:46 +0200 Julien Cristau (78ed233) +2013-05-23 20:39:46 +0200 Julien Cristau (78ed23330) * xkb: fix off-by-one in _XkbReadGetNamesReply and _XkbReadVirtualModMap -2016-10-06 23:34:06 +0200 Ulrich Sibiller (082e831) +2016-10-06 23:34:06 +0200 Ulrich Sibiller (082e83130) * Revert "Add a couple fixups for the security patches" -2013-03-07 23:46:05 -0800 Alan Coopersmith (e15023b) +2013-03-07 23:46:05 -0800 Alan Coopersmith (e15023b2a) * Remove more unnecessary casts from Xmalloc/calloc calls -2013-03-16 18:30:56 -0700 Alan Coopersmith (47d0ea1) +2013-03-16 18:30:56 -0700 Alan Coopersmith (47d0ea1ba) * Move big request comment in XOpenDisplay to the right place -2013-03-08 22:33:28 -0800 Alan Coopersmith (4988e9b) +2013-03-08 22:33:28 -0800 Alan Coopersmith (4988e9bd9) * Fix very weird indenting in nx-X11/lib/X11/GetFProp.c -2013-03-08 15:37:33 -0800 Alan Coopersmith (001aeb5) +2013-03-08 15:37:33 -0800 Alan Coopersmith (001aeb55b) * XAllocClassHint: Assume calloc sets pointers in allocated memory to NULL -2013-03-08 17:13:09 -0800 Alan Coopersmith (7ddc5b9) +2013-03-08 17:13:09 -0800 Alan Coopersmith (7ddc5b90f) * _xudc_code_to_glyph: check for NULL pointer *before* writing to it, not after -2013-03-01 18:10:27 -0800 Alan Coopersmith (e18ccaa) +2013-03-01 18:10:27 -0800 Alan Coopersmith (e18ccaaae) * Assume size_t is always available, since it was defined in C89 -2013-03-01 18:09:07 -0800 Alan Coopersmith (2393e1a) +2013-03-01 18:09:07 -0800 Alan Coopersmith (2393e1acd) * unifdef XKB_IN_SERVER -2013-02-16 10:42:23 -0800 Alan Coopersmith (d31b81c) +2013-02-16 10:42:23 -0800 Alan Coopersmith (d31b81c10) * Convert more sprintf calls to snprintf -2013-02-15 23:43:12 -0800 Alan Coopersmith (d43f4c3) +2013-02-15 23:43:12 -0800 Alan Coopersmith (d43f4c398) * XKeysymToString: move variable declarations to the scope of their usage -2013-02-15 23:34:40 -0800 Alan Coopersmith (5e0584c) +2013-02-15 23:34:40 -0800 Alan Coopersmith (5e0584c43) * Preserve constness in casting arguments through the Data*() routines -2013-02-15 23:25:38 -0800 Alan Coopersmith (d91c145) +2013-02-15 23:25:38 -0800 Alan Coopersmith (d91c145a4) * XStringToKeysym: preserve constness when casting off unsignedness for strcmp -2013-02-15 23:14:40 -0800 Alan Coopersmith (6417045) +2013-02-15 23:14:40 -0800 Alan Coopersmith (641704516) * XRebindKeysym: Drop unnecessary const-removing cast -2013-02-15 22:45:19 -0800 Alan Coopersmith (5608b67) +2013-02-15 22:45:19 -0800 Alan Coopersmith (5608b67f2) * cmsColNm.c: maintain constness of arguments to qsort helper function -2012-12-26 22:57:39 -0800 Alan Coopersmith (19275f9) +2012-12-26 22:57:39 -0800 Alan Coopersmith (19275f9e1) * Remove unused DECnet ("DNETCONN") code from Xlib -2012-12-26 22:56:38 -0800 Alan Coopersmith (acceb2c) +2012-12-26 22:56:38 -0800 Alan Coopersmith (acceb2cf6) * Remove unused TLI ("STREAMSCONN") code from Xlib -2011-05-20 18:25:24 +0200 Egbert Eich (53e2e92) +2011-05-20 18:25:24 +0200 Egbert Eich (53e2e92e3) * Don't hard code path to Xcms.txt file. -2012-10-22 13:54:11 -0500 Yaakov Selkowitz (11d6dac) +2012-10-22 13:54:11 -0500 Yaakov Selkowitz (11d6dac92) * XIM: remove Private and Public macros -2012-06-29 23:08:04 -0700 Alan Coopersmith (97b9864) +2012-06-29 23:08:04 -0700 Alan Coopersmith (97b9864ea) * Convert XCreate{Pix,Bit}map...Data to use C99 designated initializers -2012-06-29 22:57:13 -0700 Alan Coopersmith (7a8721b) +2012-06-29 22:57:13 -0700 Alan Coopersmith (7a8721b8a) * XCreate{Pix,Bit}map...Data: Free pixmap in error path if XCreateGC fails -2010-12-22 15:14:05 +0000 Philipp Reh (c868061) +2010-12-22 15:14:05 +0000 Philipp Reh (c86806148) * Events: Store event cookie when dequeuing event -2011-05-03 09:32:53 -0700 Jeremy Huddleston (5062342) +2011-05-03 09:32:53 -0700 Jeremy Huddleston (5062342d4) * clang analyzer: Don't warn about Xmalloc(0) -2011-05-08 09:08:07 -0700 Jeremy Huddleston (c19cda6) +2011-05-08 09:08:07 -0700 Jeremy Huddleston (c19cda6d6) * Silence clang static analysis warnings for SetReqLen -2011-05-17 20:49:59 -0700 Alan Coopersmith (c300a43) +2011-05-17 20:49:59 -0700 Alan Coopersmith (c300a430d) * Fix man page and comment references to use XFreeModifiermap (lowercase map) -2011-10-10 14:09:17 -0700 Jeremy Huddleston (f3bbb81) +2011-10-10 14:09:17 -0700 Jeremy Huddleston (f3bbb81c4) * Mark XKeycodeToKeysym as _X_DEPRECATED -2011-10-10 16:40:52 +0200 Bodo Graumann (cc4d526) +2011-10-10 16:40:52 +0200 Bodo Graumann (cc4d5260e) * libX11: Fixing modifier key range in Xutil.h (Bug #21910) -2011-10-27 13:24:10 +1000 Peter Hutterer (3bf3507) +2011-10-27 13:24:10 +1000 Peter Hutterer (3bf350742) * Switch GetEmptyReq and GetResReq to call _XGetRequest -2011-10-14 14:51:06 +1000 Peter Hutterer (3597915) +2011-10-14 14:51:06 +1000 Peter Hutterer (3597915f6) * include: Add GetReqSized() for request buffers of specific size -2011-10-27 13:53:22 +1000 Peter Hutterer (3155b9b) +2011-10-27 13:53:22 +1000 Peter Hutterer (3155b9bb2) * Use GetReqSized for GetReq and GetReqExtra -2011-01-31 14:01:59 +0200 Erkki Seppälä (79cb50e) +2011-01-31 14:01:59 +0200 Erkki Seppälä (79cb50e4c) * ximcp/imRmAttr: Handle leaking missing_list -2011-01-31 14:02:01 +0200 Erkki Seppälä (44e4720) +2011-01-31 14:02:01 +0200 Erkki Seppälä (44e472068) * ximcp/imRm: Handle leaking colormap_ret -2011-01-31 14:02:14 +0200 Erkki Seppälä (89dc7cc) +2011-01-31 14:02:14 +0200 Erkki Seppälä (89dc7ccfb) * ximcp/imTrX: Handle failing XGetWindowProperty -2011-01-31 14:02:15 +0200 Erkki Seppälä (8142209) +2011-01-31 14:02:15 +0200 Erkki Seppälä (81422098f) * ximcp/imLckup: Handle negative return value from _Xlcwctomb -2011-01-31 14:02:13 +0200 Ander Conselvan de Oliveira (a8598e0) +2011-01-31 14:02:13 +0200 Ander Conselvan de Oliveira (a8598e062) * lc/def/lcDefConv: Use Xcalloc to avoid use of uninitialized memory -2011-02-21 15:56:54 +0100 Samuel Thibault (93a4f5c) +2011-02-21 15:56:54 +0100 Samuel Thibault (93a4f5c47) * Fix status reporting for braille patterns -2011-02-21 21:54:17 +0100 Samuel Thibault (2cca621) +2011-02-21 21:54:17 +0100 Samuel Thibault (2cca621e3) * Make the Local XIM request key releases for braille -2011-01-10 16:22:45 +0200 Erkki Seppälä (e481512) +2011-01-10 16:22:45 +0200 Erkki Seppälä (e4815126b) * im/ximcp: release modifiermap before returning -2011-04-12 20:50:42 -0700 Alan Coopersmith (018d938) +2011-04-12 20:50:42 -0700 Alan Coopersmith (018d938aa) * Fix "attrinute" typo in comments in ximcp -2011-03-24 16:24:29 +0200 Ander Conselvan de Oliveira (4aa79f1) +2011-03-24 16:24:29 +0200 Ander Conselvan de Oliveira (4aa79f1f1) * Fix leaks in _XimEncodingNegotiation error paths. -2011-03-24 19:36:56 +0200 Ander Conselvan de Oliveira (3720ed7) +2011-03-24 19:36:56 +0200 Ander Conselvan de Oliveira (3720ed7bf) * Fix memory leaks on _XimProtoCreateIC error paths. -2011-03-24 19:48:44 +0200 Ander Conselvan de Oliveira (b7cc762) +2011-03-24 19:48:44 +0200 Ander Conselvan de Oliveira (b7cc762ba) * Fix memory leaks on _XimWriteCachedDefaultTree error paths. -2011-03-24 19:52:05 +0200 Ander Conselvan de Oliveira (7024f3d) +2011-03-24 19:52:05 +0200 Ander Conselvan de Oliveira (7024f3d90) * Fix memory leak on _XimCommitRecv error path. -2011-03-24 19:55:33 +0200 Ander Conselvan de Oliveira (60840dc) +2011-03-24 19:55:33 +0200 Ander Conselvan de Oliveira (60840dc31) * Fix memory leaks on _XimCbDispatch error path. -2011-03-24 20:40:41 +0200 Ander Conselvan de Oliveira (9fa1e98) +2011-03-24 20:40:41 +0200 Ander Conselvan de Oliveira (9fa1e98dd) * om: Fix memory leak on read_EncodingInfo error path. -2011-03-25 16:06:15 +0200 Ander Conselvan de Oliveira (748cf89) +2011-03-25 16:06:15 +0200 Ander Conselvan de Oliveira (748cf8946) * om: Fix potential memory leak in init_om. -2011-03-25 14:47:35 +0200 Ander Conselvan de Oliveira (6fe8d44) +2011-03-25 14:47:35 +0200 Ander Conselvan de Oliveira (6fe8d44ca) * om: Fix memory leaks on get_font_name error paths. -2011-10-09 02:26:45 -0700 Jeremy Huddleston (73a2898) +2011-10-09 02:26:45 -0700 Jeremy Huddleston (73a2898af) * Fix potential uninitialized variable access in _XimMakeICAttrIDList -2011-10-09 17:56:45 +0200 Yann Droneaud (bec22fe) +2011-10-09 17:56:45 +0200 Yann Droneaud (bec22fe97) * Return name instead of value in XGetIMValues() and XSetIMValues() -2011-10-11 17:27:59 +0200 Yann Droneaud (cded330) +2011-10-11 17:27:59 +0200 Yann Droneaud (cded3305d) * Return name instead of False in XSetICValues() -2011-10-14 17:39:21 -0700 Xue Wei (8d1e059) +2011-10-14 17:39:21 -0700 Xue Wei (8d1e05940) * mbtocs should not truncate input -2011-10-14 17:53:00 -0700 Alan Coopersmith (2f49f62) +2011-10-14 17:53:00 -0700 Alan Coopersmith (2f49f62a8) * Fix "nomal" -> "normal" typo in several comments -2011-11-08 20:18:09 +0000 Andreas Wettstein (4ef2779) +2011-11-08 20:18:09 +0000 Andreas Wettstein (4ef27790b) * XIM: Allow modifier releases in compose sequences (#26705) -2011-02-21 17:27:38 +0100 Samuel Thibault (b8b885d) +2011-02-21 17:27:38 +0100 Samuel Thibault (b8b885daf) * Match braille patterns with compose tree -2012-04-30 16:36:47 +1000 Peter Hutterer (79a5330) +2012-04-30 16:36:47 +1000 Peter Hutterer (79a5330db) * Typo fix -2012-03-15 22:03:21 -0700 Alan Coopersmith (4c7f0af) +2012-03-15 22:03:21 -0700 Alan Coopersmith (4c7f0af73) * Remove "register" qualifier that annoys Solaris Studio compiler -2012-03-04 02:00:13 -0800 Keith Packard (3d37513) +2012-03-04 02:00:13 -0800 Keith Packard (3d37513eb) * Block for other threads in _XUserLockDisplay -2011-02-20 17:09:43 +0200 Marko Myllynen (e8e91b6) +2011-02-20 17:09:43 +0200 Marko Myllynen (e8e91b69e) * Provide translation from XK_permille (ad5) to Unicode (U2030) -2012-01-01 21:04:52 +0000 Ryan Pavlik (fd71577) +2012-01-01 21:04:52 +0000 Ryan Pavlik (fd7157723) * Use pthreads on MinGW also -2011-12-14 02:17:55 -0500 Kusanagi Kouichi (5eb1147) +2011-12-14 02:17:55 -0500 Kusanagi Kouichi (5eb1147cc) * XQueryColors: Split a request into multiple requests if necessary -2011-11-29 23:56:57 -0800 Alan Coopersmith (30d4454) +2011-11-29 23:56:57 -0800 Alan Coopersmith (30d4454e3) * Reject negative string counts in copy_string_list -2011-11-09 21:00:36 -0800 Alan Coopersmith (0f08982) +2011-11-09 21:00:36 -0800 Alan Coopersmith (0f089824e) * XlcSL.c: convert old-style function definitions to ANSI C89 style -2011-10-17 09:45:15 +1000 Peter Hutterer (02dad70) +2011-10-17 09:45:15 +1000 Peter Hutterer (02dad70a8) * Add _XGetRequest as substitute for GetReq/GetReqExtra -2011-10-13 07:58:02 +0900 Choe Hwanjin (1871ff0) +2011-10-13 07:58:02 +0900 Choe Hwanjin (1871ff031) * XIM: Make Xim handle NEED_SYNC_REPLY flag -2011-05-04 15:34:31 -0700 Jeremy Huddleston (7efa7da) +2011-05-04 15:34:31 -0700 Jeremy Huddleston (7efa7da59) * XKB: XkbComputeSectionBounds: Check correct bounds in default switch-case -2011-05-04 11:35:31 -0700 Jeremy Huddleston (1d806a5) +2011-05-04 11:35:31 -0700 Jeremy Huddleston (1d806a555) * Dead code removal -2011-04-21 16:21:04 -0700 Alan Coopersmith (8127b17) +2011-04-21 16:21:04 -0700 Alan Coopersmith (8127b17dc) * Delete special case code to append "/sparcv9" to i18n module path -2011-04-12 22:30:45 -0700 Alan Coopersmith (dde00b2) +2011-04-12 22:30:45 -0700 Alan Coopersmith (dde00b2f6) * Convert malloc(strlen()); strcpy() sets to strdup -2011-04-12 21:27:45 -0700 Alan Coopersmith (7d7224d) +2011-04-12 21:27:45 -0700 Alan Coopersmith (7d7224d85) * Replace Xmalloc+bzero pairs with Xcalloc calls -2011-03-24 19:42:36 +0200 Ander Conselvan de Oliveira (369c956) +2011-03-24 19:42:36 +0200 Ander Conselvan de Oliveira (369c95668) * Fix memory leaks on _XimGetAttributeID error paths. -2011-03-30 15:06:10 +0300 Ander Conselvan de Oliveira (f50e651) +2011-03-30 15:06:10 +0300 Ander Conselvan de Oliveira (f50e651e8) * xcms: Fix memory leaks on LINEAR_RGB_InitSCCData error path. -2011-03-30 15:19:28 +0300 Ander Conselvan de Oliveira (fefb909) +2011-03-30 15:19:28 +0300 Ander Conselvan de Oliveira (fefb909a0) * xcms: Fix error on LINEAR_RGB_InitSCCData error path. -2011-03-24 14:17:44 +0200 Ander Conselvan de Oliveira (dce8150) +2011-03-24 14:17:44 +0200 Ander Conselvan de Oliveira (dce81504f) * FSWrap: fix potential leak in copy_string_list -2011-03-23 14:36:22 +0200 Ander Conselvan de Oliveira (0f71486) +2011-03-23 14:36:22 +0200 Ander Conselvan de Oliveira (0f7148695) * Fix memory leak with broken bitmap files in XReadBitmapFileData -2011-03-21 14:49:37 +0000 Harshula Jayasuriya (417e041) +2011-03-21 14:49:37 +0000 Harshula Jayasuriya (417e04111) * Add #define XK_SINHALA -2011-01-18 15:58:20 +0200 Erkki Seppälä (29ad23b) +2011-01-18 15:58:20 +0200 Erkki Seppälä (29ad23b98) * xkb: XkbPropertyPtr determined allocation success from wrong variables -2011-01-10 16:37:22 +0200 Erkki Seppälä (bbeee4f) +2011-01-10 16:37:22 +0200 Erkki Seppälä (bbeee4fd1) * keyBind: Use Xcalloc to initialize allocated _XKeytrans -2011-02-11 14:49:17 -0800 Alan Coopersmith (2618bd3) +2011-02-11 14:49:17 -0800 Alan Coopersmith (2618bd3fc) * Clean up memory when first XCreateRegion succeeds and second fails -2011-02-03 17:08:57 +0200 Erkki Seppälä (07fae91) +2011-02-03 17:08:57 +0200 Erkki Seppälä (07fae919a) * cmsProp: don't deal with uninitialized values, fail instead -2011-01-31 14:02:07 +0200 Ander Conselvan de Oliveira (ae4e753) +2011-01-31 14:02:07 +0200 Ander Conselvan de Oliveira (ae4e7538e) * xcms/LRGB: don't double-free property_return -2011-02-02 08:58:45 -0800 Alan Coopersmith (26270ab) +2011-02-02 08:58:45 -0800 Alan Coopersmith (26270ab1c) * Xrm.c: ReadInFile: refactor fstat error handling -2011-02-02 08:56:00 -0800 Alan Coopersmith (563318a) +2011-02-02 08:56:00 -0800 Alan Coopersmith (563318af9) * Expand GetSizeOfFile() macro at the one place it's called -2011-01-31 14:01:57 +0200 Erkki Seppälä (20470a8) +2011-01-31 14:01:57 +0200 Erkki Seppälä (20470a83e) * XlibInt: Use strncpy+zero termination instead of strcpy to enforce buffer size -2011-01-31 14:02:16 +0200 Erkki Seppälä (7576f5f) +2011-01-31 14:02:16 +0200 Erkki Seppälä (7576f5f15) * xlibi18n/lcFile: Removed superfluous check for NULL target_dir -2011-01-31 14:02:12 +0200 Ander Conselvan de Oliveira (698270c) +2011-01-31 14:02:12 +0200 Ander Conselvan de Oliveira (698270c47) * XlibInt: info_list->watch_data was reallocated, but result was discarded -2011-02-01 11:07:25 +0200 Ander Conselvan de Oliveira (7482afc) +2011-02-01 11:07:25 +0200 Ander Conselvan de Oliveira (7482afcaa) * xcms/LRGB: Add a label for freeing property_return. -2011-01-31 14:02:08 +0200 Ander Conselvan de Oliveira (8f5a564) +2011-01-31 14:02:08 +0200 Ander Conselvan de Oliveira (8f5a56474) * xcms/LRGB: Fix potential resource leak. -2011-01-31 14:02:05 +0200 Erkki Seppälä (afd1d4e) +2011-01-31 14:02:05 +0200 Erkki Seppälä (afd1d4eb5) * Xrm: NEWTABLE had a memory leak after a memory allocation error -2011-01-31 14:02:03 +0200 Erkki Seppälä (1ac1b69) +2011-01-31 14:02:03 +0200 Erkki Seppälä (1ac1b691d) * ImUtil: Handle a memory leak in one early return branch -2011-01-31 14:01:56 +0200 Erkki Seppälä (52d2c35) +2011-01-31 14:01:56 +0200 Erkki Seppälä (52d2c3558) * xlibi18n/lcGeneric: Initialize uninitialized local variable -2011-01-31 14:01:54 +0200 Erkki Seppälä (865043e) +2011-01-31 14:01:54 +0200 Erkki Seppälä (865043ea0) * xcmx/cmxColNm: Removed unused assignments to pBuf (in two functions) -2011-02-01 12:30:56 +0200 Alan Coopersmith (54550eb) +2011-02-01 12:30:56 +0200 Alan Coopersmith (54550ebb2) * XDefaultOMIF.c: Fix memory leaks in get_font_name -2011-01-18 12:49:48 +0200 Erkki Seppälä (b7694b0) +2011-01-18 12:49:48 +0200 Erkki Seppälä (b7694b0b5) * Comparing array against NULL is not useful "&xkb->server->vmods != NULL" -2011-01-12 15:51:11 +0200 Erkki Seppälä (3147ddb) +2011-01-12 15:51:11 +0200 Erkki Seppälä (3147ddbf4) * Variable "entry" tracked as NULL was dereferenced. -2011-01-27 09:54:00 +0200 Erkki Seppälä (e175587) +2011-01-27 09:54:00 +0200 Erkki Seppälä (e17558786) * Dereferencing possibly NULL "str" in call to function "memcpy" (Deref assumed on the basis of 'nonnull' parameter attribute.) -2011-01-10 16:17:47 +0200 Erkki Seppälä (8aacb3f) +2011-01-10 16:17:47 +0200 Erkki Seppälä (8aacb3fab) * Using freed pointer "e" -2011-01-03 12:25:28 -0500 Pauli Nieminen (1a72bc4) +2011-01-03 12:25:28 -0500 Pauli Nieminen (1a72bc414) * Initialize event type -2010-06-04 13:20:17 -0700 Alan Coopersmith (8ff5261) +2010-06-04 13:20:17 -0700 Alan Coopersmith (8ff526111) * LINEAR_RGB_InitSCCData: When malloc fails, don't try to free unallocated bits -2010-07-09 18:13:13 +0100 Daniel Stone (93b55ee) +2010-07-09 18:13:13 +0100 Daniel Stone (93b55eeec) * XStringToKeysym: Cope with 0x1234cafe-style input -2010-07-08 16:49:51 +0100 Daniel Stone (b414bc2) +2010-07-08 16:49:51 +0100 Daniel Stone (b414bc2c6) * XStringToKeysym: Check strdup() return value -2010-06-15 18:49:43 +0100 Daniel Stone (c1b175d) +2010-06-15 18:49:43 +0100 Daniel Stone (c1b175d3d) * Delete now-redundant XKeysymDB -2010-06-15 18:47:37 +0100 Daniel Stone (f0b87f3) +2010-06-15 18:47:37 +0100 Daniel Stone (f0b87f3de) * XStringToKeysym: Special case for XF86 keysyms -2016-10-14 16:49:08 +0200 Mike Gabriel (6c303d9) +2016-10-14 16:49:08 +0200 Mike Gabriel (6c303d9e4) * debian/rules: Don't use -pie -fPIE at build time for 3.5.99.2 as it causes nxagent to segfault. Investigating the reasons - behind it is in process... (origin/release-builds/3.6.x, - release-builds/3.6.x) + behind it is in process... -2016-10-14 02:31:38 +0000 Mihai Moldovan (75e0808) +2016-10-14 02:31:38 +0000 Mihai Moldovan (75e080800) * nx-X11/programs/Xserver/GL/glx/Imakefile: typo fix, leading to glcontextmodes.c not being compiled. -2016-10-13 14:10:28 +0200 Mike Gabriel (29e2934) +2016-10-13 14:10:28 +0200 Mike Gabriel (29e29342e) * release 3.5.99.2 (tag: 3.5.99.2) -2016-10-13 15:05:37 +0200 Mike Gabriel (64aa45a) +2016-10-13 15:05:37 +0200 Mike Gabriel (64aa45a61) * debian/*.triggers: Call ldconfig via a trigger for all shared libraries. -2016-10-13 15:05:31 +0200 Mike Gabriel (440c675) +2016-10-13 15:05:31 +0200 Mike Gabriel (440c675c2) * debian/rules: Don't modify/create post{inst,rm} scripts during dh_makeshlibs. This avoids adding ldconfig calls to such scripts. -2016-10-13 14:45:37 +0200 Mike Gabriel (bd25086) +2016-10-13 14:45:37 +0200 Mike Gabriel (bd25086c3) * hw/nxagent/{Clipboard|Events}.c: Typo fix in error messages. -2016-10-13 14:44:27 +0200 Mike Gabriel (d2fb76d) +2016-10-13 14:44:27 +0200 Mike Gabriel (d2fb76d8b) * nxcomp/{Client|}Proxy.cpp: Typo fix in error messages. -2016-10-13 14:17:55 +0200 Mike Gabriel (0006fc0) +2016-10-13 14:17:55 +0200 Mike Gabriel (0006fc04b) * debian/libnx-x11-6.symbols: Update symbols for new backports in libNX_X11 API. -2016-10-07 21:19:07 +0200 Ulrich Sibiller (97c2697) +2016-10-07 21:19:07 +0200 Ulrich Sibiller (97c26978b) * Pending.c: conditionally include stdio.h -2016-10-10 01:00:38 +0200 Ulrich Sibiller (0bf52dc) +2016-10-10 01:00:38 +0200 Ulrich Sibiller (0bf52dc99) * nxcomp: Fix typo in usage message. -2016-10-13 14:02:51 +0200 Mike Gabriel (133c91f) +2016-10-13 14:02:51 +0200 Mike Gabriel (133c91f73) * Merge branch 'uli42-pr/libX11_debian_backports' into 3.6.x -2013-05-21 21:54:55 +0200 Julien Cristau (a9f623f) +2013-05-21 21:54:55 +0200 Julien Cristau (a9f623f0a) * Add a couple fixups for the security patches -2013-05-08 19:33:09 +0200 Matthieu Herrb (838108c) +2013-05-08 19:33:09 +0200 Matthieu Herrb (838108c29) * XListFontsWithInfo: Re-decrement flist[0] before calling free() on it. -2013-03-31 12:22:35 -0700 Alan Coopersmith (dc749a4) +2013-03-31 12:22:35 -0700 Alan Coopersmith (dc749a457) * _XkbReadGetMapReply: reject maxKeyCodes smaller than the minKeyCode -2013-03-16 10:03:13 -0700 Alan Coopersmith (37f8d3e) +2013-03-16 10:03:13 -0700 Alan Coopersmith (37f8d3eb8) * Use calloc in XOpenDisplay to initialize structs containing pointers -2013-03-02 12:39:58 -0800 Alan Coopersmith (e386187) +2013-03-02 12:39:58 -0800 Alan Coopersmith (e386187e9) * Unbounded recursion in _XimParseStringFile() when parsing include files [CVE-2013-2004 2/2] -2013-03-02 12:01:39 -0800 Alan Coopersmith (bddfee4) +2013-03-02 12:01:39 -0800 Alan Coopersmith (bddfee4a9) * Unbounded recursion in GetDatabase() when parsing include files [CVE-2013-2004 1/2] -2013-03-02 15:08:21 -0800 Alan Coopersmith (dbc1171) +2013-03-02 15:08:21 -0800 Alan Coopersmith (dbc117193) * Avoid overflows in XListExtensions() [CVE-2013-1997 15/15] -2013-03-02 15:08:21 -0800 Alan Coopersmith (77edd88) +2013-03-02 15:08:21 -0800 Alan Coopersmith (77edd88e1) * Avoid overflows in XGetFontPath() [CVE-2013-1997 14/15] -2013-03-02 15:08:21 -0800 Alan Coopersmith (f6c5069) +2013-03-02 15:08:21 -0800 Alan Coopersmith (f6c5069ac) * Avoid overflows in XListFonts() [CVE-2013-1997 13/15] -2013-03-02 11:25:25 -0800 Alan Coopersmith (0284afb) +2013-03-02 11:25:25 -0800 Alan Coopersmith (0284afb80) * unvalidated length in _XimXGetReadData() [CVE-2013-1997 12/15] -2013-03-02 11:11:08 -0800 Alan Coopersmith (0bf09b4) +2013-03-02 11:11:08 -0800 Alan Coopersmith (0bf09b4bb) * unvalidated index/length in _XkbReadGetNamesReply() [CVE-2013-1997 11/15] -2013-03-02 11:01:04 -0800 Alan Coopersmith (e6d8856) +2013-03-02 11:01:04 -0800 Alan Coopersmith (e6d8856ef) * unvalidated index in _XkbReadVirtualModMap() [CVE-2013-1997 10/15] -2013-03-02 11:04:44 -0800 Alan Coopersmith (e27df80) +2013-03-02 11:04:44 -0800 Alan Coopersmith (e27df8070) * unvalidated index in _XkbReadExplicitComponents() [CVE-2013-1997 9/15] -2013-03-02 10:51:51 -0800 Alan Coopersmith (7564bf7) +2013-03-02 10:51:51 -0800 Alan Coopersmith (7564bf7ef) * unvalidated index in _XkbReadModifierMap() [CVE-2013-1997 8/15] -2013-03-02 10:39:21 -0800 Alan Coopersmith (8f2c050) +2013-03-02 10:39:21 -0800 Alan Coopersmith (8f2c05082) * unvalidated index in _XkbReadKeyBehaviors() [CVE-2013-1997 7/15] -2013-03-02 09:40:22 -0800 Alan Coopersmith (4c19cd0) +2013-03-02 09:40:22 -0800 Alan Coopersmith (4c19cd0c7) * unvalidated index in _XkbReadKeyActions() [CVE-2013-1997 6/15] -2013-03-02 09:28:33 -0800 Alan Coopersmith (5dae1d3) +2013-03-02 09:28:33 -0800 Alan Coopersmith (5dae1d3f4) * unvalidated index in _XkbReadKeySyms() [CVE-2013-1997 5/15] -2013-03-02 09:18:26 -0800 Alan Coopersmith (e6fbdea) +2013-03-02 09:18:26 -0800 Alan Coopersmith (e6fbdea84) * unvalidated indexes in _XkbReadGetGeometryReply() [CVE-2013-1997 4/15] -2013-03-02 09:12:47 -0800 Alan Coopersmith (0445730) +2013-03-02 09:12:47 -0800 Alan Coopersmith (0445730b1) * unvalidated indexes in _XkbReadGeomShapes() [CVE-2013-1997 3/15] -2013-03-01 22:49:01 -0800 Alan Coopersmith (b069526) +2013-03-01 22:49:01 -0800 Alan Coopersmith (b06952603) * unvalidated index in _XkbReadGetDeviceInfoReply() [CVE-2013-1997 2/15] -2013-03-01 19:30:09 -0800 Alan Coopersmith (2a1fbb1) +2013-03-01 19:30:09 -0800 Alan Coopersmith (2a1fbb181) * unvalidated lengths in XAllocColorCells() [CVE-2013-1997 1/15] -2013-03-09 11:04:37 -0800 Alan Coopersmith (e03f392) +2013-03-09 11:04:37 -0800 Alan Coopersmith (e03f3922a) * Make XGetWindowProperty() always initialize returned values -2013-03-02 13:03:55 -0800 Alan Coopersmith (b207105) +2013-03-02 13:03:55 -0800 Alan Coopersmith (b20710586) * Move repeated #ifdef magic to find PATH_MAX into a common header -2013-03-02 16:56:16 -0800 Alan Coopersmith (05b72b8) +2013-03-02 16:56:16 -0800 Alan Coopersmith (05b72b8da) * Convert more _XEatData callers to _XEatDataWords -2013-03-02 15:08:21 -0800 Alan Coopersmith (306ca00) +2013-03-02 15:08:21 -0800 Alan Coopersmith (306ca006a) * integer overflow in XGetModifierMapping() [CVE-2013-1981 13/13] -2013-03-02 15:08:21 -0800 Alan Coopersmith (748af52) +2013-03-02 15:08:21 -0800 Alan Coopersmith (748af521e) * integer overflow in XGetPointerMapping() & XGetKeyboardMapping() [CVE-2013-1981 12/13] -2013-03-02 15:08:21 -0800 Alan Coopersmith (9501bce) +2013-03-02 15:08:21 -0800 Alan Coopersmith (9501bce22) * integer overflow in XGetImage() [CVE-2013-1981 11/13] -2013-03-08 22:25:35 -0800 Alan Coopersmith (361d367) +2013-03-08 22:25:35 -0800 Alan Coopersmith (361d36770) * integer overflow in XGetWindowProperty() [CVE-2013-1981 10/13] -2013-03-02 13:18:48 -0800 Alan Coopersmith (2517230) +2013-03-02 13:18:48 -0800 Alan Coopersmith (25172302a) * integer overflows in TransFileName() [CVE-2013-1981 9/13] -2013-03-01 18:37:37 -0800 Alan Coopersmith (8468165) +2013-03-01 18:37:37 -0800 Alan Coopersmith (8468165ae) * integer truncation in _XimParseStringFile() [CVE-2013-1981 8/13] -2013-03-01 18:37:37 -0800 Alan Coopersmith (00d7a2e) +2013-03-01 18:37:37 -0800 Alan Coopersmith (00d7a2e5b) * integer overflow in ReadInFile() in Xrm.c [CVE-2013-1981 7/13] -2013-03-02 11:44:19 -0800 Alan Coopersmith (0349af1) +2013-03-02 11:44:19 -0800 Alan Coopersmith (0349af114) * Integer overflows in stringSectionSize() cause buffer overflow in ReadColornameDB() [CVE-2013-1981 6/13] -2013-03-01 22:49:01 -0800 Alan Coopersmith (8673bf0) +2013-03-01 22:49:01 -0800 Alan Coopersmith (8673bf071) * integer overflow in XListHosts() [CVE-2013-1981 5/13] -2013-03-01 22:49:01 -0800 Alan Coopersmith (7d18bbe) +2013-03-01 22:49:01 -0800 Alan Coopersmith (7d18bbe93) * integer overflow in XGetMotionEvents() [CVE-2013-1981 4/13] -2013-03-01 22:49:01 -0800 Alan Coopersmith (2977955) +2013-03-01 22:49:01 -0800 Alan Coopersmith (29779559c) * integer overflow in XListFontsWithInfo() [CVE-2013-1981 3/13] -2013-03-01 21:05:27 -0800 Alan Coopersmith (dda0c65) +2013-03-01 21:05:27 -0800 Alan Coopersmith (dda0c652f) * integer overflow in _XF86BigfontQueryFont() [CVE-2013-1981 2/13] -2013-03-01 21:05:27 -0800 Alan Coopersmith (de2d3cb) +2013-03-01 21:05:27 -0800 Alan Coopersmith (de2d3cb6b) * integer overflow in _XQueryFont() on 32-bit platforms [CVE-2013-1981 1/13] -2013-01-22 10:03:00 -0500 Nickolai Zeldovich (e8ada07) +2013-01-22 10:03:00 -0500 Nickolai Zeldovich (e8ada07fa) * XListFontsWithInfo: avoid accessing realloc'ed memory -2011-02-11 14:20:24 -0800 Alan Coopersmith (290f94a) +2011-02-11 14:20:24 -0800 Alan Coopersmith (290f94aea) * ximcp: Prevent memory leak & double free if multiple %L in string -2011-01-31 14:02:06 +0200 Erkki Seppälä (9361547) +2011-01-31 14:02:06 +0200 Erkki Seppälä (936154728) * Xrm: Handle the extremely unlikely situation of fstat failing -2016-10-12 08:32:04 +0200 Mike Gabriel (051d521) +2016-10-12 08:32:04 +0200 Mike Gabriel (051d521f6) * Merge branch 'uli42-pr/upgrade_libX11' into 3.6.x -2016-10-09 17:49:20 +0200 Ulrich Sibiller (b8de7bf) +2016-10-09 17:49:20 +0200 Ulrich Sibiller (b8de7bf65) * Use both __APPLE__ and __DARWIN__ defines -2015-04-15 10:16:18 +0200 Karl Tomlinson (0186533) +2015-04-15 10:16:18 +0200 Karl Tomlinson (01865335b) * MakeBigReq: don't move the last word, already handled by Data32 (X.Org CVE-2013-7439). -2013-04-19 14:30:40 -0700 Alan Coopersmith (670b8ef) +2013-04-19 14:30:40 -0700 Alan Coopersmith (670b8ef64) * Give GNU & Solaris Studio compilers hints about XEatData branches -2011-12-13 19:58:30 -0800 Alan Coopersmith (6165daf) +2011-12-13 19:58:30 -0800 Alan Coopersmith (6165dafda) * makekeys: move buf declaration from global to main to silence gcc -Wshadow -2011-09-22 18:44:13 -0400 Derek Buitenhuis (62e5b0f) +2011-09-22 18:44:13 -0400 Derek Buitenhuis (62e5b0ff8) * makekeys: Fix build/target word size mismatch when cross-compiling -2016-08-27 03:24:22 +0200 Ulrich Sibiller (0bcb4bb) +2016-08-27 03:24:22 +0200 Ulrich Sibiller (0bcb4bba2) * adapt Imakefile to call makekeys correctly after update -2010-06-15 18:48:48 +0100 Daniel Stone (c98265a) +2010-06-15 18:48:48 +0100 Daniel Stone (c98265ab4) * makekeys: Scan vendor keysyms as well as core -2009-03-17 15:42:19 -0700 Alan Coopersmith (7032799) +2009-03-17 15:42:19 -0700 Alan Coopersmith (70327993a) * When makekeys fails to find a good hash, print error instead of divide-by-zero -2008-10-25 09:13:08 -0400 James Cloos (f573654) +2008-10-25 09:13:08 -0400 James Cloos (f57365400) * Increase size of working arrays in the makekeys utility program. -2016-08-27 02:24:46 +0200 Ulrich Sibiller (9a3096a) +2016-08-27 02:24:46 +0200 Ulrich Sibiller (9a3096a2a) * Update keysym includes -2016-08-27 02:13:27 +0200 Ulrich Sibiller (1baa27d) +2016-08-27 02:13:27 +0200 Ulrich Sibiller (1baa27d09) * update files from modules dir of libX11 1.3.4 -2016-08-27 02:13:02 +0200 Ulrich Sibiller (da3e7fd) +2016-08-27 02:13:02 +0200 Ulrich Sibiller (da3e7fd28) * Xutil.h: Fix wrong include path -2016-08-27 01:44:41 +0200 Ulrich Sibiller (d3ae0b2) +2016-08-27 01:44:41 +0200 Ulrich Sibiller (d3ae0b2c9) * replace {x11,xim}trans.c links by libX11 1.3.4 solution -2016-08-27 01:22:46 +0200 Ulrich Sibiller (385dc2b) +2016-08-27 01:22:46 +0200 Ulrich Sibiller (385dc2b07) * update xlibi18n files to libX11 1.3.4 -2016-08-27 01:00:43 +0200 Ulrich Sibiller (e868fbb) +2016-08-27 01:00:43 +0200 Ulrich Sibiller (e868fbbfd) * update xcms files to libX11 1.3.4 -2016-08-27 00:37:53 +0200 Ulrich Sibiller (2749290) +2016-08-27 00:37:53 +0200 Ulrich Sibiller (274929053) * Update some missing files to libX11 1.3.4 -2016-08-27 00:31:05 +0200 Ulrich Sibiller (8a5f30f) +2016-08-27 00:31:05 +0200 Ulrich Sibiller (8a5f30fb1) * Add (Free|Get)EventData.c from libX11 1.3.4 -2016-08-27 00:16:07 +0200 Ulrich Sibiller (efa70b0) +2016-08-27 00:16:07 +0200 Ulrich Sibiller (efa70b0cf) * remove more NEED_REPLIES/EVENTS -2016-08-27 00:24:37 +0200 Ulrich Sibiller (0079db6) +2016-08-27 00:24:37 +0200 Ulrich Sibiller (0079db696) * Purge more remaining VCS refs -2016-08-27 00:04:03 +0200 Ulrich Sibiller (af1f7ce) +2016-08-27 00:04:03 +0200 Ulrich Sibiller (af1f7cee0) * Lift XKB*.c to libX11 1.3.4 -2016-08-25 21:43:53 +0200 Ulrich Sibiller (3e75c81) +2016-08-25 21:43:53 +0200 Ulrich Sibiller (3e75c816d) * XlibInt.c: shorten one ifdef -2016-08-24 16:52:58 +0200 Ulrich Sibiller (a497ebf) +2016-08-24 16:52:58 +0200 Ulrich Sibiller (a497ebf88) * update X.h and Xproto.h because of GenericEvent -2016-08-03 19:19:58 +0200 Ulrich Sibiller (2265215) +2016-08-03 19:19:58 +0200 Ulrich Sibiller (22652155f) * set USE_XCB define to 0 to prevent compiler complaints -2016-08-02 01:06:35 +0200 Ulrich Sibiller (e51b961) +2016-08-02 01:06:35 +0200 Ulrich Sibiller (e51b961a7) * Remove CRAY support -2016-08-02 01:23:54 +0200 Ulrich Sibiller (35270a3) +2016-08-02 01:23:54 +0200 Ulrich Sibiller (35270a3d9) * adapt include files to libX11 1.3.4 -2016-08-02 00:51:13 +0200 Ulrich Sibiller (7b0bdde) +2016-08-02 00:51:13 +0200 Ulrich Sibiller (7b0bdde5c) * update makekeys.c to libX11 1.3.4 (+ fix) -2016-08-01 23:54:34 +0200 Ulrich Sibiller (b4571a8) +2016-08-01 23:54:34 +0200 Ulrich Sibiller (b4571a8ff) * update lcUniConv subdir to libX11 1.3.4 -2016-07-29 00:44:38 +0200 Ulrich Sibiller (687d44b) +2016-07-29 00:44:38 +0200 Ulrich Sibiller (687d44b6e) * update src files *[ch] to libX11 1.3.4 -2016-07-26 23:19:36 +0200 Ulrich Sibiller (ea24f0b) +2016-07-26 23:19:36 +0200 Ulrich Sibiller (ea24f0b0e) * add XLOCALELIBDIR -2016-07-26 23:18:33 +0200 Ulrich Sibiller (ef5565f) +2016-07-26 23:18:33 +0200 Ulrich Sibiller (ef5565f8e) * improve header guards -2016-07-26 00:34:34 +0200 Ulrich Sibiller (5930731) +2016-07-26 00:34:34 +0200 Ulrich Sibiller (593073142) * update all files with NX relevant changes to libX11 1.3.4 -2016-08-24 16:41:42 +0200 Ulrich Sibiller (a053df0) +2016-08-24 16:41:42 +0200 Ulrich Sibiller (a053df0a7) * fix wrong include in XlibInt.c -2016-10-08 21:31:17 +0200 Mike Gabriel (6dce607) +2016-10-08 21:31:17 +0200 Mike Gabriel (6dce607ba) * Merge branch 'uli42-pr/decouple-xserver' into 3.6.x -2016-10-08 00:40:36 +0200 Ulrich Sibiller (b062272) +2016-10-08 00:40:36 +0200 Ulrich Sibiller (b0622729a) * xserver: add missing xkbfile.h -2016-10-07 13:12:39 +0200 Vadim Troshchinskiyddd (f55852c) +2016-10-07 13:12:39 +0200 Vadim Troshchinskiyddd (f55852c2e) * Fix nxproxy hostname parsing. -2016-10-07 13:58:57 +0200 Vadim Troshchinskiy (85f5fdf) +2016-10-07 13:58:57 +0200 Vadim Troshchinskiy (85f5fdfd2) * Check if unixPath is NULL before accessing it; this fixes crashing of nxagent when TEST is enabled. -2016-10-07 21:38:18 +0200 Mike Gabriel (3039a34) +2016-10-07 21:38:18 +0200 Mike Gabriel (3039a34cb) * Merge branch 'uli42-pr/decouple-xserver' into 3.6.x -2016-10-04 21:24:56 +0200 Ulrich Sibiller (736a233) +2016-10-04 21:24:56 +0200 Ulrich Sibiller (736a2333e) * xserver: adapt xkbsrc includes syntax to match upstream -2015-02-17 14:40:27 +1000 Dave Airlie (a2a7482) +2015-02-17 14:40:27 +1000 Dave Airlie (a2a7482f2) * os/access: fix regression in server interpreted auth -2014-10-22 14:24:55 -0700 Keith Packard (a116296) +2014-10-22 14:24:55 -0700 Keith Packard (a11629656) * os: Eliminate uninitialized value warnings from access.c -2014-12-09 09:31:00 -0800 Keith Packard (057cdaf) +2014-12-09 09:31:00 -0800 Keith Packard (057cdafdc) * dix: GetHosts bounds check using wrong pointer value [CVE-2014-8092 pt. 6] -2008-06-13 21:59:09 -0400 Eamon Walsh (da5da20) +2008-06-13 21:59:09 -0400 Eamon Walsh (da5da2091) * Fix multiple warnings in os/xdmauth.c. -2016-09-26 23:00:04 +0200 Ulrich Sibiller (b60f66b) +2016-09-26 23:00:04 +0200 Ulrich Sibiller (b60f66bb9) * replace transport.c link by xstrans.c -2016-09-26 22:20:45 +0200 Ulrich Sibiller (2a5364d) +2016-09-26 22:20:45 +0200 Ulrich Sibiller (2a5364d5f) * xserver: drop XKBSRV_NEED_FILE_FUNCS -2016-09-26 21:32:05 +0200 Ulrich Sibiller (7c5d836) +2016-09-26 21:32:05 +0200 Ulrich Sibiller (7c5d836c2) * xserver: remove define XKB_IN_SERVER -2016-09-26 21:12:23 +0200 Ulrich Sibiller (2fdb1ad) +2016-09-26 21:12:23 +0200 Ulrich Sibiller (2fdb1add0) * xserver: use own copy of XKBgeom.h header -2016-09-26 21:09:36 +0200 Ulrich Sibiller (2c31ce2) +2016-09-26 21:09:36 +0200 Ulrich Sibiller (2c31ce2f2) * xserver: use own copy of XKBrules.h header -2016-09-26 21:05:32 +0200 Ulrich Sibiller (e601843) +2016-09-26 21:05:32 +0200 Ulrich Sibiller (e60184393) * xserver: use own copy of XKBrules.h header -2016-09-26 21:03:02 +0200 Ulrich Sibiller (3b88190) +2016-09-26 21:03:02 +0200 Ulrich Sibiller (3b8819087) * xserver: use own copy of XKBstr.h header -2016-09-26 20:43:23 +0200 Ulrich Sibiller (3739a9b) +2016-09-26 20:43:23 +0200 Ulrich Sibiller (3739a9b30) * xserver: use own copy of XKBsrv.h header -2016-09-21 20:54:53 +0200 Ulrich Sibiller (f0c0ff4) +2016-09-21 20:54:53 +0200 Ulrich Sibiller (f0c0ff41b) * copy files from libX11 to xserver dir -2016-10-06 13:04:25 +0200 Mike Gabriel (168c063) +2016-10-06 13:04:25 +0200 Mike Gabriel (168c063dc) * run-nxproxy2nxagent-over-network: Improve comment that describes script usage. Fix commented-out NX_HOST assignment. -2016-10-06 12:59:52 +0200 Mike Gabriel (834f13f) +2016-10-06 12:59:52 +0200 Mike Gabriel (834f13fa1) * testscripts: Rename run-nxagent and run-nxagent-over-sockets. -2016-10-06 12:59:25 +0200 Mike Gabriel (cd0da09) +2016-10-06 12:59:25 +0200 Mike Gabriel (cd0da096a) * run-nxproxy2nxagent-over-network: New test script that tests nxproxy/nxagent connectivity between networked hosts. -2016-10-01 20:22:18 +0200 Mike Gabriel (3e59f16) +2016-10-01 20:22:18 +0200 Mike Gabriel (3e59f165f) * Merge branch 'sunweaver-pr/update-X11s-XKeysymDB' into 3.6.x -2011-03-22 11:28:56 +1000 Peter Hutterer (5dcf0d5) +2011-03-22 11:28:56 +1000 Peter Hutterer (5dcf0d573) * Add XF86TouchpadOn and XF86TouchpadOff to keysymdb (gh-sunweaver/pr/update-X11s-XKeysymDB) -2016-08-25 00:52:51 +0200 Mike Gabriel (34cb7b5) +2016-08-25 00:52:51 +0200 Mike Gabriel (34cb7b558) * lib/X11/XKeysymDB: Update to last version found in X.org (between 1.3.5 and 1.3.6). -2016-10-01 20:20:18 +0200 Mike Gabriel (5d52d21) +2016-10-01 20:20:18 +0200 Mike Gabriel (5d52d21bc) * Merge branch 'sunweaver-pr/use-gccmakedep' into 3.6.x -2016-10-01 12:04:54 +0200 Mike Gabriel (b160371) +2016-10-01 12:04:54 +0200 Mike Gabriel (b1603713e) * Imake.tmpl: Use gccmakedep instead of makedepend. (gh-sunweaver/pr/use-gccmakedep) -2016-10-01 20:16:39 +0200 Mike Gabriel (e3ea748) +2016-10-01 20:16:39 +0200 Mike Gabriel (e3ea74823) * Merge branch 'sunweaver-pr/fix-protoheader-mess' into 3.6.x -2016-10-01 11:28:50 +0200 Mike Gabriel (3698cf2) +2016-10-01 11:28:50 +0200 Mike Gabriel (3698cf27b) * include/extensions/damageproto.h: Use nx-X11's xfixesproto.h and damagewire.h instead of X.org's. (gh-sunweaver/pr/fix-protoheader-mess, pr/fix-protoheader-mess) -2016-10-01 11:25:29 +0200 Mike Gabriel (9acfa3b) +2016-10-01 11:25:29 +0200 Mike Gabriel (9acfa3b28) * randrproto: It was discovered that nx-libs shipped two different version of randr.h and randrproto.h. This commit leaves the newer file versions in the package and let's the build process use those everywhere. -2016-10-01 11:00:01 +0200 Mike Gabriel (f4f0b44) +2016-10-01 11:00:01 +0200 Mike Gabriel (f4f0b4490) * nx-X11: Enable -Wpedantic as default CFLAG. This is to detect redefined typedefs when building nxagent. -2016-10-01 10:53:37 +0200 Mike Gabriel (b50b0af) +2016-10-01 10:53:37 +0200 Mike Gabriel (b50b0af97) * hw/nxagent/X11/include/Xrandr_nxagent.h: Reduce injected libXrandr(_nxagent) header file, so that it only contains the XRRScreenChangeNotifyEvent typedef. -2016-09-29 20:58:15 +0200 Ulrich Sibiller (4858052) +2016-09-29 20:58:15 +0200 Ulrich Sibiller (485805235) * nx-libs.spec: Fix warning because of double reference to nxproxy.1.gz. -2016-09-29 20:28:59 +0200 Ulrich Sibiller (ce31b9c) +2016-09-29 20:28:59 +0200 Ulrich Sibiller (ce31b9c97) * Fix FTBFS with gcc 4.4 -2016-10-01 10:29:48 +0200 Mike Gabriel (a788c68) +2016-10-01 10:29:48 +0200 Mike Gabriel (a788c6856) * Makefile: Adapt install target to the new situation where we fake X11 headers in .build-export. This fixes FTBFS during file installation into .deb and .rpm packages. -2016-09-29 08:40:05 -0400 Mike DePaulo (5c2a8cd) +2016-09-29 08:40:05 -0400 Mike DePaulo (5c2a8cdc9) * Merge pull request #203 from mikedep333/issue-202 -2016-09-25 08:28:29 -0400 Mike DePaulo (cf435b3) +2016-09-25 08:28:29 -0400 Mike DePaulo (cf435b3bc) * nx-libs.spec: Add BuildRequires: imake -2016-09-24 23:59:02 +0200 Mike Gabriel (049bf68) +2016-09-24 23:59:02 +0200 Mike Gabriel (049bf681e) * Merge branch 'uli42-pr/improve_include_path_handling' into 3.6.x -2016-09-24 23:44:09 +0200 Ulrich Sibiller (97a5cec) +2016-09-24 23:44:09 +0200 Ulrich Sibiller (97a5cec70) * Revert "Fix wrong include" -2016-09-24 23:43:01 +0200 Ulrich Sibiller (c061022) +2016-09-24 23:43:01 +0200 Ulrich Sibiller (c061022a9) * whitespace cleanup -2016-09-24 23:41:55 +0200 Ulrich Sibiller (35e8c02) +2016-09-24 23:41:55 +0200 Ulrich Sibiller (35e8c02d9) * ensure that headers references use nx-X11 files if existing -2016-09-22 08:41:24 +0200 Mike Gabriel (a906bf0) +2016-09-22 08:41:24 +0200 Mike Gabriel (a906bf0f2) * Merge branch 'uli42-remove-misc' into 3.6.x -2016-09-21 18:37:10 +0200 Ulrich Sibiller (09d5e07) +2016-09-21 18:37:10 +0200 Ulrich Sibiller (09d5e073a) * remove misc dir -2016-09-21 18:28:22 +0200 Ulrich Sibiller (8d4d2bc) +2016-09-21 18:28:22 +0200 Ulrich Sibiller (8d4d2bc20) * move xkblib to xserver -2016-09-13 15:45:03 +0200 Mike Gabriel (43f135b) +2016-09-13 15:45:03 +0200 Mike Gabriel (43f135be0) * release 3.5.99.1 (tag: 3.5.99.1) -2016-08-26 12:49:28 +0200 Mike Gabriel (60e88a0) +2016-08-26 12:49:28 +0200 Mike Gabriel (60e88a0b1) * nxcomp/Loop.cpp: We have PrintVersionInfo(), why not use it? Use endl instead of \n for EOLs when streaming application's preamble to stderr. -2016-08-26 12:40:49 +0200 Mike Gabriel (01ebcfa) +2016-08-26 12:40:49 +0200 Mike Gabriel (01ebcfa35) * nxcomp/Loop.cpp: Mention DXPC copyright holders on application (i.e. nxproxy) start-up. -2016-08-24 16:29:46 +0200 Mike Gabriel (efa309a) +2016-08-24 16:29:46 +0200 Mike Gabriel (efa309add) * nxcomp/Loop.cpp: We have GetCopyrightInfo() in Misc.cpp, so why not use it? Also: point to ArcticaProject/nx-libs namespace on Github for further information. -2016-08-24 16:17:24 +0200 Mike Gabriel (3520015) +2016-08-24 16:17:24 +0200 Mike Gabriel (3520015b4) * hw/nxagent/Init.c: Fix copy+paste flaw when re-arranging copyright information as display by nxagent. -2016-08-24 16:13:52 +0200 Mike Gabriel (e201160) +2016-08-24 16:13:52 +0200 Mike Gabriel (e2011608f) * nxcomp/Misc.cpp: Display new list of copyright holders when launching nxproxy / nxagent. -2016-08-24 16:11:04 +0200 Mike Gabriel (8fc2e80) +2016-08-24 16:11:04 +0200 Mike Gabriel (8fc2e80bc) * nxcomp/*.c: Update copyright headers, use new list of copyright holders like for the .cpp files. -2016-08-24 16:08:41 +0200 Mike Gabriel (ed5d920) +2016-08-24 16:08:41 +0200 Mike Gabriel (ed5d920f6) * nxcomp/Loop.cpp: Refer to Github namespace of Arctica Project as location to search for software updates. -2016-08-24 15:59:36 +0200 Mike Gabriel (0ea971b) +2016-08-24 15:59:36 +0200 Mike Gabriel (0ea971b9e) * Merge branch 'uli42-fix_x2go_952' into 3.6.x -2016-08-21 13:12:23 +0200 Ulrich Sibiller (2d450e3) +2016-08-21 13:12:23 +0200 Ulrich Sibiller (2d450e383) * Fix pasting the clipboard directly after session start. -2016-07-28 13:21:29 +0200 Mike Gabriel (46fef31) +2016-07-28 13:21:29 +0200 Mike Gabriel (46fef3150) * nxagent.1 man page: Some layout fixes for string options with well-defined expected selections of values. -2016-07-28 13:20:38 +0200 Mike Gabriel (e9a3734) +2016-07-28 13:20:38 +0200 Mike Gabriel (e9a3734ae) * hw/nxagent/Display.c: Fix comment where the meaning of the "bypass" reconnectchecks parameter value is explained. -2016-07-28 12:59:37 +0200 Mike Gabriel (bff3305) +2016-07-28 12:59:37 +0200 Mike Gabriel (bff330577) * nxagent.1 man page: Add explanation about the new reconnectchecks nx/nx option. -2016-07-28 12:16:23 +0200 Mike Gabriel (aadf317) +2016-07-28 12:16:23 +0200 Mike Gabriel (aadf3175c) * hw/nxagent/Args.c: Follow-up fix for PR #183: expect reconnectchecks=bypass instead of =none. -2016-07-28 12:14:22 +0200 Mike Gabriel (443b527) +2016-07-28 12:14:22 +0200 Mike Gabriel (443b52723) * Merge branch 'Ionic-feature/reconnect-checks' into 3.6.x -2016-07-03 23:52:43 +0000 Mihai Moldovan (64a83d1) +2016-07-03 23:52:43 +0000 Mihai Moldovan (64a83d1e0) * nx-X11/programs/Xserver/hw/nxagent/Display.c: add FIXME comment to nxagentCheckForColormapsCompatibility(). (Ionic-feature/reconnect-checks) -2016-07-03 23:52:06 +0000 Mihai Moldovan (5ec7e48) +2016-07-03 23:52:06 +0000 Mihai Moldovan (5ec7e48ac) * nx-X11/programs/Xserver/hw/nxagent/Display.c: add FIXME comment to nxagentInitAndCheckVisuals(). -2016-07-09 03:28:27 +0000 Mihai Moldovan (e61c8c8) +2016-07-09 03:28:27 +0000 Mihai Moldovan (e61c8c85c) * nx-X11/programs/Xserver/hw/nxagent/Display.c: split up nxagentCheckForPixmapFormatsCompatibility() and nxagentInitPixmapFormats(). -2016-06-29 02:13:03 +0000 Mihai Moldovan (6618271) +2016-06-29 02:13:03 +0000 Mihai Moldovan (661827149) * nx-X11/programs/Xserver/hw/nxagent/Display.c: use new ReconnectTolerance nxagentOption value in nxagentCheckForPixmapFormatsCompatibility() and modify behavior based on this value. -2016-06-28 23:54:17 +0000 Mihai Moldovan (bb9b50b) +2016-06-28 23:54:17 +0000 Mihai Moldovan (bb9b50bfc) * nx-X11/programs/Xserver/hw/nxagent/Display.c: use new ReconnectTolerance nxagentOption value in nxagentCheckForDepthsCompatibility() and modify behavior based on this value. -2016-06-28 23:51:14 +0000 Mihai Moldovan (6effea5) +2016-06-28 23:51:14 +0000 Mihai Moldovan (6effea543) * nx-X11/programs/Xserver/hw/nxagent/Display.c: use new ReconnectTolerance nxagentOption in nxagentCheckForDefaultDepthCompatibility() and modify behavior based on this value. -2016-07-02 21:49:10 +0000 Mihai Moldovan (29be5cc) +2016-07-02 21:49:10 +0000 Mihai Moldovan (29be5cc07) * {nx-X11/programs/Xserver/hw/nxagent/{Args.c,Options.{c,h}},nxcomp/{Loop,Misc}.cpp}: add tolerancechecks parameter as an nx/nx option and ReconnectTolerance as an nxagentOption. -2016-07-27 13:05:27 +0200 Mike Gabriel (e1c85ca) +2016-07-27 13:05:27 +0200 Mike Gabriel (e1c85caac) * Merge branch 'uli42-3.6.x' into 3.6.x -2016-07-26 23:25:26 +0200 Ulrich Sibiller (9a4bb50) +2016-07-26 23:25:26 +0200 Ulrich Sibiller (9a4bb50af) * Fix wrong include -2016-07-06 10:38:25 +0200 Mike Gabriel (470611e) +2016-07-06 10:38:25 +0200 Mike Gabriel (470611e02) * release 3.5.99.0 (tag: 3.5.99.0) -2016-07-06 10:02:37 +0200 Mike Gabriel (961fa2a) +2016-07-06 10:02:37 +0200 Mike Gabriel (961fa2a0e) * README.md: Add build howto for openSUSE based RPMs. -2016-07-06 10:02:16 +0200 Mike Gabriel (b41369f) +2016-07-06 10:02:16 +0200 Mike Gabriel (b41369f27) * README.md: Status update of listed 3.6.x features. -2016-07-06 08:29:38 +0200 Mike Gabriel (98922f7) +2016-07-06 08:29:38 +0200 Mike Gabriel (98922f7b1) * make-changelog.sh: Ship simple script for updating the upstream ChangeLog file from Git history. -2016-07-06 01:14:56 +0200 Mike Gabriel (9b50e00) +2016-07-06 01:14:56 +0200 Mike Gabriel (9b50e0088) * Merge branch 'sunweaver-pr/update-license-files' into 3.6.x -2016-07-05 16:32:57 +0200 Mike Gabriel (6144b61) +2016-07-05 16:32:57 +0200 Mike Gabriel (6144b615d) * VCS info lines: Remove ancient X.org / XFree86 VCS info line from code files. -2016-07-05 16:22:51 +0200 Mike Gabriel (51c3d42) +2016-07-05 16:22:51 +0200 Mike Gabriel (51c3d42f3) * Per-file copyright notices: Update copyright information in file headers that NoMachine placed there own copyright statement in. -2016-07-05 13:44:32 +0200 Mike Gabriel (3c79d5c) +2016-07-05 13:44:32 +0200 Mike Gabriel (3c79d5cf4) * LICENSE files: Update copyright holders, FSF address and various other minor things. -2016-07-06 00:40:36 +0200 Mike Gabriel (5cbc936) +2016-07-06 00:40:36 +0200 Mike Gabriel (5cbc93678) * nxproxy.1 man page: Another rendering flaw fixed. -2016-07-06 00:25:06 +0200 Mike Gabriel (8ec78a0) +2016-07-06 00:25:06 +0200 Mike Gabriel (8ec78a0c3) * debian/*.doc-base: Add .doc-base files for bin:packages containing documentation. -2016-07-06 00:07:11 +0200 Ulrich Sibiller (196d38f) +2016-07-06 00:07:11 +0200 Ulrich Sibiller (196d38f96) * Xserver/dix/events.c: Drop unused i variable from TryClientEvents. -2016-07-06 00:04:05 +0200 Mike Gabriel (0369bf5) +2016-07-06 00:04:05 +0200 Mike Gabriel (0369bf5e9) * nxproxy.1 man page: Fix a typo + a rendering error. Detected by lintian. -2016-07-05 23:47:49 +0200 Mike Gabriel (67f937c) +2016-07-05 23:47:49 +0200 Mike Gabriel (67f937c4a) * debian/rules: Enable -fPIE / -pie hardening support for nxagent and nxproxy. -2016-07-05 22:56:01 +0200 Ulrich Sibiller (d7655e1) +2016-07-05 22:56:01 +0200 Ulrich Sibiller (d7655e15a) * Merge pull request #180 from uli42/pr/remove_need_events_replies -2016-07-04 21:11:21 +0200 Ulrich Sibiller (fa65199) +2016-07-04 21:11:21 +0200 Ulrich Sibiller (fa6519947) * remove unreferenced NEED_EVENTS/NEED_REPLIES -2016-07-05 22:23:27 +0200 Mike Gabriel (ff0d46e) +2016-07-05 22:23:27 +0200 Mike Gabriel (ff0d46e0b) * bin/nxauth: Remove deprecated wrapper script "nxauth". -2016-07-05 22:18:40 +0200 Mike Gabriel (f397f3a) +2016-07-05 22:18:40 +0200 Mike Gabriel (f397f3a42) * debian/nxagent.docs: whitespace only -2016-07-05 22:17:51 +0200 Mike Gabriel (754d33d) +2016-07-05 22:17:51 +0200 Mike Gabriel (754d33d81) * README.keystrokes: Move from base folder to doc/nxagent/. -2016-07-05 21:58:42 +0200 Mike Gabriel (a39c5c1) +2016-07-05 21:58:42 +0200 Mike Gabriel (a39c5c155) * nx-libs.spec: Adapt RPM packaging to doc files having been moved around. -2016-07-05 21:57:45 +0200 Mike Gabriel (cd9a6b9) +2016-07-05 21:57:45 +0200 Mike Gabriel (cd9a6b9dd) * debian/libxcomp3.docs: Install libxcomp3 documentation files into bin:package. -2016-07-05 21:48:27 +0200 Mike Gabriel (3ec3f61) +2016-07-05 21:48:27 +0200 Mike Gabriel (3ec3f6162) * debian/nxproxy.docs: Fix FTBFS due to missing documentation files (moved out of the way with recent commits). -2016-07-05 21:47:28 +0200 Mike Gabriel (2555bd5) +2016-07-05 21:47:28 +0200 Mike Gabriel (2555bd5ac) * documentation: Move README-VALGRIND out of doc/_attic_/ folder to doc/nxproxy/. -2016-07-05 13:34:26 +0200 Mike Gabriel (381706a) +2016-07-05 13:34:26 +0200 Mike Gabriel (381706aa2) * Merge branch 'sunweaver-pr/no-more-type-casting-in-writetoclient' into 3.6.x -2016-07-04 00:28:47 +0200 Alan Coopersmith (f6a1bda) +2016-07-04 00:28:47 +0200 Alan Coopersmith (f6a1bda2d) * Remove unneccesary casts from WriteToClient calls -2016-07-04 00:21:45 +0200 Kristian Høgsberg (ff81a52) +2016-07-04 00:21:45 +0200 Kristian Høgsberg (ff81a5269) * Make WriteToClient take a const void * like any decent IO write function. -2016-07-05 13:25:48 +0200 Mike Gabriel (06a9785) +2016-07-05 13:25:48 +0200 Mike Gabriel (06a97857a) * nxcomp/Misc.cpp: The clipboard nx/nx option is a string option, not int. -2016-07-05 13:25:17 +0200 Mike Gabriel (7e18fdf) +2016-07-05 13:25:17 +0200 Mike Gabriel (7e18fdf6e) * Xserver.man: Drop original and old Xserver man page. Relevant parts have now been added to nxagent.1 man page. -2016-07-05 13:24:16 +0200 Mike Gabriel (ebb2026) +2016-07-05 13:24:16 +0200 Mike Gabriel (ebb2026a7) * man pages: Greatly improve man pages nxagent.1 and nxproxy.1. -2016-07-05 10:47:55 +0200 Mike Gabriel (ee02822) +2016-07-05 10:47:55 +0200 Mike Gabriel (ee0282207) * File permission fixes: No executable bit on Imakefile files, *.c and *.h files. -2016-07-05 10:41:55 +0200 Mike Gabriel (5214930) +2016-07-05 10:41:55 +0200 Mike Gabriel (5214930a1) * X2Go remnants: Drop x2goagent.1 man page. Shipped in X2Go Server sources nowadays. -2016-07-05 10:41:24 +0200 Mike Gabriel (4017939) +2016-07-05 10:41:24 +0200 Mike Gabriel (40179398d) * nxcomp licensing: Move README.on-retroactive-DXPC-license to doc/nxcomp/ folder. -2016-07-05 10:40:11 +0200 Mike Gabriel (b38f010) +2016-07-05 10:40:11 +0200 Mike Gabriel (b38f01092) * NoMachine documentation files: Move to doc/_attic_/ folder. -2016-07-05 10:33:08 +0200 Mike Gabriel (d38ccd1) +2016-07-05 10:33:08 +0200 Mike Gabriel (d38ccd197) * LICENSE files: Have a main LICENSE file and one for nxcomp in the project's base folder. -2016-07-05 10:28:40 +0200 Mike Gabriel (cc4fdf6) +2016-07-05 10:28:40 +0200 Mike Gabriel (cc4fdf6f0) * X.org 6.9 documentation files: Move into doc/_attic_/. -2016-07-05 10:26:34 +0200 Mike Gabriel (4ad2943) +2016-07-05 10:26:34 +0200 Mike Gabriel (4ad29435c) * Drop multiple COPYING files contaning the GPL-2 license text. -2016-07-05 10:16:00 +0200 Mike Gabriel (d14cc53) +2016-07-05 10:16:00 +0200 Mike Gabriel (d14cc5361) * doc/_attic_/: Introduce an "_attic_" folder. Move diffs between NoMachine's nx-X11 3.5 and X.org 6.9 here. -2016-07-05 10:15:12 +0200 Mike Gabriel (74a52dd) +2016-07-05 10:15:12 +0200 Mike Gabriel (74a52dd35) * doc/ folder: Have one sub-folder per nx-libs component. -2016-07-05 10:11:19 +0200 Mike Gabriel (74edd6e) +2016-07-05 10:11:19 +0200 Mike Gabriel (74edd6e73) * test scripts: Move to top folder "testscripts/" in source tree. -2016-07-05 10:08:03 +0200 Mike Gabriel (aa42107) +2016-07-05 10:08:03 +0200 Mike Gabriel (aa4210715) * Merge branch 'sunweaver-pr/rpm-packaging-updates' into 3.6.x -2016-07-05 09:54:47 +0200 Mike Gabriel (058ae3e) +2016-07-05 09:54:47 +0200 Mike Gabriel (058ae3e76) * nx-libs.spec: Add Conflicts: fields for removed shared library bin:packages. -2016-07-04 16:34:38 +0200 Mike Gabriel (1910142) +2016-07-04 16:34:38 +0200 Mike Gabriel (1910142cf) * nx-libs.spec: Let libNX_X11-6 and libNX_X11-devel conflict with deprecated libXau6 and libXau-devel. -2016-07-04 16:31:18 +0200 Mike Gabriel (6dded30) +2016-07-04 16:31:18 +0200 Mike Gabriel (6dded30a7) * nx-libs.spec: Let nxagent conflict with nxauth, which is not provided anymore. -2016-07-04 16:27:34 +0200 Mike Gabriel (59eab0a) +2016-07-04 16:27:34 +0200 Mike Gabriel (59eab0a82) * nx-libs.spec: Add correct Obsoletes:/Provides: fields for lib* bin:packages. -2016-07-04 15:32:58 +0200 Mike Gabriel (5c65e9b) +2016-07-04 15:32:58 +0200 Mike Gabriel (5c65e9b40) * nx-libs.spec: Fix various issues since last testing the RPM builds of nx-libs: -2016-07-05 09:46:45 +0200 Mike Gabriel (a1a7b1a) +2016-07-05 09:46:45 +0200 Mike Gabriel (a1a7b1aab) * debian/control: Add some hard and exact-versioned dependencies for our bin:packages. Assure that no old share lib packages with the same set of symbols remain on the system when upgrading. -2016-07-05 09:10:28 +0200 Mike Gabriel (bf08b99) +2016-07-05 09:10:28 +0200 Mike Gabriel (bf08b9960) * Merge branch 'sunweaver-pr/writeeventstoclients-no-sequencenumber' into 3.6.x -2016-07-03 22:52:13 +0200 Jamey Sharp (cb0089b) +2016-07-03 22:52:13 +0200 Jamey Sharp (cb0089bad) * Set event sequence number in WriteEventsToClient instead of at callers. -2016-07-03 22:06:43 +0200 Jamey Sharp (9ea8871) +2016-07-03 22:06:43 +0200 Jamey Sharp (9ea88717d) * Make WriteEventsToClient/WriteToClient no-op on fake or dead clients. -2016-07-05 08:34:17 +0200 Mike Gabriel (320a8cc) +2016-07-05 08:34:17 +0200 Mike Gabriel (320a8cc0c) * Merge branch 'sunweaver-pr/silencing-compiler-warnings' into 3.6.x -2016-07-05 08:16:09 +0200 Tomas Carnecky (b15fc63) +2016-07-05 08:16:09 +0200 Tomas Carnecky (b15fc63f4) * Replace INITARGS with void -2016-06-29 15:07:16 +0200 Mike Gabriel (f0af82c) +2016-06-29 15:07:16 +0200 Mike Gabriel (f0af82cbb) * nx-X11/lib/X11/XKBMisc.c: Avoid warning about maybe non-assigned variables (mask, newMask). -2016-06-29 15:02:00 +0200 Daniel Stone (d60297e) +2016-06-29 15:02:00 +0200 Daniel Stone (d60297e41) * Remove INITARGS braindamage, change to void; add XkbExtensionInit prototype to xkb.h. Explicitly initialise nTypes in xkb.c. -2016-06-29 14:58:47 +0200 Keith Packard (ecaf4df) +2016-06-29 14:58:47 +0200 Keith Packard (ecaf4df7f) * Xserver/Xext/xres.c: Drop unused REQUEST macro call (for xXResQueryVersionReq). -2016-06-29 14:28:49 +0200 Mike Gabriel (8949935) +2016-06-29 14:28:49 +0200 Mike Gabriel (894993501) * Xserver: Post-REGION-macros-to-inline-funcs clean-up. -2016-06-29 14:17:53 +0200 Mike Gabriel (8df1a67) +2016-06-29 14:17:53 +0200 Mike Gabriel (8df1a67b6) * Xserver/mi/mizerarc.c: Initialize oddPtrs as NULL before using it (in miZeroPolyArc). -2016-06-29 14:14:15 +0200 Mike Gabriel (c08d030) +2016-06-29 14:14:15 +0200 Mike Gabriel (c08d0308d) * Xserver/mi/miarc.c: Initialize dashRemaining with 0 before using it. -2016-06-29 14:09:52 +0200 Mike Gabriel (a8fd16c) +2016-06-29 14:09:52 +0200 Mike Gabriel (a8fd16ce6) * Xserver/os/xdmauth.c: Avoid compiler warnings due to -Wswitch being enabled. Use if statement rather than switch. -2016-06-29 14:05:12 +0200 Mike Gabriel (141316a) +2016-06-29 14:05:12 +0200 Mike Gabriel (141316af0) * Xserver/os/log.c: Make sure strlcpy is defined in log.c. Immitate what is done in X.org. -2016-06-29 13:57:05 +0200 Adam Jackson (f46af7d) +2016-06-29 13:57:05 +0200 Adam Jackson (f46af7de8) * Restore compression of duplicate log file entries. -2016-06-29 13:45:20 +0200 Keith Packard (b5cceb7) +2016-06-29 13:45:20 +0200 Keith Packard (b5cceb740) * os: Make sure that writing our pid to the lock file actually worked -2016-06-29 13:35:06 +0200 Mike Gabriel (bad0e8b) +2016-06-29 13:35:06 +0200 Mike Gabriel (bad0e8bdd) * Xserver/os/connection.c: Drop unused variable 'restore_trans_conn' from ClientAuthorized(). -2016-06-29 13:33:51 +0200 Mike Gabriel (00ebfaf) +2016-06-29 13:33:51 +0200 Mike Gabriel (00ebfaf53) * Xserver/os/connection.c: Only define XSERV_t, TRANS_SERVER and TRANS_REOPEN if not yet defined. -2016-06-29 13:30:08 +0200 Mike Gabriel (b34b47e) +2016-06-29 13:30:08 +0200 Mike Gabriel (b34b47ed5) * nx-X11/lib/X11/imTrX.c: Fix warning ‘len’ may be used uninitialized in this function (_XimRead). -2016-06-29 13:28:23 +0200 Mike Gabriel (eddd487) +2016-06-29 13:28:23 +0200 Mike Gabriel (eddd4876b) * nx-X11/lib/X11/imInsClbk.c: Fix warning 'right-hand operand of comma expression has no effect' in _XimFilterPropertyNotify. -2016-06-29 13:24:38 +0200 Mike Gabriel (3569ac1) +2016-06-29 13:24:38 +0200 Mike Gabriel (3569ac171) * nx-X11/lib/X11/lcFile.c: Drop conditional always evaluating as True. -2016-06-29 13:20:30 +0200 Mike Gabriel (365fa4f) +2016-06-29 13:20:30 +0200 Mike Gabriel (365fa4f3e) * nx-X11/lib/X11/XKBMisc.c: Drop conditional always evaluating as True. -2016-06-29 13:17:04 +0200 Mike Gabriel (ed61433) +2016-06-29 13:17:04 +0200 Mike Gabriel (ed61433e1) * nx-X11/lib/X11/LiHosts.c: Drop unused variable (in XListHosts). -2016-06-29 13:10:08 +0200 Mike Gabriel (5e2e760) +2016-06-29 13:10:08 +0200 Mike Gabriel (5e2e760d3) * Avoid 'siAddr' maybe being used uninitialized in XAddHost and XRemoveHost. -2016-06-29 12:53:21 +0200 Mike Gabriel (35dbbd7) +2016-06-29 12:53:21 +0200 Mike Gabriel (35dbbd7e4) * hw/nxagent/Exrensions.c: Post-RandR 1.5 update fix. Properly set rrProvider hook functions to NULL. -2016-06-29 12:50:14 +0200 Mike Gabriel (e02bdf9) +2016-06-29 12:50:14 +0200 Mike Gabriel (e02bdf929) * hw/nxagent/Args.c: Fix fprintf placeholder (%u -> %lu). -2016-06-29 12:45:45 +0200 Adam Jackson (7e21611) +2016-06-29 12:45:45 +0200 Adam Jackson (7e21611db) * Remove fbpseudocolor -2016-06-29 12:37:22 +0200 Cyril Brulebois (3a54da8) +2016-06-29 12:37:22 +0200 Cyril Brulebois (3a54da8bc) * fb: Mark some variables as unused. -2016-06-29 12:38:31 +0200 Jeremy Huddleston (b91099b) +2016-06-29 12:38:31 +0200 Jeremy Huddleston (b91099b97) * Add _X_UNUSED attribute to designate unused variables and silence warnings -2016-06-29 12:18:52 +0200 Mike Gabriel (cef6d72) +2016-06-29 12:18:52 +0200 Mike Gabriel (cef6d723c) * Xserver/composite/compint.h: Disable debugging in Copmosite extension. -2016-06-29 12:07:26 +0200 Mike Gabriel (f364bac) +2016-06-29 12:07:26 +0200 Mike Gabriel (f364bacf8) * Xserver/xfixes/region.c: Don't declare and set PictureScreenPtr ps (in ProcXFixesSetPictureClipRegion). Variable is not used. -2016-07-05 08:09:24 +0200 Mike Gabriel (854f3fa) +2016-07-05 08:09:24 +0200 Mike Gabriel (854f3fa49) * Merge branch 'sunweaver-pr/proxy-to-proxy-over-unix-socket' into 3.6.x -2016-06-15 16:44:28 +0200 Mike Gabriel (5a22f2e) +2016-06-15 16:44:28 +0200 Mike Gabriel (5a22f2ec1) * test scripts: Add test scripts for testing Unix file socket support (i.e. proxy2proxy and proxy2agent sessions via Unix file sockets). -2016-06-15 10:29:12 +0200 Mike Gabriel (c6e9565) +2016-06-15 10:29:12 +0200 Mike Gabriel (c6e956512) * nxcomp/Loop.cpp: Add Unix file socket support for proxy <-> proxy connection. -2015-06-02 14:55:40 +0200 Salvador Fandino (b23dcd1) +2015-06-02 14:55:40 +0200 Salvador Fandino (b23dcd101) * merge code paths depending on acceptHost being "" -2015-06-02 15:35:50 +0200 Salvador Fandino (f706d77) +2015-06-02 15:35:50 +0200 Salvador Fandino (f706d774b) * remove now unused function ParseListenOption -2015-06-02 13:25:34 +0200 Salvador Fandino (c92a102) +2015-06-02 13:25:34 +0200 Salvador Fandino (c92a102ba) * rewrite WaitForRemote to build on top of ListenConnectionTCP -2015-06-02 12:54:15 +0200 Salvador Fandino (28736a8) +2015-06-02 12:54:15 +0200 Salvador Fandino (28736a888) * remove unused listenHost parameter -2015-06-02 12:34:20 +0200 Salvador Fandino (d6edd7c) +2015-06-02 12:34:20 +0200 Salvador Fandino (d6edd7c97) * Remove work around for OS/X that was doing nothing -2015-06-02 12:30:49 +0200 Salvador Fandino (d2e8551) +2015-06-02 12:30:49 +0200 Salvador Fandino (d2e8551ef) * Simplify ParseListenOption -2015-06-02 10:31:53 +0200 Salvador Fandino (5ea2d90) +2015-06-02 10:31:53 +0200 Salvador Fandino (5ea2d901b) * rewrite SetupUnixSocket to use ListenConnectionUnix -2015-06-01 17:52:33 +0200 Salvador Fandino (c5a2cf8) +2015-06-01 17:52:33 +0200 Salvador Fandino (c5a2cf82f) * Rework SetupTcpSocket to use ListenConnectionTCP -2016-07-04 22:55:23 +0200 Mike Gabriel (e0edae0) +2016-07-04 22:55:23 +0200 Mike Gabriel (e0edae04d) * Merge branch 'sunweaver-pr/xerrordb-from-xorg' into 3.6.x -2016-06-28 20:30:42 +0200 Mike Gabriel (1bd2463) +2016-06-28 20:30:42 +0200 Mike Gabriel (1bd2463a2) * libNX_X11 data files: Install libNX_X11 related data files. -2016-07-04 16:37:55 +0200 Mike Gabriel (27b0b57) +2016-07-04 16:37:55 +0200 Mike Gabriel (27b0b5723) * Merge branch 'sunweaver-pr/type-safe-swapping' into 3.6.x -2016-06-29 01:36:31 +0200 Mike Gabriel (286d832) +2016-06-29 01:36:31 +0200 Mike Gabriel (286d83260) * Use internal temp variable for swap macros. Make swaps/swapl type safe (introducing wrong_size check at build time). -2016-06-15 16:46:10 +0200 Mike Gabriel (d1d859d) +2016-06-15 16:46:10 +0200 Mike Gabriel (d1d859dfd) * test scripts: Update copyright headers. -2016-06-15 16:42:25 +0200 Mike Gabriel (b767ca5) +2016-06-15 16:42:25 +0200 Mike Gabriel (b767ca5c3) * test scripts: Rename run-nxproxy2nxproxy-test -> run-nxproxy2nxproxy. -2016-07-02 14:11:38 +0200 Mike Gabriel (1dbd3c8) +2016-07-02 14:11:38 +0200 Mike Gabriel (1dbd3c888) * Merge branch 'sunweaver-pr/backport-Xorg-memory-handling' into 3.6.x -2016-06-27 12:53:03 +0200 Mike Gabriel (e858082) +2016-06-27 12:53:03 +0200 Mike Gabriel (e85808245) * debian/patches: Refresh patches after changes in upstream code. -2016-06-28 16:55:26 +0200 Mike Gabriel (40e3984) +2016-06-28 16:55:26 +0200 Mike Gabriel (40e398409) * nx-X11/include/extensions/XKBsrv.h: Different memory handling when built with Xserver and with Xlib. -2016-06-27 12:12:31 +0200 Mike Gabriel (f779b2e) +2016-06-27 12:12:31 +0200 Mike Gabriel (f779b2e3c) * os: Remove deprecated malloc/free wrappers, clean {X,XNF}{alloc,calloc,realloc,free,strdup} from pre-C89 baggage -2016-06-27 11:51:31 +0200 Mike Gabriel (ce40aec) +2016-06-27 11:51:31 +0200 Mike Gabriel (ce40aec08) * nx-X11/programs/Xserver: Drop {X,x}calloc() macros, use calloc() instead. -2016-06-26 02:08:32 +0200 Mike Gabriel (74a5450) +2016-06-26 02:08:32 +0200 Mike Gabriel (74a5450bc) * nx-X11/programs/Xserver: Drop {X,x}realloc() macros, use realloc() instead. -2016-06-26 01:51:18 +0200 Mike Gabriel (2646fc2) +2016-06-26 01:51:18 +0200 Mike Gabriel (2646fc254) * nx-X11/programs/Xserver: Drop {X,x}alloc() macros, use malloc() instead. -2016-06-26 01:38:22 +0200 Mike Gabriel (acf8714) +2016-06-26 01:38:22 +0200 Mike Gabriel (acf87144d) * nx-X11/programs/Xserver: Drop {X,x}free() macros, use free() instead. -2016-07-02 13:53:16 +0200 Mike Gabriel (279d371) +2016-07-02 13:53:16 +0200 Mike Gabriel (279d37127) * Merge branch 'sunweaver-pr/protocols-version-h' into 3.6.x -2016-06-28 12:07:10 +0200 Mike Gabriel (487870f) +2016-06-28 12:07:10 +0200 Mike Gabriel (487870fff) * Xserver/include/protocol-versions.h: Switch to having an Xserver-specific header file containing all use protocol versions. -2016-06-28 12:06:50 +0200 Mike Gabriel (a08e232) +2016-06-28 12:06:50 +0200 Mike Gabriel (a08e2323e) * Xserver Imakefiles: Make sure NXAGENT_SERVER is defined for all extensions. -2016-07-01 16:08:55 +0200 Mike Gabriel (dd5f5b5) +2016-07-01 16:08:55 +0200 Mike Gabriel (dd5f5b56b) * Merge branch 'sunweaver-pr/ld-loading-libX11-hack' into 3.6.x -2016-06-30 23:50:12 +0200 Mike Gabriel (5934d03) +2016-06-30 23:50:12 +0200 Mike Gabriel (5934d03ef) * Rework nxagent and nxproxy wrapper scripts. -2016-07-01 16:00:04 +0200 Mike Gabriel (da7261c) +2016-07-01 16:00:04 +0200 Mike Gabriel (da7261cfe) * Merge branch 'uli42-pr/drop_libNX_Xext' into 3.6.x -2016-07-01 13:54:11 +0200 Ulrich Sibiller (1cd7e35) +2016-07-01 13:54:11 +0200 Ulrich Sibiller (1cd7e35cb) * finally drop libNX_Xext -2016-07-01 13:54:10 +0200 Ulrich Sibiller (e78c5bc) +2016-07-01 13:54:10 +0200 Ulrich Sibiller (e78c5bc3c) * remove shm code from libNX_Xext -2016-07-01 00:55:53 +0200 Ulrich Sibiller (232c7ad) +2016-07-01 00:55:53 +0200 Ulrich Sibiller (232c7ad91) * avoid conflicts when mixing own includes with upstream includes -2016-07-01 00:05:30 +0200 Ulrich Sibiller (e77e37f) +2016-07-01 00:05:30 +0200 Ulrich Sibiller (e77e37ff0) * remove XShape code from libNX_Xext -2016-07-01 15:48:55 +0200 Mike Gabriel (2f19f2f) +2016-07-01 15:48:55 +0200 Mike Gabriel (2f19f2f66) * Merge branch 'sunweaver-pr/libXau-cleanup' into 3.6.x -2016-06-23 10:46:48 +0200 Mike Gabriel (2045452) +2016-06-23 10:46:48 +0200 Mike Gabriel (204545286) * nxagent Xserver: Drop Kerberos code. Not used in nxagent. -2016-06-23 10:31:42 +0200 Mike Gabriel (26bf48b) +2016-06-23 10:31:42 +0200 Mike Gabriel (26bf48bab) * library-cleanup: Don't build libNX_Xau anymore. Use system's libXau shared library. -2016-06-23 10:27:37 +0200 Mike Gabriel (b214c73) +2016-06-23 10:27:37 +0200 Mike Gabriel (b214c73b5) * nxauth: Drop nxauth tool completely, xauth can be successfully used with nxagent / nxproxy instead. -2016-07-01 14:02:52 +0200 Mike Gabriel (a3a2952) +2016-07-01 14:02:52 +0200 Mike Gabriel (a3a295288) * Merge branch 'sunweaver-pr/debian-packaging-updates' into 3.6.x -2016-07-01 00:00:29 +0200 Mike Gabriel (12ca29b) +2016-07-01 00:00:29 +0200 Mike Gabriel (12ca29bf5) * debian/*.dirs: Don't create directories in the Debian package. All handled well by the upstream Makefile. -2016-06-23 21:33:23 +0200 Mike Gabriel (2d016f8) +2016-06-23 21:33:23 +0200 Mike Gabriel (2d016f826) * roll-tarball.sh: Move out of debian/ folder into project's base folder. -2016-06-23 21:28:42 +0200 Mike Gabriel (82a8d59) +2016-06-23 21:28:42 +0200 Mike Gabriel (82a8d595d) * debian/libxcompext3.symbols: Add symbols file for libXcompext3. -2016-06-23 21:13:20 +0200 Mike Gabriel (ba5f32c) +2016-06-23 21:13:20 +0200 Mike Gabriel (ba5f32cda) * nx-X11/extras/Mesa/src/mesa/shader/arbprogparse.c: Fix typo (grammer -> grammar). -2016-06-23 21:09:19 +0200 Mike Gabriel (7d66941) +2016-06-23 21:09:19 +0200 Mike Gabriel (7d66941ae) * debian/rules: Use buildflags.mk from dpkg-dev. Enable bindnow hardening flag. -2016-06-23 21:08:47 +0200 Mike Gabriel (56f776c) +2016-06-23 21:08:47 +0200 Mike Gabriel (56f776ced) * debian/control: Versioned B-D: dpkg-dev (>= 1.16.1.1). -2016-06-23 15:45:33 +0200 Mike Gabriel (2a2d7f0) +2016-06-23 15:45:33 +0200 Mike Gabriel (2a2d7f0e2) * debian/control: Remove all Pre-Depends: fields from all bin:pkgs. -2016-06-22 12:14:00 +0200 Mike Gabriel (9663b1c) +2016-06-22 12:14:00 +0200 Mike Gabriel (9663b1ce2) * debian/control: Bump Standards: to 3.9.8. (Various changes were needed). -2016-06-22 12:13:23 +0200 Mike Gabriel (87ce9b4) +2016-06-22 12:13:23 +0200 Mike Gabriel (87ce9b4b0) * debian/{control,compat}: Bump to DH compat level 9. -2016-06-22 12:08:49 +0200 Mike Gabriel (2e1ec61) +2016-06-22 12:08:49 +0200 Mike Gabriel (2e1ec6181) * debian/control: Use my DD address in Uploaders: field. -2016-06-22 12:08:35 +0200 Mike Gabriel (24ff7db) +2016-06-22 12:08:35 +0200 Mike Gabriel (24ff7db2b) * debian/changelog: Suppress warnings from lintian about -0 revision in version string. -2016-06-22 10:26:15 +0200 Mike Gabriel (b4d7b99) +2016-06-22 10:26:15 +0200 Mike Gabriel (b4d7b9989) * debian/control: Drop various not-used-anymore libNX_* related packages. Add B:/R: to libnx-x11-{6,dev,6-dbg) to uninstall those package when upgrading to nx-libs 3.6.x. -2016-06-22 10:12:33 +0200 Mike Gabriel (6b423ee) +2016-06-22 10:12:33 +0200 Mike Gabriel (6b423eefd) * roll-tarball.sh: Don't ship doc/X11-symbols/ in the lite (proxy-only) tarball derived from the nx-libs code tree. -2016-06-22 10:10:49 +0200 Mike Gabriel (908b930) +2016-06-22 10:10:49 +0200 Mike Gabriel (908b930c9) * debian/rules: Don't attempt at removing $(CURDIR)/.preserve/. Not needed anymore since we removed the CODE-REDUCTION_* hacks from debian/rules. -2016-06-22 10:09:17 +0200 Mike Gabriel (593e15c) +2016-06-22 10:09:17 +0200 Mike Gabriel (593e15ca1) * debian/*: Drop non-multi-arch support (i.e. Debian squeeze, Ubuntu 10.04 and earlier). -2016-06-22 10:04:16 +0200 Mike Gabriel (3983b11) +2016-06-22 10:04:16 +0200 Mike Gabriel (3983b111a) * debian/*: Drop not-use-anymore CODE-REDUCTION_* files. -2016-07-01 13:46:26 +0200 Mike Gabriel (8307d4f) +2016-07-01 13:46:26 +0200 Mike Gabriel (8307d4f33) * Merge branch 'sunweaver-pr/define-default-source-not-bsd+svid-source' into 3.6.x -2016-06-23 20:52:27 +0200 Mike Gabriel (da4410c) +2016-06-23 20:52:27 +0200 Mike Gabriel (da4410cce) * build flags: Use -D_DEFAULT_SOURCE instead of deprecated -D_BSD_SOURCE and -D_SVID_SOURCE. -2016-07-01 13:13:48 +0200 Mike Gabriel (4b3081c) +2016-07-01 13:13:48 +0200 Mike Gabriel (4b3081c48) * Merge branch 'sunweaver-pr/drop-really-old-X10-API-code' into 3.6.x -2016-06-23 09:58:54 +0200 Mike Gabriel (f0bf303) +2016-06-23 09:58:54 +0200 Mike Gabriel (f0bf303c8) * nx-X11/lib/X10: Drop really ancient X10 API code. Not used within nxagent. -2016-07-01 13:10:06 +0200 Mike Gabriel (b666a37) +2016-07-01 13:10:06 +0200 Mike Gabriel (b666a3776) * Merge branch 'sunweaver-pr/properly-apply-optflags-at-buildtime' into 3.6.x -2016-06-23 14:27:15 +0200 Mike Gabriel (d650a0b) +2016-06-23 14:27:15 +0200 Mike Gabriel (d650a0b47) * OPTFLAGS: Properly propagate build option flags to nxcomp{,ext,shad} and the nx-X11 build scripts. -2016-06-23 09:58:54 +0200 Mike Gabriel (4693c32) +2016-06-23 09:58:54 +0200 Mike Gabriel (4693c3203) * nx-X11/lib/X10: Drop really ancient X10 API code. Not used within nxagent. -2016-06-23 14:27:15 +0200 Mike Gabriel (a1e9abc) +2016-06-23 14:27:15 +0200 Mike Gabriel (a1e9abc78) * OPTFLAGS: Properly propagate build option flags to nxcomp{,ext,shad} and the nx-X11 build scripts. -2016-06-30 22:41:00 +0200 Mike Gabriel (4cbfc5f) +2016-06-30 22:41:00 +0200 Mike Gabriel (4cbfc5f98) * debian/libnx-x11-6.symbols: Update symbols (added: _XEatDataWords@Base 3.5.99.0, _XGetRequest@Base 3.5.99.0). -2016-06-30 15:41:03 +0200 Mike Gabriel (ba10cef) +2016-06-30 15:41:03 +0200 Mike Gabriel (ba10ceffc) * Merge branch 'sunweaver-pr/drop-embedded-imake-and-makedepend' into 3.6.x -2016-06-22 13:22:06 +0200 Mike Gabriel (298744e) +2016-06-22 13:22:06 +0200 Mike Gabriel (298744e94) * nx-X11/Makefile: Drop build support for World.Win32 and World.OS2. Not our target platforms. -2016-06-22 12:41:50 +0200 Mike Gabriel (2f3d394) +2016-06-22 12:41:50 +0200 Mike Gabriel (2f3d394e8) * nx-X11/config/{imake,makedepend}: Use system-wide available imake and makedepend tools. -2016-06-30 00:26:37 +0200 Mike Gabriel (5b36f64) +2016-06-30 00:26:37 +0200 Mike Gabriel (5b36f6443) * Merge branch 'sunweaver-pr/backport-xgetrequest-and-xeatdatawords' into 3.6.x -2016-06-29 21:44:08 +0200 Ulrich Sibiller (bd2650c) +2016-06-29 21:44:08 +0200 Ulrich Sibiller (bd2650ca0) * Port _XEatDataWords -2016-06-29 21:25:24 +0200 Ulrich Sibiller (36d0fac) +2016-06-29 21:25:24 +0200 Ulrich Sibiller (36d0fac77) * Backport of _XGetRequest() -2016-06-29 11:21:09 +0200 Mike Gabriel (3314c24) +2016-06-29 11:21:09 +0200 Mike Gabriel (3314c24a7) * Merge branch 'sunweaver-pr/drop-x2goagent' into 3.6.x -2016-06-22 08:16:35 +0200 Mike Gabriel (c355dc9) +2016-06-22 08:16:35 +0200 Mike Gabriel (c355dc91d) * Makefile,debian/*,nx-libs.spec,: Drop references to X2Go Project, esp. drop x2goagent. -2016-06-29 11:13:34 +0200 Mike Gabriel (b9fb7a0) +2016-06-29 11:13:34 +0200 Mike Gabriel (b9fb7a05a) * Merge branch 'sunweaver-pr/libnx-xext-drop-unused-extensions' into 3.6.x -2016-06-28 12:20:00 +0000 Mike Gabriel (f051b7a) +2016-06-28 12:20:00 +0000 Mike Gabriel (f051b7a2d) * libNX_Xext: Drop unused extensions: DPMS, XTestExt1, XSync, XSecurity. -2016-06-28 12:13:27 +0000 Mike Gabriel (e9857d5) +2016-06-28 12:13:27 +0000 Mike Gabriel (e9857d5ea) * nx-X11/lib/Xext/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-06-28 12:05:01 +0000 Mike Gabriel (d595125) +2016-06-28 12:05:01 +0000 Mike Gabriel (d595125a1) * fix wrong bin:package for Xext proto headers: Move dpmsstr.h and securstr.h from Xext devel package into proto header package. -2016-06-28 11:43:06 +0000 Mike Gabriel (3ded4a2) +2016-06-28 11:43:06 +0000 Mike Gabriel (3ded4a2d6) * Fix linking order hack in nxagent. -2016-06-15 16:42:58 +0200 Mike Gabriel (b83a148) +2016-06-15 16:42:58 +0200 Mike Gabriel (b83a14843) * test scripts: Add run-nxagent test script. -2016-06-25 01:35:40 +0200 Mihai Moldovan (975511c) +2016-06-25 01:35:40 +0200 Mihai Moldovan (975511c87) * Merge branch 'sunweaver-pr/hw-nxagent-drop-duplicate-Xserver-code_disable-Xserver-code-and-include-in-nxagent' into arctica-3.6.x -2016-05-02 12:14:14 +0200 Mike Gabriel (a5befd4) +2016-05-02 12:14:14 +0200 Mike Gabriel (a5befd4e2) * hw/nxagent: Drop code referring to the following removed Xserver extensions: XAPPGROUP, LBX, XEVIE. -2016-05-02 11:29:53 +0200 Mike Gabriel (3bdcd17) +2016-05-02 11:29:53 +0200 Mike Gabriel (3bdcd1727) * hw/nxagent/NX*.c: Amend re-introduced nxagent warnings by fixing the corresponding code section in files included from "somewhere" in nx-X11/programs/Xserver/. -2016-05-01 23:02:20 +0200 Mike Gabriel (a5c7b24) +2016-05-01 23:02:20 +0200 Mike Gabriel (a5c7b248e) * hw/nxagent/NXdixfonts.c: Shrink file, drop duplicate code that can identically be found in dix/dixfonts.c. Also remove NX'ish code from dix/dixfonts.c. -2016-05-01 21:58:22 +0200 Mike Gabriel (2ba5008) +2016-05-01 21:58:22 +0200 Mike Gabriel (2ba500864) * hw/nxagent/NXdispatch.c: Shrink file, drop duplicate code that can identically be found in dix/dispatch.c. -2016-04-26 05:59:56 +0200 Mike Gabriel (a434613) +2016-04-26 05:59:56 +0200 Mike Gabriel (a43461335) * hw/nxagent/NXproperty.c: Shrink file, drop duplicate code that can identically be found in dix/property.c. -2016-04-11 14:53:15 +0200 Mike Gabriel (c6f86b3) +2016-04-11 14:53:15 +0200 Mike Gabriel (c6f86b3b2) * hw/nxagent/NXshm.c: Shrink file, drop duplicate code that can identically be found in Xext/shm.c. -2016-04-10 01:57:57 +0200 Mike Gabriel (51e4ed0) +2016-04-10 01:57:57 +0200 Mike Gabriel (51e4ed0fc) * hw/nxagent/NXxvdisp.c: Shrink file, drop duplicate code that can identically be found in Xext/xvdisp.c. -2016-04-18 13:02:34 +0200 Mike Gabriel (add8819) +2016-04-18 13:02:34 +0200 Mike Gabriel (add881931) * hw/nxagent/NXevents.c: Shrink file, drop duplicate code that can identically be found in dix/events.c. -2016-04-18 08:19:05 +0200 Mike Gabriel (0571ece) +2016-04-18 08:19:05 +0200 Mike Gabriel (0571ece6a) * hw/nxagent/NXglyph.c: Shrink file, drop duplicate code that can identically be found in render/glyph.c. -2016-04-18 08:10:08 +0200 Mike Gabriel (12130a4) +2016-04-18 08:10:08 +0200 Mike Gabriel (12130a4d9) * hw/nxagent/NXglyphcurs.c: Shrink file, drop duplicate code that can identically be found in dix/glyphcurs.c. -2016-04-13 15:29:32 +0200 Mike Gabriel (a648558) +2016-04-13 15:29:32 +0200 Mike Gabriel (a64855879) * hw/nxagent/NXrender.c: Shrink file, drop duplicate code that can identically be found in render/render.c. -2016-04-13 15:28:33 +0200 Mike Gabriel (778e83a) +2016-04-13 15:28:33 +0200 Mike Gabriel (778e83a3c) * hw/nxagent/NX{glyphstr,picturestr}.h: Don't ship the complete header files in nxagent's code base. Rather replace structures we need modified only. -2016-04-13 11:33:33 +0200 Mike Gabriel (de03d62) +2016-04-13 11:33:33 +0200 Mike Gabriel (de03d6227) * NXrenderint.h: Move into subfolder X11/include/ and rename to Xrender_nxagent.h. (Like we have done with all other non-public Xlib related header files that are required for building nxagent. -2016-04-11 16:37:00 +0200 Mike Gabriel (ab6bb89) +2016-04-11 16:37:00 +0200 Mike Gabriel (ab6bb890e) * hw/nxagent/NXresource.c: Shrink file, drop duplicate code that can identically be found in dix/resource.c. -2016-04-11 13:46:36 +0200 Mike Gabriel (1384776) +2016-04-11 13:46:36 +0200 Mike Gabriel (1384776fd) * Xserver/dix/window.c: Don't reintroduce build warnings with previous commit due to now-unnecessary assignements of pScreen pointers. -2016-04-11 13:41:11 +0200 Mike Gabriel (4690d6b) +2016-04-11 13:41:11 +0200 Mike Gabriel (4690d6b71) * hw/nxagent/NXwindow.c: Shrink file, drop duplicate code that can identically be found in dix/window.c. -2016-04-10 02:45:24 +0200 Mike Gabriel (e60f281) +2016-04-10 02:45:24 +0200 Mike Gabriel (e60f281aa) * hw/nxagent/NXglxext.c: Shrink file, drop duplicate code that can identically be found in GL/glx/glxext.c. -2016-04-10 02:37:19 +0200 Mike Gabriel (b4e2ec7) +2016-04-10 02:37:19 +0200 Mike Gabriel (b4e2ec709) * Xserver/GL/glx/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-04-09 00:36:40 +0200 Mike Gabriel (0c29f81) +2016-04-09 00:36:40 +0200 Mike Gabriel (0c29f81f1) * hw/nxagent/NXpicture.c: Shrink file, drop duplicate code that can identically be found in render/picture.c. -2016-04-08 13:53:36 +0200 Mike Gabriel (809fed6) +2016-04-08 13:53:36 +0200 Mike Gabriel (809fed649) * hw/nxagent/NXmiexpose.c: Shrink file, drop duplicate code that can identically be found in mi/miexpose.c. -2016-04-08 13:52:59 +0200 Mike Gabriel (69ac981) +2016-04-08 13:52:59 +0200 Mike Gabriel (69ac98165) * hw/nxagent/Pixmaps.h: Make RESTYPE well-defined by adding resource.h to includes. -2016-04-08 10:01:30 +0200 Mike Gabriel (5088a6d) +2016-04-08 10:01:30 +0200 Mike Gabriel (5088a6d13) * Xserver/mi/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-04-08 09:45:32 +0200 Mike Gabriel (ae1a218) +2016-04-08 09:45:32 +0200 Mike Gabriel (ae1a218d1) * hw/nxagent/NXmiglyph.c: Shrink file, drop code that can be identically found in render/miglyph.c. -2016-04-08 09:38:20 +0200 Mike Gabriel (500544f) +2016-04-08 09:38:20 +0200 Mike Gabriel (500544f82) * hw/nxagent/NXmitrap.c: Shrink file, drop duplicate code that can identically be found in render/mitrap.c. -2016-04-08 09:26:12 +0200 Mike Gabriel (8fab4af) +2016-04-08 09:26:12 +0200 Mike Gabriel (8fab4afbb) * hw/nxagent/NXmiwindow.c: Drop complete file. -2016-04-07 12:22:51 +0200 Mike Gabriel (148f750) +2016-04-07 12:22:51 +0200 Mike Gabriel (148f75067) * hw/nxagent/NXdamage.c: Shrink file, drop duplicate code that can identically be found in miext/damage/damage.c. -2016-04-07 09:36:18 +0200 Mike Gabriel (fd31518) +2016-04-07 09:36:18 +0200 Mike Gabriel (fd31518f4) * NXcomposite.h: Move fake header file NXcomposite.h to hw/nxagent/X11/include/ and drop all symbols that are not explicitly used by nxagent. -2016-04-07 00:54:44 +0200 Mike Gabriel (28acdaf) +2016-04-07 00:54:44 +0200 Mike Gabriel (28acdaff7) * Xserver/hw/nxagent: Drop NXcompositeext.h, it is a duplicate of nx-X11/include/extensions/composite.h. -2016-04-06 23:31:52 +0200 Mike Gabriel (ca1e857) +2016-04-06 23:31:52 +0200 Mike Gabriel (ca1e85710) * hw/nxagent/NXextension.c: Shrink file, drop duplicate code that is indentically found in dix/extension.c. -2016-04-06 23:18:07 +0200 Mike Gabriel (5d16046) +2016-04-06 23:18:07 +0200 Mike Gabriel (5d1604616) * Xserver/dix/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-06-25 00:38:01 +0200 Mike Gabriel (9df1536) +2016-06-25 00:38:01 +0200 Mike Gabriel (9df153668) * Merge branch 'uli42-pr/run_xinerama_without_debug_output' into 3.6.x -2016-06-24 21:22:01 +0200 Ulrich Sibiller (b7d7ff3) +2016-06-24 21:22:01 +0200 Ulrich Sibiller (b7d7ff3e4) * libX11: Extend Event functions to handle IOErrors -2016-06-25 00:31:35 +0200 Ulrich Sibiller (e079b0b) +2016-06-25 00:31:35 +0200 Ulrich Sibiller (e079b0b35) * Screen.c: fix RRGetInfo call -2016-06-25 00:31:05 +0200 Ulrich Sibiller (cec31e2) +2016-06-25 00:31:05 +0200 Ulrich Sibiller (cec31e2f0) * Xinerama: undef debug/test flags -2016-06-25 00:17:10 +0200 Mike Gabriel (9c1275f) +2016-06-25 00:17:10 +0200 Mike Gabriel (9c1275f58) * Merge branch 'uli42-pr/fix-crash-in-XPeekEvent' into 3.6.x -2016-06-24 21:22:01 +0200 Ulrich Sibiller (5ee04c2) +2016-06-24 21:22:01 +0200 Ulrich Sibiller (5ee04c24c) * libX11: Extend Event functions to handle IOErrors -2016-06-21 04:12:07 +0200 Mike Gabriel (17f3e3b) +2016-06-21 04:12:07 +0200 Mike Gabriel (17f3e3bc5) * Merge branch 'sunweaver-pr/xrandr-extension-upgrade-1.5' into 3.6.x -2016-06-20 17:21:33 +0200 Mike Gabriel (4c8fc6b) +2016-06-20 17:21:33 +0200 Mike Gabriel (4c8fc6be8) * debian/patches: Update 102_xserver-xext_set-securitypolicy-path.debian.patch. -2016-06-20 11:10:06 +0200 Mike Gabriel (c2b1f48) +2016-06-20 11:10:06 +0200 Mike Gabriel (c2b1f489d) * Backport RANDR proto version 1.5 to nx-X11's Xserver. -2016-06-20 15:53:20 +0200 Mike Gabriel (2e5b989) +2016-06-20 15:53:20 +0200 Mike Gabriel (2e5b98986) * Move matrix operations from X server to pixman 0.13.2. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). -2016-06-20 15:51:55 +0200 Mike Gabriel (36e17bd) +2016-06-20 15:51:55 +0200 Mike Gabriel (36e17bdc6) * [render] Split out filter finding from filter setting. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). -2016-06-20 15:50:05 +0200 Mike Gabriel (3f4e503) +2016-06-20 15:50:05 +0200 Mike Gabriel (3f4e503d6) * nx-libs.spec, debian/control: versioned B-R / B-D: pixman-1 (>= 0.13.2). -2016-06-20 15:43:35 +0200 Mike Gabriel (f9dbc64) +2016-06-20 15:43:35 +0200 Mike Gabriel (f9dbc64f0) * Move matrix operations from X server to pixman 0.13.2, handle RandR transform matrices in floating point. -2016-06-20 15:36:52 +0200 Mike Gabriel (6859815) +2016-06-20 15:36:52 +0200 Mike Gabriel (6859815ec) * Call pScreen->ConstrainCursorHarder from the position update path -2016-06-20 15:29:28 +0200 Mike Gabriel (a60c22f) +2016-06-20 15:29:28 +0200 Mike Gabriel (a60c22f45) * dix/randr: add a hooks into screen to (a) replace scanout pixmap and (b) for additional cursor confinement -2016-06-20 13:25:23 +0200 Mike Gabriel (19ebd77) +2016-06-20 13:25:23 +0200 Mike Gabriel (19ebd7722) * include: add version_compare helper function -2016-06-20 13:19:08 +0200 Mike Gabriel (21c3d20) +2016-06-20 13:19:08 +0200 Mike Gabriel (21c3d20fb) * [render] Split out filter finding from filter setting. -2016-06-20 12:21:39 +0200 Mike Gabriel (e383881) +2016-06-20 12:21:39 +0200 Mike Gabriel (e38388174) * debian/patches-pending-evaluation: Adapt fix-icon-and-clipboard.patch to removal of the WindowTable array. -2016-06-20 16:51:59 +0200 Mike Gabriel (8c7d7be) +2016-06-20 16:51:59 +0200 Mike Gabriel (8c7d7bed9) * hw/nxagent/NXresource.c: remove caching of drawables and graphics contexts. The security checks simply bypass the cached @@ -3129,2590 +3372,2590 @@ nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). -2016-06-20 16:45:38 +0200 Mike Gabriel (e6f2f64) +2016-06-20 16:45:38 +0200 Mike Gabriel (e6f2f6427) * dix: remove caching of drawables and graphics contexts. The security checks simply bypass the cached values so they are unused. -2016-06-20 16:47:28 +0200 Mike Gabriel (2745986) +2016-06-20 16:47:28 +0200 Mike Gabriel (274598651) * Xserver/dix/events.c: Don't declare and assign unused pScreen. -2016-06-20 12:18:53 +0200 Mike Gabriel (c61bb8c) +2016-06-20 12:18:53 +0200 Mike Gabriel (c61bb8cc5) * Move each screen's root-window pointer into ScreenRec. -2016-06-20 11:16:08 +0200 Mike Gabriel (590862d) +2016-06-20 11:16:08 +0200 Mike Gabriel (590862d39) * Centralize declaration of ConnectionInfo. -2016-06-20 11:21:46 +0200 Mike Gabriel (560fd4e) +2016-06-20 11:21:46 +0200 Mike Gabriel (560fd4e5f) * nxagent/hw/NXextension.c: Allow CloseDownProc to be NULL. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). -2016-06-20 11:12:11 +0200 Mike Gabriel (4aec113) +2016-06-20 11:12:11 +0200 Mike Gabriel (4aec11346) * Allow CloseDownProc to be NULL. -2016-06-07 10:26:58 +0200 Mike Gabriel (e440ea7) +2016-06-07 10:26:58 +0200 Mike Gabriel (e440ea768) * randr extension: Convert to Xorg coding style. -2016-06-07 10:26:12 +0200 Mike Gabriel (7f7c96c) +2016-06-07 10:26:12 +0200 Mike Gabriel (7f7c96c7c) * Copy x-indent.sh and x-indent-all.sh from xorg/util/modular. -2016-06-07 10:14:50 +0200 Mike Gabriel (b943cfe) +2016-06-07 10:14:50 +0200 Mike Gabriel (b943cfe2a) * Drop trailing whitespaces (randr extension) -2016-05-31 16:12:15 +0200 Adam Jackson (e2b0f27) +2016-05-31 16:12:15 +0200 Adam Jackson (e2b0f279e) * randr: Remove mirandr -2016-05-31 16:11:40 +0200 Mike Gabriel (6343fa6) +2016-05-31 16:11:40 +0200 Mike Gabriel (6343fa664) * Xserver/randr/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-06-21 03:56:29 +0200 Mike Gabriel (3db9a75) +2016-06-21 03:56:29 +0200 Mike Gabriel (3db9a757f) * hw/nxagent/Handlers.c: Regression fix since 6051dec. Close unclosed '#ifdef TEST'. -2016-06-18 19:50:10 +0200 Mike Gabriel (9de3d26) +2016-06-18 19:50:10 +0200 Mike Gabriel (9de3d26ef) * hw/nxagent/Options.h: Grammar fix in comment. -2016-06-10 01:05:58 +0200 Mike Gabriel (d130494) +2016-06-10 01:05:58 +0200 Mike Gabriel (d13049403) * Properly enable/disable Xinerama support in nxagent via cmdline options provider in Xserver/os/utils.c. -2016-06-09 16:24:10 +0200 Mike Gabriel (059f031) +2016-06-09 16:24:10 +0200 Mike Gabriel (059f03188) * noRRXineramaExtension: Make Boolean configurable via new cmdline switch (+|-rrxinerama). -2016-06-17 01:45:40 +0000 Mihai Moldovan (4d6d3c5) +2016-06-17 01:45:40 +0000 Mihai Moldovan (4d6d3c567) * {nx-X11/programs/Xserver/hw/nxagent/{{Args,Handlers,Image,Options}.c,Options.h},nxcomp/{Loop,Misc}.cpp}: add configurable sleep delay if session is suspended. -2016-06-13 01:56:07 +0200 Mike Gabriel (04d2fe3) +2016-06-13 01:56:07 +0200 Mike Gabriel (04d2fe3ae) * nxagentReversePointerMap: Don't assume Xevent.xbutton.button is always greater than zero. We have seen Xevent.xbutton.button being set to AnyButton (equaling 0). -2016-05-27 15:52:50 +0000 Mihai Moldovan (129cc6a) +2016-05-27 15:52:50 +0000 Mihai Moldovan (129cc6afd) * nx-X11/programs/Xserver/hw/nxagent/Handlers.h: fix stack smashing related to different data type sizes between Xserver and Xlib. -2016-06-21 03:56:29 +0200 Mike Gabriel (9013a24) +2016-06-21 03:56:29 +0200 Mike Gabriel (9013a24da) * hw/nxagent/Handlers.c: Regression fix since 6051dec. Close unclosed '#ifdef TEST'. -2016-06-18 19:50:10 +0200 Mike Gabriel (d5cc12c) +2016-06-18 19:50:10 +0200 Mike Gabriel (d5cc12c2a) * hw/nxagent/Options.h: Grammar fix in comment. -2016-06-18 19:46:28 +0200 Mike Gabriel (c31ae1e) +2016-06-18 19:46:28 +0200 Mike Gabriel (c31ae1eed) * Merge branch 'sunweaver-pr/rrxinerama-vs-panoramix-with-disable-support' into 3.6.x -2016-06-10 01:05:58 +0200 Mike Gabriel (4b4a6a3) +2016-06-10 01:05:58 +0200 Mike Gabriel (4b4a6a35c) * Properly enable/disable Xinerama support in nxagent via cmdline options provider in Xserver/os/utils.c. -2016-06-09 16:24:10 +0200 Mike Gabriel (3f8aa38) +2016-06-09 16:24:10 +0200 Mike Gabriel (3f8aa38fe) * noRRXineramaExtension: Make Boolean configurable via new cmdline switch (+|-rrxinerama). -2016-06-18 09:27:39 +0200 Mike Gabriel (2dd1a1f) +2016-06-18 09:27:39 +0200 Mike Gabriel (2dd1a1fe6) * Merge branch 'Ionic-feature/configurablesleep' into 3.6.x -2016-06-17 01:45:40 +0000 Mihai Moldovan (6051dec) +2016-06-17 01:45:40 +0000 Mihai Moldovan (6051dec4a) * {nx-X11/programs/Xserver/hw/nxagent/{{Args,Handlers,Image,Options}.c,Options.h},nxcomp/{Loop,Misc}.cpp}: add configurable sleep delay if session is suspended. -2016-06-15 00:39:04 +0200 Mike Gabriel (3dea5a8) +2016-06-15 00:39:04 +0200 Mike Gabriel (3dea5a88c) * Merge branch 'sunweaver-pr/nxagentReversePointerMapping-negative-index' into 3.6.x -2016-06-13 01:56:07 +0200 Mike Gabriel (5e17d05) +2016-06-13 01:56:07 +0200 Mike Gabriel (5e17d05aa) * nxagentReversePointerMap: Don't assume Xevent.xbutton.button is always greater than zero. We have seen Xevent.xbutton.button being set to AnyButton (equaling 0). (gh-sunweaver/pr/nxagentReversePointerMapping-negative-index) -2016-06-13 21:07:38 +0200 Mike Gabriel (61d0fbe) +2016-06-13 21:07:38 +0200 Mike Gabriel (61d0fbea7) * Merge branch 'Ionic-bugfix/Xserver-Xlib-type-mismatch' into 3.6.x -2016-05-27 15:52:50 +0000 Mihai Moldovan (639a2c3) +2016-05-27 15:52:50 +0000 Mihai Moldovan (639a2c36f) * nx-X11/programs/Xserver/hw/nxagent/Handlers.h: fix stack smashing related to different data type sizes between Xserver and Xlib. -2016-06-13 13:13:55 +0200 Mike Gabriel (35613d1) +2016-06-13 13:13:55 +0200 Mike Gabriel (35613d1dc) * Merge branch 'sunweaver-pr/nxcomp+ext+shad-system-wide-headers' into 3.6.x -2016-04-06 22:09:31 +0200 Mike Gabriel (f5eff9b) +2016-04-06 22:09:31 +0200 Mike Gabriel (f5eff9bc0) * nx-X11/programs/Xserver: Include nxcomp{,ext,shad} headers like one would do with system-wide shared libraries. (gh-sunweaver/pr/nxcomp+ext+shad-system-wide-headers) -2016-04-05 14:29:02 +0200 Mike Gabriel (2f706cb) +2016-04-05 14:29:02 +0200 Mike Gabriel (2f706cbeb) * nxcomp/Makefile.in: Only install MD5.h, NX.h, NXalert.h, NXpack.h, NXproto.h and NXvars.h as publicly available header files. -2016-04-05 14:20:24 +0200 Mike Gabriel (f55249d) +2016-04-05 14:20:24 +0200 Mike Gabriel (f55249dc6) * nxcomshad/Makefile.in: Only install Shadow.h as publicly available header file. -2016-06-09 16:26:51 +0200 Mike Gabriel (734da21) +2016-06-09 16:26:51 +0200 Mike Gabriel (734da2139) * hw/nxagent/Args.c: Fix syntax errors for builds using -UPANORAMIX. -2016-06-03 14:58:02 +0200 Mike Gabriel (4998e62) +2016-06-03 14:58:02 +0200 Mike Gabriel (4998e62c4) * nx-X11/programs/Xserver/Imakefile: Don't overlink nxagent. Linking against libXrandr and libXtst is not necessary for nxagent. -2016-06-03 14:42:54 +0200 Mike Gabriel (15440ca) +2016-06-03 14:42:54 +0200 Mike Gabriel (15440cad7) * nx-X11/config/cf/lnxLib.tmpl requires post-library removal cleanup: Drop references to dropped X11 extension client libraries. -2016-06-01 21:57:36 +0200 Mihai Moldovan (3d54338) +2016-06-01 21:57:36 +0200 Mihai Moldovan (3d5433833) * Merge branch 'sunweaver-pr/xserver-drop-outdated-xext-extensions' into arctica-3.6.x -2016-04-26 23:44:55 +0200 Mike Gabriel (b214532) +2016-04-26 23:44:55 +0200 Mike Gabriel (b2145323c) * XTRAP: Drop all Xserver code blocks that relate to removed XTRAP extension. (gh-sunweaver/pr/xserver-drop-outdated-xext-extensions) -2016-04-19 12:04:57 +0200 Mike Gabriel (8c1d16d) +2016-04-19 12:04:57 +0200 Mike Gabriel (8c1d16dae) * XFreeXDGA: Drop all Xserver code blocks that relate to removed XFreeXDGA extension. -2016-04-19 12:02:12 +0200 Mike Gabriel (2ff2c92) +2016-04-19 12:02:12 +0200 Mike Gabriel (2ff2c92bb) * XF86MISC: Drop all Xserver code blocks that relate to removed XF86MISC extension. -2016-04-19 11:58:37 +0200 Mike Gabriel (004f8f8) +2016-04-19 11:58:37 +0200 Mike Gabriel (004f8f896) * MITMISC: Drop all Xserver code blocks that relate to removed MITMISC extension. -2016-04-19 11:56:20 +0200 Mike Gabriel (e142314) +2016-04-19 11:56:20 +0200 Mike Gabriel (e14231443) * XF86VIDMODE: Drop all Xserver code blocks that relate to removed XF86VIDMODE extension. -2016-04-19 11:53:59 +0200 Mike Gabriel (74a1e4e) +2016-04-19 11:53:59 +0200 Mike Gabriel (74a1e4e83) * MULTIBUFFER: Drop all Xserver code blocks that relate to removed MULTIBUFFER extension. -2016-04-19 11:52:13 +0200 Mike Gabriel (2f0d2d3) +2016-04-19 11:52:13 +0200 Mike Gabriel (2f0d2d388) * LBX: Drop all Xserver code blocks that relate to removed LBX extension. -2016-04-19 11:36:27 +0200 Mike Gabriel (e80842c) +2016-04-19 11:36:27 +0200 Mike Gabriel (e80842cc4) * EVI: Drop all Xserver code blocks that relate to removed EVI extension. -2016-04-19 11:34:20 +0200 Mike Gabriel (25ffbbb) +2016-04-19 11:34:20 +0200 Mike Gabriel (25ffbbb22) * FONTCACHE: Drop all Xserver code blocks that relate to removed FONTCACHE extension. -2016-04-19 11:02:14 +0200 Mike Gabriel (3aedac1) +2016-04-19 11:02:14 +0200 Mike Gabriel (3aedac174) * XEVIE: Drop all Xserver code blocks that relate to removed XEVIE extension. -2016-04-19 11:31:48 +0200 Mike Gabriel (cd39f13) +2016-04-19 11:31:48 +0200 Mike Gabriel (cd39f1393) * XFree86DGA: Drop all Xserver code blocks that relate to removed XFree86DGA extension. -2016-04-19 11:07:49 +0200 Mike Gabriel (a25c0de) +2016-04-19 11:07:49 +0200 Mike Gabriel (a25c0de09) * TOGCUP: Drop all Xserver code blocks that relate to removed TOGCUP extension. -2016-04-19 11:05:41 +0200 Mike Gabriel (683415d) +2016-04-19 11:05:41 +0200 Mike Gabriel (683415dfe) * XAPPGROUP: Drop all Xserver code blocks that relate to removed XAPPGROUP extension. -2016-03-01 20:55:27 +0000 Mike Gabriel (9bc6ff2) +2016-03-01 20:55:27 +0000 Mike Gabriel (9bc6ff269) * Drop X11 extensions not shipped with recent X.Org server versions anymore: -2016-05-31 12:44:02 +0200 Nito Martinez (c646808) +2016-05-31 12:44:02 +0200 Nito Martinez (c646808bc) * Fix debugging function for Loop.cpp. getDebugSpec was replaced by << operand in ChannelEndPoint.{h|cpp}, fixes #130 -2016-05-31 12:12:39 +0200 Mike Gabriel (e3051f7) +2016-05-31 12:12:39 +0200 Mike Gabriel (e3051f7a7) * Merge branch 'nitomartinez-3.6.x' into 3.6.x (origin/3713346f) -2016-05-30 16:10:32 +0000 Mihai Moldovan (36c3613) +2016-05-30 16:10:32 +0000 Mihai Moldovan (36c3613a7) * nx-X11/programs/Xserver/{hw/nxagent/NX,render/}picture.c: add and use new function ReduceCompositeOp(). -2016-04-09 19:41:48 +0000 Mihai Moldovan (62aac69) +2016-04-09 19:41:48 +0000 Mihai Moldovan (62aac6950) * nx-X11/programs/Xserver/composite/Imakefile: add new file to SRCS and OBJS and define -DNXAGENT_SERVER while building the Composite extension to disable some code that depends upon a newer X.Org architecture. -2016-04-09 19:40:24 +0000 Mihai Moldovan (7d2dd2a) +2016-04-09 19:40:24 +0000 Mihai Moldovan (7d2dd2aac) * misc nx-X11/{programs/Xserver/composite,include/extensions}: update to Composite 0.4 - with changes where neccessary and rough edges. -2016-04-09 19:38:12 +0000 Mihai Moldovan (fe3fa5e) +2016-04-09 19:38:12 +0000 Mihai Moldovan (fe3fa5ef3) * nx-X11/programs/Xserver/{dix/{colormap.c,window.c},hw/nxagent/NXwindow.c,include/{colormap,window{,str}}.h}: backport features needed for Composite 0.4. -2016-05-31 12:09:23 +0200 Mike Gabriel (4a9c1b9) +2016-05-31 12:09:23 +0200 Mike Gabriel (4a9c1b946) * Merge branch 'Ionic-feature/composite-update' into 3.6.x -2016-05-31 11:23:40 +0200 Nito Martinez (035995a) +2016-05-31 11:23:40 +0200 Nito Martinez (035995a8c) * display version number in nxcomp log, fixes #127 -2016-05-30 16:10:32 +0000 Mihai Moldovan (cad9f4e) +2016-05-30 16:10:32 +0000 Mihai Moldovan (cad9f4ef8) * nx-X11/programs/Xserver/{hw/nxagent/NX,render/}picture.c: add and use new function ReduceCompositeOp(). -2016-04-09 19:41:48 +0000 Mihai Moldovan (dd9eb3a) +2016-04-09 19:41:48 +0000 Mihai Moldovan (dd9eb3adf) * nx-X11/programs/Xserver/composite/Imakefile: add new file to SRCS and OBJS and define -DNXAGENT_SERVER while building the Composite extension to disable some code that depends upon a newer X.Org architecture. -2016-04-09 19:40:24 +0000 Mihai Moldovan (be824bc) +2016-04-09 19:40:24 +0000 Mihai Moldovan (be824bc8d) * misc nx-X11/{programs/Xserver/composite,include/extensions}: update to Composite 0.4 - with changes where neccessary and rough edges. -2016-04-09 19:38:12 +0000 Mihai Moldovan (f7cff02) +2016-04-09 19:38:12 +0000 Mihai Moldovan (f7cff021e) * nx-X11/programs/Xserver/{dix/{colormap.c,window.c},hw/nxagent/NXwindow.c,include/{colormap,window{,str}}.h}: backport features needed for Composite 0.4. -2016-05-13 06:19:21 +0200 Mihai Moldovan (aba2a53) +2016-05-13 06:19:21 +0200 Mihai Moldovan (aba2a534f) * Merge branch 'sunweaver-pr/nxagent-no-compiler-warnings' into arctica-3.6.x -2016-05-03 19:42:46 +0200 Mike Gabriel (52dc496) +2016-05-03 19:42:46 +0200 Mike Gabriel (52dc49607) * hw/nxagent/Display.c: Avoid incompatible pointer type. (gh-sunweaver/pr/nxagent-no-compiler-warnings) -2016-05-03 19:28:48 +0200 Mike Gabriel (a0e5589) +2016-05-03 19:28:48 +0200 Mike Gabriel (a0e5589ed) * hw/nxagent/Display.c: Define Pixmap from XlibPixmap before including Icons.h (which includes hw/nxagent/X11/include/xpm_nxagent.h). -2016-05-03 17:49:54 +0200 Mike Gabriel (e79fe3b) +2016-05-03 17:49:54 +0200 Mike Gabriel (e79fe3b9a) * hw/nxagent/Holder.c: Define Pixmap from XlibPixmap before including hw/nxagent/X11/include/xpm_nxagent.h. -2016-04-19 10:43:40 +0200 Mihai Moldovan (b91135b) +2016-04-19 10:43:40 +0200 Mihai Moldovan (b91135b0c) * hw/nxagent/Events.c: Avoid '#endif #ifdef DEBUG' blocks. -2016-03-22 01:11:55 +0100 Mike Gabriel (c2de5f1) +2016-03-22 01:11:55 +0100 Mike Gabriel (c2de5f198) * hw/nxagent/NXmiexpose.c: Initialize all items of the newValues[] array. -2016-03-21 22:49:25 +0100 Mike Gabriel (0210232) +2016-03-21 22:49:25 +0100 Mike Gabriel (021023202) * hw/nxagent/Keystroke.c: Fix warning: pointer type mismatch in conditional expression. -2016-03-21 22:37:38 +0100 Mike Gabriel (0005979) +2016-03-21 22:37:38 +0100 Mike Gabriel (00059798d) * hw/nxagent/Window.c: Initialize tmp_mask and attributes.event_mask with NoEventMask. -2016-03-21 22:22:07 +0100 Mike Gabriel (7251ef4) +2016-03-21 22:22:07 +0100 Mike Gabriel (7251ef492) * hw/nxagent/Colormap.c: Don't declare and assign flexibility variable if not used later on. -2016-03-21 16:36:38 +0100 Mike Gabriel (634484b) +2016-03-21 16:36:38 +0100 Mike Gabriel (634484bb3) * hw/nxagent/GCOps.c: Don't declare and assign oldDstxyValue if not used later on. -2016-03-21 16:36:15 +0100 Mike Gabriel (e8042c9) +2016-03-21 16:36:15 +0100 Mike Gabriel (e8042c9ff) * hw/nxagent/GC.c: Don't declare and assign flexibility variable if not used later on. -2016-03-21 16:32:41 +0100 Mike Gabriel (7876d1f) +2016-03-21 16:32:41 +0100 Mike Gabriel (7876d1f28) * hw/nxagent/Events.c: Only declare and assign message_data and box variables if compiled with -DTEST / -DDEBUG (plus drop commented out code). -2016-03-21 16:31:49 +0100 Mike Gabriel (30cd3a6) +2016-03-21 16:31:49 +0100 Mike Gabriel (30cd3a6c2) * hw/nxagent/Display.c: Don't declare and assign packMethod / packQuality if not used later on. -2016-03-21 16:14:00 +0100 Mike Gabriel (ab196f3) +2016-03-21 16:14:00 +0100 Mike Gabriel (ab196f3a1) * hw/nxagent/NXrender.c: Don't declare and assign the colors variable, if not used later on. -2016-03-21 16:11:46 +0100 Mike Gabriel (ce8fb1f) +2016-03-21 16:11:46 +0100 Mike Gabriel (ce8fb1f93) * HAVE_STDINT_H: Always include . -2016-05-02 15:38:30 +0200 Mike Gabriel (e3e4516) +2016-05-02 15:38:30 +0200 Mike Gabriel (e3e451629) * hw/nxagent/NXdixfonts.c: Fix implicit declaration for register_fpe_functions(). -2016-03-21 15:54:24 +0100 Mike Gabriel (fb832b0) +2016-03-21 15:54:24 +0100 Mike Gabriel (fb832b01e) * Adapt API for MakeAtom() and CopyISOLatin1Lowered to latest changes in X.org. -2016-03-21 14:18:42 +0100 Mike Gabriel (5e6b72d) +2016-03-21 14:18:42 +0100 Mike Gabriel (5e6b72dc7) * hw/nxagent/NXdixfonts.c: Don't include . No symbol needed from that header file. -2016-03-21 11:55:31 +0100 Mike Gabriel (23d3821) +2016-03-21 11:55:31 +0100 Mike Gabriel (23d3821f0) * hw/nxagent/NXpicture.c: Don't declare anything in empty function nxagentReconnectPictFormat. -2016-03-21 11:54:55 +0100 Mike Gabriel (292d88d) +2016-03-21 11:54:55 +0100 Mike Gabriel (292d88d07) * hw/nxagent/NXglyphcurs.c: Don't declare and set gcval, if not being used later on. -2016-03-21 09:48:11 +0100 Mike Gabriel (182569b) +2016-03-21 09:48:11 +0100 Mike Gabriel (182569bf6) * hw/nxagent/Keyboard.c: The ret variable is only used later on when compiled with -DTEST. -2016-03-21 09:47:29 +0100 Mike Gabriel (66f8895) +2016-03-21 09:47:29 +0100 Mike Gabriel (66f889542) * hw/nxagent/Handlers.c: Don't declare and assign result variable if not used later on. -2016-03-21 09:43:02 +0100 Mike Gabriel (fc39317) +2016-03-21 09:43:02 +0100 Mike Gabriel (fc393174c) * hw/nxagent/Keyboard.c: Don't declare and set XkbDescPtr xkb if not used later on. -2016-03-21 09:41:16 +0100 Mike Gabriel (eb68218) +2016-03-21 09:41:16 +0100 Mike Gabriel (eb682184c) * hw/nxagent/*.c: Drop various declarations of unused ScreenPtr pScreen. -2016-03-18 16:46:34 +0100 Mike Gabriel (b5b7a2d) +2016-03-18 16:46:34 +0100 Mike Gabriel (b5b7a2d26) * hw/nxagent/Screen.c: Cast proper types before handing values over to fprintf(). -2016-03-18 16:45:59 +0100 Mike Gabriel (ab50f84) +2016-03-18 16:45:59 +0100 Mike Gabriel (ab50f84b5) * hw/nxagent/Screen.c: Drop various unused variables. -2016-03-18 16:35:43 +0100 Mike Gabriel (ef287b5) +2016-03-18 16:35:43 +0100 Mike Gabriel (ef287b54f) * hw/nxagent/Screen.h: Provide prototype for nxagentAdjustRandRXinerama(). Avoid implicit-declaration compiler warning. -2016-03-18 16:34:43 +0100 Mike Gabriel (72386e1) +2016-03-18 16:34:43 +0100 Mike Gabriel (72386e171) * hw/nxagent/Screen.c: Correctly use already defined MIN/MAX macros. -2016-03-18 16:27:09 +0100 Mike Gabriel (7d3d47f) +2016-03-18 16:27:09 +0100 Mike Gabriel (7d3d47f1f) * hw/nxagent/Window.c: Don't declare "XWindowChanges changes;" and later not use it. -2016-03-18 16:17:30 +0100 Mike Gabriel (5ea2457) +2016-03-18 16:17:30 +0100 Mike Gabriel (5ea2457ef) * hw/nxagent/Pixmap.c: pBool pointer is only required when compiled in -DTEST mode. -2016-03-18 16:15:29 +0100 Mike Gabriel (08d3848) +2016-03-18 16:15:29 +0100 Mike Gabriel (08d384841) * hw/nxagent/Extension.c: Don't declare pRandRScrPriv without using it later on. -2016-03-18 16:08:45 +0100 Mike Gabriel (802f581) +2016-03-18 16:08:45 +0100 Mike Gabriel (802f58163) * hw/nxagent/Rootless.c: Type cast type Atom to type long unsigned int before handing it over to %lu in fprintf(). -2016-03-18 16:06:59 +0100 Mike Gabriel (c206a0c) +2016-03-18 16:06:59 +0100 Mike Gabriel (c206a0c69) * hw/nxagent/Splash.c: Drop unused variable declaration "XPoint m[12];". -2016-03-18 16:05:01 +0100 Mike Gabriel (5bbdbfc) +2016-03-18 16:05:01 +0100 Mike Gabriel (5bbdbfce2) * hw/nxagent/Clipboard.c: The result variable is only needed when combiled with -DDEBUG. -2016-03-18 15:59:58 +0100 Mike Gabriel (f3f0a6b) +2016-03-18 15:59:58 +0100 Mike Gabriel (f3f0a6b4b) * hw/nxagent/Drawable.c: RegionNumRects returns int, not long int anymore. -2016-03-18 13:06:30 +0100 Mike Gabriel (1202046) +2016-03-18 13:06:30 +0100 Mike Gabriel (120204631) * Add REGION_ macros for source compatibility with existing drivers. -2016-03-18 13:05:05 +0100 Mike Gabriel (b0e69fe) +2016-03-18 13:05:05 +0100 Mike Gabriel (b0e69fe35) * Change region implementation names to eliminate the 'mi' prefix -2016-03-18 04:49:09 +0100 Keith Packard (2881365) +2016-03-18 04:49:09 +0100 Keith Packard (288136514) * Move mi/miregion.c to dix/region.c -2016-03-18 05:13:43 +0100 Mike Gabriel (d9e7f6a) +2016-03-18 05:13:43 +0100 Mike Gabriel (d9e7f6ae4) * pixman-devel: Build against shared library pkg-config(pixman-1). -2016-03-18 05:11:40 +0100 Mike Gabriel (4a8d6ec) +2016-03-18 05:11:40 +0100 Mike Gabriel (4a8d6eca3) * Change region implementation from macros to inline functions. -2016-03-16 11:11:43 +0100 Mike Gabriel (63f1fff) +2016-03-16 11:11:43 +0100 Mike Gabriel (63f1fff8f) * Rename region macros to eliminate screen argument -2016-03-04 16:12:12 +0100 Mike Gabriel (28ba877) +2016-03-04 16:12:12 +0100 Mike Gabriel (28ba87780) * gcc: Build using -std=c99 instead of -ansi. -2016-03-16 11:08:49 +0100 Mike Gabriel (101c895) +2016-03-16 11:08:49 +0100 Mike Gabriel (101c895e6) * fix-patch-whitepspace: Copy script from X.Org's xserver Git repo. -2016-03-16 08:05:01 +0100 Mike Gabriel (eaa19eb) +2016-03-16 08:05:01 +0100 Mike Gabriel (eaa19eb55) * NXwindow.c: Don't set w and h, not used later on. -2016-03-22 14:23:12 +0100 Mike Gabriel (6c6b6b9) +2016-03-22 14:23:12 +0100 Mike Gabriel (6c6b6b962) * lib/Imakefile: Drop $(XINERAMADIR) from nx-X11/lib/Imakefile. (gh-sunweaver/3.6.x) -2016-04-27 14:00:57 +0200 Mike Gabriel (2137ee7) +2016-04-27 14:00:57 +0200 Mike Gabriel (2137ee7e2) * Merge branch 'sunweaver-pr/nxcomp-unix-sockets-for-channels' into 3.6.x -2016-04-20 16:22:56 +0200 Salvador Fandino (3713346) +2016-04-20 16:22:56 +0200 Salvador Fandino (3713346f3) * Provide support for channel endpoints being UNIX file sockets in addition to being TCP/IP sockets. (gh-sunweaver/pr/nxcomp-unix-sockets-for-channels) -2016-04-27 13:56:55 +0200 Mike Gabriel (b326eda) +2016-04-27 13:56:55 +0200 Mike Gabriel (b326eda73) * nxcomp: Rephrase comment in previous commit. -2016-04-27 13:54:56 +0200 Mike Gabriel (416fc18) +2016-04-27 13:54:56 +0200 Mike Gabriel (416fc186b) * Merge branch 'fcarvajaldev-3.6.x-nxcomp-amend-compiler-warnings' into 3.6.x -2016-04-25 12:53:00 +0200 Fernando Carvajal (a436cba) +2016-04-25 12:53:00 +0200 Fernando Carvajal (a436cba04) * Clean up compiler warnings in nxcomp -2016-04-26 22:35:00 +0200 Mihai Moldovan (12104a2) +2016-04-26 22:35:00 +0200 Mihai Moldovan (12104a232) * Merge branch 'sunweaver-pr/libxrender-cleanup' into arctica-3.6.x -2015-06-25 05:37:03 +0200 Mike Gabriel (ebcb6a6) +2015-06-25 05:37:03 +0200 Mike Gabriel (ebcb6a6e1) * library-cleanup: Don't build libNX_Xrender anymore. Use system's libXrender shared library. (gh-sunweaver/pr/libxrender-cleanup) -2016-04-20 16:16:40 +0200 Mike Gabriel (5729783) +2016-04-20 16:16:40 +0200 Mike Gabriel (5729783db) * Merge branch 'theqvd-fix-for-112' into 3.6.x -2016-04-20 15:46:16 +0200 Salvador Fandino (7d05395) +2016-04-20 15:46:16 +0200 Salvador Fandino (7d053959f) * Fix copyright notice in nxcomp/Version.c -2016-04-19 10:47:43 +0200 Mike Gabriel (03b6521) +2016-04-19 10:47:43 +0200 Mike Gabriel (03b652112) * Merge branch 'fcarvajaldev-3.6.x-remove-old-proto-compat' into 3.6.x -2016-04-15 09:49:09 +0200 Fernando Carvajal (5c49524) +2016-04-15 09:49:09 +0200 Fernando Carvajal (5c4952410) * Remove TextCompressor class and files from nxcomp -2016-04-14 17:10:07 +0200 Fernando Carvajal (00464ae) +2016-04-14 17:10:07 +0200 Fernando Carvajal (00464aea0) * Add testing doc for nxcomp drop-old-proto-compat -2016-04-12 16:03:37 +0200 Fernando Carvajal (1346481) +2016-04-12 16:03:37 +0200 Fernando Carvajal (134648169) * Remove obsolete compatibility files from nxcomp -2016-04-12 11:52:22 +0200 Fernando Carvajal (a9be6f5) +2016-04-12 11:52:22 +0200 Fernando Carvajal (a9be6f591) * Remove compatibility code for nxcomp before 3.5.0 -2016-03-22 20:03:42 +0100 Mike Gabriel (2ffe52c) +2016-03-22 20:03:42 +0100 Mike Gabriel (2ffe52c5e) * nxcomp: Properly define NX*Version(void) prototypes in NX.h. -2016-03-17 16:46:13 +0100 Mike Gabriel (af923fb) +2016-03-17 16:46:13 +0100 Mike Gabriel (af923fba3) * debian/patches/401_nxcomp_bigrequests-and-genericevent-extensions.full+lite.patch: Move into debian/patches-pending-evaluation/. -2016-03-15 10:49:25 +0100 Mike Gabriel (1568148) +2016-03-15 10:49:25 +0100 Mike Gabriel (156814860) * doc: Collect data on what libX11 symbols are used by nx-X11, nx-Xserver and nxagent. -2016-03-02 09:33:13 +0100 Nito Martinez (b8c5f67) +2016-03-02 09:33:13 +0100 Nito Martinez (b8c5f677c) * Rename file for windows environments, Fixes #96 -2016-02-26 08:14:28 +0100 Mike Gabriel (abd6cf1) +2016-02-26 08:14:28 +0100 Mike Gabriel (abd6cf1bd) * rename original NX patches, so that we can see the patched file's name in the patch file name. -2016-01-19 05:59:51 +0100 Mike Gabriel (2eb85d1) +2016-01-19 05:59:51 +0100 Mike Gabriel (2eb85d140) * README.md: Update open / completed tasks regarding 3.6.x and 3.7.x releases. -2016-01-19 04:55:01 +0100 Mike Gabriel (e3539ec) +2016-01-19 04:55:01 +0100 Mike Gabriel (e3539ec58) * README.md: Update release dates for 3.6.x and 3.7.x (as earlier discussed with Salve from TheQVD). -2016-01-19 04:50:57 +0100 Mike Gabriel (125f031) +2016-01-19 04:50:57 +0100 Mike Gabriel (125f03110) * Merge branch 'mikedep333-README.md' into 3.6.x -2016-01-18 22:37:46 -0500 Mike DePaulo (0239ba7) +2016-01-18 22:37:46 -0500 Mike DePaulo (0239ba72b) * README.md: Add debuild instructions -2016-01-18 21:49:03 -0500 Mike DePaulo (474e9c0) +2016-01-18 21:49:03 -0500 Mike DePaulo (474e9c0ba) * README.md: Update signature -2016-01-09 22:26:34 +0100 Mike Gabriel (72801f6) +2016-01-09 22:26:34 +0100 Mike Gabriel (72801f6d5) * Merge pull request #68 from mikedep333/mock-build-instructions -2016-01-02 07:30:02 +0100 Mike Gabriel (e794be3) +2016-01-02 07:30:02 +0100 Mike Gabriel (e794be341) * debian/nx-x11proto-xinerama-dev.install.in: Install PANORAMIX extension header files into its own nx-x11proto bin:package. (more Xinerama clean-up, fix FTBFS during dh_install). -2016-01-01 12:27:14 -0500 Mike DePaulo (b7657cf) +2016-01-01 12:27:14 -0500 Mike DePaulo (b7657cfba) * nx-libs.spec: FTBFS Fixes (more libNX_Xinerama cleanup) -2016-01-01 12:01:43 -0500 Mike DePaulo (0428db4) +2016-01-01 12:01:43 -0500 Mike DePaulo (0428db4db) * nx-libs.spec: Misc FTBFS fixes for %files due to recent library changes -2016-01-01 11:32:25 -0500 Mike DePaulo (7f5480d) +2016-01-01 11:32:25 -0500 Mike DePaulo (7f5480dd7) * Fedora/EPEL: Add the implicit build dependencies also -2016-01-01 11:21:47 -0500 Mike DePaulo (1330c41) +2016-01-01 11:21:47 -0500 Mike DePaulo (1330c4125) * Fedora/EPEL: Fix FTBFS due to missing libXpm -2016-01-01 16:26:50 +0100 Mike Gabriel (3ba3165) +2016-01-01 16:26:50 +0100 Mike Gabriel (3ba31659e) * Fix c4a3889. Add forgotten file nx-X11/programs/Xserver/Xinerama_nxagent.h. -2016-01-01 16:08:05 +0100 Mike Gabriel (12b4a0e) +2016-01-01 16:08:05 +0100 Mike Gabriel (12b4a0e7a) * nx-libs.spec: Re-add erroneously removed (during rebasing) BR libXdamage-devel. -2016-01-01 09:52:26 -0500 Mike DePaulo (daace15) +2016-01-01 09:52:26 -0500 Mike DePaulo (daace15e2) * Add instructions for building using Mock under Fedora/EPEL -2015-12-30 19:25:08 +0100 Mike Gabriel (fa497ac) +2015-12-30 19:25:08 +0100 Mike Gabriel (fa497ac95) * nxcomp: Make nxcomp/nxproxy aware of nxagent's xinerama option in the $DISPLAY variable. -2015-05-23 09:28:57 -0400 Mike DePaulo (6da41e6) +2015-05-23 09:28:57 -0400 Mike DePaulo (6da41e6f6) * Complete changes from commit 0d56c45 in NXpicturestr.h (i.e. add a missing comment). (Fixes ArcticaProject/nx-libs#38). -2015-12-30 00:06:58 +0100 Mike Gabriel (1391c0a) +2015-12-30 00:06:58 +0100 Mike Gabriel (1391c0ad7) * Merge branch 'sunweaver-pr/xinerama-xrandr' into 3.6.x -2015-10-08 22:25:09 +0200 Ulrich Sibiller (c4a3889) +2015-10-08 22:25:09 +0200 Ulrich Sibiller (c4a388937) * Xinerama: do not cut off at outer edges (gh-sunweaver/pr/xinerama-xrandr) -2015-10-07 20:45:14 +0200 Mike Gabriel (4ba8df8) +2015-10-07 20:45:14 +0200 Mike Gabriel (4ba8df855) * Xserver globals.h: Make PanoramiXExtensionDisabledHack globally available. -2015-10-07 20:44:19 +0200 Mike Gabriel (d49b062) +2015-10-07 20:44:19 +0200 Mike Gabriel (d49b0625e) * Xserver help: Document -disablexineramaextension cmdline option. -2015-10-07 21:33:55 +0200 Mike Gabriel (522cf00) +2015-10-07 21:33:55 +0200 Mike Gabriel (522cf0089) * X2Go Agent: Add x2goagent.features file that informs X2Go clients about the new RandR based Xinerama feature. -2015-10-07 20:51:12 +0200 Mike Gabriel (0297567) +2015-10-07 20:51:12 +0200 Mike Gabriel (0297567cd) * Provide support for re-enabling Xinerama on session resumptions. -2015-10-07 17:24:01 +0200 Mike Gabriel (f40792c) +2015-10-07 17:24:01 +0200 Mike Gabriel (f40792c43) * Initialize XRandR based Xinerama extension properly when session is started with "-geometry fullscreen". -2015-10-07 17:23:13 +0200 Mike Gabriel (e7e2f16) +2015-10-07 17:23:13 +0200 Mike Gabriel (e7e2f164b) * Only declare nxagentRandRCrtcSet if RANDR_12_INTERFACE is defined. -2015-10-07 15:17:59 +0200 Mike Gabriel (f1eafea) +2015-10-07 15:17:59 +0200 Mike Gabriel (f1eafeaa4) * Screen.c: Rename NX_USE_MODE_PREFIX to NXAGENT_RANDR_MODE_PREFIX, fix unclosed comment. -2015-10-06 22:53:16 +0200 Ulrich Sibiller (9b87a38) +2015-10-06 22:53:16 +0200 Ulrich Sibiller (9b87a384e) * Screen.c: restructure xinerama code, much shorter now -2015-10-06 22:32:12 +0200 Ulrich Sibiller (359f48d) +2015-10-06 22:32:12 +0200 Ulrich Sibiller (359f48dd7) * Screen.c: Fix freeing of unsued modes -2015-10-06 22:30:39 +0200 Ulrich Sibiller (76a2034) +2015-10-06 22:30:39 +0200 Ulrich Sibiller (76a203410) * Screen.c: improve comments and DEBUG output -2015-10-06 22:27:10 +0200 Ulrich Sibiller (8b0e2af) +2015-10-06 22:27:10 +0200 Ulrich Sibiller (8b0e2af36) * rrmode.c: add debug output -2015-05-02 21:53:25 +0200 Ulrich Sibiller (c6482d2) +2015-05-02 21:53:25 +0200 Ulrich Sibiller (c6482d24f) * Reimplement xinerama via randr in nxagent (not libNX_Xinerama). (Fixes ArcticaProject/nx-libs#23). -2015-05-05 10:24:24 +0200 Mike Gabriel (2d776b1) +2015-05-05 10:24:24 +0200 Mike Gabriel (2d776b14f) * library clean-up: Don't build libNX_Xinerama anymore. Use system's libXinerama shared library. (Fixes ArcticaProject/nx-libs#49). -2015-12-29 22:34:04 +0100 Mike Gabriel (e4763fb) +2015-12-29 22:34:04 +0100 Mike Gabriel (e4763fb48) * debian/rules: Don't strips symbols from not-build-anymore libNX_Xtst.so. -2015-06-21 18:12:11 +0200 Mike Gabriel (bd592c2) +2015-06-21 18:12:11 +0200 Mike Gabriel (bd592c2e7) * library clean-up: Don't build libNX_Xtst anymore. Use system's libXtst shared library. (Fixes ArcticaProject/nx-libs#32). -2015-12-29 17:34:36 +0100 Mike Gabriel (b768e81) +2015-12-29 17:34:36 +0100 Mike Gabriel (b768e8124) * Fix for too overall Xdamage and Xrandr client lib removal: Bring back the nx-x11proto-{randr,damage} header files and use those at compile time. -2015-12-29 17:27:47 +0100 Mike Gabriel (9618380) +2015-12-29 17:27:47 +0100 Mike Gabriel (9618380bd) * X11/nx-X11 clear-up: More places where we need to explicitly distinguish between X11 and nx-X11 namespace regarding header include paths. -2015-12-29 17:28:54 +0100 Mike Gabriel (eafc94f) +2015-12-29 17:28:54 +0100 Mike Gabriel (eafc94f16) * nx-X11/lib/X11/Marcos.c: white-space cleanup (EOL blanks). -2015-12-28 22:32:52 +0100 Mike Gabriel (b7f1556) +2015-12-28 22:32:52 +0100 Mike Gabriel (b7f155654) * pointer typedef in Xdefs.h: also catch Xdefs.h include in include/misc.h, make undoing the FIXME more obvious. -2015-12-28 21:33:30 +0100 Mike Gabriel (7eab400) +2015-12-28 21:33:30 +0100 Mike Gabriel (7eab400ab) * libray clean (Xfixes): Provide a fake libXfixes.h header from latest X.Org, that includes headers from our Xlib version. This avoids FTBFS caused by type redefinitions and should really be a temporary measure. -2015-12-28 21:31:58 +0100 Mike Gabriel (f63641b) +2015-12-28 21:31:58 +0100 Mike Gabriel (f63641b13) * Xrandr_nxagent.h: When faking Xrandr.h, we better include our own Xfuncproto.h. -2015-12-28 20:47:49 +0100 Mike Gabriel (cc43e2b) +2015-12-28 20:47:49 +0100 Mike Gabriel (cc43e2bf6) * nxcompshad/X11/include/Xdamage_nxcompshad.h: Update FIXME statement. Work-around needs to persist until libX11 from X.Org gets used by nxagent. -2015-12-28 19:09:42 +0100 Mike Gabriel (6217812) +2015-12-28 19:09:42 +0100 Mike Gabriel (6217812c8) * library clean-up: Don't build libNX_Xfixes anymore. Use system's libXfixes shared library. -2015-12-28 19:55:38 +0100 Mike Gabriel (27e06a5) +2015-12-28 19:55:38 +0100 Mike Gabriel (27e06a5e2) * library clean-up: Don't build libNX_Xcomposite anymore. Use system's libXcomposite shared library. -2015-12-28 15:53:09 +0100 Mike Gabriel (96e1f86) +2015-12-28 15:53:09 +0100 Mike Gabriel (96e1f867d) * pointer typedef in Xdefs.h: Define pointer type for building against older Xlib versions that still expect the pointer type to exist (e.g. Ubuntu <= 14.04, Debian <= 7.0). -2015-12-28 13:17:21 +0100 Mike Gabriel (ca0f639) +2015-12-28 13:17:21 +0100 Mike Gabriel (ca0f639a4) * Merge branch 'sunweaver-pr/NX-include-path' into 3.6.x -2015-07-08 16:16:40 +0200 Mike Gabriel (433d818) +2015-07-08 16:16:40 +0200 Mike Gabriel (433d81865) * Clear header file namespace separation ( vs. ). -2015-12-28 13:08:47 +0100 Mike Gabriel (f58006d) +2015-12-28 13:08:47 +0100 Mike Gabriel (f58006d93) * Merge branch 'sunweaver-pr/dixfont-fix' into 3.6.x -2015-06-23 15:04:16 +0200 Mike Gabriel (aea7106) +2015-06-23 15:04:16 +0200 Mike Gabriel (aea71067d) * On realloc failure, free font_path_string instead of leaking it -2015-12-28 13:03:52 +0100 Mike Gabriel (edce252) +2015-12-28 13:03:52 +0100 Mike Gabriel (edce25213) * Merge branch 'sunweaver-pr/change-pointer-into-void' into 3.6.x -2015-06-22 09:36:08 +0200 Keith Packard (68dd0b5) +2015-06-22 09:36:08 +0200 Keith Packard (68dd0b52e) * Replace 'pointer' type with 'void *' -2015-10-07 17:28:27 +0200 Mike Gabriel (e9f4422) +2015-10-07 17:28:27 +0200 Mike Gabriel (e9f44221b) * Drop all references to printver.c. Not provided in source tree anymore. -2015-10-06 17:12:16 +0200 Mike Gabriel (e0b8f3e) +2015-10-06 17:12:16 +0200 Mike Gabriel (e0b8f3eef) * Re-add -sync option back to nxagent to allow synchronous debugging of the nxagent DDX. -2015-09-28 09:57:12 +0200 Mike Gabriel (81d92cd) +2015-09-28 09:57:12 +0200 Mike Gabriel (81d92cd0f) * Xinerama symlinking: Create / remove folder containing Xinerama sylinks on installation/upgrade and removal. -2015-09-28 08:15:52 +0200 Mike Gabriel (45983d1) +2015-09-28 08:15:52 +0200 Mike Gabriel (45983d130) * Xinerama symlinking: Attach Xinerama symlinking to nxagent bin:package (and not libnx-xinerama1). -2015-09-28 08:10:59 +0200 Mike Gabriel (0382b40) +2015-09-28 08:10:59 +0200 Mike Gabriel (0382b4018) * debian/changelog: Drop unnecessary "~build1" from version string -2015-09-28 07:59:12 +0200 Mike Gabriel (ca990cf) +2015-09-28 07:59:12 +0200 Mike Gabriel (ca990cf0a) * Merge pull request #64 from uli42/pr/add_pkgconfig -2015-09-28 07:53:57 +0200 Mike Gabriel (f9653af) +2015-09-28 07:53:57 +0200 Mike Gabriel (f9653af3b) * Merge branch 'uli42-pr/backported_fixes' into 3.6.x -2015-09-23 12:15:06 +0200 Mike Gabriel (3a022e3) +2015-09-23 12:15:06 +0200 Mike Gabriel (3a022e35c) * debian/libnx-xinerama1.postinst.in: Enforce symlink creation for Xinerama support. -2015-09-22 15:02:22 +0200 Mike Gabriel (899f865) +2015-09-22 15:02:22 +0200 Mike Gabriel (899f865cf) * Revert "debian/libnx-xinerama1.*: fix faulty logic when creating symlinks." -2015-07-17 18:13:00 +0200 Mihai Moldovan (9b126b8) +2015-07-17 18:13:00 +0200 Mihai Moldovan (9b126b852) * nx-libs.spec: add xkeyboard-config to nxagent's Requires. -2015-07-17 17:57:24 +0200 Mihai Moldovan (3a1226e) +2015-07-17 17:57:24 +0200 Mihai Moldovan (3a1226ea6) * debian/control: add xkb-data to nxagent's Recommends. -2015-07-17 17:48:44 +0200 Mihai Moldovan (2aa8535) +2015-07-17 17:48:44 +0200 Mihai Moldovan (2aa853530) * debian/roll-tarballs.sh: more quotes, more curly braces, replace cd with pushd and pop. -2015-07-15 09:30:29 +0200 Mike Gabriel (c36501b) +2015-07-15 09:30:29 +0200 Mike Gabriel (c36501b53) * roll-tarball.sh: more quotes (follow-up for previous commit), drop debug code -2015-07-14 20:39:58 +0200 Mike Gabriel (99a7271) +2015-07-14 20:39:58 +0200 Mike Gabriel (99a7271e3) * roll-tarball.sh: Make sure symlinked files are included in tarballs. -2015-07-14 15:14:55 +0200 Mike Gabriel (0897c06) +2015-07-14 15:14:55 +0200 Mike Gabriel (0897c062e) * nx-libs.spec: Install nxcomp{,ext,shad}.pc into the corresponding development packages. -2015-07-14 14:46:42 +0200 Mike Gabriel (2cc1792) +2015-07-14 14:46:42 +0200 Mike Gabriel (2cc179223) * debian/libxcomp{,ext,shad}-dev.install.in: Install nxcomp{,ext,shad}.pc file into the corresponding development packages. -2015-07-14 14:43:34 +0200 Mike Gabriel (eb5f07c) +2015-07-14 14:43:34 +0200 Mike Gabriel (eb5f07ccd) * nxcomp{,ext,shad}/Makefile.in: Create pkgconfigdir before putting files in it. -2015-07-14 01:39:17 +0200 Mike Gabriel (bc35168) +2015-07-14 01:39:17 +0200 Mike Gabriel (bc35168fb) * nxcomp{,shad,ext}: Remove nxcomp*.pc file on clean and distclean. -2015-07-14 01:26:33 +0200 Mike Gabriel (eee7cb4) +2015-07-14 01:26:33 +0200 Mike Gabriel (eee7cb4fb) * Makefile: Also remove nxversion.def on distclean. -2015-07-12 01:52:29 +0200 Ulrich Sibiller (708cf86) +2015-07-12 01:52:29 +0200 Ulrich Sibiller (708cf86a5) * Add pkg-config support to nxcomp, nxcompext and nxcompshad -2015-07-04 06:46:29 +0200 Mihai Moldovan (8c0a616) +2015-07-04 06:46:29 +0200 Mihai Moldovan (8c0a6161d) * debian/changelog: sync with master/3.5.0.x branch. -2015-06-29 03:40:58 +0200 Mihai Moldovan (34670f8) +2015-06-29 03:40:58 +0200 Mihai Moldovan (34670f8ab) * debian/changelog: sync with master/3.5.0.x branch. -2015-06-28 01:50:00 -0400 Mike DePaulo (a1dfd14) +2015-06-28 01:50:00 -0400 Mike DePaulo (a1dfd145d) * Correct nxproxy manpage also: --help -> -help -2015-06-28 01:33:49 -0400 Mike DePaulo (d8132cb) +2015-06-28 01:33:49 -0400 Mike DePaulo (d8132cbfe) * Correct manpages: --help -> -help -2015-06-23 16:24:56 +0200 Mike Gabriel (5720842) +2015-06-23 16:24:56 +0200 Mike Gabriel (5720842b6) * library clean-up: No autotools cruft in nx-libs. -2015-06-25 05:04:12 +0200 Mike Gabriel (8365e22) +2015-06-25 05:04:12 +0200 Mike Gabriel (8365e22bb) * doc/examples/run-nxproxy2nxproxy-test: Create NX_COOKIE dynamically using the mcookie tool. -2015-05-28 14:52:24 +0200 Mike Gabriel (7dc2633) +2015-05-28 14:52:24 +0200 Mike Gabriel (7dc263333) * COPYING: Replace content with GPL-2 license text, because that is the overall (i.e., strictest) license we have to deal with in nx-libs. -2015-05-28 14:50:05 +0200 Mike Gabriel (c68dad5) +2015-05-28 14:50:05 +0200 Mike Gabriel (c68dad542) * debian/roll-tarball.sh: Auto-generate ChangeLog from Git history. -2015-05-28 14:49:40 +0200 Mike Gabriel (ce53377) +2015-05-28 14:49:40 +0200 Mike Gabriel (ce5337799) * debian/roll-tarball.sh: Rename README.md to README.NX-Development before moving it into doc/ folder. -2015-05-28 14:33:08 +0200 Mike Gabriel (122fd23) +2015-05-28 14:33:08 +0200 Mike Gabriel (122fd234c) * debian/roll-tarball.sh: Prevent several files/folders from ending up in nx-libs-lite tarball. -2015-05-28 13:33:43 +0200 Mike Gabriel (2d50be9) +2015-05-28 13:33:43 +0200 Mike Gabriel (2d50be9da) * debian/roll-tarball.sh: Support tarring up the HEAD of the current branch. -2015-05-28 13:29:27 +0200 Mike Gabriel (51a679a) +2015-05-28 13:29:27 +0200 Mike Gabriel (51a679ac2) * debian/roll-tarball.sh: Allow patch files names having a dash next to the four digits (i.e., 1234-.). -2015-06-23 16:09:50 +0200 Emanuele Giaquinta (931d24c) +2015-06-23 16:09:50 +0200 Emanuele Giaquinta (931d24cc2) * Fix alpha premultiplication in XRenderParseColor. -2015-05-27 12:34:12 +0200 Mike Gabriel (6deaaf5) +2015-05-27 12:34:12 +0200 Mike Gabriel (6deaaf50f) * library clean-up: Drop libXx86{misc,vm,dga} libraries. Not needed by nx-libs. -2015-05-27 10:20:29 +0200 Mike Gabriel (fe0065c) +2015-05-27 10:20:29 +0200 Mike Gabriel (fe0065c55) * library clean-up: Drop nx-X11/lib/Xxf86rush and references to libglide{2,3}. Unused in nx-libs. -2015-05-27 09:48:26 +0200 Mike Gabriel (018c512) +2015-05-27 09:48:26 +0200 Mike Gabriel (018c51293) * nx-X11/config/cf: Drop build-logic for all hardware drivers. -2015-05-27 08:38:11 +0200 Mike Gabriel (17334df) +2015-05-27 08:38:11 +0200 Mike Gabriel (17334df9b) * nx-X11/config/cf: Drop unnecessary xf86site.def, xf86.tmpl, xfree86.cf. -2015-05-27 08:26:40 +0200 Mike Gabriel (8dd6d2f) +2015-05-27 08:26:40 +0200 Mike Gabriel (8dd6d2fe7) * nx-X11/config/cf/Imakefile: Don't list non-present-anymore imake configuration files. -2015-06-20 17:47:39 +0200 Mike Gabriel (32b4439) +2015-06-20 17:47:39 +0200 Mike Gabriel (32b44398a) * libgl clean-up, fix-up commit -2015-06-20 17:35:00 +0200 Mike DePaulo (d7108d2) +2015-06-20 17:35:00 +0200 Mike DePaulo (d7108d206) * README.md: typo fix -2015-06-20 11:34:04 +0200 Henning Heinold (2699d60) +2015-06-20 11:34:04 +0200 Henning Heinold (2699d60f6) * remove libxkbui, looks like it is not used anywhere -2015-06-19 23:58:49 +0200 Mike Gabriel (f1778d0) +2015-06-19 23:58:49 +0200 Mike Gabriel (f1778d0c2) * debian/control: Add Breaks:/Replaces: for qvd-libxcomp3 and qvd-nxproxy. -2015-05-27 08:10:38 +0200 Mike Gabriel (858b9bc) +2015-05-27 08:10:38 +0200 Mike Gabriel (858b9bc2a) * imake clean-up: Enforce build of Mesa GLX extension. Drop all other GLX build methods (built-in DRI drivers, etc.). -2015-05-26 16:44:49 +0200 Mike Gabriel (0887e3a) +2015-05-26 16:44:49 +0200 Mike Gabriel (0887e3ad5) * Drop unused / untested Xserver GLX extension support / build logic. -2015-05-26 16:22:40 +0200 Mike Gabriel (d877b46) +2015-05-26 16:22:40 +0200 Mike Gabriel (d877b46dd) * Drop nx-X11/lib/GL and move Imakefile.inc include files into Xserver code tree. -2015-06-16 22:43:21 +0200 Mihai Moldovan (8f41384) +2015-06-16 22:43:21 +0200 Mihai Moldovan (8f4138457) * nxcomp/Loop.cpp: tiny whitespace fix. No functional change. -2015-05-20 15:47:45 +0200 Vadim Troshchinskiy (8d9e8f7) +2015-05-20 15:47:45 +0200 Vadim Troshchinskiy (8d9e8f70b) * Fix negotiation in stage 10 error -2015-09-26 00:28:14 +0200 Ulrich Sibiller (1fe33b7) +2015-09-26 00:28:14 +0200 Ulrich Sibiller (1fe33b710) * use xfree instead of free for xalloced data -2015-09-23 12:15:06 +0200 Mike Gabriel (da6b89f) +2015-09-23 12:15:06 +0200 Mike Gabriel (da6b89f7e) * debian/libnx-xinerama1.postinst.in: Enforce symlink creation for Xinerama support. -2015-09-22 15:02:22 +0200 Mike Gabriel (4db753e) +2015-09-22 15:02:22 +0200 Mike Gabriel (4db753eb7) * Revert "debian/libnx-xinerama1.*: fix faulty logic when creating symlinks." -2015-08-26 01:06:28 +0200 Ulrich Sibiller (f8772b6) +2015-08-26 01:06:28 +0200 Ulrich Sibiller (f8772b6fc) * adapt pkgconfigdir in nxcompshad -2015-08-26 01:02:34 +0200 Ulrich Sibiller (96a1c5e) +2015-08-26 01:02:34 +0200 Ulrich Sibiller (96a1c5edf) * Fix "Makefile.in seems to ignore the --datarootdir setting" warning -2015-08-26 00:29:14 +0200 Ulrich Sibiller (6615de8) +2015-08-26 00:29:14 +0200 Ulrich Sibiller (6615de8dd) * create pkgcnfig dir before copying anything -2015-07-17 18:13:00 +0200 Mihai Moldovan (edeb4e1) +2015-07-17 18:13:00 +0200 Mihai Moldovan (edeb4e196) * nx-libs.spec: add xkeyboard-config to nxagent's Requires. -2015-07-17 17:57:24 +0200 Mihai Moldovan (813d0cf) +2015-07-17 17:57:24 +0200 Mihai Moldovan (813d0cf13) * debian/control: add xkb-data to nxagent's Recommends. -2015-07-17 17:48:44 +0200 Mihai Moldovan (0606ec8) +2015-07-17 17:48:44 +0200 Mihai Moldovan (0606ec814) * debian/roll-tarballs.sh: more quotes, more curly braces, replace cd with pushd and pop. -2015-07-15 09:30:29 +0200 Mike Gabriel (01ad7da) +2015-07-15 09:30:29 +0200 Mike Gabriel (01ad7dad4) * roll-tarball.sh: more quotes (follow-up for previous commit), drop debug code -2015-07-14 20:39:58 +0200 Mike Gabriel (c2761fb) +2015-07-14 20:39:58 +0200 Mike Gabriel (c2761fb7c) * roll-tarball.sh: Make sure symlinked files are included in tarballs. -2015-07-14 15:14:55 +0200 Mike Gabriel (c1d502e) +2015-07-14 15:14:55 +0200 Mike Gabriel (c1d502e1c) * nx-libs.spec: Install nxcomp{,ext,shad}.pc into the corresponding development packages. -2015-07-14 14:46:42 +0200 Mike Gabriel (931050c) +2015-07-14 14:46:42 +0200 Mike Gabriel (931050cbe) * debian/libxcomp{,ext,shad}-dev.install.in: Install nxcomp{,ext,shad}.pc file into the corresponding development packages. -2015-07-14 14:43:34 +0200 Mike Gabriel (ee0ed87) +2015-07-14 14:43:34 +0200 Mike Gabriel (ee0ed871a) * nxcomp{,ext,shad}/Makefile.in: Create pkgconfigdir before putting files in it. -2015-07-14 01:39:17 +0200 Mike Gabriel (39ae817) +2015-07-14 01:39:17 +0200 Mike Gabriel (39ae81788) * nxcomp{,shad,ext}: Remove nxcomp*.pc file on clean and distclean. -2015-07-14 01:26:33 +0200 Mike Gabriel (5eecadb) +2015-07-14 01:26:33 +0200 Mike Gabriel (5eecadb53) * Makefile: Also remove nxversion.def on distclean. -2015-07-14 00:04:01 +0200 Mike Gabriel (e5fbb11) +2015-07-14 00:04:01 +0200 Mike Gabriel (e5fbb11b2) * Merge branch 'uli42-pr/add_pkgconfig' into 3.6.x -2015-07-12 01:52:29 +0200 Ulrich Sibiller (00cec49) +2015-07-12 01:52:29 +0200 Ulrich Sibiller (00cec4924) * Add pkg-config support to nxcomp, nxcompext and nxcompshad -2015-07-04 06:46:29 +0200 Mihai Moldovan (f4c07c0) +2015-07-04 06:46:29 +0200 Mihai Moldovan (f4c07c077) * debian/changelog: sync with master/3.5.0.x branch. -2015-07-03 17:07:30 +0200 Mihai Moldovan (ca19c34) +2015-07-03 17:07:30 +0200 Mihai Moldovan (ca19c342c) * Merge branch 'uli42-pr/backported_fixes' into arctica-3.6.x -2009-02-13 10:23:28 +0100 Peter Åstrand (d088698) +2009-02-13 10:23:28 +0100 Peter Åstrand (d08869832) * Backport: xserver: Avoid sending uninitialized padding data over the network -2015-06-29 04:13:59 +0200 Mihai Moldovan (61013ec) +2015-06-29 04:13:59 +0200 Mihai Moldovan (61013ec4f) * Merge branch 'sunweaver-pr/no-autotools-cruft' into arctica-3.6.x -2015-06-29 03:40:58 +0200 Mihai Moldovan (fa0286e) +2015-06-29 03:40:58 +0200 Mihai Moldovan (fa0286ed6) * debian/changelog: sync with master/3.5.0.x branch. -2015-06-28 01:50:00 -0400 Mike DePaulo (779d546) +2015-06-28 01:50:00 -0400 Mike DePaulo (779d54645) * Correct nxproxy manpage also: --help -> -help -2015-06-28 01:33:49 -0400 Mike DePaulo (12acd90) +2015-06-28 01:33:49 -0400 Mike DePaulo (12acd909b) * Correct manpages: --help -> -help -2015-06-23 16:24:56 +0200 Mike Gabriel (a28be4a) +2015-06-23 16:24:56 +0200 Mike Gabriel (a28be4aa9) * library clean-up: No autotools cruft in nx-libs. -2015-06-25 05:04:12 +0200 Mike Gabriel (e7f3187) +2015-06-25 05:04:12 +0200 Mike Gabriel (e7f3187ee) * doc/examples/run-nxproxy2nxproxy-test: Create NX_COOKIE dynamically using the mcookie tool. -2015-06-23 16:39:33 +0200 Mihai Moldovan (32bbe01) +2015-06-23 16:39:33 +0200 Mihai Moldovan (32bbe01dd) * Merge branch 'sunweaver-pr/roll-tarball-fixes' into arctica-3.6.x -2015-05-28 14:52:24 +0200 Mike Gabriel (5af9863) +2015-05-28 14:52:24 +0200 Mike Gabriel (5af9863e7) * COPYING: Replace content with GPL-2 license text, because that is the overall (i.e., strictest) license we have to deal with in nx-libs. -2015-05-28 14:50:05 +0200 Mike Gabriel (438f3df) +2015-05-28 14:50:05 +0200 Mike Gabriel (438f3df14) * debian/roll-tarball.sh: Auto-generate ChangeLog from Git history. -2015-05-28 14:49:40 +0200 Mike Gabriel (7e1effb) +2015-05-28 14:49:40 +0200 Mike Gabriel (7e1effbe7) * debian/roll-tarball.sh: Rename README.md to README.NX-Development before moving it into doc/ folder. -2015-05-28 14:33:08 +0200 Mike Gabriel (47afc48) +2015-05-28 14:33:08 +0200 Mike Gabriel (47afc48ea) * debian/roll-tarball.sh: Prevent several files/folders from ending up in nx-libs-lite tarball. -2015-05-28 13:33:43 +0200 Mike Gabriel (895ee3b) +2015-05-28 13:33:43 +0200 Mike Gabriel (895ee3b3b) * debian/roll-tarball.sh: Support tarring up the HEAD of the current branch. -2015-05-28 13:29:27 +0200 Mike Gabriel (701471e) +2015-05-28 13:29:27 +0200 Mike Gabriel (701471e8e) * debian/roll-tarball.sh: Allow patch files names having a dash next to the four digits (i.e., 1234-.). -2015-06-23 16:14:41 +0200 Mike Gabriel (ce9ea54) +2015-06-23 16:14:41 +0200 Mike Gabriel (ce9ea5448) * Merge branch 'pr/anti-aliasing-rgba-crash' into 3.6.x -2015-06-23 16:09:50 +0200 Emanuele Giaquinta (ffc87da) +2015-06-23 16:09:50 +0200 Emanuele Giaquinta (ffc87da60) * Fix alpha premultiplication in XRenderParseColor. -2015-06-23 02:30:02 +0200 Mihai Moldovan (8cf9283) +2015-06-23 02:30:02 +0200 Mihai Moldovan (8cf9283bd) * Merge branch 'sunweaver-pr/libXx86FOO-cleanup' into arctica-3.6.x -2015-05-27 12:34:12 +0200 Mike Gabriel (06d389a) +2015-05-27 12:34:12 +0200 Mike Gabriel (06d389a0c) * library clean-up: Drop libXx86{misc,vm,dga} libraries. Not needed by nx-libs. (gh-sunweaver/pr/libXx86FOO-cleanup) -2015-06-22 03:38:46 +0200 Mihai Moldovan (e7dfbd5) +2015-06-22 03:38:46 +0200 Mihai Moldovan (e7dfbd511) * Merge branch 'sunweaver-pr/libxf86rush-cleanup' into arctica-3.6.x -2015-05-27 10:20:29 +0200 Mike Gabriel (5365f90) +2015-05-27 10:20:29 +0200 Mike Gabriel (5365f9059) * library clean-up: Drop nx-X11/lib/Xxf86rush and references to libglide{2,3}. Unused in nx-libs. (gh-sunweaver/pr/libxf86rush-cleanup) -2015-06-21 10:50:31 +0200 Mihai Moldovan (fb2a4e4) +2015-06-21 10:50:31 +0200 Mihai Moldovan (fb2a4e4c5) * Merge branch 'sunweaver-pr/hw-driver-cleanup' into arctica-3.6.x -2015-05-27 09:48:26 +0200 Mike Gabriel (26091f4) +2015-05-27 09:48:26 +0200 Mike Gabriel (26091f4bd) * nx-X11/config/cf: Drop build-logic for all hardware drivers. (gh-sunweaver/pr/hw-driver-cleanup) -2015-05-27 08:38:11 +0200 Mike Gabriel (ae443bd) +2015-05-27 08:38:11 +0200 Mike Gabriel (ae443bd5b) * nx-X11/config/cf: Drop unnecessary xf86site.def, xf86.tmpl, xfree86.cf. -2015-05-27 08:26:40 +0200 Mike Gabriel (c0662d6) +2015-05-27 08:26:40 +0200 Mike Gabriel (c0662d6de) * nx-X11/config/cf/Imakefile: Don't list non-present-anymore imake configuration files. -2015-06-20 17:47:39 +0200 Mike Gabriel (cc92f77) +2015-06-20 17:47:39 +0200 Mike Gabriel (cc92f77e9) * libgl clean-up, fix-up commit -2015-06-20 17:35:00 +0200 Mike DePaulo (88ab5a3) +2015-06-20 17:35:00 +0200 Mike DePaulo (88ab5a34f) * README.md: typo fix -2015-06-20 14:39:56 +0200 Mike Gabriel (905c74d) +2015-06-20 14:39:56 +0200 Mike Gabriel (905c74da3) * Merge pull request #52 from woglinde/3.6.x -2015-06-20 11:34:04 +0200 Henning Heinold (a287e9d) +2015-06-20 11:34:04 +0200 Henning Heinold (a287e9dbe) * remove libxkbui, looks like it is not used anywhere -2015-06-19 23:58:49 +0200 Mike Gabriel (4674a4a) +2015-06-19 23:58:49 +0200 Mike Gabriel (4674a4ae4) * debian/control: Add Breaks:/Replaces: for qvd-libxcomp3 and qvd-nxproxy. -2015-06-16 23:58:50 +0200 Mihai Moldovan (51b60ea) +2015-06-16 23:58:50 +0200 Mihai Moldovan (51b60ea7a) * Merge branch 'sunweaver-pr/libglx-cleanup' into arctica-3.6.x -2015-05-27 08:10:38 +0200 Mike Gabriel (5cd80d2) +2015-05-27 08:10:38 +0200 Mike Gabriel (5cd80d272) * imake clean-up: Enforce build of Mesa GLX extension. Drop all other GLX build methods (built-in DRI drivers, etc.). (gh-sunweaver/pr/libglx-cleanup) -2015-05-26 16:44:49 +0200 Mike Gabriel (73fa899) +2015-05-26 16:44:49 +0200 Mike Gabriel (73fa89991) * Drop unused / untested Xserver GLX extension support / build logic. -2015-05-26 16:22:40 +0200 Mike Gabriel (cb4a2d7) +2015-05-26 16:22:40 +0200 Mike Gabriel (cb4a2d732) * Drop nx-X11/lib/GL and move Imakefile.inc include files into Xserver code tree. -2015-06-16 22:43:21 +0200 Mihai Moldovan (5a64974) +2015-06-16 22:43:21 +0200 Mihai Moldovan (5a64974cc) * nxcomp/Loop.cpp: tiny whitespace fix. No functional change. -2015-06-16 10:41:12 +0200 Mike Gabriel (d8f3aa4) +2015-06-16 10:41:12 +0200 Mike Gabriel (d8f3aa414) * Merge pull request #28 from theqvd/3.6.x -2009-05-28 14:43:27 -0700 Keith Packard (cf660f4) +2009-05-28 14:43:27 -0700 Keith Packard (cf660f485) * Backport: Make RANDR 'set' timestamps follow client specified time. Bug 21987. -2012-06-21 18:42:46 -0700 Keith Packard (9dbd747) +2012-06-21 18:42:46 -0700 Keith Packard (9dbd74793) * Backport: randr: Clean up compiler warnings about unused and shadowing variables -2012-06-29 13:33:58 -0700 Aaron Plattner (9e2ac01) +2012-06-29 13:33:58 -0700 Aaron Plattner (9e2ac01a4) * Backport: randr: Fix REQUEST vs. REQUEST_SIZE_MATCH mismatch -2012-07-09 19:12:42 -0700 Alan Coopersmith (bd5754f) +2012-07-09 19:12:42 -0700 Alan Coopersmith (bd5754f94) * Backport: ProcRRGetScreenInfo: swap configTimestamp as well -2012-07-14 11:21:15 -0700 Alan Coopersmith (0fc4193) +2012-07-14 11:21:15 -0700 Alan Coopersmith (0fc419314) * Backport: RRModeCreate: plug memory leak of newModes if AddResource fails -2009-05-22 09:54:38 +0200 Julien Cristau (faddfbe) +2009-05-22 09:54:38 +0200 Julien Cristau (faddfbec6) * Backport: randr: fix server crash in RRGetScreenInfo -2010-12-17 16:09:35 +0200 Tiago Vignatti (da678db) +2010-12-17 16:09:35 +0200 Tiago Vignatti (da678db0e) * Backport: randr: check for virtual size limits before set crtc -2009-09-17 18:14:37 -0700 Keith Packard (2aeb767) +2009-09-17 18:14:37 -0700 Keith Packard (2aeb76719) * Backport: Free randr crtc and output pointer arrays -2008-09-10 13:11:09 +0800 Keith Packard (f454761) +2008-09-10 13:11:09 +0800 Keith Packard (f45476100) * Backport: Drop a reference to user mode after create -2012-07-09 19:12:42 -0700 Jaroslav Šmíd (8fd0b52) +2012-07-09 19:12:42 -0700 Jaroslav Šmíd (8fd0b52f2) * Backport: Bug 51375: Xorg doesn't set status for RRGetOutputInfo -2015-06-02 21:54:12 +0200 Mihai Moldovan (b5d7827) +2015-06-02 21:54:12 +0200 Mihai Moldovan (b5d78278d) * Merge branch 'sunweaver-pr/libxres-cleanup' into arctica-3.6.x -2015-06-02 21:12:05 +0200 Mihai Moldovan (167d09e) +2015-06-02 21:12:05 +0200 Mihai Moldovan (167d09ed7) * debian/changelog: sync with master/3.5.0.x branch. -2015-05-26 12:30:48 +0200 Mike Gabriel (6a74e67) +2015-05-26 12:30:48 +0200 Mike Gabriel (6a74e671a) * library clean-up: Don't compile (i.e., remove) libNX_Xres.a anymore. It is not used anywhere. (gh-sunweaver/pr/libxres-cleanup) -2015-05-31 17:21:10 +0200 Mike Gabriel (01b142d) +2015-05-31 17:21:10 +0200 Mike Gabriel (01b142ddf) * Update README.md: Move more release goals to 3.6.x. -2015-05-31 17:15:24 +0200 Mike Gabriel (dddffb7) +2015-05-31 17:15:24 +0200 Mike Gabriel (dddffb760) * Merge pull request #46 from ArcticaProject/pr/Xext-cve-fixes -2015-05-31 16:50:39 +0200 Mike Gabriel (11b2643) +2015-05-31 16:50:39 +0200 Mike Gabriel (11b26436b) * Merge pull request #45 from ArcticaProject/pr/dix-cve-fixes -2014-01-26 19:23:17 -0800 Alan Coopersmith (d1ca211) +2014-01-26 19:23:17 -0800 Alan Coopersmith (d1ca2119a) * Xv: unvalidated lengths in XVideo extension swapped procs [CVE-2014-8099] (origin/pr/Xext-cve-fixes) -2015-05-01 13:09:24 +0200 Keith Packard (2db01a9) +2015-05-01 13:09:24 +0200 Keith Packard (2db01a9a2) * dix: Allow zero-height PutImage requests (fix for X.Org's CVE-2015-3418). (origin/pr/dix-cve-fixes) -2014-01-22 21:11:16 -0800 Alan Coopersmith (8623faa) +2014-01-22 21:11:16 -0800 Alan Coopersmith (8623faa42) * dix: integer overflow in ProcPutImage() [CVE-2014-8092 1/4] -2015-02-08 20:01:27 -0500 Mike DePaulo (c2298e0) +2015-02-08 20:01:27 -0500 Mike DePaulo (c2298e075) * Avoid use-after-free in dix/dixfonts.c: doImageText() [CVE-2013-4396] from xorg/Xserver http://lists.x.org/archives/xorg-announce/2013-October/002332.html -2015-05-29 11:15:19 +0200 Mike Gabriel (4ed85e8) +2015-05-29 11:15:19 +0200 Mike Gabriel (4ed85e8ef) * nxcomp/README.on-retroactive-DXPC-license: Some layout and interpunctuation fixes. -2015-05-28 22:36:59 +0200 Mihai Moldovan (5bc91ad) +2015-05-28 22:36:59 +0200 Mihai Moldovan (5bc91ad49) * nxcomp/Misc.cpp: fix build failure introduced in 1f44331574bdbe4069d13e4c26df18094b49e658. -2015-05-26 16:51:38 +0200 Mihai Moldovan (beb08f9) +2015-05-26 16:51:38 +0200 Mihai Moldovan (beb08f96c) * Merge branch 'sunweaver-pr/DXPC-re-license-retroactively' into arctica-3.6.x -2015-05-26 10:31:46 +0200 Mike Gabriel (e364fde) +2015-05-26 10:31:46 +0200 Mike Gabriel (e364fde72) * Merge pull request #36 from ArcticaProject/pr/render-cve-fixes -2015-05-21 12:25:13 +0200 Mike Gabriel (1f44331) +2015-05-21 12:25:13 +0200 Mike Gabriel (1f4433157) * Document retroactive re-licensing of the original DXPC code (closes #30). -2015-05-25 23:23:22 +0200 Mihai Moldovan (230852e) +2015-05-25 23:23:22 +0200 Mihai Moldovan (230852e0e) * Merge branch 'sunweaver-pr/libxrandr-cleanup' into arctica-3.6.x -2014-01-26 19:51:29 -0800 Alan Coopersmith (a0c90ad) +2014-01-26 19:51:29 -0800 Alan Coopersmith (a0c90ad34) * render: unvalidated lengths in Render extn. swapped procs [CVE-2014-8100 2/2] (origin/pr/render-cve-fixes) -2014-10-28 10:30:04 +0100 Julien Cristau (e469cff) +2014-10-28 10:30:04 +0100 Julien Cristau (e469cff02) * render: check request size before reading it [CVE-2014-8100 1/2] -2015-05-22 00:58:38 +0200 Mihai Moldovan (608ee99) +2015-05-22 00:58:38 +0200 Mihai Moldovan (608ee9928) * README.md: replace simple link with a text link, capitalization. -2015-05-22 00:43:53 +0200 Mihai Moldovan (7846638) +2015-05-22 00:43:53 +0200 Mihai Moldovan (7846638a8) * Merge branch 'nitomartinez-qindel-readme' into arctica-3.6.x -2015-05-21 21:43:30 +0200 Nito Martinez (900b0cc) +2015-05-21 21:43:30 +0200 Nito Martinez (900b0cc2d) * Update the Qindel Company name (Qindel is without u ;-)) -2015-05-20 15:47:45 +0200 Vadim Troshchinskiy (f982cbc) +2015-05-20 15:47:45 +0200 Vadim Troshchinskiy (f982cbc85) * Fix negotiation in stage 10 error -2015-05-20 11:30:05 +0200 Mike Gabriel (a6185ab) +2015-05-20 11:30:05 +0200 Mike Gabriel (a6185abd9) * hw/nxagent clean-up: Drop NXrandr.{c|h} client lib copy-of-code from nxagent hardware driver. -2015-05-01 15:57:02 +0200 Mike Gabriel (e9dcab6) +2015-05-01 15:57:02 +0200 Mike Gabriel (e9dcab679) * library clean-up: Don't build libNX_Xrandr anymore. Use system's libXrandr shared library. -2015-05-16 15:54:37 +0200 Mike Gabriel (24903c9) +2015-05-16 15:54:37 +0200 Mike Gabriel (24903c921) * README.md: mark the iOS support for nxproxy/nxcomp as completed. -2015-05-16 15:15:41 +0200 Mike Gabriel (657acf9) +2015-05-16 15:15:41 +0200 Mike Gabriel (657acf98a) * Merge pull request #26 from nitomartinez/fix_developer_debugging -2015-05-16 15:12:19 +0200 Mike Gabriel (91ac79e) +2015-05-16 15:12:19 +0200 Mike Gabriel (91ac79ecc) * Merge pull request #25 from nitomartinez/nxtranscleanup_for_reconnect -2015-05-15 22:40:05 +0200 Nito Martinez (cf4ed91) +2015-05-15 22:40:05 +0200 Nito Martinez (cf4ed917e) * This patch is some code fixes to debug some debuging macro usage in the NX code. -2015-05-15 17:06:00 +0200 Mihai Moldovan (ab96962) +2015-05-15 17:06:00 +0200 Mihai Moldovan (ab96962b1) * README.md: reword a few sections, whitespace fixes. -2015-05-15 16:34:27 +0200 Mike Gabriel (8512c70) +2015-05-15 16:34:27 +0200 Mike Gabriel (8512c700a) * README.md: grammar fix -2015-05-15 16:33:20 +0200 Mike Gabriel (d733515) +2015-05-15 16:33:20 +0200 Mike Gabriel (d73351532) * README.md: phase 2 release series will be 3.7.0.x -2015-05-15 16:26:58 +0200 Mike Gabriel (50c3f56) +2015-05-15 16:26:58 +0200 Mike Gabriel (50c3f5628) * update README.md with newest plans for nx-libs 3.6.x -2015-05-15 15:20:52 +0200 Nito Martinez (4fefe35) +2015-05-15 15:20:52 +0200 Nito Martinez (4fefe352c) * This patch allows to cleanup the nxcomp resources to allow for a second connection inside the same process, instead of a new process as is the nxproxy case. -2015-05-12 06:07:45 +0200 Mihai Moldovan (f729583) +2015-05-12 06:07:45 +0200 Mihai Moldovan (f7295831a) * Merge branch 'sunweaver-pr/libxdamage-cleanup' into arctica-3.6.x -2015-05-05 01:23:04 +0200 Mihai Moldovan (027f593) +2015-05-05 01:23:04 +0200 Mihai Moldovan (027f593fc) * debian/changelog: merge with master branch. -2015-05-05 01:22:41 +0200 Mihai Moldovan (998527c) +2015-05-05 01:22:41 +0200 Mihai Moldovan (998527ce5) * debian/changelog: add entry for last change. -2015-05-05 01:22:18 +0200 Mihai Moldovan (b77b26f) +2015-05-05 01:22:18 +0200 Mihai Moldovan (b77b26f4a) * debian/libnx-xinerama1.*: fix faulty logic when creating symlinks. -2015-05-05 01:23:04 +0200 Mihai Moldovan (b573cbb) +2015-05-05 01:23:04 +0200 Mihai Moldovan (b573cbba9) * debian/changelog: merge with master branch. -2015-05-05 01:22:41 +0200 Mihai Moldovan (fca264f) +2015-05-05 01:22:41 +0200 Mihai Moldovan (fca264fd0) * debian/changelog: add entry for last change. -2015-05-05 01:22:18 +0200 Mihai Moldovan (06f36d0) +2015-05-05 01:22:18 +0200 Mihai Moldovan (06f36d0f0) * debian/libnx-xinerama1.*: fix faulty logic when creating symlinks. -2015-05-01 16:16:30 -0400 Mike DePaulo (c9d81fc) +2015-05-01 16:16:30 -0400 Mike DePaulo (c9d81fc38) * Merge pull request #20 from sunweaver/pr/fix-CVE-2015-3418 -2015-04-27 16:08:06 +0200 Mike Gabriel (06aa416) +2015-04-27 16:08:06 +0200 Mike Gabriel (06aa41671) * library clean-up: Don't build libNX_Xdamage anymore. Use system's libXdamage shared library. (Fixes ArcticaProject/nx-libs#6, X2GoBTS#826). -2015-05-01 13:09:24 +0200 Keith Packard (dba779d) +2015-05-01 13:09:24 +0200 Keith Packard (dba779d9f) * dix: Allow zero-height PutImage requests (fix for X.Org's CVE-2015-3418). -2015-04-30 15:51:48 +0200 Mihai Moldovan (7ccbb07) +2015-04-30 15:51:48 +0200 Mihai Moldovan (7ccbb073f) * debian/changelog: sync with 3.5.0.x branch. -2015-04-30 15:14:24 +0200 Mihai Moldovan (e6e323a) +2015-04-30 15:14:24 +0200 Mihai Moldovan (e6e323a22) * nx-libs.spec: actually create libXinerama.so.1 symlink during build phase. -2015-04-30 14:43:04 +0200 Mihai Moldovan (e595613) +2015-04-30 14:43:04 +0200 Mihai Moldovan (e59561387) * debian/changelog: correctly sync with 3.5.0.x branch. Add latest entries. -2015-04-30 14:25:25 +0200 Mihai Moldovan (a9bc7bd) +2015-04-30 14:25:25 +0200 Mihai Moldovan (a9bc7bdb6) * debian/libnx-xinerama1.*: move Xinerama dir back to nx-x11-common. Only delete known files. Fixes RPM build failures. -2015-04-29 08:04:44 +0200 Mike Gabriel (7a6b40a) +2015-04-29 08:04:44 +0200 Mike Gabriel (7a6b40a11) * Merge pull request #19 from ArcticaProject/PR-ionic/libXinerama_symlink_to_libnx-xinerama1 -2015-04-28 23:00:43 +0200 Mihai Moldovan (83983e9) +2015-04-28 23:00:43 +0200 Mihai Moldovan (83983e944) * libnx-xinerama1: also create libXinerama symlink in postinst (and remove in prerm.) -2015-04-28 05:15:19 +0200 Mihai Moldovan (7b7ba94) +2015-04-28 05:15:19 +0200 Mihai Moldovan (7b7ba9441) * Merge branch 'sunweaver-pr/imake-cleanup-nonpresent-buildlogic' into arctica-3.6.x -2015-04-22 00:37:47 +0200 Mike Gabriel (662a895) +2015-04-22 00:37:47 +0200 Mike Gabriel (662a89545) * imake cleanup: Drop references to X11 build-logic that is not present in nx-X11. -2015-04-21 10:57:56 +0200 Mike Gabriel (c189f6e) +2015-04-21 10:57:56 +0200 Mike Gabriel (c189f6efc) * imake cleanup: Break up multiple vars into invidual lines to ease further work on patches / pull requests. -2015-04-27 16:10:26 +0200 Mike Gabriel (cbf4e4d) +2015-04-27 16:10:26 +0200 Mike Gabriel (cbf4e4dbe) * COPYING: Add Arctica Project to copyright holders. -2015-04-27 02:56:07 +0200 Mihai Moldovan (99ef17f) +2015-04-27 02:56:07 +0200 Mihai Moldovan (99ef17f90) * debian/changelog: merge with 3.5.0.x branch. -2015-04-27 02:45:10 +0200 Mihai Moldovan (f717a7e) +2015-04-27 02:45:10 +0200 Mihai Moldovan (f717a7e81) * README.keystrokes: remove accidentally copied Dokuwiki syntax. -2015-04-27 02:02:15 +0200 Mihai Moldovan (380a4df) +2015-04-27 02:02:15 +0200 Mihai Moldovan (380a4df0f) * etc/keystrokes.cfg: fix whitespace errors. -2015-04-27 02:00:43 +0200 Mihai Moldovan (a430b4a) +2015-04-27 02:00:43 +0200 Mihai Moldovan (a430b4a87) * README.keystrokes: add documentation for branding behavior. -2015-04-27 01:59:53 +0200 Mihai Moldovan (1c0f42d) +2015-04-27 01:59:53 +0200 Mihai Moldovan (1c0f42d30) * README.keystrokes: copy actions documentation from the wiki. -2015-04-26 23:49:06 +0200 Mihai Moldovan (347e973) +2015-04-26 23:49:06 +0200 Mihai Moldovan (347e97335) * debian/roll-tarballs.sh: don't escape last newline of a multiline command. -2015-04-26 23:48:02 +0200 Mihai Moldovan (21a556b) +2015-04-26 23:48:02 +0200 Mihai Moldovan (21a556b37) * debian/roll-tarballs.sh: use more curly braces. -2015-04-26 23:47:33 +0200 Mihai Moldovan (cf91819) +2015-04-26 23:47:33 +0200 Mihai Moldovan (cf9181918) * debian/roll-tarballs.sh: convert tabs to spaces. -2015-04-26 23:45:42 +0200 Mihai Moldovan (e68c366) +2015-04-26 23:45:42 +0200 Mihai Moldovan (e68c36625) * debian/roll-tarballs.sh: use more quotes. -2015-04-26 16:35:14 +0200 Mike Gabriel (f2fd794) +2015-04-26 16:35:14 +0200 Mike Gabriel (f2fd79416) * libXcompshad underlinking problem: Fix undefined reference to 'XShmQueryVersion', 'XShmDetach', 'XShmCreateImage', 'XShmAttach', and 'XShmGetImage'. -2015-04-26 16:11:57 +0200 Mike Gabriel (4a3a473) +2015-04-26 16:11:57 +0200 Mike Gabriel (4a3a4737f) * Fix underlinking issues for libNX_X{composite,damage,fixes}. -2015-04-26 15:41:46 +0200 Mike Gabriel (305ac78) +2015-04-26 15:41:46 +0200 Mike Gabriel (305ac7889) * libX11 underlinking problem: Fix undefined reference to 'XdmcpWrap' (by linking against X.Org'x libXdmcp). -2015-04-26 15:12:39 +0200 Mike Gabriel (f46b432) +2015-04-26 15:12:39 +0200 Mike Gabriel (f46b43261) * libX11 underlinking problem: Fix undefined reference to 'dlopen' and 'dlsym'. (Fixes: X2GoBTS#853). -2015-04-23 13:29:10 +0200 Mihai Moldovan (2b159e1) +2015-04-23 13:29:10 +0200 Mihai Moldovan (2b159e18d) * Merge branch 'sunweaver-pr/xbitmaps-cleanup' into arctica-3.6.x -2015-04-21 10:42:47 +0200 Mike Gabriel (e69b7d1) +2015-04-21 10:42:47 +0200 Mike Gabriel (e69b7d1ec) * xbitmaps cleanup: The headers are not required at build time for NX. -2015-04-22 22:48:54 +0200 Mihai Moldovan (825af18) +2015-04-22 22:48:54 +0200 Mihai Moldovan (825af1835) * Merge branch 'sunweaver-pr/libxdmcp-cleanup' into arctica-3.6.x -2015-04-05 18:07:53 +0200 Mike Gabriel (49fc383) +2015-04-05 18:07:53 +0200 Mike Gabriel (49fc383a4) * library clean-up: Don't build libNX_Xdmcp anymore. Use system's libXdmcp shared library. -2015-04-22 22:41:14 +0200 Mike Gabriel (a5bb888) +2015-04-22 22:41:14 +0200 Mike Gabriel (a5bb88824) * nx-libs.spec: Drop packaging of libNX_Xpm*, in RPM packages there is no such concept for transitional/dummy packages as know from Debian/Ubuntu. -2015-04-22 22:39:14 +0200 Mike Gabriel (294d912) +2015-04-22 22:39:14 +0200 Mike Gabriel (294d91223) * debian/control: Typo fix (Meas -> Mesa). -2015-04-22 08:38:21 +0200 Mihai Moldovan (b964406) +2015-04-22 08:38:21 +0200 Mihai Moldovan (b964406ba) * Merge branch 'sunweaver-pr/libxfont-cleanup' into arctica-3.6.x -2015-04-14 09:24:55 +0200 Mike Gabriel (70b77a0) +2015-04-14 09:24:55 +0200 Mike Gabriel (70b77a0fc) * library clean-up: Don't build and link libXfont.a anymore. Use system's libXfont shared library and link dynamically. (origin/pr/libxfont-cleanup) -2015-04-21 15:28:25 +0200 Mike Gabriel (a77ca87) +2015-04-21 15:28:25 +0200 Mike Gabriel (a77ca871c) * fix for Xcursor clean-up (422fe90) -2015-04-17 00:12:52 +0200 Mike Gabriel (a20e77b) +2015-04-17 00:12:52 +0200 Mike Gabriel (a20e77b7c) * imake cleanup (nx-X11/programs/Xserver/Imakefile): Drop build rules for XF86Server and XorgServer. -2015-04-16 18:30:39 -0400 Mike DePaulo (8b15775) +2015-04-16 18:30:39 -0400 Mike DePaulo (8b1577599) * Merge pull request #12 from sunweaver/pr/arch-cleanup.CRAY -2015-04-16 22:12:45 +0200 Mihai Moldovan (0d92171) +2015-04-16 22:12:45 +0200 Mihai Moldovan (0d9217127) * Merge branch 'sunweaver-pr/xcursor-cleanup' into arctica-3.6.x -2015-04-08 21:52:51 +0200 Mike Gabriel (422fe90) +2015-04-08 21:52:51 +0200 Mike Gabriel (422fe9071) * library clean-up: Drop nx-X11/lib/Xcursor. Not used at build time. -2015-04-16 18:03:18 +0200 Mihai Moldovan (cfc0202) +2015-04-16 18:03:18 +0200 Mihai Moldovan (cfc0202b4) * Merge branch 'sunweaver-pr/nxupgradeagent-cleanup' into arctica-3.6.x -2015-04-14 09:42:35 +0200 Mike Gabriel (a5f71f0) +2015-04-14 09:42:35 +0200 Mike Gabriel (a5f71f084) * NXAGENT_UPGRADE code cleanup: -2015-04-15 10:16:18 +0200 Karl Tomlinson (ac9fbaa) +2015-04-15 10:16:18 +0200 Karl Tomlinson (ac9fbaabd) * MakeBigReq: don't move the last word, already handled by Data32 (X.Org CVE-2013-7439). -2015-04-15 09:58:01 +0200 Mike Gabriel (bad6779) +2015-04-15 09:58:01 +0200 Mike Gabriel (bad677992) * old-arch cleanup: Drop CRAY support (i.e., drop code related to CRAY, _CRAY, WORD64, WORD64ALIGN, MUSTCOPY, UNSIGNEDBITFIELDS definitions). -2015-04-15 12:37:30 +0200 Mike Gabriel (fad840c) +2015-04-15 12:37:30 +0200 Mike Gabriel (fad840cfe) * test script: doc/examples/run-nxproxy2nxproxy-test -2015-04-13 15:48:07 +0200 Mike Gabriel (097562b) +2015-04-13 15:48:07 +0200 Mike Gabriel (097562b8b) * drop: nx-X11/config/util/ (not needed at build time). -2015-04-13 15:39:36 +0200 Mike Gabriel (a8dad09) +2015-04-13 15:39:36 +0200 Mike Gabriel (a8dad09a5) * imake clean-up: nx-X11/config/Imakefile (drop BuildDPSLibrary related build-logic). -2015-04-11 17:38:02 +0200 Mike Gabriel (2f4d7db) +2015-04-11 17:38:02 +0200 Mike Gabriel (2f4d7dbb4) * fix for libXpm4-cleanup -2015-04-05 22:31:33 +0200 Mike Gabriel (d97b0ca) +2015-04-05 22:31:33 +0200 Mike Gabriel (d97b0ca93) * fix for ebe00df38f264ef71dac3c73d416a74685c8cbd2 (removal of DmxLibrary) -2015-04-05 20:58:58 +0200 Mihai Moldovan (bb23f7a) +2015-04-05 20:58:58 +0200 Mihai Moldovan (bb23f7a3d) * Merge branch 'feature/other-Xserver-cleanup' into arctica-3.6.x -2015-03-04 14:08:50 +0100 Mike Gabriel (d280fa1) +2015-03-04 14:08:50 +0100 Mike Gabriel (d280fa15e) * imake clean: Remove (probably incomplete) support for NXZaurusXServer, NXiPAQXServer. -2015-03-04 13:56:53 +0100 Mike Gabriel (6db94c3) +2015-03-04 13:56:53 +0100 Mike Gabriel (6db94c3e1) * imake cleanup: nx-X11/programs/Xserver/Imakefile (drop non-provided Xserver variants) -2015-03-04 13:43:54 +0100 Mike Gabriel (05d2083) +2015-03-04 13:43:54 +0100 Mike Gabriel (05d208351) * imake cleanup: nx-X11/programs/Imakefile (reduce to minimal). -2015-03-04 13:34:21 +0100 Mike Gabriel (78ac439) +2015-03-04 13:34:21 +0100 Mike Gabriel (78ac4396a) * imake cleanup: Drop all references to BuildFontServer. -2015-03-04 13:29:02 +0100 Mike Gabriel (f5f2804) +2015-03-04 13:29:02 +0100 Mike Gabriel (f5f280417) * imake cleanup: Drop all references to XprtServer and BuildXprint*. -2015-03-04 08:35:50 +0100 Mike Gabriel (ebe00df) +2015-03-04 08:35:50 +0100 Mike Gabriel (ebe00df38) * imake cleanup: Drop all references to XdmxServer and BuildXdmx*. -2015-03-03 12:30:51 +0100 Mike Gabriel (b1fc73a) +2015-03-03 12:30:51 +0100 Mike Gabriel (b1fc73ad4) * imake cleanup: Drop all references to XVirtualFramebufferServer. -2015-03-03 12:13:59 +0100 Mike Gabriel (6471f66) +2015-03-03 12:13:59 +0100 Mike Gabriel (6471f66c9) * imake cleanup: Drop all references to XNestServer. -2015-03-03 12:09:06 +0100 Mike Gabriel (9c46d3d) +2015-03-03 12:09:06 +0100 Mike Gabriel (9c46d3ddb) * imake cleanup: Drop all references to XWinServer. -2015-03-29 08:03:13 +0200 Mihai Moldovan (8ed8a43) +2015-03-29 08:03:13 +0200 Mihai Moldovan (8ed8a43d2) * nx-X11: add more NULL guards to TEST and DEBUG sections of Render.c. -2015-03-29 08:02:43 +0200 Mihai Moldovan (ab4e5bf) +2015-03-29 08:02:43 +0200 Mihai Moldovan (ab4e5bf66) * debian/changelog: sync with 3.5.0.x branch. -2015-03-29 04:53:52 +0200 Mihai Moldovan (f1ab3f2) +2015-03-29 04:53:52 +0200 Mihai Moldovan (f1ab3f27b) * nx-X11: fix typo in previous commit. -2015-03-29 04:26:10 +0200 Mihai Moldovan (0d56c45) +2015-03-29 04:26:10 +0200 Mihai Moldovan (0d56c45a7) * nx-X11: handle source pictures (those without a Drawable surface) gracefully. -2015-03-26 00:41:45 +0100 Mihai Moldovan (68be7d1) +2015-03-26 00:41:45 +0100 Mihai Moldovan (68be7d1c8) * debian/changelog: sync with 3.5.0.x branch. -2015-03-26 00:32:27 +0100 Mihai Moldovan (d86ce9c) +2015-03-26 00:32:27 +0100 Mihai Moldovan (d86ce9c7a) * nxcomp{,ext,shad}: only use the first three numbers in the full version for current_version on OS X. ld(1) on 10.6 fails otherwise. -2015-03-17 18:28:15 +0100 Mihai Moldovan (fcb2cb5) +2015-03-17 18:28:15 +0100 Mihai Moldovan (fcb2cb5e0) * nx-libs.spec: add overlooked Obsolete: statement to libNX_Xfixes3. -2015-03-17 18:26:26 +0100 Mihai Moldovan (8a260b9) +2015-03-17 18:26:26 +0100 Mihai Moldovan (8a260b94f) * nx-libs.spec: Versioned libXcomp* should obsolete unversioned libXcomp*, not libNX_Xcomp*. -2015-03-16 03:29:16 +0100 Mihai Moldovan (d8de592) +2015-03-16 03:29:16 +0100 Mihai Moldovan (d8de5928e) * nx{comp{,ext,shad},proxy}: try really hard to find makedepend. Do not fail if it is not available. -2015-03-15 17:29:50 +0100 Clemens Lang (638e31c) +2015-03-15 17:29:50 +0100 Clemens Lang (638e31c2f) * nxcomp{,ext,shad}: use the correct library naming scheme on OS X. It differs from other UNIX-based systems. -2015-03-15 17:26:24 +0100 Clemens Lang (ad7e12e) +2015-03-15 17:26:24 +0100 Clemens Lang (ad7e12ed3) * nxcomp{,shad}: fix dynamic library linking on OS X. Use -dynamiclib instead of -bundle. -2015-03-15 17:22:38 +0100 Clemens Lang (5464a6d) +2015-03-15 17:22:38 +0100 Clemens Lang (5464a6dba) * nx{comp{,ext,shad},proxy}: use path discovery for finding makedepend. Remove old cruft. -2015-03-15 01:13:56 +0100 Mihai Moldovan (c460e09) +2015-03-15 01:13:56 +0100 Mihai Moldovan (c460e090b) * debian/changelog: fix wrong signature. -2015-03-15 01:10:31 +0100 Mihai Moldovan (98e56c1) +2015-03-15 01:10:31 +0100 Mihai Moldovan (98e56c125) * debian/changelog: merge with 3.5.0.x release branch. -2015-03-13 15:14:07 +0100 Mike Gabriel (7d22541) +2015-03-13 15:14:07 +0100 Mike Gabriel (7d2254185) * README.md: Fix typo, update date. -2015-03-13 15:13:00 +0100 Mike Gabriel (286d891) +2015-03-13 15:13:00 +0100 Mike Gabriel (286d8917c) * README.md markdown fixup -2015-03-13 15:08:10 +0100 Mike Gabriel (2922ec5) +2015-03-13 15:08:10 +0100 Mike Gabriel (2922ec512) * README.md: Add 3.6.x release goals. -2015-03-05 12:24:42 +0100 Mike Gabriel (18e186b) +2015-03-05 12:24:42 +0100 Mike Gabriel (18e186b51) * Makefile: clean-up auto-generated nxversion.def in clean rule (not in build rule). -2015-03-03 12:34:48 +0100 Mike Gabriel (1a4d0c7) +2015-03-03 12:34:48 +0100 Mike Gabriel (1a4d0c7c5) * nx-X11/**: Drop non-imake Makefile* files. -2015-03-03 12:01:01 +0100 Mike Gabriel (f11393a) +2015-03-03 12:01:01 +0100 Mike Gabriel (f11393a05) * nx-X11/config/cf/X11.tmpl: Fix imake warning ("UseInstalledOnCrossCompile" is not defined). -2015-03-04 08:09:34 +0100 Mike Gabriel (897e2e2) +2015-03-04 08:09:34 +0100 Mike Gabriel (897e2e2de) * Merge pull request #4 from sunweaver/feature/libxpm-cleanup -2015-02-27 00:14:10 +0100 Mike Gabriel (1d71c9e) +2015-02-27 00:14:10 +0100 Mike Gabriel (1d71c9ebd) * library clean-up: Don't build libNX_Xpm anymore. Use system's libXpm shared library. -2015-02-18 08:14:09 -0500 Mike DePaulo (46318a5) +2015-02-18 08:14:09 -0500 Mike DePaulo (46318a51e) * Drop unused .cvsignore files -2015-02-18 07:51:55 -0500 Mike DePaulo (c29c331) +2015-02-18 07:51:55 -0500 Mike DePaulo (c29c331ce) * Update changelog for the CVE-2015-0255 commit and its 3 prereq commits -2015-02-18 08:01:54 +0100 Mike Gabriel (ec018a7) +2015-02-18 08:01:54 +0100 Mike Gabriel (ec018a79c) * Fix symlink to renamed README.md. -2015-02-18 06:18:03 +0100 Mike Gabriel (f7e109e) +2015-02-18 06:18:03 +0100 Mike Gabriel (f7e109e5c) * README.md: Mention the TheQVD project as collaborator on NX. -2015-02-18 05:06:41 +0100 Mike Gabriel (5c24a09) +2015-02-18 05:06:41 +0100 Mike Gabriel (5c24a09a1) * rename README.txt to README.md -2015-02-18 05:05:27 +0100 Mike Gabriel (04af6fe) +2015-02-18 05:05:27 +0100 Mike Gabriel (04af6fefb) * switch symlink and real file -2015-02-18 05:03:57 +0100 Mike Gabriel (f29801f) +2015-02-18 05:03:57 +0100 Mike Gabriel (f29801f37) * Add README.txt symlink to README.NX-development (to have it shown on the Github summary page). -2015-01-16 08:44:45 +0100 Olivier Fourdan (d725844) +2015-01-16 08:44:45 +0100 Olivier Fourdan (d7258444a) * xkb: Check strings length against request size -2015-01-16 20:08:59 +0100 Olivier Fourdan (9308c79) +2015-01-16 20:08:59 +0100 Olivier Fourdan (9308c79ba) * xkb: Don't swap XkbSetGeometry data in the input buffer -2009-06-29 13:09:57 +1000 Peter Hutterer (3937db1) +2009-06-29 13:09:57 +1000 Peter Hutterer (3937db18a) * include: introduce byte counting functions. -2006-04-07 16:07:50 +0000 Daniel Stone (d6ce946) +2006-04-07 16:07:50 +0000 Daniel Stone (d6ce946f9) * Coverity #844, #845, #846: Fix memory leaks. -2015-02-17 09:28:03 +0100 Mike Gabriel (c910bf7) +2015-02-17 09:28:03 +0100 Mike Gabriel (c910bf7cd) * Merge pull request #3 from sunweaver/feature/nxagent-version-v2 -2015-02-16 15:11:02 +0100 Mike Gabriel (203d971) +2015-02-16 15:11:02 +0100 Mike Gabriel (203d97147) * Make nxagent process aware of its current NX'ish version. -2015-02-16 15:10:43 +0100 Mike Gabriel (eb49d40) +2015-02-16 15:10:43 +0100 Mike Gabriel (eb49d408c) * nx-X11/programs/Xserver/hw/nxagent/: Drop unused VERSION file. -2011-08-21 18:51:53 +0200 Joerg Sonnenberger (65deb86) +2011-08-21 18:51:53 +0200 Joerg Sonnenberger (65deb86f8) * Do proper input validation to fix for CVE-2011-2895. -2015-02-16 10:29:14 +0100 Mike Gabriel (18e337d) +2015-02-16 10:29:14 +0100 Mike Gabriel (18e337ddf) * Revert "Do proper input validation to fix for CVE-2011-2895." -2015-02-16 06:24:38 +0100 Mike Gabriel (26cfe93) +2015-02-16 06:24:38 +0100 Mike Gabriel (26cfe931f) * fix 3.5.0.29 changelog entry -2015-02-16 06:19:54 +0100 Mike Gabriel (1f3222f) +2015-02-16 06:19:54 +0100 Mike Gabriel (1f3222fa0) * debian/changelog: fix too-long lines -2015-02-16 05:51:02 +0100 Mike Gabriel (db12538) +2015-02-16 05:51:02 +0100 Mike Gabriel (db12538dd) * Makefile.nx-libs: Fix uninstall-lite rule. The nxproxy and nxcomp uninstallation has to be in uninstall-lite, not in uninstall-full. -2015-02-16 05:45:17 +0100 Mike Gabriel (892c08d) +2015-02-16 05:45:17 +0100 Mike Gabriel (892c08ddc) * Make install-lite rule in Makefile.nx-libs more predictable and not rely on nxproxy/Makefile.in. -2015-02-14 21:55:30 +0100 Mike Gabriel (f29cc29) +2015-02-14 21:55:30 +0100 Mike Gabriel (f29cc29fd) * Install "%{_libdir}/nx/bin" into nxproxy package. -2015-02-14 21:53:00 +0100 Mike Gabriel (7424308) +2015-02-14 21:53:00 +0100 Mike Gabriel (742430826) * nx-libs.spec: Typo fix in comment. -2015-02-14 17:07:21 -0500 Mike DePaulo (e4d9701) +2015-02-14 17:07:21 -0500 Mike DePaulo (e4d97018b) * Fix FTBFS due to the nxproxy executable already existing under /usr/lib/nx/bin/nx -2011-08-21 18:51:53 +0200 Joerg Sonnenberger (6acafc9) +2011-08-21 18:51:53 +0200 Joerg Sonnenberger (6acafc933) * Do proper input validation to fix for CVE-2011-2895. -2015-02-16 06:03:48 +0100 Mihai Moldovan (b04f119) +2015-02-16 06:03:48 +0100 Mihai Moldovan (b04f11915) * nx-X11/lib/font/fc/fserve.c: initialize remaining bufleft variables. -2014-01-06 23:30:14 -0800 Alan Coopersmith (b6b5b14) +2014-01-06 23:30:14 -0800 Alan Coopersmith (b6b5b14e4) * dix: integer overflow in GetHosts() [CVE-2014-8092 2/4] -2015-02-16 05:55:23 +0100 Mihai Moldovan (03a2922) +2015-02-16 05:55:23 +0100 Mihai Moldovan (03a2922d9) * Revert "dix: integer overflow in GetHosts() [CVE-2014-8092 2/4]" -2015-02-08 21:03:33 -0500 Mike DePaulo (31322c2) +2015-02-08 21:03:33 -0500 Mike DePaulo (31322c2bd) * CVE-2014-0210: unvalidated length in _fs_recv_conn_setup() from xorg/lib/libXfont commit 891e084b26837162b12f841060086a105edde86d -2015-02-16 05:52:09 +0100 Mihai Moldovan (c0d0e37) +2015-02-16 05:52:09 +0100 Mihai Moldovan (c0d0e373d) * Revert "CVE-2014-0210: unvalidated length in _fs_recv_conn_setup() from xorg/lib/libXfont commit 891e084b26837162b12f841060086a105edde86d" -2015-02-08 22:08:09 -0500 Mike DePaulo (e29bbd5) +2015-02-08 22:08:09 -0500 Mike DePaulo (e29bbd5bf) * CVE-2014-0210: unvalidated length fields in fs_read_query_info() from xorg/lib/libXfont commit 491291cabf78efdeec8f18b09e14726a9030cc8f -2015-02-16 05:26:40 +0100 Mihai Moldovan (5fc2f57) +2015-02-16 05:26:40 +0100 Mihai Moldovan (5fc2f57fb) * Revert "CVE-2014-0210: unvalidated length fields in fs_read_query_info() from xorg/lib/libXfont commit 491291cabf78efdeec8f18b09e14726a9030cc8f" -2014-11-10 12:13:48 -0500 Adam Jackson (1ea1cd8) +2014-11-10 12:13:48 -0500 Adam Jackson (1ea1cd8c4) * glx: Pass remaining request length into ->varsize (v2) [CVE-2014-8098 8/8] (V3) -2014-11-10 12:13:43 -0500 Adam Jackson (9c558f9) +2014-11-10 12:13:43 -0500 Adam Jackson (9c558f9ca) * glx: Length checking for RenderLarge requests (v2) [CVE-2014-8098 3/8] (v3) -2014-11-10 12:13:47 -0500 Adam Jackson (8931066) +2014-11-10 12:13:47 -0500 Adam Jackson (893106607) * glx: Length checking for non-generated single requests (v2) [CVE-2014-8098 7/8] -2014-11-10 12:13:44 -0500 Adam Jackson (ad29acd) +2014-11-10 12:13:44 -0500 Adam Jackson (ad29acd76) * glx: Top-level length checking for swapped VendorPrivate requests [CVE-2014-8098 4/8] -2014-11-10 12:13:42 -0500 Adam Jackson (ddb1235) +2014-11-10 12:13:42 -0500 Adam Jackson (ddb1235bc) * glx: Integer overflow protection for non-generated render requests (v3) [CVE-2014-8093 5/6] -2014-11-10 12:13:41 -0500 Julien Cristau (78b38a8) +2014-11-10 12:13:41 -0500 Julien Cristau (78b38a8a3) * glx: Length checking for GLXRender requests (v2) [CVE-2014-8098 2/8] (v3) -2014-11-10 12:13:40 -0500 Adam Jackson (1a9f231) +2014-11-10 12:13:40 -0500 Adam Jackson (1a9f23118) * glx: Add safe_{add,mul,pad} (v3) [CVE-2014-8093 4/6] (v4) -2014-11-10 12:13:38 -0500 Adam Jackson (d0fcbc8) +2014-11-10 12:13:38 -0500 Adam Jackson (d0fcbc8a6) * glx: Additional paranoia in __glXGetAnswerBuffer / __GLX_GET_ANSWER_BUFFER (v2) [CVE-2014-8093 3/6] -2014-11-10 12:13:37 -0500 Adam Jackson (cdf0c3e) +2014-11-10 12:13:37 -0500 Adam Jackson (cdf0c3e65) * glx: Be more strict about rejecting invalid image sizes [CVE-2014-8093 2/6] -2014-11-10 12:13:36 -0500 Adam Jackson (5c43bb2) +2014-11-10 12:13:36 -0500 Adam Jackson (5c43bb248) * glx: Be more paranoid about variable-length requests [CVE-2014-8093 1/6] (v2) -2014-01-26 19:38:09 -0800 Alan Coopersmith (cea4467) +2014-01-26 19:38:09 -0800 Alan Coopersmith (cea44678d) * randr: unvalidated lengths in RandR extension swapped procs [CVE-2014-8101] -2014-01-26 20:02:20 -0800 Alan Coopersmith (c12a473) +2014-01-26 20:02:20 -0800 Alan Coopersmith (c12a473f2) * xfixes: unvalidated length in SProcXFixesSelectSelectionInput [CVE-2014-8102] -2014-01-26 19:51:29 -0800 Alan Coopersmith (9c3842a) +2014-01-26 19:51:29 -0800 Alan Coopersmith (9c3842a4f) * render: unvalidated lengths in Render extn. swapped procs [CVE-2014-8100 2/2] -2014-10-28 10:30:04 +0100 Julien Cristau (6c82064) +2014-10-28 10:30:04 +0100 Julien Cristau (6c820648b) * render: check request size before reading it [CVE-2014-8100 1/2] -2014-01-26 19:23:17 -0800 Alan Coopersmith (2abde56) +2014-01-26 19:23:17 -0800 Alan Coopersmith (2abde565d) * Xv: unvalidated lengths in XVideo extension swapped procs [CVE-2014-8099] -2014-01-26 17:18:54 -0800 Alan Coopersmith (0d53194) +2014-01-26 17:18:54 -0800 Alan Coopersmith (0d53194f7) * xcmisc: unvalidated length in SProcXCMiscGetXIDList() [CVE-2014-8096] -2014-01-26 10:54:41 -0800 Alan Coopersmith (fde1375) +2014-01-26 10:54:41 -0800 Alan Coopersmith (fde1375e3) * Xi: unvalidated lengths in Xinput extension [CVE-2014-8095] -2014-01-22 23:12:04 -0800 Alan Coopersmith (985ca32) +2014-01-22 23:12:04 -0800 Alan Coopersmith (985ca320f) * dbe: unvalidated lengths in DbeSwapBuffers calls [CVE-2014-8097] -2014-01-22 23:44:46 -0800 Alan Coopersmith (82d7279) +2014-01-22 23:44:46 -0800 Alan Coopersmith (82d7279eb) * dix: integer overflow in REQUEST_FIXED_SIZE() [CVE-2014-8092 4/4] -2014-01-22 22:37:15 -0800 Alan Coopersmith (ed1e13a) +2014-01-22 22:37:15 -0800 Alan Coopersmith (ed1e13a1f) * dix: integer overflow in RegionSizeof() [CVE-2014-8092 3/4] -2014-01-06 23:30:14 -0800 Alan Coopersmith (d4c7698) +2014-01-06 23:30:14 -0800 Alan Coopersmith (d4c76981f) * dix: integer overflow in GetHosts() [CVE-2014-8092 2/4] -2014-01-22 21:11:16 -0800 Alan Coopersmith (c1225fe) +2014-01-22 21:11:16 -0800 Alan Coopersmith (c1225fe64) * dix: integer overflow in ProcPutImage() [CVE-2014-8092 1/4] -2014-01-17 18:54:03 -0800 Alan Coopersmith (37e7fb1) +2014-01-17 18:54:03 -0800 Alan Coopersmith (37e7fb1f6) * unchecked malloc may allow unauthed client to crash Xserver [CVE-2014-8091] -2015-02-08 22:38:32 -0500 Mike DePaulo (b65259b) +2015-02-08 22:38:32 -0500 Mike DePaulo (b65259bf3) * CVE-2014-0210: unvalidated length fields in fs_read_list_info() from xorg/lib/libXfont commit d338f81df1e188eb16e1d6aeea7f4800f89c1218 -2015-02-08 22:35:21 -0500 Mike DePaulo (ef439da) +2015-02-08 22:35:21 -0500 Mike DePaulo (ef439da38) * CVE-2014-0210: unvalidated length fields in fs_read_list() from xorg/lib/libXfont commit 5fa73ac18474be3032ee7af9c6e29deab163ea39 -2015-02-08 22:27:47 -0500 Mike DePaulo (ece5149) +2015-02-08 22:27:47 -0500 Mike DePaulo (ece51493f) * CVE-2014-0210: unvalidated length fields in fs_read_glyphs() from xorg/lib/libXfont commit 520683652564c2a4e42328ae23eef9bb63271565 -2015-02-08 22:26:16 -0500 Mike DePaulo (d2b96c5) +2015-02-08 22:26:16 -0500 Mike DePaulo (d2b96c5d5) * CVE-2014-0210: unvalidated length fields in fs_read_extent_info() from xorg/lib/libXfont commit a3f21421537620fc4e1f844a594a4bcd9f7e2bd8 -2015-02-08 22:23:51 -0500 Mike DePaulo (a0bed4d) +2015-02-08 22:23:51 -0500 Mike DePaulo (a0bed4d9f) * CVE-2014-0211: integer overflow in fs_alloc_glyphs() from xorg/lib/libXfont commit a42f707f8a62973f5e8bbcd08afb10a79e9cee33 -2015-02-08 22:19:01 -0500 Mike DePaulo (bb7abd9) +2015-02-08 22:19:01 -0500 Mike DePaulo (bb7abd9da) * CVE-2014-0211: integer overflow in fs_read_extent_info() from xorg/lib/libXfont commit c578408c1fd4db09e4e3173f8a9e65c81cc187c1 -2015-02-08 22:08:09 -0500 Mike DePaulo (c6aebf9) +2015-02-08 22:08:09 -0500 Mike DePaulo (c6aebf928) * CVE-2014-0210: unvalidated length fields in fs_read_query_info() from xorg/lib/libXfont commit 491291cabf78efdeec8f18b09e14726a9030cc8f -2015-02-08 21:43:42 -0500 Mike DePaulo (2d724c1) +2015-02-08 21:43:42 -0500 Mike DePaulo (2d724c1a0) * CVE-2014-0211: Integer overflow in fs_get_reply/_fs_start_read from xorg/lib/libXfont commit 0f1a5d372c143f91a602bdf10c917d7eabaee09b -2015-02-08 21:39:55 -0500 Mike DePaulo (50e80a0) +2015-02-08 21:39:55 -0500 Mike DePaulo (50e80a06c) * CVE-2014-0210: unvalidated lengths when reading replies from font server from xorg/lib/libXfont commit cbb64aef35960b2882be721f4b8fbaa0fb649d12 -2015-02-08 21:33:30 -0500 Mike DePaulo (a2c7cd9) +2015-02-08 21:33:30 -0500 Mike DePaulo (a2c7cd9fe) * Don't crash when we receive an FS_Error from the font server (Guillem Jover). from xorg/lib/libXfont commit bfb8a71f4f7e5c5ed4278cb3ee271bf9990d276d -2015-02-08 21:03:33 -0500 Mike DePaulo (94c6de0) +2015-02-08 21:03:33 -0500 Mike DePaulo (94c6de064) * CVE-2014-0210: unvalidated length in _fs_recv_conn_setup() from xorg/lib/libXfont commit 891e084b26837162b12f841060086a105edde86d -2015-02-08 20:53:14 -0500 Mike DePaulo (36f1dae) +2015-02-08 20:53:14 -0500 Mike DePaulo (36f1dae74) * CVE-2014-0209: integer overflow of realloc() size in lexAlias() from xorg/lib/libXfont commit 05c8020a49416dd8b7510cbba45ce4f3fc81a7dc -2015-02-08 20:28:30 -0500 Mike DePaulo (f53f247) +2015-02-08 20:28:30 -0500 Mike DePaulo (f53f2474d) * CVE-2014-0209: integer overflow of realloc() size in FontFileAddEntry() from xorg/lib/libXfont commit 2f5e57317339c526e6eaee1010b0e2ab8089c42e -2015-02-08 20:12:25 -0500 Mike DePaulo (ac66943) +2015-02-08 20:12:25 -0500 Mike DePaulo (ac6694378) * CVE-2013-6462: unlimited sscanf overflows stack buffer in bdfReadCharacters() from xorg/lib/libXfont http://lists.x.org/archives/xorg-announce/2014-January/002389.html -2015-02-08 20:01:27 -0500 Mike DePaulo (72790a5) +2015-02-08 20:01:27 -0500 Mike DePaulo (72790a558) * Avoid use-after-free in dix/dixfonts.c: doImageText() [CVE-2013-4396] from xorg/Xserver http://lists.x.org/archives/xorg-announce/2013-October/002332.html -2015-02-08 19:16:38 -0500 Mike DePaulo (df4a3b7) +2015-02-08 19:16:38 -0500 Mike DePaulo (df4a3b727) * Fix CVE-2011-4028: File disclosure vulnerability. upstream xorg/xserver commit 6ba44b91e37622ef8c146d8f2ac92d708a18ed34 -2015-02-08 19:15:20 -0500 Mike DePaulo (af55da1) +2015-02-08 19:15:20 -0500 Mike DePaulo (af55da1e9) * LZW decompress: fix for CVE-2011-2895 From xorg/lib/Xfont commit d11ee5886e9d9ec610051a206b135a4cdc1e09a0 -2015-02-14 15:58:11 +0100 Mike Gabriel (902dc51) +2015-02-14 15:58:11 +0100 Mike Gabriel (902dc519d) * Move COPYING.full+lite as COPYING to / -2015-02-14 15:52:29 +0100 Mike Gabriel (9000c00) +2015-02-14 15:52:29 +0100 Mike Gabriel (9000c00dc) * Move all config files from $(srcbase)/debian/ into $(srcbase)/etc/ folder. -2015-02-14 15:29:25 +0100 Mike Gabriel (53329e6) +2015-02-14 15:29:25 +0100 Mike Gabriel (53329e609) * Provide wrapper scripts for launch NX components in $(src)/bin/. -2015-02-14 15:23:59 +0100 Mike Gabriel (1a824cf) +2015-02-14 15:23:59 +0100 Mike Gabriel (1a824cfb5) * Prepare for maintaing upstream changes in upstream ChangeLog. -2015-02-14 15:14:23 +0100 Mike Gabriel (ce53123) +2015-02-14 15:14:23 +0100 Mike Gabriel (ce531230f) * VERSION file: master VERSION file is in base folder, symlinked from nx*/VERSION and hw/nxagent/VERSION. -2015-02-14 15:08:07 +0100 Mike Gabriel (ea8ca04) +2015-02-14 15:08:07 +0100 Mike Gabriel (ea8ca04a7) * Move Makefile (and auxiliary file replace.sh) into base folder. Adapt packaging these scripts: -2015-02-14 14:50:20 +0100 Mike Gabriel (ebf71e0) +2015-02-14 14:50:20 +0100 Mike Gabriel (ebf71e0a4) * Add README.keystrokes file. Fix for commit e91277d02bf1288909daed3b0de8f876f6403acf. -2015-02-14 14:43:13 +0100 Mike Gabriel (8234505) +2015-02-14 14:43:13 +0100 Mike Gabriel (823450515) * nxcomp: Add Version.c file. Fix for commit d4d3fe0e6e77a58e68defc5895a589a681d7d092. -2015-02-14 14:28:35 +0100 Mike Gabriel (2d4a61d) +2015-02-14 14:28:35 +0100 Mike Gabriel (2d4a61d3c) * Version bump, continuing NX 3.x development.. Targetting NX 3.6.x some time. -2015-02-14 14:23:10 +0100 Mike Gabriel (e54e896) +2015-02-14 14:23:10 +0100 Mike Gabriel (e54e896a6) * Use proper quoting on build flag vars (they may contain spaces). -2015-02-14 14:21:52 +0100 Mike Gabriel (db3c6a6) +2015-02-14 14:21:52 +0100 Mike Gabriel (db3c6a6d2) * Revert "Fix build when LDFLAGS (etc) contains spaces." -2015-02-13 14:14:26 +0100 Mike Gabriel (1e5ee57) +2015-02-13 14:14:26 +0100 Mike Gabriel (1e5ee575d) * nx-X11 vs. X.Org 6.9 patches for further studying / documentation -2015-02-13 13:57:39 +0100 Oleksandr Shneyder (1fd8551) +2015-02-13 13:57:39 +0100 Oleksandr Shneyder (1fd8551f1) * Unbrand NX Agent Startup Screen / Brand X2Go Agent Startup Screen (999_nxagent_unbrand-nxagent-brand-x2goagent.full.patch). -2015-02-13 13:43:54 +0100 Mike Gabriel (23fb617) +2015-02-13 13:43:54 +0100 Mike Gabriel (23fb61755) * Fix several typos in nxcomp. -2015-02-13 13:41:31 +0100 Mihai Moldovan (6e66247) +2015-02-13 13:41:31 +0100 Mihai Moldovan (6e6624731) * Several fixes for building debug versions of NX (990_fix-DEBUG-and-TEST-builds.full.patch). -2015-02-13 13:38:39 +0100 Mike Gabriel (a8fb7d4) +2015-02-13 13:38:39 +0100 Mike Gabriel (a8fb7d4f5) * Detection for Mac OS X's launchd service on Mac OS X 10.10 and beyond (607_nxcomp_macosx-X11-launcher-in-private-tmp.full+lite.patch). -2015-02-13 13:37:33 +0100 Orion Poplawski (31cdd87) +2015-02-13 13:37:33 +0100 Orion Poplawski (31cdd874c) * Provide build support for aarch64 architecture (606_nx-X11_build-on-aarch64.full.patch). -2015-02-13 13:35:40 +0100 Clemens Lang (ab8d127) +2015-02-13 13:35:40 +0100 Clemens Lang (ab8d1276f) * In Types.h, don't use STL internals on libc++ (605_nxcomp_Types.h-dont-use-STL-internals-on-libc++.full+lite.patch). -2015-02-13 13:34:16 +0100 Mirraz Mirraz (96d5e74) +2015-02-13 13:34:16 +0100 Mirraz Mirraz (96d5e74a3) * Handle some serious compilation warnings (603_nx-X11_compilation_warnings.full.patch). -2015-02-13 13:32:17 +0100 Orion Poplawski (415b20b) +2015-02-13 13:32:17 +0100 Orion Poplawski (415b20b6f) * Be compliant with POS36-C: Observe correct revocation order while relinquishing privileges (602_nx-X11_initgroups.full.patch). -2015-02-13 13:30:31 +0100 Orion Poplawski (456f887) +2015-02-13 13:30:31 +0100 Orion Poplawski (456f887d9) * Do not build bundled libraries (601_nx-X11_build-option-changes-to-not-use-bundled-libraries.full.patch). -2015-02-13 13:27:42 +0100 Jan Engelhardt (c4a8556) +2015-02-13 13:27:42 +0100 Jan Engelhardt (c4a8556c4) * Unique Library Names Patch (600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch). -2015-02-13 13:26:27 +0100 Nito Martinez (d4d3fe0) +2015-02-13 13:26:27 +0100 Nito Martinez (d4d3fe0e6) * Allow version 4-digit version comparison/handshake (400_nxcomp-version.full+lite.patch). -2015-02-13 13:06:53 +0100 Horst Schirmeier (fea8fb5) +2015-02-13 13:06:53 +0100 Horst Schirmeier (fea8fb5ae) * Adapt paths of keystrokes.cfg if nxagent runs as x2goagent (321_nxagent_x2go-specific-keystroke-config.full.patch). -2015-02-13 09:52:21 +0100 Alexander Wuerstlein (e91277d) +2015-02-13 09:52:21 +0100 Alexander Wuerstlein (e91277d02) * Make nxagent-specific keyboard bindings configurable (320_nxagent_configurable-keystrokes.full.patch). -2015-02-13 09:49:52 +0100 Mike Gabriel (4dc1bd0) +2015-02-13 09:49:52 +0100 Mike Gabriel (4dc1bd004) * Test for xkb/rules/base instead of xkb/keymap.dir for setting XkbBaseDir (302_nx-X11_xkbbasedir-detection.full.patch). -2015-02-03 05:11:09 +0100 Mike Gabriel (a43c495) +2015-02-03 05:11:09 +0100 Mike Gabriel (a43c49594) * update changelog -2015-02-01 22:27:06 +0100 Ulrich Sibiller (08114b1) +2015-02-01 22:27:06 +0100 Ulrich Sibiller (08114b1e4) * Fix patch rollout in tarball -2015-02-12 10:07:40 +0100 Mike Gabriel (fa8fb72) +2015-02-12 10:07:40 +0100 Mike Gabriel (fa8fb7288) * changelog: add 3.5.0.x entry for commit 4436e97 -2015-02-12 09:59:57 +0100 Mike Gabriel (d569145) +2015-02-12 09:59:57 +0100 Mike Gabriel (d569145e6) * Makefile.nx-libs: Run make install for nxproxy first, then create the wrapper script. -2015-02-12 09:59:12 +0100 Mike Gabriel (a7cc4ed) +2015-02-12 09:59:12 +0100 Mike Gabriel (a7cc4edef) * Remove upstream nx-libs ChangeLog during override_dh_clean. -2015-02-11 19:02:57 -0500 Mike DePaulo (4436e97) +2015-02-11 19:02:57 -0500 Mike DePaulo (4436e9790) * Fix build when LDFLAGS (etc) contains spaces. -2015-02-10 21:47:31 +0100 Jan Engelhardt (6fc37fa) +2015-02-10 21:47:31 +0100 Jan Engelhardt (6fc37fa76) * Use shared libraries (301_nx-X11_use-shared-libs.full.patch). -2015-02-10 21:45:19 +0100 Oleksandr Shneyder (1e99734) +2015-02-10 21:45:19 +0100 Oleksandr Shneyder (1e99734ec) * Set WM_CLASS to X2GoAgent/NXAgent (300_nxagent_set-wm-class.full.patch). -2015-02-10 21:11:27 +0100 Mike Gabriel (1be1c4a) +2015-02-10 21:11:27 +0100 Mike Gabriel (1be1c4a21) * Force NX proxy to bind to loopback devices only (loopback option) (220_nxproxy_bind-loopback-only.full+lite.patch). -2015-02-10 19:47:58 +0100 Nito Martinez (79f218b) +2015-02-10 19:47:58 +0100 Nito Martinez (79f218b56) * Fix FTBFS of nxproxy/nxcomp on Android (212_nxcomp_build-on-Android.full+lite.patch). -2015-02-10 19:46:04 +0100 Oleksandr Shneyder (46c2aeb) +2015-02-10 19:46:04 +0100 Oleksandr Shneyder (46c2aebca) * Set default pack and link options to avoid damage of session (211_nxcomp_set_default_options.full+lite.patch). -2015-02-10 19:43:41 +0100 Oleksandr Shneyder (8c1b852) +2015-02-10 19:43:41 +0100 Oleksandr Shneyder (8c1b852ab) * Save session state in file. -2015-02-10 19:38:45 +0100 Mike Gabriel (4a6ccd5) +2015-02-10 19:38:45 +0100 Mike Gabriel (4a6ccd503) * Add x2goagent man page (209_x2goagent_add-man-page.full.patch). -2015-02-10 19:36:57 +0100 Ulrich Sibiller (57a58c7) +2015-02-10 19:36:57 +0100 Ulrich Sibiller (57a58c73c) * Fix XFIXES selection handling (copy and paste via middle mouse button) (207_nxagent_fix-xfixes-selection.full.patch). -2015-02-10 19:33:51 +0100 Mike Gabriel (4ef611e) +2015-02-10 19:33:51 +0100 Mike Gabriel (4ef611eea) * Add -clipboard cmdline option to nxagent (206_nxagent_clipboard-as-nxoption.full.patch). -2015-02-10 19:32:12 +0100 Oleksandr Shneyder (35aab85) +2015-02-10 19:32:12 +0100 Oleksandr Shneyder (35aab85c7) * Fix refresh errors on Win2012 RDP connections with speed=ADS (205_nxagent_refresh-adsl.full.patch). -2015-02-10 19:29:53 +0100 Oleksandr Shneyder (db87055) +2015-02-10 19:29:53 +0100 Oleksandr Shneyder (db8705564) * Fix repainting of SolidFill pictures with libcairo > 1.12.x (204_nxagent_repaint-solidpict.full.patch). -2015-02-10 19:26:42 +0100 Oleksandr Shneyder (4f5dc80) +2015-02-10 19:26:42 +0100 Oleksandr Shneyder (4f5dc807a) * Add -norootlessexit cmdline option to nxagent (203_nxagent_disable-rootless-exit.full.patch). -2015-02-10 19:23:16 +0100 Oleksandr Shneyder (d26930d) +2015-02-10 19:23:16 +0100 Oleksandr Shneyder (d26930d59) * Enable Xinerama support for NX (202_nx-X11_enable-xinerama.full.patch). -2015-02-10 19:21:35 +0100 Oleksandr Shneyder (6aa18cc) +2015-02-10 19:21:35 +0100 Oleksandr Shneyder (6aa18cc28) * X2Go icon when run with x2goagent flavour (201_nxagent_set-x2go-icon-if-x2goagent-flavour.full.patch). -2015-02-10 19:19:25 +0100 Oleksandr Shneyder (1681f11) +2015-02-10 19:19:25 +0100 Oleksandr Shneyder (1681f1110) * Detect nxagent/x2goagent flavour (200_nxagent_check-binary-x2go-flavour.full.patch). -2015-02-10 19:17:58 +0100 Mike Gabriel (4712239) +2015-02-10 19:17:58 +0100 Mike Gabriel (471223907) * Avoid large pixmaps (110_nxagent_createpixmap-bounds-check.full.patch). -2015-02-10 19:14:04 +0100 Mike Gabriel (223f554) +2015-02-10 19:14:04 +0100 Mike Gabriel (223f5548b) * Wine Close Delay (108_nxagent_wine-close-delay.full.patch). -2015-02-10 19:04:00 +0100 Mike Gabriel (658d07e) +2015-02-10 19:04:00 +0100 Mike Gabriel (658d07e93) * Prevent sending COMPOUND_TEXT (107_nxagent_clipboard-compound-text+small-bed-sheets.full.patch). -2015-02-10 19:00:06 +0100 Mike Gabriel (9674c43) +2015-02-10 19:00:06 +0100 Mike Gabriel (9674c4346) * UTF-8 Clipboard copying (106_nxagent_utf8-copy-clipboard.full.patch). -2015-02-10 18:56:59 +0100 Marcelo Boveto Shima (c91fe98) +2015-02-10 18:56:59 +0100 Marcelo Boveto Shima (c91fe980b) * Export remote keyboard configuration to session directory (105_nxagent_export-remote-keyboard-config.full.patch) -2015-02-10 18:54:29 +0100 Mike Gabriel (c106ad8) +2015-02-10 18:54:29 +0100 Mike Gabriel (c106ad8e8) * FHS path fix for keyboard config file (103_nxagent_set-X0-config-path.full.patch). -2015-02-10 18:52:39 +0100 Marcelo Boveto Shima (057999e) +2015-02-10 18:52:39 +0100 Marcelo Boveto Shima (057999efa) * FHS path fix for SecurityPolicy file (102_xserver-xext_set-securitypolicy-path.full.patch). -2015-02-10 18:48:39 +0100 Marcelo Boveto Shima (ceb7050) +2015-02-10 18:48:39 +0100 Marcelo Boveto Shima (ceb70505c) * FHS path fix for rgb file This patch is needed on Debian only, not reporting this path addition to upstream. -2015-02-10 18:41:08 +0100 Mihai Moldovan (2d68cac) +2015-02-10 18:41:08 +0100 Mihai Moldovan (2d68caca7) * Create Windows and fix drawing issues on Big Endian 64bit systems (057_nx-X11_sanitize-eventmasks.full.patch). -2015-02-09 15:58:22 +0100 Orion Poplawski (4dac57f) +2015-02-09 15:58:22 +0100 Orion Poplawski (4dac57f3d) * Fix -Werror=format-security errors (056_nx-X11_Werror-format-security.full.patch). -2015-02-09 15:51:26 +0100 Orion Poplawski (95dbaa6) +2015-02-09 15:51:26 +0100 Orion Poplawski (95dbaa614) * Fix FTBFS when compiled with -Werror=format-security (055_nx-X11_imake-Werror-format-security.full.patch). -2015-02-09 15:49:51 +0100 Orion Poplawski (0b711de) +2015-02-09 15:49:51 +0100 Orion Poplawski (0b711de48) * Fix FTBFS on ppc64 architecture (054_nx-X11_ppc64-ftbfs.full.patch). -2015-02-09 15:47:44 +0100 Orion Poplawski (9ea734b) +2015-02-09 15:47:44 +0100 Orion Poplawski (9ea734b21) * Avoid building libXcomp.so.1 (which is identical to libXcomp.so.3), (053_nx-X11_no-xcomp1-install-target.full.patch). -2015-02-09 15:45:33 +0100 Mihai Moldovan (e736fff) +2015-02-09 15:45:33 +0100 Mihai Moldovan (e736fff09) * Fix nxauth location on Mac OS X 10 (052_nxcomp_macos10-nxauth-location.full+lite.patch) -2015-02-09 15:41:35 +0100 Mihai Moldovan (9054786) +2015-02-09 15:41:35 +0100 Mihai Moldovan (905478694) * workaround for Mac OS X 10.5 (051_nxcomp_macos105-fdisset.full+lite.patch( -2015-02-09 15:38:59 +0100 Jan Engelhardt (6101bd9) +2015-02-09 15:38:59 +0100 Jan Engelhardt (6101bd956) * Description: Enable parallel make (031_nx-X11_parallel-make.full.patch). -2015-02-09 15:34:02 +0100 Jan Engelhardt (9f4b494) +2015-02-09 15:34:02 +0100 Jan Engelhardt (9f4b494fa) * Allow to pass in configure args (030_nx-X11_configure-args.full.patch). -2015-02-09 15:31:46 +0100 Mihai Moldovan (bd10fe5) +2015-02-09 15:31:46 +0100 Mihai Moldovan (bd10fe591) * Fix BIGENDIAN issue in nxcomp (relevant on PPC64 arch) (029_nxcomp_ppc64.full+lite.patch) -2015-02-09 15:29:53 +0100 Mike Gabriel (f661907) +2015-02-09 15:29:53 +0100 Mike Gabriel (f6619070b) * Support abstract local sockets for Linux systems (028_nx-X11_abstract-kernel-sockets.full.patch). -2015-02-09 15:27:46 +0100 Mike Gabriel (aaf4a59) +2015-02-09 15:27:46 +0100 Mike Gabriel (aaf4a59e4) * Add X11 abstract socket support to nxcomp/nxproxy (027_nxcomp_abstract-X11-socket.full+lite.patch). -2015-02-09 15:22:07 +0100 Orion Poplawski (3384aba) +2015-02-09 15:22:07 +0100 Orion Poplawski (3384aba38) * Honour compiler/linker option flags. -2015-02-09 15:19:12 +0100 Gabriel Marcano (78efa8b) +2015-02-09 15:19:12 +0100 Gabriel Marcano (78efa8bf9) * Fix FTBFS against libjpeg9a (025_nxcomp-fix-ftbfs-against-jpeg9a.full+lite.patch). -2015-02-09 15:16:30 +0100 Mike Gabriel (236ee4f) +2015-02-09 15:16:30 +0100 Mike Gabriel (236ee4ffa) * nxcomp*, nxproxy: Fix clean-up of source tree via Makefile.in templates. -2015-02-09 15:12:11 +0100 Mike Gabriel (9b72eea) +2015-02-09 15:12:11 +0100 Mike Gabriel (9b72eeaa2) * FHS adaptation for Debian packaging (016_nx-X11_install-location.full.patch). From tarball, @@ -5722,42 +5965,42 @@ debian/rules. This should be merged into the NX build logic finally. -2015-02-09 08:37:40 -0500 Mike DePaulo (519bcac) +2015-02-09 08:37:40 -0500 Mike DePaulo (519bcac93) * Fix RPM spec syntax error -2015-02-09 14:26:02 +0100 Mike Gabriel (4bc550e) +2015-02-09 14:26:02 +0100 Mike Gabriel (4bc550e86) * nxcomp*,nxproxy: Add clean rules to Makefile.in templates. -2015-02-09 14:23:12 +0100 Mike Gabriel (27ddd16) +2015-02-09 14:23:12 +0100 Mike Gabriel (27ddd1695) * Work on man pages. -2015-02-09 14:20:22 +0100 Mike Gabriel (a0b2fd8) +2015-02-09 14:20:22 +0100 Mike Gabriel (a0b2fd836) * sa_restorer vs. memset (008_nxcomp_sa-restorer.full+lite.patch). Use memset instead of setting sa_restorer to NULL. -2015-02-09 14:18:50 +0100 Mike Gabriel (a720908) +2015-02-09 14:18:50 +0100 Mike Gabriel (a720908a6) * Remove .gch files during cleanup (007_nxcompshad_clean-gch-files.full.patch). When building nxcompshad .gch files get created. On cleanup these should be removed. -2015-02-09 14:16:10 +0100 Mike Gabriel (f27e742) +2015-02-09 14:16:10 +0100 Mike Gabriel (f27e7424f) * Fix building against libpng 1.5 (006_nxcomp_libpng15.full+lite.patch). From the libpng homepage... -2015-02-09 11:57:55 +0100 Marcelo Boveto Shima (48c8281) +2015-02-09 11:57:55 +0100 Marcelo Boveto Shima (48c828107) * Description: gcc43 fix (005_nxcomp_gcc43.full+lite.patch) Use builtin includes to build with gcc43. -2015-02-09 11:56:14 +0100 Mike Gabriel (dd20ab5) +2015-02-09 11:56:14 +0100 Mike Gabriel (dd20ab5e6) * Description: Fix build on Debian (004_nx-X11_fix-nxcompshad-build.full.patch) By an @@ -5765,12 +6008,12 @@ nx-X11, nxcomp, nxcompshad and nxcompext with dpkg-buildpackage and debuild. -2015-02-09 11:53:47 +0100 Marcelo Boveto Shima (b3496d0) +2015-02-09 11:53:47 +0100 Marcelo Boveto Shima (b3496d0a7) * gcc43 fix (003_nxcompshad_gcc43.full.patch) Use builtin includes to build with gcc43. -2015-02-09 11:46:07 +0100 Mike Gabriel (3b4a915) +2015-02-09 11:46:07 +0100 Mike Gabriel (3b4a91598) * Build nxcompshad against nx-X11 (002_nxcompshad_build-against-nx-x11-only.full.patch). @@ -5778,477 +6021,477 @@ Furthermore /usr/X11R6/lib is an outdated path on current Debian systems. -2015-02-09 11:44:17 +0100 Mike Gabriel (7a1bd6b) +2015-02-09 11:44:17 +0100 Mike Gabriel (7a1bd6b29) * Provide README.NX-development file. Drop README.NX-redistribution file. -2015-02-09 10:46:10 +0100 Mike Gabriel (abbe938) +2015-02-09 10:46:10 +0100 Mike Gabriel (abbe93861) * fix long-line in changelog -2015-02-09 10:37:17 +0100 Mike Gabriel (eb55dc8) +2015-02-09 10:37:17 +0100 Mike Gabriel (eb55dc8fd) * Drop not-used-anymore NX source tree clean-up code. Source tree has been cleaned up natively. -2015-02-09 10:32:49 +0100 Mike Gabriel (939492d) +2015-02-09 10:32:49 +0100 Mike Gabriel (939492d83) * Revert "Add patch 700_nx-X11_mesa-initialize-server-support-correctly.full.patch. Initialize server_support array with correct size. Fix Mesa upstream bugzilla bug #7353. (Fixes: #776)." -2015-02-03 04:59:13 +0100 Mike Gabriel (4db6f0f) +2015-02-03 04:59:13 +0100 Mike Gabriel (4db6f0fdb) * Add patch 700_nx-X11_mesa-initialize-server-support-correctly.full.patch. Initialize server_support array with correct size. Fix Mesa upstream bugzilla bug #7353. (Fixes: #776). -2015-02-02 15:31:35 +0100 Mike Gabriel (231ffa8) +2015-02-02 15:31:35 +0100 Mike Gabriel (231ffa85e) * Update 991_fix-hr-typos.full.patch. Don't patch files that get removed by the NX code reduction effort. -2015-02-02 15:29:45 +0100 Mike Gabriel (91dc4b5) +2015-02-02 15:29:45 +0100 Mike Gabriel (91dc4b509) * Drop 604_nx-X11_recent-freetype-API.full.patch. Not used in current build process. -2015-02-02 15:26:51 +0100 Mike Gabriel (237d748) +2015-02-02 15:26:51 +0100 Mike Gabriel (237d7487f) * Update 600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch. Don't patch files matter to the NX code reduction efforts. -2015-02-02 15:25:43 +0100 Mike Gabriel (0c42e33) +2015-02-02 15:25:43 +0100 Mike Gabriel (0c42e33b4) * Update 031_nx-X11_parallel-make.full.patch. Don't patch .original files in NX code tree. -2015-02-02 15:24:31 +0100 Mike Gabriel (42f3b14) +2015-02-02 15:24:31 +0100 Mike Gabriel (42f3b1442) * Drop patches: 017_nx-X11_update-autotools-helper-files.full.patch, 018_nx-X11_update-libtool-ltmain-script.full.patch, 019_nx-X11_expat-build-against-system-libxmltok.full.patch. They patch files that are not used at build time. -2015-02-02 15:20:12 +0100 Mike Gabriel (86f96b0) +2015-02-02 15:20:12 +0100 Mike Gabriel (86f96b065) * empty CODE-REDUCTION_* files (maybe usable later for futher code reduction efforts -2015-02-02 15:04:01 +0100 Mike Gabriel (e399356) +2015-02-02 15:04:01 +0100 Mike Gabriel (e399356ed) * drop .original files from the current code base -2015-02-02 15:02:49 +0100 Mike Gabriel (b16b9e4) +2015-02-02 15:02:49 +0100 Mike Gabriel (b16b9e465) * massive reduction of unneeded files -2015-02-02 14:47:22 +0100 Mike Gabriel (0d5a83e) +2015-02-02 14:47:22 +0100 Mike Gabriel (0d5a83e98) * On SLE 11.x: libX* packages are prefixed with "xorg-x11-". -2015-01-29 13:04:46 +0100 Mike Gabriel (dc74950) +2015-01-29 13:04:46 +0100 Mike Gabriel (dc7495063) * Assure that BuildRoot: is set. -2015-01-29 12:48:05 +0100 Mike Gabriel (d9a4836) +2015-01-29 12:48:05 +0100 Mike Gabriel (d9a48367e) * nx-libs.spec: Set PREFIX=%{_prefix} USRLIBDIR=%{_libdir} SHLIBDIR=%{_libdir} at build time. -2015-01-29 12:40:22 +0100 Mike Gabriel (804584c) +2015-01-29 12:40:22 +0100 Mike Gabriel (804584cb1) * Don't fail if removing *.a files fails due to the files being non-present. -2015-01-29 12:12:15 +0100 Mike Gabriel (0b9fce2) +2015-01-29 12:12:15 +0100 Mike Gabriel (0b9fce27b) * Makefile.nx-libs: fix faulty path to nxproxy.1 man page -2015-01-29 12:05:23 +0100 Mike Gabriel (5e85638) +2015-01-29 12:05:23 +0100 Mike Gabriel (5e8563876) * nx-libs.spec: several dependency fixes... -2015-01-29 11:53:16 +0100 Mike Gabriel (a161173) +2015-01-29 11:53:16 +0100 Mike Gabriel (a161173d1) * Make libNX_X11-6 and libXinerama1 compliant to Shared Library Policy. -2015-01-29 11:49:37 +0100 Mike Gabriel (76c5291) +2015-01-29 11:49:37 +0100 Mike Gabriel (76c529124) * nx-libs.spec: Install man pages into bin:packages. -2015-01-29 11:49:28 +0100 Mike Gabriel (9a901a9) +2015-01-29 11:49:28 +0100 Mike Gabriel (9a901a9f6) * Makefile.nx-libs: Install man pages via main Makefile. -2015-01-29 11:46:31 +0100 Mike Gabriel (7e0de4d) +2015-01-29 11:46:31 +0100 Mike Gabriel (7e0de4df1) * nx-libs.spec: Mention NX technology in every package description. -2015-01-29 09:46:34 +0100 Mike Gabriel (10d670c) +2015-01-29 09:46:34 +0100 Mike Gabriel (10d670c0c) * Support .symbols for 64bit and 32bit alike. -2015-01-28 23:18:58 +0100 Mike Gabriel (cde624f) +2015-01-28 23:18:58 +0100 Mike Gabriel (cde624f45) * Use SONAME based library package naming scheme. -2015-01-28 23:17:45 +0100 Mike Gabriel (5a74175) +2015-01-28 23:17:45 +0100 Mike Gabriel (5a74175cd) * Revert "Use SONAME based library package naming scheme." -2015-01-28 23:14:49 +0100 Mike Gabriel (1e5c83e) +2015-01-28 23:14:49 +0100 Mike Gabriel (1e5c83e8b) * Use SONAME based library package naming scheme. -2015-01-28 23:06:25 +0100 Mike Gabriel (6d54eba) +2015-01-28 23:06:25 +0100 Mike Gabriel (6d54eba6c) * debian/control: don't use 1 person plural in LONG_DESCRIPTION -2015-01-28 23:01:59 +0100 Mike Gabriel (d306c90) +2015-01-28 23:01:59 +0100 Mike Gabriel (d306c9004) * nx-libs.spec: Make %{_libdir}/nx{,/X11} owned by libNX_X11 bin:package -2015-01-28 22:54:40 +0100 Mike Gabriel (752dac2) +2015-01-28 22:54:40 +0100 Mike Gabriel (752dac2b5) * CODE-REDUCTION_PRESERVE-NEEDED: keep cross.def and cross.rules -2015-01-28 22:52:34 +0100 Mike Gabriel (f992999) +2015-01-28 22:52:34 +0100 Mike Gabriel (f99299998) * debian/control: fix several packaging issues since the re-packaging started -2015-01-28 22:52:01 +0100 Mike Gabriel (1d7eb36) +2015-01-28 22:52:01 +0100 Mike Gabriel (1d7eb36d3) * Add Description: and Author: fields to various patch headers. -2015-01-28 22:32:09 +0100 Mike Gabriel (89b285f) +2015-01-28 22:32:09 +0100 Mike Gabriel (89b285f2a) * nx-libs.spec: Non-packaged files detected: nxagent.xpm, /usr/share/nx/rgb in bin:package nxagent -2015-01-28 22:31:16 +0100 Mike Gabriel (06212f5) +2015-01-28 22:31:16 +0100 Mike Gabriel (06212f51f) * latest tarball size: 41MiB -2015-01-28 22:24:24 +0100 Mike Gabriel (ce1078e) +2015-01-28 22:24:24 +0100 Mike Gabriel (ce1078e87) * Makefile.nx-libs: Don't allow symlinks to point into buildroot. -2015-01-28 22:21:22 +0100 Mike Gabriel (279b741) +2015-01-28 22:21:22 +0100 Mike Gabriel (279b74158) * Add 991_fix-hr-typos.full+lite.patch and 991_fix-hr-typos.full.patch. Fix several typos in upstream code detected by lintian. -2015-01-28 22:08:16 +0100 Mike Gabriel (3de4659) +2015-01-28 22:08:16 +0100 Mike Gabriel (3de46599f) * debian/libnx-xinerama1.dirs: no non-multi-arch dir in multi-arch packages -2015-01-28 21:56:13 +0100 Mike Gabriel (2a548a0) +2015-01-28 21:56:13 +0100 Mike Gabriel (2a548a079) * Provide CDBS-generated debian/copyright.in file. -2015-01-28 21:52:17 +0100 Mike Gabriel (79c0bac) +2015-01-28 21:52:17 +0100 Mike Gabriel (79c0bac99) * enable official changelog -2015-01-28 21:50:33 +0100 Mike Gabriel (94d5bb3) +2015-01-28 21:50:33 +0100 Mike Gabriel (94d5bb3c1) * debian/control: dummy packages don't have the substvar -2015-01-28 21:47:56 +0100 Mike Gabriel (e2cc535) +2015-01-28 21:47:56 +0100 Mike Gabriel (e2cc535c7) * nx-libs.spec: NX libs are installed in %{_libdir} -2015-01-28 21:43:27 +0100 Mike Gabriel (1d39845) +2015-01-28 21:43:27 +0100 Mike Gabriel (1d39845b3) * Add debian/*.symbols files for shared nx-X11 libraries. -2015-01-28 21:42:15 +0100 Mike Gabriel (dd79903) +2015-01-28 21:42:15 +0100 Mike Gabriel (dd79903cd) * nx-libs.spec: fix permission setting on outdated path -2015-01-28 21:31:37 +0100 Mike Gabriel (801dc1f) +2015-01-28 21:31:37 +0100 Mike Gabriel (801dc1fe8) * fix typos in CODE-REDUCTION scripts -2015-01-28 21:28:04 +0100 Mike Gabriel (912d62b) +2015-01-28 21:28:04 +0100 Mike Gabriel (912d62ba5) * Install upstream ChangeLogs into bin:packages. -2015-01-28 21:26:40 +0100 Mike Gabriel (f72fb34) +2015-01-28 21:26:40 +0100 Mike Gabriel (f72fb34eb) * silence lintian warning about licence file being a symlink -2015-01-28 20:42:34 +0100 Mike Gabriel (72ecc24) +2015-01-28 20:42:34 +0100 Mike Gabriel (72ecc24e6) * CODE-REDUCTION_PRESERVE-SYMLINKED: fix Mesa builds on 32bit intel arch -2015-01-28 20:41:56 +0100 Mike Gabriel (1b458e3) +2015-01-28 20:41:56 +0100 Mike Gabriel (1b458e32e) * CODE-REDUCTION_CLEANUP-UNUSED: remove DPS include files, remove XTrap shared lib -2015-01-28 19:51:32 +0100 Mike Gabriel (62d4f6a) +2015-01-28 19:51:32 +0100 Mike Gabriel (62d4f6a06) * CODE-REDUCTION_CLEANUP-BACKUPFILES: fine-tune dropped file -2015-01-28 19:49:11 +0100 Mike Gabriel (4fae286) +2015-01-28 19:49:11 +0100 Mike Gabriel (4fae286b8) * CODE-REDUCTION_CLEANUP-UNUSED: remove faulty path -2015-01-28 19:39:16 +0100 Mike Gabriel (8b05e19) +2015-01-28 19:39:16 +0100 Mike Gabriel (8b05e1918) * Update .spec file to meet changes in tarball size reduction and restructuring. -2015-01-28 18:21:44 +0100 Mike Gabriel (3c7c3b7) +2015-01-28 18:21:44 +0100 Mike Gabriel (3c7c3b7f4) * Support hardened builds for nxagent and libNX_*.so files. -2015-01-28 18:21:17 +0100 Mike Gabriel (f0f1df2) +2015-01-28 18:21:17 +0100 Mike Gabriel (f0f1df262) * more code reduction and adaptation of patch 600_....patch -2015-01-28 15:11:12 +0100 Mike Gabriel (350fb90) +2015-01-28 15:11:12 +0100 Mike Gabriel (350fb90d6) * remove more unused code from nx-X11/lib/ -2015-01-28 15:04:50 +0100 Mike Gabriel (151bca3) +2015-01-28 15:04:50 +0100 Mike Gabriel (151bca3a1) * Update 600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch. Don't patch files that get removed during code reduction. -2015-01-28 14:58:17 +0100 Mike Gabriel (2a40158) +2015-01-28 14:58:17 +0100 Mike Gabriel (2a4015865) * Support hardened builds for nxcomp* libraries. -2015-01-28 14:57:42 +0100 Mike Gabriel (8b432c7) +2015-01-28 14:57:42 +0100 Mike Gabriel (8b432c7a5) * debian/changelog: whitespace fix -2015-01-28 15:10:54 +0100 Mike Gabriel (f18608d) +2015-01-28 15:10:54 +0100 Mike Gabriel (f18608de2) * rebase with unify -2015-01-28 12:58:30 +0100 Mike Gabriel (5565184) +2015-01-28 12:58:30 +0100 Mike Gabriel (5565184a6) * Unify source tree reduction (debian/rules vs. roll-tarball.sh) via file/folder lists in text files named debian/CODE-REDUCTION_*. -2015-01-28 11:44:04 +0100 Mike Gabriel (22f0208) +2015-01-28 11:44:04 +0100 Mike Gabriel (22f0208cb) * re-arrange changelog, work-in missing entries for previous commits -2015-01-28 11:31:41 +0100 Mike Gabriel (1002761) +2015-01-28 11:31:41 +0100 Mike Gabriel (100276175) * debian/roll-tarball.sh: Install etc/ files into etc/ subfolder (rgb, nxagent.keyboard, x2goagent.keyboard). -2015-01-28 11:34:05 +0100 Mike Gabriel (a7a4246) +2015-01-28 11:34:05 +0100 Mike Gabriel (a7a4246f4) * debian/rules: Correctly link config files (etc/rgb, etc/nxagent.keyboard, etc/x2goagent.keyboard) before dh_auto_build. -2015-01-28 11:25:02 +0100 Mike Gabriel (0956f0c) +2015-01-28 11:25:02 +0100 Mike Gabriel (0956f0c7d) * Provide support for separate .keyboard files for nxagent/x2goagent. -2015-01-28 11:24:34 +0100 Mike Gabriel (04307b2) +2015-01-28 11:24:34 +0100 Mike Gabriel (04307b247) * Allow sysadmins to manipulate nxagent's / x2goagent's rgb file by placing it into /etc/nxagent or /etc/x2go. -2015-01-28 11:29:52 +0100 Mike Gabriel (78c016e) +2015-01-28 11:29:52 +0100 Mike Gabriel (78c016e77) * Extend 999_nxagent_unbrand-nxagent-brand-x2goagent.full.patch. Allow separate .keyboard files for x2goagent and nxagent. -2015-01-28 11:28:38 +0100 Mike Gabriel (fc2dcc9) +2015-01-28 11:28:38 +0100 Mike Gabriel (fc2dcc9c3) * Extend 999_nxagent_unbrand-nxagent-brand-x2goagent.full.patch. Let rgb file shipped with x2goagent supersede rgb file shipped with nxagent. FIXME: a better approach would be to decide at runtime if to use /etc/x2go/rgb or /etc/nxagent/rgb. -2015-01-28 11:21:02 +0100 Mike Gabriel (bb70adf) +2015-01-28 11:21:02 +0100 Mike Gabriel (bb70adf75) * Modify 101_nxagent_set-rgb-path.full.patch. Allow configurable rgb files. -2015-01-28 11:13:45 +0100 Mike Gabriel (7357f8c) +2015-01-28 11:13:45 +0100 Mike Gabriel (7357f8c0e) * Base Debian packaging 100% on Makefile install. -2015-01-27 13:56:36 +0100 Mike Gabriel (b3d32ec) +2015-01-27 13:56:36 +0100 Mike Gabriel (b3d32ec56) * Fully rework the way nx-libs gets packaged for Debian/Ubuntu. -2015-01-22 15:50:30 +0100 Mike Gabriel (a3087ee) +2015-01-22 15:50:30 +0100 Mike Gabriel (a3087eec9) * fix for last commit -2015-01-22 15:43:36 +0100 Mike Gabriel (caa9e8c) +2015-01-22 15:43:36 +0100 Mike Gabriel (caa9e8c9a) * Header files need not be removed anymore. They don't get installed via Makefile.nx-libs anymore. -2015-01-22 15:17:47 +0100 Mike Gabriel (c5ceb16) +2015-01-22 15:17:47 +0100 Mike Gabriel (c5ceb16a5) * Makefile.nx-libs: Don't install Mesa header files into DESTDIR anymore. -2015-01-22 13:48:18 +0100 Mike Gabriel (30ade9c) +2015-01-22 13:48:18 +0100 Mike Gabriel (30ade9cb7) * More source tree size reduction by analyzing what exactly of the Mesa source code in nx-X11/extras/ is used and what not. -2015-01-22 11:47:31 +0100 Mike Gabriel (4c73b97) +2015-01-22 11:47:31 +0100 Mike Gabriel (4c73b97cf) * debian/control: Turn libnx-*-dev packages into dummy packages. Shipping development files for nx-X11 makes no sense. No other programme build against nx-X11's header files except nxagent itself. -2015-01-22 11:00:15 +0100 Mike Gabriel (8de5a89) +2015-01-22 11:00:15 +0100 Mike Gabriel (8de5a897a) * Drop more unused folders from tarball release / before .deb package build. -2015-01-22 10:16:50 +0100 Mike Gabriel (3cfe4bf) +2015-01-22 10:16:50 +0100 Mike Gabriel (3cfe4bfa3) * Drop nx-X11/programs/Xserver/hw/xfree86 except of four files symlinked to other locations in the source tree at build time. -2015-01-22 06:19:42 +0100 Mike Gabriel (b590ce3) +2015-01-22 06:19:42 +0100 Mike Gabriel (b590ce38c) * Stop shipping unused / very old xterm code. -2015-01-22 06:12:10 +0100 Mike Gabriel (be832e8) +2015-01-22 06:12:10 +0100 Mike Gabriel (be832e8e1) * Drop more unused code in nx-X11/programs/Xserver/hw/. Do this in roll-tarball.sh and in debian/rules alike. -2015-01-22 06:10:11 +0100 Mike Gabriel (040962d) +2015-01-22 06:10:11 +0100 Mike Gabriel (040962da7) * Fix removal of unused code (that part of the code that we know of so far). (The debian/rules file is a Makefile and Makefiles don't understand shell globbing with curly braces). -2015-01-22 06:06:37 +0100 Mike Gabriel (694523e) +2015-01-22 06:06:37 +0100 Mike Gabriel (694523eee) * debian/rules: Backup nxcomp/VERSION file from NoMachine before replacing it with a symlink to debian/VERSION. Recreate the original file when cleaning up. -2015-01-19 10:32:03 +0100 Mike Gabriel (24986dd) +2015-01-19 10:32:03 +0100 Mike Gabriel (24986dd2e) * Update 320_nxagent_configurable-keystrokes.full.patch. Fix patch header referring to keystrokes.cfg (plural), not keystroke.cfg. -2015-01-19 10:28:59 +0100 Horst Schirmeier (4e5a115) +2015-01-19 10:28:59 +0100 Horst Schirmeier (4e5a11596) * Add 321_nxagent_x2go-specific-keystroke-config.full.patch. If nxagent is launched as x2goagent, use X2Go-specific paths for the keystrokes.cfg file. (Fixes: #744). -2015-01-13 12:17:58 +0100 Mike Gabriel (6ca1073) +2015-01-13 12:17:58 +0100 Mike Gabriel (6ca1073ea) * give credits to Horst Schirmeier for solving #741 -2015-01-13 06:05:32 +0100 Mike Gabriel (0648d56) +2015-01-13 06:05:32 +0100 Mike Gabriel (0648d56a9) * grammar fix in changelog -2015-01-13 05:36:24 +0100 Mike Gabriel (c09580a) +2015-01-13 05:36:24 +0100 Mike Gabriel (c09580a52) * Update 320_nxagent_configurable-keystrokes.full.patch. Fix a typo that prevented the /etc/nxagent/keystrokes.cfg file to be parsed. (Fixes: #741). -2015-01-09 04:51:03 +0100 Mihai Moldovan (3fb038d) +2015-01-09 04:51:03 +0100 Mihai Moldovan (3fb038d6c) * debian/changelog: add entry for last change. -2015-01-09 03:46:38 +0100 Mihai Moldovan (7750a7e) +2015-01-09 03:46:38 +0100 Mihai Moldovan (7750a7eaf) * common: change X2go -> X2Go. -2014-12-03 15:28:59 +0100 Mike Gabriel (3fa67b6) +2014-12-03 15:28:59 +0100 Mike Gabriel (3fa67b673) * fix for last commit(2) -2014-12-03 15:23:14 +0100 Mike Gabriel (8b36b79) +2014-12-03 15:23:14 +0100 Mike Gabriel (8b36b798e) * fix for last commit -2014-12-03 15:19:03 +0100 Mike Gabriel (992ec61) +2014-12-03 15:19:03 +0100 Mike Gabriel (992ec61a1) * nx-libs.spec: The gpg-offline bin:package is not available in our SLE repo. We can do without. -2014-12-03 15:09:54 +0100 Mike Gabriel (e44f1ae) +2014-12-03 15:09:54 +0100 Mike Gabriel (e44f1aec8) * DISABLED:401_nxcomp_bigrequests-and-genericevent-extensions.full+lite.patch. -2014-11-13 23:29:07 +0100 Paul Szabo (b2ac5aa) +2014-11-13 23:29:07 +0100 Paul Szabo (b2ac5aaf1) * Add 401_nxcomp_bigrequests-and-genericevent-extensions.full+lite.patch. Enable support for the X11 big requests extension and the generic events extension. -2014-11-13 21:59:11 +0100 Mike Gabriel (ec61d2e) +2014-11-13 21:59:11 +0100 Mike Gabriel (ec61d2e72) * Continue development... -2014-11-13 21:39:59 +0100 Mike Gabriel (c697894) +2014-11-13 21:39:59 +0100 Mike Gabriel (c69789464) * release 3.5.0.28 (tag: redist-server/3.5.0.28, tag: redist-client/3.5.0.28) -2014-11-13 21:38:32 +0100 Mike Gabriel (0f5dbb9) +2014-11-13 21:38:32 +0100 Mike Gabriel (0f5dbb95c) * Revert "Add 401_nxcomp_big-requests.full+lite.patch. Support usage of the BIG-REQUESTS X11 extension on the server-side. (See Debian bug #766299)." -2014-11-13 21:38:24 +0100 Mike Gabriel (6f59493) +2014-11-13 21:38:24 +0100 Mike Gabriel (6f59493da) * Revert "401_nxcomp_bigrequests.full+lite.patch: PATCH DISABLED FOR NOW, IT CAUSES NXPROXY CRASHES EVERY 1-2 minutes." -2014-11-05 10:07:39 +0100 Ulrich Sibiller (d1f0401) +2014-11-05 10:07:39 +0100 Ulrich Sibiller (d1f040121) * Add 207_nxagent_fix-xfixes-selection.full.patch. Fix selection handling when XFIXES is enabled. (Fixes: #585) -2014-10-25 23:02:16 +0200 Mike Gabriel (d505944) +2014-10-25 23:02:16 +0200 Mike Gabriel (d505944e0) * 401_nxcomp_bigrequests.full+lite.patch: PATCH DISABLED FOR NOW, IT CAUSES NXPROXY CRASHES EVERY 1-2 minutes. -2014-10-25 22:11:45 +0200 Mike Gabriel (c69c2e2) +2014-10-25 22:11:45 +0200 Mike Gabriel (c69c2e2ea) * Add 401_nxcomp_big-requests.full+lite.patch. Support usage of the BIG-REQUESTS X11 extension on the server-side. (See Debian bug #766299). -2014-10-19 00:19:38 +0200 Mike Gabriel (429dbe7) +2014-10-19 00:19:38 +0200 Mike Gabriel (429dbe708) * Rename 605_nxcomp_Types.h-dont-use-STL-internals-on-libc++.full.patch @@ -6257,182 +6500,182 @@ It is an nxcomp patch that needs to be applied in the nx-libs-lite _and_ the nx-libs-full tarball release. -2014-10-18 23:04:25 +0200 Mike Gabriel (b0727a0) +2014-10-18 23:04:25 +0200 Mike Gabriel (b0727a02f) * Add 607_nxcomp_macosx-X11-launcher-in-private-tmp.full+lite.patch. Fix check for launchd socket path in $DISPLAY on recent Mac OS X systems. -2014-10-14 19:17:11 +0200 Mike Gabriel (efe4d1f) +2014-10-14 19:17:11 +0200 Mike Gabriel (efe4d1f73) * nx-libs.spec: Fix more rpmlint warnings. -2014-10-13 15:47:05 +0200 Mike Gabriel (aa7a0c8) +2014-10-13 15:47:05 +0200 Mike Gabriel (aa7a0c834) * nx-libs.spec: Fix SUSE-specific R for libXext(6). -2014-10-13 14:54:11 +0200 Mike Gabriel (33f69da) +2014-10-13 14:54:11 +0200 Mike Gabriel (33f69da55) * nx-libs.spec: typo fix -2014-10-13 14:28:04 +0200 Mike Gabriel (370e56e) +2014-10-13 14:28:04 +0200 Mike Gabriel (370e56ec4) * nx-libs.spec: minor dep fix -2014-10-13 14:26:57 +0200 Mike Gabriel (44b7138) +2014-10-13 14:26:57 +0200 Mike Gabriel (44b7138b3) * nx-libs.spec: Fix Xinerama deps for SUSE builds. -2014-10-13 13:49:42 +0200 Mike Gabriel (ef4a6c8) +2014-10-13 13:49:42 +0200 Mike Gabriel (ef4a6c845) * nx-libs.spec: Do not conflict with nx... This will break our own neck. -2014-10-13 13:29:18 +0200 Mike Gabriel (aeb9b43) +2014-10-13 13:29:18 +0200 Mike Gabriel (aeb9b430c) * nx-libs.spec: fix nx-libs builds in mock -2014-10-13 11:48:15 +0200 Mike Gabriel (61c21fc) +2014-10-13 11:48:15 +0200 Mike Gabriel (61c21fce0) * nx-libs.spec: fix for last commit -2014-10-13 11:42:00 +0200 Mike Gabriel (d86c1be) +2014-10-13 11:42:00 +0200 Mike Gabriel (d86c1be2c) * Fix Xinerama symlink installation into RPM bin:package libNX_Xinerama. (Fixes: #269). -2014-10-13 11:27:50 +0200 Mike Gabriel (827cbcc) +2014-10-13 11:27:50 +0200 Mike Gabriel (827cbcc04) * Make sure all package directories are owned by one of the built bin:packages. -2014-10-13 11:27:23 +0200 Mike Gabriel (26e55cf) +2014-10-13 11:27:23 +0200 Mike Gabriel (26e55cf81) * fix last changelog entry -2014-10-13 11:19:14 +0200 Mike Gabriel (52ac26b) +2014-10-13 11:19:14 +0200 Mike Gabriel (52ac26bec) * nx-libs.spec: Fix for last commit. -2014-10-13 11:01:57 +0200 Mike Gabriel (0387e38) +2014-10-13 11:01:57 +0200 Mike Gabriel (0387e383d) * nx-libs.spec: SUSE hack for linking to files in libX11-6 and libXext6. -2014-10-13 10:36:53 +0200 Mike Gabriel (1bc6c85) +2014-10-13 10:36:53 +0200 Mike Gabriel (1bc6c85e5) * nx-libs.spec: follow up for last commits -2014-10-13 10:33:12 +0200 Mike Gabriel (894199e) +2014-10-13 10:33:12 +0200 Mike Gabriel (894199e60) * nx-libs.spec: follow up for last commits -2014-10-13 10:29:51 +0200 Mike Gabriel (b96e120) +2014-10-13 10:29:51 +0200 Mike Gabriel (b96e120f1) * nx-libs.spec: follow-up commit for last commit -2014-10-13 10:20:34 +0200 Mike Gabriel (5e4ae04) +2014-10-13 10:20:34 +0200 Mike Gabriel (5e4ae04ef) * Additionally adapt to building on openSUSE/SLES. -2014-10-11 10:13:33 +0200 Mike Gabriel (45c592c) +2014-10-11 10:13:33 +0200 Mike Gabriel (45c592cf4) * Update 027_nxcomp_abstract-X11-socket.full+lite: Add patch header (Description: and Author: field). -2014-10-02 13:52:00 +0200 Mike Gabriel (bddc7e0) +2014-10-02 13:52:00 +0200 Mike Gabriel (bddc7e0ba) * debian/rules: fix nxcomp/VERSION symlink creation at build-time -2014-10-02 13:32:13 +0200 Mike Gabriel (0cac9ef) +2014-10-02 13:32:13 +0200 Mike Gabriel (0cac9efd4) * debian/rules: No such option for dh_auto_build: --with quilt." -2014-10-02 12:34:22 +0200 Mike Gabriel (0277e08) +2014-10-02 12:34:22 +0200 Mike Gabriel (0277e0857) * nx-libs.spec: Adapt installation of debian/VERSION as VERSION.x2goagent and nxcomp/VERSION to latest changes introduced by 400_nxcomp-version.full+lite.patch. -2014-10-02 12:30:20 +0200 Mike Gabriel (8d0798e) +2014-10-02 12:30:20 +0200 Mike Gabriel (8d0798ec7) * fix symlink creation -2014-10-02 11:53:47 +0200 Mike Gabriel (5a82f59) +2014-10-02 11:53:47 +0200 Mike Gabriel (5a82f5994) * debian/libnx-x11.postinst: Don't use dpkg-architecture (bin:package dpkg-dev) in postinst script. Instead prep a libnx-x11.postinst script at build time. (Fixes: #621). -2014-10-02 10:40:55 +0200 Nito Martinez (61d047d) +2014-10-02 10:40:55 +0200 Nito Martinez (61d047d63) * Add 400_nxcomp-version.full+lite.patch. Allow 4-digit version comparison during NX session handshake. (Fixes: #610). -2014-08-20 13:02:53 +0200 Mike Gabriel (c9bc8ac) +2014-08-20 13:02:53 +0200 Mike Gabriel (c9bc8accc) * Add 025_nxcomp-fix-ftbfs-against-jpeg9a.full+lite.patch. Fix FTBFS when built against libjpeg9a. Thanks to Gabriel Marcano for sending this in. -2014-07-09 19:04:25 +0200 Mike Gabriel (0e3b414) +2014-07-09 19:04:25 +0200 Mike Gabriel (0e3b414ea) * Provide COPYING file in tarball. Update debian/copyright. -2014-06-30 15:06:06 +0200 Mike Gabriel (340ec14) +2014-06-30 15:06:06 +0200 Mike Gabriel (340ec14a4) * Continue development... -2014-06-30 14:53:48 +0200 Mike Gabriel (aeb5e8a) +2014-06-30 14:53:48 +0200 Mike Gabriel (aeb5e8ad5) * release 3.5.0.27 (tag: redist-server/3.5.0.27, tag: redist-client/3.5.0.27) -2014-06-30 14:53:09 +0200 Mike Gabriel (77c3e15) +2014-06-30 14:53:09 +0200 Mike Gabriel (77c3e1550) * Split up patch 210 (for correct creation nx-libs, nx-libs-lite tarballs): -2014-06-30 14:43:02 +0200 Mike Gabriel (035de82) +2014-06-30 14:43:02 +0200 Mike Gabriel (035de8281) * release 3.5.0.26 (tag: redist-server/3.5.0.26, tag: redist-client/3.5.0.26) -2014-06-30 14:42:40 +0200 Mike Gabriel (9c7bf9d) +2014-06-30 14:42:40 +0200 Mike Gabriel (9c7bf9da2) * Fix patch names... -2014-06-30 14:25:25 +0200 Mike Gabriel (c927045) +2014-06-30 14:25:25 +0200 Mike Gabriel (c92704558) * Continue development... -2014-06-30 14:14:35 +0200 Mike Gabriel (752a80c) +2014-06-30 14:14:35 +0200 Mike Gabriel (752a80cee) * release 3.5.0.25 (tag: redist-server/3.5.0.25, tag: redist-client/3.5.0.25) -2014-06-29 15:34:25 +0200 Mike Gabriel (2a31f67) +2014-06-29 15:34:25 +0200 Mike Gabriel (2a31f67c7) * changelog fix -2014-06-29 15:11:31 +0200 Mike Gabriel (cf029b6) +2014-06-29 15:11:31 +0200 Mike Gabriel (cf029b619) * Add 212_nxcomp_build-on-Android.patch. Fix FTBFS of nxproxy/nxcomp when build against the Android system. (Fixes: #339). -2014-06-27 17:40:00 +0200 Mike Gabriel (fa886df) +2014-06-27 17:40:00 +0200 Mike Gabriel (fa886dff8) * update patch name in changelog -2014-06-27 17:39:00 +0200 Mike Gabriel (e474a3f) +2014-06-27 17:39:00 +0200 Mike Gabriel (e474a3f35) * update changelog, update patches -2014-06-27 10:52:52 +0200 Oleksandr Shneyder (92a0f58) +2014-06-27 10:52:52 +0200 Oleksandr Shneyder (92a0f58e8) * Rename Patches 210 and 211. Update series file. -2014-06-27 02:01:15 +0200 Mike Gabriel (0cf283d) +2014-06-27 02:01:15 +0200 Mike Gabriel (0cf283dca) * Add 206_nxagent_clipboard-as-nxoption.full.patch. Make the clipboard option configurable in nxagent via NX options as @@ -6441,13 +6684,13 @@ option. Possible values are both or 1, client, server, none or 0. -2014-06-25 11:43:44 +0200 Oleksandr Shneyder (c62b813) +2014-06-25 11:43:44 +0200 Oleksandr Shneyder (c62b81304) * Add 211_nxcomp_set_default_options.patch. Set default arguments for options 'link' and 'pack' to avoid session damage by resuming with incorrect options file. -2014-06-25 10:02:02 +0200 Oleksandr Shneyder (9f6eb6f) +2014-06-25 10:02:02 +0200 Oleksandr Shneyder (9f6eb6f79) * Add 210_nxagent_nxcomp_save_session_state.patch. Save session state in path specified by "state" option in agent options file. @@ -6455,7 +6698,7 @@ Session states are: STARTING, RUNNING, SUSPENDING, SUSPENDED, RESUMING, TERMINATING, TERMINATED. -2014-06-25 09:59:35 +0200 Oleksandr Shneyder (480a055) +2014-06-25 09:59:35 +0200 Oleksandr Shneyder (480a05519) * Revert "Add 210_nxagent_nxcomp_save_session_state.patch. Save session state in path specified by "state" option in agent @@ -6463,7 +6706,7 @@ be saved. Session states are: STARTING, RUNNING, SUSPENDING, SUSPENDED, RESUMING, TERMINATING, TERMINATED." -2014-06-25 09:57:42 +0200 Oleksandr Shneyder (fcd9b71) +2014-06-25 09:57:42 +0200 Oleksandr Shneyder (fcd9b71bc) * Add 210_nxagent_nxcomp_save_session_state.patch. Save session state in path specified by "state" option in agent options file. @@ -6471,49 +6714,49 @@ Session states are: STARTING, RUNNING, SUSPENDING, SUSPENDED, RESUMING, TERMINATING, TERMINATED. -2014-06-22 09:16:45 +0200 Mike Gabriel (7154096) +2014-06-22 09:16:45 +0200 Mike Gabriel (7154096b7) * fix changelog entry for patch 057 -2014-06-22 09:16:02 +0200 Mike Gabriel (c00d269) +2014-06-22 09:16:02 +0200 Mike Gabriel (c00d26974) * fix Description: in patch 057 -2014-06-22 09:14:35 +0200 Mike Gabriel (ead0f65) +2014-06-22 09:14:35 +0200 Mike Gabriel (ead0f653f) * Rename patches to match our naming scheme: -2014-06-22 09:07:56 +0200 Mike Gabriel (53a0a47) +2014-06-22 09:07:56 +0200 Mike Gabriel (53a0a47b8) * renmae patch 057 -2014-06-21 23:40:09 +0200 Mike Gabriel (d8c9f89) +2014-06-21 23:40:09 +0200 Mike Gabriel (d8c9f89b1) * update description for patch 057_nx-X11-bigendian-ppc64-no-session-window.full.patch as proposed by the patch author -2014-06-21 23:20:33 +0200 Mike Gabriel (eca0ee9) +2014-06-21 23:20:33 +0200 Mike Gabriel (eca0ee98c) * Update patches, to make them apply cleanly after above changes: -2014-06-21 23:17:41 +0200 Mike Gabriel (8be0a04) +2014-06-21 23:17:41 +0200 Mike Gabriel (8be0a0472) * fix 057, rebase -2014-06-21 23:04:16 +0200 Mihai Moldovan (abbe7e8) +2014-06-21 23:04:16 +0200 Mihai Moldovan (abbe7e840) * Add 990_fix-DEBUG-and-TEST-builds.full.patch. Fix debug builds (e.g. when globally setting -DDEBUG and -DTEST at build time). -2014-06-21 22:39:10 +0200 Mihai Moldovan (3446d14) +2014-06-21 22:39:10 +0200 Mihai Moldovan (3446d14ea) * Improve 028_nx-X11_abstract-kernel-sockets.full.patch. Make it more Big Endian robust by assigning correct types for socklen_t objects. -2014-06-21 22:35:47 +0200 Mihai Moldovan (afcc7a9) +2014-06-21 22:35:47 +0200 Mihai Moldovan (afcc7a93d) * Improve 105_nxagent_export-remote-keyboard-config.full.patch. Don't print out nonsensical information, if there really was no @@ -6522,235 +6765,235 @@ keyboard file. Only print an error message if SessionPath *really* is not defined. -2014-06-21 22:29:44 +0200 Mihai Moldovan (cfb1990) +2014-06-21 22:29:44 +0200 Mihai Moldovan (cfb1990d4) * Add 057_nx-X11-bigendian-ppc64-no-session-window.patch. Fix failures in session windows coming up on Big Endian systems like PPC64. (Fixes: #516). -2014-06-15 01:03:15 +0200 Mike Gabriel (359c458) +2014-06-15 01:03:15 +0200 Mike Gabriel (359c458f1) * update last committed patch, fix EOL style -2014-06-15 00:49:26 +0200 Mike Gabriel (ecd6d4e) +2014-06-15 00:49:26 +0200 Mike Gabriel (ecd6d4e85) * giving credits to Mihai for digging out patch 029_nxcomp_ppc64.full+lite.patch -2014-06-15 00:33:28 +0200 Mike Gabriel (36f4e34) +2014-06-15 00:33:28 +0200 Mike Gabriel (36f4e34b2) * Add 029_nxcomp_ppc64.full+lite.patch. Fix sockaddr handling on Big Endian systems (like PPC64). (Fixes: #515). -2014-06-13 01:55:49 +0200 Mike Gabriel (75987a7) +2014-06-13 01:55:49 +0200 Mike Gabriel (75987a76f) * Add 302_nx-X11_xkbbasedir-detection.patch. For detecting XkbBaseDir test for xkb/rules/base instead of testing for deprecated file xkb/keymap.dir. (Fixes: #40). -2014-06-11 16:37:37 +0200 Mike Gabriel (e30d46d) +2014-06-11 16:37:37 +0200 Mike Gabriel (e30d46d85) * Make 016_nx-X11_install-location.debian.patch cleanly apply again. -2014-06-11 16:35:13 +0200 Mike Gabriel (656f29c) +2014-06-11 16:35:13 +0200 Mike Gabriel (656f29cc6) * Add 028_nx-X11_abstract-kernel-sockets.full.patch. Provide abstract local socket support for Linux based systems. This patch pulls in abstract socket relevant code from xtrans 1.2.7. -2014-06-11 14:48:08 +0200 Mike Gabriel (9268d27) +2014-06-11 14:48:08 +0200 Mike Gabriel (9268d270e) * Wrap too-long-line in changelog. -2014-06-11 12:25:52 +0200 Mike Gabriel (065dcc9) +2014-06-11 12:25:52 +0200 Mike Gabriel (065dcc903) * fix patch name -2014-06-11 10:43:14 +0200 Mike Gabriel (5a07d00) +2014-06-11 10:43:14 +0200 Mike Gabriel (5a07d00e0) * Make 220_nxproxy-bind-loopback-only.full+lite.patch cleanly apply after having added 027_nxcomp_abstract-X11-socket.patch. -2014-06-11 10:42:04 +0200 Mike Gabriel (57fb5bb) +2014-06-11 10:42:04 +0200 Mike Gabriel (57fb5bb57) * Add 027_nxcomp_abstract-X11-socket.patch. In proxy mode server let NX proxy attempt connecting to the abstract X11 socket first, and only fallback to the file system socket, if the abstract socket is not available. (Fixes: #505). -2014-05-09 12:57:23 +0200 Mike Gabriel (eb36421) +2014-05-09 12:57:23 +0200 Mike Gabriel (eb3642101) * Add 606_nx-X11_build-on-aarch64.full.patch. Build on aarch64 architectures. (Fixes: #490). -2014-05-07 09:59:08 +0200 Mike Gabriel (21ba6e2) +2014-05-07 09:59:08 +0200 Mike Gabriel (21ba6e22c) * Continue development... -2014-05-07 09:56:12 +0200 Mike Gabriel (460a3cb) +2014-05-07 09:56:12 +0200 Mike Gabriel (460a3cb39) * release 3.5.0.24 (tag: redist-server/3.5.0.24, tag: redist-client/3.5.0.24) -2014-05-07 09:55:40 +0200 Mike Gabriel (c6f84a4) +2014-05-07 09:55:40 +0200 Mike Gabriel (c6f84a448) * Configurable keystrokes: Don't ignore first XML element in keystrokes.cfg anymore. (Fixes: #488). -2014-05-07 09:38:04 +0200 Mike Gabriel (7e55c36) +2014-05-07 09:38:04 +0200 Mike Gabriel (7e55c36f4) * Update 320_nxagent_configurable-keystrokes.full.patch: The keystrokes config file's default name now is keystrokes.cfg (plural). -2014-05-07 09:24:45 +0200 Mike Gabriel (a481c13) +2014-05-07 09:24:45 +0200 Mike Gabriel (a481c137a) * Debian lintian: Fix: nx-libs source: not-binnmuable-all-depends-any x2goagent -> nxagent. -2014-05-07 09:08:13 +0200 Mike Gabriel (440fd40) +2014-05-07 09:08:13 +0200 Mike Gabriel (440fd40c5) * Make sure, patch 056_nx-X11-Werror-format-security.full.patch gets included into rolled tarball (by renaming *.patch to *.full.patch). -2014-05-07 09:04:55 +0200 Mike Gabriel (a8be15e) +2014-05-07 09:04:55 +0200 Mike Gabriel (a8be15e1d) * Clean debian/patches/series: Remove commented out patches. -2014-05-06 18:34:53 +0200 Mike Gabriel (43ee510) +2014-05-06 18:34:53 +0200 Mike Gabriel (43ee5101c) * Continue development... -2014-05-06 18:06:05 +0200 Mike Gabriel (085bfbd) +2014-05-06 18:06:05 +0200 Mike Gabriel (085bfbd25) * release 3.5.0.23 (tag: redist-server/3.5.0.23, tag: redist-client/3.5.0.23) -2014-05-06 17:59:42 +0200 Mike Gabriel (f0aa665) +2014-05-06 17:59:42 +0200 Mike Gabriel (f0aa66536) * fix changelog -2014-05-06 13:27:49 +0200 Oleksandr Shneyder (a544b9d) +2014-05-06 13:27:49 +0200 Oleksandr Shneyder (a544b9d4c) * nxagent: add patch to fix refresh error on RDP connections to Windows 2012 if speed=ADSL. -2014-03-29 21:22:59 +0100 Mike Gabriel (4bbcbe5) +2014-03-29 21:22:59 +0100 Mike Gabriel (4bbcbe505) * Add patch: 056_nx-X11-Werror-format-security.patch. Fix more -Werror=format-security errors that only show up on ARM builds. (Fixes: #423). -2014-01-28 23:47:15 +0100 Mike Gabriel (d999822) +2014-01-28 23:47:15 +0100 Mike Gabriel (d999822bf) * nx-libs.spec: Build our imake against xorg-x11-proto-devel. -2014-01-28 23:45:10 +0100 Mike Gabriel (d95e47f) +2014-01-28 23:45:10 +0100 Mike Gabriel (d95e47f3b) * debian/control: Build our imake against x11proto-core-dev headers. -2014-01-28 19:48:21 +0100 Mike Gabriel (faa289a) +2014-01-28 19:48:21 +0100 Mike Gabriel (faa289a82) * nx-libs.spec: Sync nx-libs.spec in Fedora with upstream's nx-libs.spec file. (Fixes: #393). -2014-01-28 19:41:15 +0100 Mike Gabriel (fc91d4d) +2014-01-28 19:41:15 +0100 Mike Gabriel (fc91d4d04) * Add patch: 055_nx-X11_imake-Werror-format-security.full.patch. Fix FTBFS of imake on current Fedora rawhide (21) which uses the compiler option -Werror=format-security for all builds. (Fixes: #412). -2014-01-28 19:40:45 +0100 Mike Gabriel (d5f2bbb) +2014-01-28 19:40:45 +0100 Mike Gabriel (d5f2bbb3d) * fix patch 054_nx-X11_ppc64-ftbfs.full.patch -2014-01-28 19:32:53 +0100 Mike Gabriel (54f3975) +2014-01-28 19:32:53 +0100 Mike Gabriel (54f39758c) * Add patch: 054_nx-X11_ppc64-ftbfs.full.patch. Fix FTBFS on ppc64 architecture. (Fixes: #411). -2014-01-04 22:03:44 +0100 Mike Gabriel (e8a69d2) +2014-01-04 22:03:44 +0100 Mike Gabriel (e8a69d261) * Continue development... -2014-01-04 22:02:09 +0100 Mike Gabriel (80d10df) +2014-01-04 22:02:09 +0100 Mike Gabriel (80d10df87) * release hotfix build -2014-01-04 22:01:16 +0100 Mike Gabriel (0d07f3e) +2014-01-04 22:01:16 +0100 Mike Gabriel (0d07f3e8b) * Update version in VERSION.x2goagent. -2014-01-04 21:39:35 +0100 Mike Gabriel (626b5db) +2014-01-04 21:39:35 +0100 Mike Gabriel (626b5dbae) * release 3.5.0.22 (tag: redist-server/3.5.0.22, tag: redist-client/3.5.0.22) -2013-12-17 21:03:26 +0100 Mike Gabriel (1d074b1) +2013-12-17 21:03:26 +0100 Mike Gabriel (1d074b1ae) * nx-libs.spec: fix symlink creation for Xinerama (missing subfolder) -2013-12-17 17:16:47 +0100 Mike Gabriel (edbd95b) +2013-12-17 17:16:47 +0100 Mike Gabriel (edbd95b90) * attempt to correct symlink creation for Xinerama support -2013-12-17 12:32:34 +0100 Mike Gabriel (36cdfdc) +2013-12-17 12:32:34 +0100 Mike Gabriel (36cdfdcb5) * Make sure all nx-libs components depend on the very same version. -2013-12-17 12:09:54 +0100 Mike Gabriel (a96a43f) +2013-12-17 12:09:54 +0100 Mike Gabriel (a96a43f14) * Enable Xinerama support for RPM packages. (Fixes: #370). -2013-12-17 11:50:25 +0100 Mike Gabriel (ded2017) +2013-12-17 11:50:25 +0100 Mike Gabriel (ded201707) * Drop symlinking libNX_xrandr for setting a custom LD_LIBRARY_PATH. Not in use anymore and not recommended at all to have that. -2013-12-08 12:05:46 +0100 Mike Gabriel (a6ab07d) +2013-12-08 12:05:46 +0100 Mike Gabriel (a6ab07de8) * Clear (Fedora package) changelog. -2013-12-13 18:48:59 +0100 Mike Gabriel (501112b) +2013-12-13 18:48:59 +0100 Mike Gabriel (501112b2a) * nx-libs.spec: x2goagent does not depend on x2goserver (rather vice versa) -2013-12-13 18:24:09 +0100 Mike Gabriel (3fbb9ca) +2013-12-13 18:24:09 +0100 Mike Gabriel (3fbb9ca30) * nx-libs.spec: fix spellings in package descriptions -2013-12-08 01:19:44 +0100 Mike Gabriel (19033a1) +2013-12-08 01:19:44 +0100 Mike Gabriel (19033a157) * make sure our RPM package version is lower than a package version from EPEL -2013-12-08 00:27:53 +0100 Mike Gabriel (ce11917) +2013-12-08 00:27:53 +0100 Mike Gabriel (ce11917ad) * typo fix -2013-12-08 00:07:14 +0100 Mike Gabriel (703a67a) +2013-12-08 00:07:14 +0100 Mike Gabriel (703a67ac7) * compensate missing %buildroot macro in EPEL5 -2013-12-07 23:04:18 +0100 Mike Gabriel (51afd69) +2013-12-07 23:04:18 +0100 Mike Gabriel (51afd69b2) * The RPM macro for the linker flags does not exist on EPEL. Thus, hardcode __global_ldflags macro for EPEL builds. -2013-12-07 22:11:17 +0100 Mike Gabriel (1ac043b) +2013-12-07 22:11:17 +0100 Mike Gabriel (1ac043b94) * debian/rules: Remove bundled libraries from source tree before building the package. -2013-12-06 15:42:26 +0100 Mike Gabriel (1061630) +2013-12-06 15:42:26 +0100 Mike Gabriel (1061630f1) * adapt spec file to last commit -2013-12-06 15:39:59 +0100 Mike Gabriel (523d505) +2013-12-06 15:39:59 +0100 Mike Gabriel (523d50529) * Improve patch: 601_nx-X11_build-option-changes-to-not-use-bundled-libraries.full.patch. @@ -6758,81 +7001,81 @@ to Orion Paplowski!!! Also adapt roll-tarball.sh do dropping more bundled libraries. -2013-12-06 15:20:15 +0100 Mike Gabriel (40aa275) +2013-12-06 15:20:15 +0100 Mike Gabriel (40aa275cd) * Add patch: 302_nx-X11_do-not-build-bundled-libs.full.patch. Rename patch: 302_nxagent_configurable-keystrokes.full.patch. -2013-12-06 15:06:42 +0100 Mike Gabriel (e3da345) +2013-12-06 15:06:42 +0100 Mike Gabriel (e3da34510) * prep source tree after unpacking tarball, bring files from debian/ folder in place before building the RPM package -2013-12-06 14:54:38 +0100 Mike Gabriel (21cde6e) +2013-12-06 14:54:38 +0100 Mike Gabriel (21cde6e42) * nx-libs.spec: Use local tarball, don't expect ,,-full'' in tarball name. -2013-12-06 14:50:59 +0100 Mike Gabriel (2fceb10) +2013-12-06 14:50:59 +0100 Mike Gabriel (2fceb10d2) * nx-libs.specs: remove duplication of file contents -2013-12-06 13:55:53 +0100 Mike Gabriel (8c78f32) +2013-12-06 13:55:53 +0100 Mike Gabriel (8c78f3204) * Ship nx-libs.spec (RPM package definitions) in upstream project. (Thanks to the Fedora package maintainers). File differs from the Fedora file already. -2013-12-06 13:54:42 +0100 Mike Gabriel (b413799) +2013-12-06 13:54:42 +0100 Mike Gabriel (b413799fb) * Refresh patch: 600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch. -2013-12-03 21:33:08 +0100 Mike Gabriel (08312e2) +2013-12-03 21:33:08 +0100 Mike Gabriel (08312e2e1) * Add patch 605_nxcomp_Types.h-dont-use-STL-internals-on-libc++.full.patch. Fix FTBFS of nx-libs-lite on Mac OS X Mavericks. (Fixes: #337). -2013-12-03 15:08:30 +0100 Mike Gabriel (2382d88) +2013-12-03 15:08:30 +0100 Mike Gabriel (2382d8835) * Add patch 604_nx-X11_recent-freetype-API.full.patch. Fix FTBFS against recent (>= 2.5.0) libfreetype6 API. -2013-11-30 21:55:36 +0100 Mike Gabriel (8cd7d82) +2013-11-30 21:55:36 +0100 Mike Gabriel (8cd7d82d7) * debian/control: Add libfreetype6-dev to Build-Depends: field. -2013-11-29 12:37:48 +0100 Mike Gabriel (c50b2a9) +2013-11-29 12:37:48 +0100 Mike Gabriel (c50b2a90e) * change versioning scheme -2013-11-27 14:54:44 +0100 Mike Gabriel (ca414e1) +2013-11-27 14:54:44 +0100 Mike Gabriel (ca414e175) * debian/source/format: Switch to format 1.0. -2013-09-30 21:00:41 +0200 Mike Gabriel (2ef4ab4) +2013-09-30 21:00:41 +0200 Mike Gabriel (2ef4ab414) * Add patch: 603_nx-X11_compilation_warnings.full.patch. Fix 3 evident bugs: one implicit function declaration issue and two array index out of bounds issues. (Fixes: #314). -2013-08-30 16:20:29 +0200 Mike Gabriel (b29654d) +2013-08-30 16:20:29 +0200 Mike Gabriel (b29654d54) * Continue development... -2013-08-30 16:18:40 +0200 Mike Gabriel (b2a3143) +2013-08-30 16:18:40 +0200 Mike Gabriel (b2a3143f8) * release 3.5.0.21 (tag: redist-server/3.5.0.21, tag: redist-client/3.5.0.21) -2013-08-29 22:58:19 +0200 Mike Gabriel (13f2b57) +2013-08-29 22:58:19 +0200 Mike Gabriel (13f2b57d4) * Fix keystrokes.cfg, use Ctrl+Alt+ instead of just Ctrl+. (Adds to fixing #223). -2013-08-29 22:24:26 +0200 Mike Gabriel (0946b43) +2013-08-29 22:24:26 +0200 Mike Gabriel (0946b4375) * Add patch: 602_nx-X11_initgroups.full.patch. Fix calling setuid and setgid without setgroups or initgroups. There is a high @@ -6841,641 +7084,641 @@ Seek POS36-C on the web for details about the problem. (Fixes: #293). -2013-08-29 20:48:09 +0200 Mike Gabriel (e46b434) +2013-08-29 20:48:09 +0200 Mike Gabriel (e46b43443) * fix underscore in name of patch 601_... -2013-07-19 19:27:09 +0200 Mike Gabriel (2a41a2c) +2013-07-19 19:27:09 +0200 Mike Gabriel (2a41a2ca5) * /debian/nx-libs-dev.install: Remove unrelated files from -dev package. -2013-07-19 19:26:37 +0200 Mike Gabriel (19ef7a2) +2013-07-19 19:26:37 +0200 Mike Gabriel (19ef7a2ca) * /debian/control: Add B-Ds: libfontconfig1-dev, libfontenc-dev. -2013-07-19 19:25:05 +0200 Orion Poplawski (9113131) +2013-07-19 19:25:05 +0200 Orion Poplawski (9113131a7) * Change build options so that bundled libraries are not used anymore at build time. Remove bundled libraries from rolled tarballs, as well. (Fixes: #116, #238). -2013-05-29 19:02:02 +0200 Mike Gabriel (d90c457) +2013-05-29 19:02:02 +0200 Mike Gabriel (d90c457c4) * Use a keystrokes.cfg that reflects the normally hard-coded defaults of a vanilla nxagent. (Fixes: #223). -2013-05-11 20:40:57 +0200 Mike Gabriel (ead1e82) +2013-05-11 20:40:57 +0200 Mike Gabriel (ead1e823a) * * Tarball roller script: + Only install keystrokes.cfg when in full mode. + Only install nxproxy wrapper when in lite mode. -2013-05-08 14:21:49 +0200 Mike Gabriel (4c462f2) +2013-05-08 14:21:49 +0200 Mike Gabriel (4c462f28d) * addition to last commit -2013-05-07 20:20:43 +0200 Mike Gabriel (dafbbf2) +2013-05-07 20:20:43 +0200 Mike Gabriel (dafbbf21a) * For vanilla nxagent move keystrokes.cfg from /etc/nx to /etc/nxagent. -2013-05-07 20:03:27 +0200 Mike Gabriel (995b70c) +2013-05-07 20:03:27 +0200 Mike Gabriel (995b70cdc) * /debian/rules: clean etc/keystrokes.cfg symlink -2013-05-07 20:00:51 +0200 Mike Gabriel (ee35c3f) +2013-05-07 20:00:51 +0200 Mike Gabriel (ee35c3ff9) * fix broker symlink -2013-05-06 23:09:35 +0200 Mike Gabriel (e0fb697) +2013-05-06 23:09:35 +0200 Mike Gabriel (e0fb697e9) * Set NXAGENT_KEYSTROKEFILE to /etc/x2go/keystrokes.cfg for wrapper x2goagent. -2013-05-06 22:44:32 +0200 Mike Gabriel (fc118b4) +2013-05-06 22:44:32 +0200 Mike Gabriel (fc118b4bb) * add forgotten file: debian/keystrokes.cfg -2013-05-06 22:38:51 +0200 Mike Gabriel (d8a55d2) +2013-05-06 22:38:51 +0200 Mike Gabriel (d8a55d2c6) * Provide a default keystrokes.cfg in /etc/nx (for nxagent) and /etc/x2go (for x2goagent). (Fixes: #199). -2013-03-28 21:09:09 +0100 Mike Gabriel (dc5faf7) +2013-03-28 21:09:09 +0100 Mike Gabriel (dc5faf7af) * increment version in VERSION.x2goagent -2013-03-28 21:07:59 +0100 Mike Gabriel (121f7ca) +2013-03-28 21:07:59 +0100 Mike Gabriel (121f7ca9d) * Continue development... -2013-03-28 20:43:53 +0100 Mike Gabriel (225445d) +2013-03-28 20:43:53 +0100 Mike Gabriel (225445db3) * release 3.5.0.20 (tag: redist-server/3.5.0.20, tag: redist-client/3.5.0.20) -2013-03-28 20:43:14 +0100 Mike Gabriel (ef0c6b4) +2013-03-28 20:43:14 +0100 Mike Gabriel (ef0c6b4b8) * add bug closure for #156 -2013-03-28 15:27:57 +0100 Mike Gabriel (bd2eb48) +2013-03-28 15:27:57 +0100 Mike Gabriel (bd2eb481a) * Fix faulty symlink path. Make sure that x2goagent symlink does not point to absolute path somewhere within the build environment. -2013-03-28 09:12:07 +0100 Mike Gabriel (5ff8e62) +2013-03-28 09:12:07 +0100 Mike Gabriel (5ff8e62d1) * Continue development... -2013-03-28 08:59:14 +0100 Mike Gabriel (436d067) +2013-03-28 08:59:14 +0100 Mike Gabriel (436d06739) * release 3.5.0.19 (tag: redist-server/3.5.0.19, tag: redist-client/3.5.0.19) -2013-03-28 08:58:35 +0100 Mike Gabriel (db7feaf) +2013-03-28 08:58:35 +0100 Mike Gabriel (db7feaf98) * Revert "release 3.5.0.19" -2013-03-28 08:55:23 +0100 Mike Gabriel (e77bf36) +2013-03-28 08:55:23 +0100 Mike Gabriel (e77bf36d9) * release 3.5.0.19 -2013-03-28 08:55:00 +0100 Mike Gabriel (d16188f) +2013-03-28 08:55:00 +0100 Mike Gabriel (d16188f08) * fix my mail address in changelog -2013-03-28 08:43:52 +0100 Mike Gabriel (478015e) +2013-03-28 08:43:52 +0100 Mike Gabriel (478015eb1) * increment version in VERSION.x2goagent -2013-03-28 08:42:56 +0100 Mike Gabriel (a40d4b7) +2013-03-28 08:42:56 +0100 Mike Gabriel (a40d4b7b1) * Fix FTBFS for .deb packages after including fix for #145. -2013-03-23 00:43:17 +0100 Mike Gabriel (1af59b3) +2013-03-23 00:43:17 +0100 Mike Gabriel (1af59b317) * Add Jan's reasoning for using string_rep() instead of bash based string substitutions as comment to /debian/Makefile.replaces.sh. -2013-03-22 23:40:44 +0100 Mike Gabriel (1b4092e) +2013-03-22 23:40:44 +0100 Mike Gabriel (1b4092e0f) * release 3.5.0.18 (tag: redist-server/3.5.0.18, tag: redist-client/3.5.0.18) -2013-03-22 23:35:40 +0100 Mike Gabriel (f81df1a) +2013-03-22 23:35:40 +0100 Mike Gabriel (f81df1a69) * Main Makefile: Use absolute symlink when linking from $(X2GOLIBDIR) into $(NXLIBDIR) (i.e. linking x2goagent -> nxagent). (Fixes: #143). -2013-03-22 22:33:40 +0100 Mike Gabriel (8f151d7) +2013-03-22 22:33:40 +0100 Mike Gabriel (8f151d797) * Work-in patch from Jan Engehardt for working around different improper bash implementations of string-in-string replacing. (Fixes: #145). -2013-02-12 08:32:30 +0100 Orion Poplawski (258902b) +2013-02-12 08:32:30 +0100 Orion Poplawski (258902bec) * Avoid building of libxcomp1 (which actually is identical to libxcomp3, just with a wrong name). (Fixes: #104). -2013-02-12 08:13:37 +0100 Orion Poplawski (d439556) +2013-02-12 08:13:37 +0100 Orion Poplawski (d439556ff) * Fix wrong symlink direction of libNX_* files. (Fixes: #107). -2013-01-21 10:35:47 +0100 Mike Gabriel (cf521a4) +2013-01-21 10:35:47 +0100 Mike Gabriel (cf521a4b6) * increment VERSION.x2goagent -2013-01-08 00:39:32 +0100 Mike Gabriel (c8a5fdd) +2013-01-08 00:39:32 +0100 Mike Gabriel (c8a5fddf1) * replaces Closes: by Fixes: statements in changelog -2013-01-07 10:45:58 +0100 Mike Gabriel (b121300) +2013-01-07 10:45:58 +0100 Mike Gabriel (b121300fd) * Remove duplicate install of nxproxy from main Makefile. Spotted by Jan Engelhard. -2013-01-04 13:27:41 +0100 Mike Gabriel (39e8422) +2013-01-04 13:27:41 +0100 Mike Gabriel (39e84229d) * Continue development... -2013-01-04 13:24:18 +0100 Mike Gabriel (69c809a) +2013-01-04 13:24:18 +0100 Mike Gabriel (69c809af9) * release 3.5.0.17 (tag: redist-server/3.5.0.17, tag: redist-client/3.5.0.17) -2013-01-03 08:03:46 +0100 Mike Gabriel (1d76694) +2013-01-03 08:03:46 +0100 Mike Gabriel (1d7669458) * let nx-x11-dbg depend on libnx-x11 and nxagent -2013-01-03 08:02:57 +0100 Mike Gabriel (abc2ce3) +2013-01-03 08:02:57 +0100 Mike Gabriel (abc2ce3f8) * fix multiple binaries-have-file-conflicts lintian issue -2013-01-02 17:41:04 +0100 Mike Gabriel (1737171) +2013-01-02 17:41:04 +0100 Mike Gabriel (17371711f) * add misc:Depends to nx-x11-dbg -2013-01-02 17:40:49 +0100 Mike Gabriel (62f66b0) +2013-01-02 17:40:49 +0100 Mike Gabriel (62f66b02a) * fix multiple binaries-have-file-conflicts lintian issue -2013-01-02 15:55:33 +0100 Mike Gabriel (bfe6f43) +2013-01-02 15:55:33 +0100 Mike Gabriel (bfe6f4349) * Continue Reinhard's work on top-level install/uninstall. Esp. integrate debian/post-nx-build.sh into main Makefile. Make value of CONFIGURE variable traversable through the Makefile tree. -2013-01-02 14:58:22 +0100 Mike Gabriel (36a2247) +2013-01-02 14:58:22 +0100 Mike Gabriel (36a2247e0) * fix lintian: missing-separator-between-items in x2goagent depends field between nxagent (>= ${source:Version}) and ${misc:Depends} -2012-12-15 14:45:26 +0100 Reinhard Tartler (300bafb) +2012-12-15 14:45:26 +0100 Reinhard Tartler (300bafb1a) * integrate install and uninstall rules into the top-level Makefile -2012-12-15 14:58:58 +0100 Reinhard Tartler (978aaa0) +2012-12-15 14:58:58 +0100 Reinhard Tartler (978aaa0a4) * integrate nx*/x2go* shell wrappers into debian/wrappers -2012-12-16 11:40:09 +0100 Reinhard Tartler (918e2b1) +2012-12-16 11:40:09 +0100 Reinhard Tartler (918e2b10d) * Use Fixes instead of Closes syntax -2012-12-15 15:05:33 +0100 Reinhard Tartler (352751e) +2012-12-15 15:05:33 +0100 Reinhard Tartler (352751ef9) * simplify clean rule in debian/rules -2012-12-16 00:00:09 +0100 Mike Gabriel (f2011a7) +2012-12-16 00:00:09 +0100 Mike Gabriel (f2011a718) * add closure for #87 -2012-12-15 14:29:41 +0100 Reinhard Tartler (08d568a) +2012-12-15 14:29:41 +0100 Reinhard Tartler (08d568a2c) * reenable parallel builds -2012-12-15 14:29:25 +0100 Reinhard Tartler (d123923) +2012-12-15 14:29:25 +0100 Reinhard Tartler (d123923a5) * update 031_nx-X11_parallel-make.full.patch. -2012-12-13 13:11:40 +0100 Mike Gabriel (0ef5ea2) +2012-12-13 13:11:40 +0100 Mike Gabriel (0ef5ea2eb) * add changelog entries for Reinhard's previous commits -2012-12-13 12:19:20 +0100 Reinhard Tartler (682c807) +2012-12-13 12:19:20 +0100 Reinhard Tartler (682c80705) * fix installation of libxcompext -2012-12-12 12:48:34 +0100 Reinhard Tartler (e559c75) +2012-12-12 12:48:34 +0100 Reinhard Tartler (e559c7522) * delete nxproxy/configure -2012-12-12 12:47:54 +0100 Reinhard Tartler (9a3737b) +2012-12-12 12:47:54 +0100 Reinhard Tartler (9a3737b14) * drop debian/patches/025_nxproxy_no-configure-file.full+lite.patch -2012-12-12 15:20:44 +0100 Reinhard Tartler (b09b686) +2012-12-12 15:20:44 +0100 Reinhard Tartler (b09b686cf) * add rewritten roll-tarballs.sh script -2012-12-12 12:45:41 +0100 Reinhard Tartler (d139e5d) +2012-12-12 12:45:41 +0100 Reinhard Tartler (d139e5d3d) * drop debian/patches/001_add-main-makefile.full+lite.patch -2012-12-12 12:42:03 +0100 Reinhard Tartler (a12ad50) +2012-12-12 12:42:03 +0100 Reinhard Tartler (a12ad5050) * integrate debian/pre-build-nx.sh into debian/rules -2012-12-12 12:27:00 +0100 Reinhard Tartler (3970fab) +2012-12-12 12:27:00 +0100 Reinhard Tartler (3970fabc5) * Rely on shlibs files instead of hard coding library dependencies -2012-12-12 12:31:51 +0100 Reinhard Tartler (263523d) +2012-12-12 12:31:51 +0100 Reinhard Tartler (263523d7b) * disable parallel builds -2012-12-12 10:07:52 +0100 Reinhard Tartler (6b505a4) +2012-12-12 10:07:52 +0100 Reinhard Tartler (6b505a48a) * remove unnecessary build-conflict on xbitmaps -2012-12-12 10:30:57 +0100 Reinhard Tartler (d634c16) +2012-12-12 10:30:57 +0100 Reinhard Tartler (d634c16aa) * make xfonts-base a recommends -2012-12-12 13:23:37 +0100 Mike Gabriel (3727d73) +2012-12-12 13:23:37 +0100 Mike Gabriel (3727d736b) * add (forgotten) files belong to last commit -2012-12-12 13:20:39 +0100 Orion Poplawski (923b7c7) +2012-12-12 13:20:39 +0100 Orion Poplawski (923b7c7eb) * Add patches: 026_nxcomp*_honour-optflags.full*.patch. (Closes upstream issue #84). -2012-12-12 13:06:25 +0100 Mike Gabriel (016959d) +2012-12-12 13:06:25 +0100 Mike Gabriel (016959d11) * changelog cleanup -2012-12-12 13:05:56 +0100 Mike Gabriel (2410103) +2012-12-12 13:05:56 +0100 Mike Gabriel (241010302) * exchange X2Go by NX -2012-12-08 18:25:28 +0100 Reinhard Tartler (19685c5) +2012-12-08 18:25:28 +0100 Reinhard Tartler (19685c566) * install debug symbols for all packages in a new binary package 'nx-x11-dbg' -2012-12-06 09:07:09 +0100 Alexander Wuerstlein (26901cc) +2012-12-06 09:07:09 +0100 Alexander Wuerstlein (26901cc52) * Follow-up commit for 302_nxagent_configurable-keystrokes.full.patch, fixes FTBFS problem with the first version of that patch. -2012-12-04 15:28:00 +0100 Mike Gabriel (fe598a1) +2012-12-04 15:28:00 +0100 Mike Gabriel (fe598a1e5) * changelog entry for having added libxml2-dev to build dependencies -2012-12-04 15:27:00 +0100 Mike Gabriel (0def009) +2012-12-04 15:27:00 +0100 Mike Gabriel (0def0092f) * control file: add some kommata at EOLs, fix dependency of x2goagent on nxagent -2012-12-04 15:24:25 +0100 Mike Gabriel (6c9bd88) +2012-12-04 15:24:25 +0100 Mike Gabriel (6c9bd8865) * Add pkg-config to build dependencies. -2012-12-04 14:55:01 +0100 Mike Gabriel (2093e70) +2012-12-04 14:55:01 +0100 Mike Gabriel (2093e705a) * Add README.keystrokes to doc section of bin:package nxagent. -2012-12-04 14:54:30 +0100 Mike Gabriel (cf5ac17) +2012-12-04 14:54:30 +0100 Mike Gabriel (cf5ac17d6) * whitespace fix -2012-12-04 13:50:47 +0100 Mike Gabriel (2a112c1) +2012-12-04 13:50:47 +0100 Mike Gabriel (2a112c1c3) * add bug closure for X2Go BTS issue #74 -2012-12-04 13:49:18 +0100 Mike Gabriel (5938c38) +2012-12-04 13:49:18 +0100 Mike Gabriel (5938c38ae) * re-add renamed patch file -2012-12-04 13:48:12 +0100 Mike Gabriel (0a91caa) +2012-12-04 13:48:12 +0100 Mike Gabriel (0a91caa98) * Add patch: 302_nxagent_configurable-keystrokes.full.patch, replaces the... (fixing patch application, fixing up follow-up patches, cleaning up patch-system). -2012-12-04 13:31:01 +0100 Alexander Wuerstlein (34f232c) +2012-12-04 13:31:01 +0100 Alexander Wuerstlein (34f232c14) * Add patch: 210_nxagent_configurable-keystrokes.full.patch, replaces the hardcoded nxagent keybindings by a configurable table of keybindings. -2012-11-12 08:45:46 +0100 Mike Gabriel (5a640ef) +2012-11-12 08:45:46 +0100 Mike Gabriel (5a640efd1) * Fix /bin/Makefile. Add $(DESTDIR) to every install path. -2012-11-07 21:14:41 +0100 Mike Gabriel (9e8a279) +2012-11-07 21:14:41 +0100 Mike Gabriel (9e8a2792f) * Continue development... -2012-11-07 21:08:06 +0100 Mike Gabriel (3fd3096) +2012-11-07 21:08:06 +0100 Mike Gabriel (3fd30962b) * release 3.5.0.16 (tag: redist-server/3.5.0.16, tag: redist-client/3.5.0.16) -2012-11-07 21:07:43 +0100 Mike Gabriel (9568a16) +2012-11-07 21:07:43 +0100 Mike Gabriel (9568a1655) * Bump Debian Standards to 3.9.3 (no changes needed). Update Home page and Vcs information. -2012-11-07 21:05:47 +0100 Mike Gabriel (232f1a4) +2012-11-07 21:05:47 +0100 Mike Gabriel (232f1a46e) * Bump Debian Standards to 3.9.3 (no changes needed). -2012-11-07 20:36:04 +0100 Mike Gabriel (b246e9f) +2012-11-07 20:36:04 +0100 Mike Gabriel (b246e9f75) * Dropping empty override rules for quilt patch from /debian/rules. -2012-10-20 22:56:14 +0200 Mike Gabriel (45b9bb8) +2012-10-20 22:56:14 +0200 Mike Gabriel (45b9bb839) * Modify patch: 001_add-main-makefile.full+lite.patch. Add uninstall routine. -2012-10-20 22:27:26 +0200 Mike Gabriel (f801d40) +2012-10-20 22:27:26 +0200 Mike Gabriel (f801d405d) * Fix wrapper scripts: make sure all NX executables can be launched if NX gets installed via the tarball installation method. -2012-10-20 17:58:04 +0200 Mike Gabriel (d397710) +2012-10-20 17:58:04 +0200 Mike Gabriel (d39771037) * Modify patch: 001_add-main-makefile.full+lite.patch. Install nx* and x2goagent wrapper scripts during make install. -2012-10-20 09:33:11 +0200 Mike Gabriel (30d311a) +2012-10-20 09:33:11 +0200 Mike Gabriel (30d311a68) * Add patch: 025_nxproxy_no-configure-file.full+lite.patch. Remove unneeded build file from NoMachine's nxproxy sources. -2012-10-20 08:15:35 +0200 Mike Gabriel (380d239) +2012-10-20 08:15:35 +0200 Mike Gabriel (380d23968) * Add patches: 024_fix-make-clean.full.patch, 024_fix-make-clean.full+lite.patch. Fix clean-up of build tree after make build has run. -2012-10-20 08:05:53 +0200 Mike Gabriel (1e3d692) +2012-10-20 08:05:53 +0200 Mike Gabriel (1e3d69216) * drop build file from nx-libs tree -2012-10-19 09:56:26 +0200 Mike Gabriel (11980c7) +2012-10-19 09:56:26 +0200 Mike Gabriel (11980c79b) * Drop patch 032, fix other patches so that installation via make install installs NX components to /usr/local/lib/nx and /usr/local/include/nx. -2012-10-05 14:37:20 +0200 Mike Gabriel (fbb3ba9) +2012-10-05 14:37:20 +0200 Mike Gabriel (fbb3ba912) * Modify patch: 032_no-x11r6.full.patch. Install nx-X11 to /usr/local/lib/nx. Add patch: 032_no-x11r6.debian.patch. Use /usr/lib/nx for nx-X11 on Debian. -2012-10-05 14:26:48 +0200 Mike Gabriel (cd631e0) +2012-10-05 14:26:48 +0200 Mike Gabriel (cd631e0bc) * Fix patch file names concerning component nx-X11. -2012-09-28 15:18:07 +0200 Mike Gabriel (e3ba4bd) +2012-09-28 15:18:07 +0200 Mike Gabriel (e3ba4bdc6) * Fix installation of header files in Debian package. -2012-09-21 10:07:07 +0200 Mike Gabriel (21b09b8) +2012-09-21 10:07:07 +0200 Mike Gabriel (21b09b85b) * Continue development... -2012-09-21 10:03:00 +0200 Mike Gabriel (51412cd) +2012-09-21 10:03:00 +0200 Mike Gabriel (51412cd02) * release 3.5.0.15 (tag: redist-server/3.5.0.15, tag: redist-client/3.5.0.15) -2012-09-20 22:13:12 +0200 Mike Gabriel (9f1868d) +2012-09-20 22:13:12 +0200 Mike Gabriel (9f1868def) * mark issue #16 as closed by last added patch -2012-09-20 22:12:00 +0200 Mike Gabriel (dc30db8) +2012-09-20 22:12:00 +0200 Mike Gabriel (dc30db8a1) * fix patch name -2012-09-20 21:27:59 +0200 Oleksandr Shneyder (f6adfd1) +2012-09-20 21:27:59 +0200 Oleksandr Shneyder (f6adfd1fa) * Add patch: 204-nxagent_repaint-solidpict.full.patch. Fixes repainting of SolidFill pictures by nxagent/x2goagent on reconnects. -2012-09-17 18:50:50 +0200 Mike Gabriel (b8db519) +2012-09-17 18:50:50 +0200 Mike Gabriel (b8db5192d) * Add patch: 220_nxproxy-bind-loopback-only.full+lite.patch, adds loopback option to nxproxy options and forces nxproxy to bind to loopback devices only. -2012-09-17 16:50:15 +0200 Mike Gabriel (b9a7a1b) +2012-09-17 16:50:15 +0200 Mike Gabriel (b9a7a1b4f) * Add patch: 220_nxproxy-bind-loopback-only.patch, adds loopback option to nxproxy options and forces nxproxy to bind to loopback devices only. -2012-09-15 21:01:51 +0200 Mike Gabriel (f830090) +2012-09-15 21:01:51 +0200 Mike Gabriel (f83009075) * remove Priorty: extra from -dev package -2012-09-15 20:39:50 +0200 Mike Gabriel (78dc96a) +2012-09-15 20:39:50 +0200 Mike Gabriel (78dc96a39) * /debian/control: Maintainer change in package: X2Go Developers . Priority: optional. -2012-09-14 16:48:43 +0200 Mike Gabriel (2d63528) +2012-09-14 16:48:43 +0200 Mike Gabriel (2d6352839) * remove weird remainders of configure files... -2012-09-14 16:47:20 +0200 Mike Gabriel (b8605d4) +2012-09-14 16:47:20 +0200 Mike Gabriel (b8605d4d6) * Link libNX_Xrandr to a separate location where we can provide it as libXrandr. -2012-09-04 12:50:38 +0200 Mike Gabriel (189bfbe) +2012-09-04 12:50:38 +0200 Mike Gabriel (189bfbe14) * Make sure the NX_TEMP envvar gets set in all wrapper script for all nx* executables -2012-09-04 12:47:27 +0200 Mike Gabriel (8d2827b) +2012-09-04 12:47:27 +0200 Mike Gabriel (8d2827b2a) * Refresh patch 200_nxagent_check-binary-x2go-flavour.full.patch -2012-07-13 16:36:27 +0200 Mike Gabriel (3fdfd51) +2012-07-13 16:36:27 +0200 Mike Gabriel (3fdfd5142) * Add VERSION.x2goagent to package x2goagent package so x2goversion command lists up x2goagent in the list of X2Go server-side packages. -2012-06-28 22:22:00 +0200 Mike Gabriel (b42268b) +2012-06-28 22:22:00 +0200 Mike Gabriel (b42268b13) * Improve 020_add-nxagent-wrapper.full.patch: Properly set NX_TEMP, make sure nxagent launches even with pam_tmpdir.so being in use. -2012-06-28 22:20:57 +0200 Mike Gabriel (7b3d592) +2012-06-28 22:20:57 +0200 Mike Gabriel (7b3d592e6) * debian/changelog -2012-06-28 14:55:16 +0200 Mike Gabriel (6af3d3b) +2012-06-28 14:55:16 +0200 Mike Gabriel (6af3d3b80) * Continue development... -2012-06-28 14:52:41 +0200 Mike Gabriel (1363751) +2012-06-28 14:52:41 +0200 Mike Gabriel (136375188) * release 3.5.0.14 (tag: redist-server/3.5.0.14) -2012-06-28 12:31:01 +0200 Mike Gabriel (b65b83b) +2012-06-28 12:31:01 +0200 Mike Gabriel (b65b83ba4) * Drop patch: 109_nxagent_locale-utf8-compound-text.patch, the patch causes Qt applications to be rendered without window decorations when running in rootless window mode. -2012-06-04 08:19:19 +0200 Mike Gabriel (dd7b5eb) +2012-06-04 08:19:19 +0200 Mike Gabriel (dd7b5eb3c) * Add patch: 052_nxcomp_macos10-nxauth-location.full+lite.patch, change nxauth search location on Mac OS X to $NX_SYSTEM/nxauth to facilitate application bundle building. -2012-05-22 00:57:21 +0200 Mike Gabriel (e2e7008) +2012-05-22 00:57:21 +0200 Mike Gabriel (e2e7008b3) * New upstream release of nxagent (3.5.0-9). -2012-05-22 00:50:51 +0200 Mike Gabriel (fdaa240) +2012-05-22 00:50:51 +0200 Mike Gabriel (fdaa24043) * Merge branch 'nxagent' -2012-05-22 00:49:10 +0200 Mike Gabriel (222a4a2) +2012-05-22 00:49:10 +0200 Mike Gabriel (222a4a222) * Imported nxagent-3.5.0-9.tar.gz (origin/nxagent, gh-sunweaver/nxagent) -2012-05-11 23:57:35 +0200 Mike Gabriel (fe72988) +2012-05-11 23:57:35 +0200 Mike Gabriel (fe72988fb) * Continue development... -2012-05-11 23:52:39 +0200 Mike Gabriel (789c758) +2012-05-11 23:52:39 +0200 Mike Gabriel (789c75851) * release 3.5.0.13 (tag: redist-server/3.5.0.13) -2012-05-11 23:51:09 +0200 Mike Gabriel (3511e87) +2012-05-11 23:51:09 +0200 Mike Gabriel (3511e8791) * add patch header for 120_nxagent_libcairo-null-source-drawables.full.patch -2012-05-11 12:48:36 +0200 Mike Gabriel (45311f7) +2012-05-11 12:48:36 +0200 Mike Gabriel (45311f783) * Add patch: 120_nxagent_libcairo-null-source-drawables.full.patch, solves crashes of GTK applications based on libcairo 1.12.1+. -2012-03-17 17:22:51 +0100 Mike Gabriel (4372dfa) +2012-03-17 17:22:51 +0100 Mike Gabriel (4372dfa53) * Let nxagent Debian package depend on xfonts-base. -2012-03-17 17:21:50 +0100 Mike Gabriel (fc87c4f) +2012-03-17 17:21:50 +0100 Mike Gabriel (fc87c4fbb) * Revert "Let nxagent Debian package depend on xfonts-base." -2012-03-17 17:20:49 +0100 Mike Gabriel (ab04ba2) +2012-03-17 17:20:49 +0100 Mike Gabriel (ab04ba217) * Let nxagent Debian package depend on xfonts-base. -2012-03-07 21:01:44 +0100 Mike Gabriel (30110dd) +2012-03-07 21:01:44 +0100 Mike Gabriel (30110dd4a) * Continue development... -2012-03-07 20:51:27 +0100 Mike Gabriel (1b1a26a) +2012-03-07 20:51:27 +0100 Mike Gabriel (1b1a26ae6) * release 3.5.0.12 (tag: redist-server/3.5.0.12, tag: redist-client/3.5.0.12) -2012-03-01 22:31:35 +0100 Mike Gabriel (4f7c8d0) +2012-03-01 22:31:35 +0100 Mike Gabriel (4f7c8d079) * Re-introduce proper Xinerama support on non-multiarch systems. -2012-03-01 22:27:26 +0100 Mike Gabriel (95929b8) +2012-03-01 22:27:26 +0100 Mike Gabriel (95929b8a5) * no bashisms in package scripts -2012-03-01 22:26:38 +0100 Mike Gabriel (9b17e8a) +2012-03-01 22:26:38 +0100 Mike Gabriel (9b17e8a96) * changelog cleanup: fixing too-long-line -2012-03-01 22:13:32 +0100 Mike Gabriel (fb27493) +2012-03-01 22:13:32 +0100 Mike Gabriel (fb274937d) * Provide temporary workaround for installation on Debian 64bit with multiarch support (via libnx-x11.postinst and .prerm). -2012-03-01 22:06:08 +0100 Mike Gabriel (055436f) +2012-03-01 22:06:08 +0100 Mike Gabriel (055436f48) * fix wrong lib-name in libnx-x11.postinst -2012-03-01 21:53:28 +0100 Mike Gabriel (3776a6f) +2012-03-01 21:53:28 +0100 Mike Gabriel (3776a6f41) * typofix in libnx-x11.postinst -2012-03-01 21:12:54 +0100 Mike Gabriel (a71cebf) +2012-03-01 21:12:54 +0100 Mike Gabriel (a71cebf04) * Provide temporary workaround for installation on Debian 64bit with multiarch support. -2012-03-01 20:43:53 +0100 Mihai Moldovan (22d41ae) +2012-03-01 20:43:53 +0100 Mihai Moldovan (22d41ae20) * Update patch: 005_nxcomp_gcc43.full+lite.patch, fix faulty path to nxcomp/Split.cpp. -2012-03-01 20:39:37 +0100 Mike Gabriel (7e5c04b) +2012-03-01 20:39:37 +0100 Mike Gabriel (7e5c04b5d) * Pass address of fd_set structs on the stack to the FD_ISSET macro/function, instead of the struct itself. -2012-02-29 15:56:49 +0100 Mihai Moldovan (655173f) +2012-02-29 15:56:49 +0100 Mihai Moldovan (655173ff2) * Add patch: 051_nxcomp_macos105-fdisset.full+lite.patch, work around issue in Mac OS X 10.5 SDK. -2012-02-28 13:44:25 +0100 Oleksandr Shneyder (be86627) +2012-02-28 13:44:25 +0100 Oleksandr Shneyder (be86627ad) * Create patch: 203_nxagent_disable-rootless-exit.full.patch -2012-02-22 22:49:06 +0100 Mike Gabriel (0586f0d) +2012-02-22 22:49:06 +0100 Mike Gabriel (0586f0d6e) * Update patch: 001_add-main-makefile.full+lite.patch, adapt patch from packaging. Test for Makefiles in subfolders before calling them. Fixes build failure during ,,make distclean'' calls. -2012-02-22 15:05:55 +0100 Mike Gabriel (a8bf2dd) +2012-02-22 15:05:55 +0100 Mike Gabriel (a8bf2dd81) * Continue development... -2012-02-22 14:41:26 +0100 Mike Gabriel (50690ea) +2012-02-22 14:41:26 +0100 Mike Gabriel (50690ea17) * release 3.5.0.11 (tag: redist-server/3.5.0.11, tag: redist-client/3.5.0.11) -2012-02-20 10:00:00 +0100 Mike Gabriel (fde6a88) +2012-02-20 10:00:00 +0100 Mike Gabriel (fde6a88a8) * Fine-tune symlinking of libXinerama. -2012-02-18 02:28:53 +0100 Mike Gabriel (ec47c22) +2012-02-18 02:28:53 +0100 Mike Gabriel (ec47c22c2) * Fix Xinerama support in Debian package libnx-x11 when NX gets built with patch @@ -7483,20 +7726,20 @@ Still on the todo list: fix the nx-X11 installation via Makefile. -2012-02-16 19:38:48 +0100 Mike Gabriel (7a6cf42) +2012-02-16 19:38:48 +0100 Mike Gabriel (7a6cf42d4) * another last patch with .diff suffix -2012-02-16 19:35:28 +0100 Mike Gabriel (e63819e) +2012-02-16 19:35:28 +0100 Mike Gabriel (e63819e64) * Fix faulty patch name suffix (has to be .patch, not .diff). -2012-02-16 19:31:08 +0100 Mike Gabriel (78fba02) +2012-02-16 19:31:08 +0100 Mike Gabriel (78fba0271) * Apply patches for the Debian package as the last patches in the series. -2012-02-15 09:42:35 +0100 Mike Gabriel (c26e4bd) +2012-02-15 09:42:35 +0100 Mike Gabriel (c26e4bd82) * Update patches: 012_nxcomp..., 013_nxcompext_..., 014_nxcompshad_.... Also make use of $(LIBFULL) in @@ -7505,320 +7748,320 @@ version name change requested in that patch has been rejected for NX (redistributed). -2012-02-15 08:50:48 +0100 Mike Gabriel (b99168f) +2012-02-15 08:50:48 +0100 Mike Gabriel (b99168fc3) * changelog cleanup, fix long-line-wraps -2012-02-15 08:49:49 +0100 Jan Engelhardt (07f9dfa) +2012-02-15 08:49:49 +0100 Jan Engelhardt (07f9dfa05) * Add patch 600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch, use unique library names for nx-X11 based X11 libraries. -2012-02-15 08:10:21 +0100 Mike Gabriel (548d50b) +2012-02-15 08:10:21 +0100 Mike Gabriel (548d50ba5) * changelog cleanup, typo fix -2012-02-15 08:09:41 +0100 Jan Engelhardt (3deee8f) +2012-02-15 08:09:41 +0100 Jan Engelhardt (3deee8f94) * Add patch 032_nx-X11_no-x11r6-project-root. We must not overlap with any existing files, therefore, both /usr/X11R6 and /usr are excluded possibilities for ProjectRoot. Use %_libexecdir/somename, since that is still allowed by FHS. -2012-02-14 23:34:51 +0100 Mike Gabriel (9282c00) +2012-02-14 23:34:51 +0100 Mike Gabriel (9282c00e2) * Update patch: 001_add-main-makefile.full+lite.patch, fix missing $(CONFIGURE) variable. -2012-02-14 23:03:45 +0100 Mike Gabriel (6a96ae4) +2012-02-14 23:03:45 +0100 Mike Gabriel (6a96ae450) * Make patch headers DEP5 compliant (030_nx-X11_... and 031_nx-X11_...). -2012-02-14 22:59:50 +0100 Jan Engelhardt (8d6d0a9) +2012-02-14 22:59:50 +0100 Jan Engelhardt (8d6d0a921) * Add patch: 301_nx-X11_use-shared-libs.full.diff, use shared libraries from distribution rather then libs included in source tree. -2012-02-14 22:42:48 +0100 Mike Gabriel (01e97f0) +2012-02-14 22:42:48 +0100 Mike Gabriel (01e97f0f8) * Rename patches 030_nx-X11_... and 031_nx-X11_..., the tarball roll script currently requires ,,full'' or ,,full+lite'' in the file name. -2012-02-14 22:40:15 +0100 Mike Gabriel (c621c22) +2012-02-14 22:40:15 +0100 Mike Gabriel (c621c22f8) * Merge honor-ac-dirs.patch from Jan Engelhardt (OpenSUSE) with already existing Makefile patches (012_nxcomp..., 013_nxcompext_..., 014_nxcompshad_...). -2012-02-14 22:30:26 +0100 Mike Gabriel (4d6e1c4) +2012-02-14 22:30:26 +0100 Mike Gabriel (4d6e1c4fb) * Enable parallel build for Debian package. -2012-02-14 08:47:19 +0100 Jan Engelhardt (ba589d1) +2012-02-14 08:47:19 +0100 Jan Engelhardt (ba589d1fd) * Add patch: 031_nx-X11_parallel-make.diff, enable parallel make. -2012-02-14 08:39:32 +0100 Mike Gabriel (b4b4e20) +2012-02-14 08:39:32 +0100 Mike Gabriel (b4b4e209b) * Update patch: 001_add-main-makefile.full+lite.patch, use curly braces for macros. -2012-02-14 08:33:42 +0100 Jan Engelhardt (280d875) +2012-02-14 08:33:42 +0100 Jan Engelhardt (280d8751c) * Add patch: 030_nx-X11_configure-args.diff. Allow passing of configure args. -2012-02-14 08:27:52 +0100 Mike Gabriel (165206e) +2012-02-14 08:27:52 +0100 Mike Gabriel (165206eb2) * changelog fix, long-line-wrap -2012-02-14 08:26:50 +0100 Jan Engelhardt (448a1db) +2012-02-14 08:26:50 +0100 Jan Engelhardt (448a1db30) * Update patch: 001_add-main-makefile.full+lite.patch, allow passing of configure args. -2012-02-12 12:40:01 +0100 Mike Gabriel (b087877) +2012-02-12 12:40:01 +0100 Mike Gabriel (b087877b2) * Xinerama path has to be put into debian/rules, that dpkg-shlibs can find the libXinerama files. -2012-02-12 01:03:38 +0100 Mike Gabriel (4feedb2) +2012-02-12 01:03:38 +0100 Mike Gabriel (4feedb214) * fix for intra-dependency lintian fix -2012-02-12 00:37:51 +0100 Mike Gabriel (278f941) +2012-02-12 00:37:51 +0100 Mike Gabriel (278f94136) * fix libXinerama removal -2012-02-11 23:39:16 +0100 Mike Gabriel (4473c3a) +2012-02-11 23:39:16 +0100 Mike Gabriel (4473c3ab9) * Do not install libXinerama directly into /usr/lib/nx. Recommended method is installing to /usr/lib/nx/Xinerama, so that you can enable/disable usage of the Xinerama extension. -2012-02-11 23:06:58 +0100 Mike Gabriel (ec72377) +2012-02-11 23:06:58 +0100 Mike Gabriel (ec7237798) * Revert "Add patch: 111_nxcomp_byerace.full+lite.patch. Work around race condition in qtnx and libnxcl." -2012-02-08 08:52:18 +0100 Mike Gabriel (4eae840) +2012-02-08 08:52:18 +0100 Mike Gabriel (4eae840bd) * Add patch: 111_nxcomp_byerace.full+lite.patch. Work around race condition in qtnx and libnxcl. -2012-02-07 21:00:44 +0100 Mike Gabriel (54792fe) +2012-02-07 21:00:44 +0100 Mike Gabriel (54792fe29) * another fix for the main Makefile -2012-02-07 16:39:58 +0100 Mike Gabriel (7f7cb5d) +2012-02-07 16:39:58 +0100 Mike Gabriel (7f7cb5d87) * more simplification of the main Makefile -2012-02-07 16:19:36 +0100 Mike Gabriel (eb5ef91) +2012-02-07 16:19:36 +0100 Mike Gabriel (eb5ef91b6) * simplify main Makefile a little... -2012-02-07 16:10:34 +0100 Mike Gabriel (00b266b) +2012-02-07 16:10:34 +0100 Mike Gabriel (00b266b82) * Use ,,$(MAKE) -C'' in main Makefile for calling Makefiles in subdirectories, make build stanza work for nx-libs-full and nx-libs-lite. -2012-02-07 15:23:45 +0100 Mike Gabriel (f4ef296) +2012-02-07 15:23:45 +0100 Mike Gabriel (f4ef2967b) * Use ,,make -C'' in main Makefile for calling Makefiles in subdirectories. -2012-02-07 13:48:36 +0100 Mike Gabriel (a751baa) +2012-02-07 13:48:36 +0100 Mike Gabriel (a751baaab) * Continue development... -2012-02-07 13:44:21 +0100 Mike Gabriel (419d505) +2012-02-07 13:44:21 +0100 Mike Gabriel (419d505c9) * release 3.5.0.10 (tag: redist-server/3.5.0.10, tag: redist-client/3.5.0.10) -2012-02-07 13:37:16 +0100 Mike Gabriel (28acb2e) +2012-02-07 13:37:16 +0100 Mike Gabriel (28acb2ea1) * changelog fix (revision was missing) -2012-02-07 13:09:02 +0100 Mike Gabriel (2f8b190) +2012-02-07 13:09:02 +0100 Mike Gabriel (2f8b190c8) * Reintroduce patch: 008_nxcomp_sa_restorer.full+lite.patch, now in a version found on etersoft.ru, fixes build on ia64 architecture. -2012-02-06 12:15:13 +0100 Mike Gabriel (6ae5c16) +2012-02-06 12:15:13 +0100 Mike Gabriel (6ae5c16b8) * cleanup patch -2012-02-06 12:12:20 +0100 Mike Gabriel (e326dd7) +2012-02-06 12:12:20 +0100 Mike Gabriel (e326dd760) * Add patch: 006_nxcomp_libpng15.full+lite.patch, fix build against libpng 1.5.x. -2012-02-01 14:48:55 +0100 Mike Gabriel (dbbbbc5) +2012-02-01 14:48:55 +0100 Mike Gabriel (dbbbbc5ff) * Continue development... -2012-02-01 14:40:41 +0100 Mike Gabriel (220c985) +2012-02-01 14:40:41 +0100 Mike Gabriel (220c985d3) * release NX re-distributed 3.5.0.9 (tag: redist-server/3.5.0.9) -2012-02-01 14:38:14 +0100 Mike Gabriel (8ba08fa) +2012-02-01 14:38:14 +0100 Mike Gabriel (8ba08fa2e) * Providing pending patches in source tree. -2012-01-30 13:45:07 +0100 Oleksandr Shneyder (2d226a6) +2012-01-30 13:45:07 +0100 Oleksandr Shneyder (2d226a609) * Update patch: 202_nx-x11_enable-xinerama.full.patch, disable Xinerama extension if NX_XINERAMA_CONF not exists. -2012-01-30 13:18:30 +0100 Oleksandr Shneyder (3467d6b) +2012-01-30 13:18:30 +0100 Oleksandr Shneyder (3467d6b76) * Revert "Update patch: 202_nx-x11_enable-xinerama.full.patch disable Xinerama extension if NX_XINERAMA_CONF not exists" -2012-01-30 13:18:12 +0100 Oleksandr Shneyder (3c0e43a) +2012-01-30 13:18:12 +0100 Oleksandr Shneyder (3c0e43a41) * Revert "changelog cleanup: add interpunctation." -2012-01-30 13:12:26 +0100 Mike Gabriel (d4d85ca) +2012-01-30 13:12:26 +0100 Mike Gabriel (d4d85ca86) * changelog cleanup: add interpunctation. -2012-01-30 13:05:01 +0100 Oleksandr Shneyder (f17b598) +2012-01-30 13:05:01 +0100 Oleksandr Shneyder (f17b59824) * Update patch: 202_nx-x11_enable-xinerama.full.patch disable Xinerama extension if NX_XINERAMA_CONF not exists -2012-01-28 08:58:43 +0100 Reinhard Tartler (36ca664) +2012-01-28 08:58:43 +0100 Reinhard Tartler (36ca6646b) * fix typos in nxproxy manpage -2012-01-23 00:05:29 +0100 Mike Gabriel (1046233) +2012-01-23 00:05:29 +0100 Mike Gabriel (104623396) * version increment, continue development... -2012-01-22 23:42:43 +0100 Mike Gabriel (f4379f6) +2012-01-22 23:42:43 +0100 Mike Gabriel (f4379f608) * release NX re-distributed 3.5.0.8 (tag: redist-server/3.5.0.8) -2012-01-22 23:02:50 +0100 Mike Gabriel (cf5a598) +2012-01-22 23:02:50 +0100 Mike Gabriel (cf5a5980c) * Fix patch: 109_nxagent_locale-utf8-compound-text.patch, fix crashes reported from Stefan Baur. Thanks for reporting and testing!!! -2012-01-22 22:47:30 +0100 Mike Gabriel (5027f1e) +2012-01-22 22:47:30 +0100 Mike Gabriel (5027f1e8b) * Add folder /debian/patches-pending-evaluation with two newly discovered patches from git.etersoft.ru (AltLinux packaging repository for NX). -2012-01-18 20:09:39 +0100 Mike Gabriel (a05b560) +2012-01-18 20:09:39 +0100 Mike Gabriel (a05b56038) * Package x2goagent is an ,,all'' package, not ,,any''. -2012-01-16 22:57:29 +0100 Mike Gabriel (8b013ce) +2012-01-16 22:57:29 +0100 Mike Gabriel (8b013ce80) * Update patch: 001_add-main-makefile.full+lite.patch, only build, install, clean etc. NX subprojects if the folder exists. -2012-01-16 22:29:05 +0100 Mike Gabriel (e9241fe) +2012-01-16 22:29:05 +0100 Mike Gabriel (e9241fe8c) * Reorganize patch names, to reflect patch inclusion into lite+full or full-only ,,NX (redistributed)'' tarball. -2012-01-16 11:28:26 +0100 Mike Gabriel (d7ecf72) +2012-01-16 11:28:26 +0100 Mike Gabriel (d7ecf7214) * release NX re-distributed 3.5.0.7 (tag: redist-server/3.5.0.7) -2012-01-16 10:54:19 +0100 Mike Gabriel (1bd66f1) +2012-01-16 10:54:19 +0100 Mike Gabriel (1bd66f19c) * Drop patch: 011_nxcomp_sa-restorer.patch. -2012-01-13 13:22:13 +0100 Mike Gabriel (28b2a3a) +2012-01-13 13:22:13 +0100 Mike Gabriel (28b2a3a93) * release NX re-distributed 3.5.0.6 (tag: redist-server/3.5.0.6) -2012-01-13 13:09:43 +0100 Mike Gabriel (8d655bc) +2012-01-13 13:09:43 +0100 Mike Gabriel (8d655bc1a) * Install libXinerama into libnx-x11 package. Header files into libnx-x11-dev. -2012-01-13 12:45:15 +0100 Mike Gabriel (d086c36) +2012-01-13 12:45:15 +0100 Mike Gabriel (d086c3699) * fix for lintian-overrids (debian-revision-should-not-be-zero), package: libxcomp-dev -2012-01-13 11:34:21 +0100 Mike Gabriel (55ee602) +2012-01-13 11:34:21 +0100 Mike Gabriel (55ee602bb) * Silence lintian on debian-revision-should-not-be-zero. As this is no Debian packaging repository, but ,,NX (redistributed)'', we will always release with rev no. set to ,,0''. -2012-01-13 11:29:10 +0100 Mike Gabriel (e32a559) +2012-01-13 11:29:10 +0100 Mike Gabriel (e32a5590f) * Add patch header/copyright to: 202_nx-x11_enable-xinerama.patch. -2012-01-13 11:28:17 +0100 Mike Gabriel (2be056d) +2012-01-13 11:28:17 +0100 Mike Gabriel (2be056d38) * Fix lintian issue: missing-separator-between-items for x2goagent package. Drop dependency on libnx-x11 as we already depend on nxagent and fix description synopsis of x2goagent package. -2012-01-13 10:29:47 +0100 Mike Gabriel (fa996b5) +2012-01-13 10:29:47 +0100 Mike Gabriel (fa996b5bc) * Add patch: 202_nx-x11_enable-xinerama.patch. -2012-01-13 00:38:30 +0100 Mike Gabriel (fdf0d1c) +2012-01-13 00:38:30 +0100 Mike Gabriel (fdf0d1ccf) * release NX re-distributed 3.5.0.5 (tag: redist-server/3.5.0.5) -2012-01-13 00:36:28 +0100 Mike Gabriel (a295d73) +2012-01-13 00:36:28 +0100 Mike Gabriel (a295d73f6) * Fix wrapper script patches for nxagent, x2goagent, nxauth, nxproxy. -2012-01-12 23:05:32 +0100 Mike Gabriel (8199a5d) +2012-01-12 23:05:32 +0100 Mike Gabriel (8199a5d2a) * release NX re-distributed 3.5.0.4 (tag: redist-server/3.5.0.4) -2012-01-12 23:04:03 +0100 Mike Gabriel (96cd432) +2012-01-12 23:04:03 +0100 Mike Gabriel (96cd4325b) * Update/fix patch: 999_nxagent_unbrand-nxagent-brand-x2goagent.patch. -2012-01-12 13:09:00 +0100 Mike Gabriel (e40208d) +2012-01-12 13:09:00 +0100 Mike Gabriel (e40208d7c) * release NX re-distributed 3.5.0.3 (tag: redist-server/3.5.0.3) -2012-01-12 13:03:59 +0100 Mike Gabriel (86dc688) +2012-01-12 13:03:59 +0100 Mike Gabriel (86dc68806) * set version to 3.5.0.3-0 -2012-01-12 13:02:36 +0100 Mike Gabriel (1bbc9cc) +2012-01-12 13:02:36 +0100 Mike Gabriel (1bbc9cc9e) * changelog cleanup -2012-01-12 13:01:47 +0100 Mike Gabriel (496f31a) +2012-01-12 13:01:47 +0100 Mike Gabriel (496f31a51) * Fix RGB color pallette (gray X2GO logo to be more accurate) for agent splash screen. -2012-01-12 13:01:04 +0100 Mike Gabriel (df8dc83) +2012-01-12 13:01:04 +0100 Mike Gabriel (df8dc83d1) * two more patches belonging to last commit: 016a_debian_nx-X11_install-location.patch, 102a_debian_xserver-xext_set-securitypolicy-path.patch -2012-01-12 13:00:23 +0100 Mike Gabriel (760c5c0) +2012-01-12 13:00:23 +0100 Mike Gabriel (760c5c07c) * Provide patches that are tarball / distro aware. Either NX (redistributed) has been installed to /usr/local/lib/nx @@ -7826,45 +8069,45 @@ is installed to /usr/lib/nx. Other installation paths are currently not supported. -2012-01-12 12:15:14 +0100 Mike Gabriel (d6fee9a) +2012-01-12 12:15:14 +0100 Mike Gabriel (d6fee9a41) * Modify patch: 101_nxagent_set-rgb-path.patch, add path to RGB file if NX (redistributed) is installed via tarball under /usr/local. -2012-01-11 17:37:45 +0100 Mike Gabriel (8f76198) +2012-01-11 17:37:45 +0100 Mike Gabriel (8f76198c5) * Add binary package: x2goagent, includes man page patch: 209_x2goagent-add-man-page.patch -2012-01-11 17:34:18 +0100 Mike Gabriel (0d3a820) +2012-01-11 17:34:18 +0100 Mike Gabriel (0d3a820b3) * Revert "Drop patch: 101_nxagent_set-rgb-path.path, add patch: 202_nxagent_set-rgb-path-x2go-flavour-aware.patch." -2012-01-11 17:25:08 +0100 Mike Gabriel (d9d49b5) +2012-01-11 17:25:08 +0100 Mike Gabriel (d9d49b5d8) * Drop patch: 101_nxagent_set-rgb-path.path, add patch: 202_nxagent_set-rgb-path-x2go-flavour-aware.patch. -2012-01-11 17:03:23 +0100 Mike Gabriel (43de8b9) +2012-01-11 17:03:23 +0100 Mike Gabriel (43de8b972) * Add patch: 209_x2goagent-add-man-page.patch. -2012-01-11 16:41:26 +0100 Mike Gabriel (fdfed53) +2012-01-11 16:41:26 +0100 Mike Gabriel (fdfed536c) * Add patch: 023_add-x2goagent-wrapper.patch. -2012-01-11 16:38:36 +0100 Mike Gabriel (9d99eeb) +2012-01-11 16:38:36 +0100 Mike Gabriel (9d99eeb53) * remove copy+paste cruft from debian/patches/999_nxagent_unbrand-nxagent-brand-x2goagent.patch -2012-01-11 16:38:10 +0100 Mike Gabriel (6ae3d7e) +2012-01-11 16:38:10 +0100 Mike Gabriel (6ae3d7efc) * add EOL at EOF -2012-01-11 16:17:51 +0100 Mike Gabriel (405bc8f) +2012-01-11 16:17:51 +0100 Mike Gabriel (405bc8f25) * Add X2Go agent / NX agent flavouring via patch system: - 200_nxagent_check-binary-x2go-flavour.patch - @@ -7872,42 +8115,42 @@ 300_nxagent_set-wm-class.patch - 999_nxagent_unbrand-nxagent-brand-x2goagent.patch -2012-01-11 16:15:38 +0100 Mike Gabriel (19f2487) +2012-01-11 16:15:38 +0100 Mike Gabriel (19f248733) * Drop NX agent unbrand patch from FreeNX. -2012-01-11 15:31:11 +0100 Mike Gabriel (3744795) +2012-01-11 15:31:11 +0100 Mike Gabriel (3744795d3) * Rename nxagent-unbrand patch, so that is the last patch to be applied (999_). -2012-01-10 14:39:07 +0100 Mike Gabriel (eaea40d) +2012-01-10 14:39:07 +0100 Mike Gabriel (eaea40dec) * release NX re-distributed 3.5.0.2 (tag: redist-server/3.5.0.2) -2012-01-10 14:37:25 +0100 Mike Gabriel (e669607) +2012-01-10 14:37:25 +0100 Mike Gabriel (e669607f9) * Update folder name where applied patches end up in the tarball release. -2012-01-10 14:34:27 +0100 Mike Gabriel (eac87da) +2012-01-10 14:34:27 +0100 Mike Gabriel (eac87da64) * Re-add binary wrapper scripts to the patch system as we want to provide them in the tarball. -2012-01-10 12:06:00 +0100 Mike Gabriel (c84ad97) +2012-01-10 12:06:00 +0100 Mike Gabriel (c84ad97a7) * release NX re-distributed 3.5.0.1 (tag: redist-server/3.5.0.1) -2012-01-10 12:05:44 +0100 Mike Gabriel (ca0994c) +2012-01-10 12:05:44 +0100 Mike Gabriel (ca0994c84) * Increment version to stay in sync with client-only branch. -2012-01-10 11:39:35 +0100 Mike Gabriel (d97802a) +2012-01-10 11:39:35 +0100 Mike Gabriel (d97802ad7) * release NX re-distributed 3.5.0.0 (tag: redist-server/3.5.0.0) -2012-01-10 11:14:36 +0100 Mike Gabriel (281b04f) +2012-01-10 11:14:36 +0100 Mike Gabriel (281b04f70) * Add patches: 009_add-nxagent-man-page.patch, 009_add-nxproxy-man-page.patch. Reintroduce man page @@ -7915,169 +8158,169 @@ their way into the NX-redistribution tarball created from this source project. -2012-01-10 10:50:01 +0100 Mike Gabriel (71cc495) +2012-01-10 10:50:01 +0100 Mike Gabriel (71cc495aa) * Fix dh_installman for nxproxy. -2012-01-10 10:12:50 +0100 Mike Gabriel (e685cc8) +2012-01-10 10:12:50 +0100 Mike Gabriel (e685cc890) * switch NX-redistribution version to 3.5.0.0 -2012-01-10 10:07:56 +0100 Mike Gabriel (736356e) +2012-01-10 10:07:56 +0100 Mike Gabriel (736356ea7) * Add patch: 000_add-NX-redistribution-README.patch. -2011-12-31 19:28:56 +0100 Mike Gabriel (c9c1f8b) +2011-12-31 19:28:56 +0100 Mike Gabriel (c9c1f8b91) * Remove branding from descriptions in control file. -2011-12-31 18:55:05 +0100 Mike Gabriel (c9bf030) +2011-12-31 18:55:05 +0100 Mike Gabriel (c9bf030aa) * Call dh_clean again. This got lost somewhere on the way. -2011-12-31 18:32:01 +0100 Mike Gabriel (e292f23) +2011-12-31 18:32:01 +0100 Mike Gabriel (e292f23ac) * forgot to add patch file: 005_nxcomp_gcc43.patch -2011-12-31 18:31:40 +0100 Mike Gabriel (91ae4d4) +2011-12-31 18:31:40 +0100 Mike Gabriel (91ae4d4e4) * Fix line hunks: 011_nxcomp_sa-restorer.patch. -2011-12-31 18:29:56 +0100 Mike Gabriel (b494b52) +2011-12-31 18:29:56 +0100 Mike Gabriel (b494b5287) * Revert "Fix linking of doc folders for nxcomp*-dev." -2011-12-31 17:12:52 +0100 Mike Gabriel (2fe05f6) +2011-12-31 17:12:52 +0100 Mike Gabriel (2fe05f6ad) * patches/series cleanup -2011-12-31 17:12:20 +0100 Mike Gabriel (6f30998) +2011-12-31 17:12:20 +0100 Mike Gabriel (6f30998ad) * Add/insert patch: 005_nxcomp_gcc43.patch. -2011-12-31 17:04:48 +0100 Mike Gabriel (448872e) +2011-12-31 17:04:48 +0100 Mike Gabriel (448872e70) * Add patch: 011_nxcomp_sa-restorer.patch. -2011-12-31 16:27:58 +0100 Mike Gabriel (82e5023) +2011-12-31 16:27:58 +0100 Mike Gabriel (82e5023ed) * Transfer patch: 009_nxproxy_add-man-page.patch into man page file in /debian/man. -2011-12-31 16:24:02 +0100 Mike Gabriel (608bbb6) +2011-12-31 16:24:02 +0100 Mike Gabriel (608bbb6d9) * Fix linking of doc folders for nxcomp*-dev. -2011-12-31 16:22:46 +0100 Mike Gabriel (eb069a4) +2011-12-31 16:22:46 +0100 Mike Gabriel (eb069a4e6) * grammar fix in pre-build-nx.sh -2011-12-31 03:18:07 +0100 Mike Gabriel (85e87ab) +2011-12-31 03:18:07 +0100 Mike Gabriel (85e87ab6c) * Add patch headers to all patch files, report most patches upstream. Waiting for feedback and quotable URLs from NoMachine. -2011-12-31 03:16:59 +0100 Mike Gabriel (24261f0) +2011-12-31 03:16:59 +0100 Mike Gabriel (24261f05e) * Remove patch: 104_nxagent_enable_debug.patch, as it breaks package build. -2011-12-31 02:57:25 +0100 Mike Gabriel (a24c4b2) +2011-12-31 02:57:25 +0100 Mike Gabriel (a24c4b2e7) * also forgotten: scripts for last two commits -2011-12-31 01:41:34 +0100 Mike Gabriel (0db1194) +2011-12-31 01:41:34 +0100 Mike Gabriel (0db119427) * changelog: forgot to ship with last commit -2011-12-31 01:39:39 +0100 Mike Gabriel (9237464) +2011-12-31 01:39:39 +0100 Mike Gabriel (92374647e) * * Remove patches and put as executable scripts into /debian/bin/ - 005_add-nxagent-wrapper.patch. - 008_add-nxproxy-wrapper.patch. - 011_add-nxauth-wrapper.patch. -2011-12-31 01:27:13 +0100 Mike Gabriel (383f8ee) +2011-12-31 01:27:13 +0100 Mike Gabriel (383f8eece) * Remove patch 006_remove-configure-files.patch. Implemented via /debian/rules. -2011-12-31 01:03:16 +0100 Mike Gabriel (faa3dee) +2011-12-31 01:03:16 +0100 Mike Gabriel (faa3dee7e) * Make package descriptions in /debian/control more explanatory. -2011-12-31 00:29:09 +0100 Mike Gabriel (a193a0a) +2011-12-31 00:29:09 +0100 Mike Gabriel (a193a0a0a) * Remove *-dbg packages from /debian/control file. -2011-12-31 00:26:16 +0100 Mike Gabriel (caa6dd5) +2011-12-31 00:26:16 +0100 Mike Gabriel (caa6dd5f1) * Add more upstream source information to README.source. -2011-12-30 23:46:45 +0100 Mike Gabriel (c2cdc1d) +2011-12-30 23:46:45 +0100 Mike Gabriel (c2cdc1da3) * Set homepage of NoMachine upstream site (using http://www.nomachine.com/sources.php). -2011-12-30 19:21:24 +0100 Mike Gabriel (7fabca5) +2011-12-30 19:21:24 +0100 Mike Gabriel (7fabca589) * Set homepage of X2Go upstream project (using http://wiki.x2go.org). Packaging Vcs has been relocated to Alioth. -2011-12-30 15:34:02 +0100 Mike Gabriel (f1c239c) +2011-12-30 15:34:02 +0100 Mike Gabriel (f1c239c07) * changelog fix for latest changelog line -2011-12-30 15:32:37 +0100 Mike Gabriel (e20dc39) +2011-12-30 15:32:37 +0100 Mike Gabriel (e20dc398f) * control file: fixing Breaks/Replaces statements -2011-12-30 15:29:39 +0100 Mike Gabriel (28a112c) +2011-12-30 15:29:39 +0100 Mike Gabriel (28a112c7a) * changelog fix: typo -2011-12-30 15:29:01 +0100 Mike Gabriel (74e810a) +2011-12-30 15:29:01 +0100 Mike Gabriel (74e810a31) * changelog fix: wrap long line -2011-12-30 15:28:23 +0100 Mike Gabriel (d6fa23c) +2011-12-30 15:28:23 +0100 Mike Gabriel (d6fa23c86) * Break/conflict with nxlibs and nxlibs-dev (packages provided by freenx-team on Launchpad). -2011-12-30 15:25:30 +0100 Mike Gabriel (290fded) +2011-12-30 15:25:30 +0100 Mike Gabriel (290fdeddf) * Make `breaks-without-version' lintian overrides needless. -2011-12-30 15:20:02 +0100 Mike Gabriel (f917768) +2011-12-30 15:20:02 +0100 Mike Gabriel (f9177685a) * changelog modification: use Debianic revision numbers -2011-12-30 15:16:59 +0100 Mike Gabriel (5287efc) +2011-12-30 15:16:59 +0100 Mike Gabriel (5287efc44) * X2Go Packaging Team becomes maintainer, Mike Gabriel + Reinhard Tartler become uploaders. -2011-12-29 21:38:51 +0100 Mike Gabriel (7d9e154) +2011-12-29 21:38:51 +0100 Mike Gabriel (7d9e1544f) * Fix LD_LIBRARY_PATH export in wrapper scripts/patches. -2011-12-29 16:33:57 +0100 Mike Gabriel (0e3b58b) +2011-12-29 16:33:57 +0100 Mike Gabriel (0e3b58b7f) * Add patch: 019_nx-x11_expat-build-against-system-libxmltok.patch, fixes lintian error: embedded-library: expat. Build-depend on libxmltok1-dev. -2011-12-29 16:28:19 +0100 Mike Gabriel (93b716f) +2011-12-29 16:28:19 +0100 Mike Gabriel (93b716f78) * Disable patch: 006_remove-configure-files.patch, remove configure files from within /debian/rules. -2011-12-29 14:45:18 +0100 Mike Gabriel (21a85ff) +2011-12-29 14:45:18 +0100 Mike Gabriel (21a85ffbe) * Make sure upstream changelog file names are in lower case. -2011-12-29 14:34:35 +0100 Mike Gabriel (5dea6a3) +2011-12-29 14:34:35 +0100 Mike Gabriel (5dea6a378) * * Override lintian warnings - libnx-x11: postinst-has-useless-call-to-ldconfig - libnx-x11: @@ -8086,92 +8329,92 @@ touch any directory controlled by /etc/ld.so.conf, amongst others see BTS issue #205142). -2011-12-29 13:51:47 +0100 Mike Gabriel (3b7914d) +2011-12-29 13:51:47 +0100 Mike Gabriel (3b7914dd7) * Add upstream CHANGELOG files to all .deb packages of this source package. -2011-12-29 13:50:34 +0100 Mike Gabriel (e1f46f9) +2011-12-29 13:50:34 +0100 Mike Gabriel (e1f46f911) * explicitly name all source version from upstream used for initial package release. -2011-12-29 13:27:14 +0100 Mike Gabriel (d57ff77) +2011-12-29 13:27:14 +0100 Mike Gabriel (d57ff7754) * Update patch: 017_nx-x11_update-autotools-helper-files.patch. Add lintian override to source.lintian-overrides: ancient-autotools-helper-file as we handle autotools helper file updates via patch system. -2011-12-29 13:22:26 +0100 Mike Gabriel (776fa97) +2011-12-29 13:22:26 +0100 Mike Gabriel (776fa97cb) * changelog fix: wrap long lines -2011-12-29 13:08:43 +0100 Mike Gabriel (fafea09) +2011-12-29 13:08:43 +0100 Mike Gabriel (fafea0918) * Add patch: 018_nx-x11_update-libtool-ltmain-script.patch. Silence lintian warning ancient-libtool via lintian override as we patch in a new version of ltmain.sh by this patch. -2011-12-29 13:06:55 +0100 Mike Gabriel (a8d1eab) +2011-12-29 13:06:55 +0100 Mike Gabriel (a8d1eab2c) * Add lintian-override: outdated-autotools-helper-file to source.lintian-overrides as we patch-update the outdated helper files before building binaries. -2011-12-29 12:29:24 +0100 Mike Gabriel (184c63e) +2011-12-29 12:29:24 +0100 Mike Gabriel (184c63e7b) * Add README.source file, fixes lintian warning: patch-system-but-no-source-readme. -2011-12-29 12:24:49 +0100 Mike Gabriel (b3eac91) +2011-12-29 12:24:49 +0100 Mike Gabriel (b3eac91c9) * Add patch: 017_nx-x11_update-autotools-helper-files.patch. -2011-12-29 12:17:22 +0100 Mike Gabriel (e68f15a) +2011-12-29 12:17:22 +0100 Mike Gabriel (e68f15a9d) * changelog fix: wrap long line -2011-12-29 11:59:40 +0100 Mike Gabriel (da0bfe6) +2011-12-29 11:59:40 +0100 Mike Gabriel (da0bfe6ea) * Disable patch: 104_nxagent_enable_debug.patch for now as it let's the build fail. -2011-12-29 11:54:02 +0100 Mike Gabriel (3d575c4) +2011-12-29 11:54:02 +0100 Mike Gabriel (3d575c45c) * add possible-new-upstream-release-without-new-version lintian override for *-dev packages, as well -2011-12-29 11:37:35 +0100 Mike Gabriel (b97f5a7) +2011-12-29 11:37:35 +0100 Mike Gabriel (b97f5a78b) * wrap long lines in /debian/changelog -2011-12-29 11:01:23 +0100 Mike Gabriel (dda2c7c) +2011-12-29 11:01:23 +0100 Mike Gabriel (dda2c7cd6) * Rename patch: 008_nxproxy_add-nx-proxy-wrapper.patch to 008_nxproxy_add-nxproxy-wrapper.patch. Add patch from FreeNX patchset: 110_nxagent_createpixmap-bounds-check.patch. -2011-12-29 10:44:39 +0100 Mike Gabriel (c93ae96) +2011-12-29 10:44:39 +0100 Mike Gabriel (c93ae9697) * Install nxagent.xpm icon to /usr/share/pixmaps. -2011-12-29 10:42:42 +0100 Mike Gabriel (43c04db) +2011-12-29 10:42:42 +0100 Mike Gabriel (43c04dbfd) * Rework FreeNX patches to be applicable to latest NX sources. -2011-12-29 10:25:45 +0100 Mike Gabriel (9f22660) +2011-12-29 10:25:45 +0100 Mike Gabriel (9f226601f) * Adapt path names in FreeNX patches to meet requirements for source tree of this package. -2011-12-29 10:03:08 +0100 Mike Gabriel (4cffd99) +2011-12-29 10:03:08 +0100 Mike Gabriel (4cffd99f2) * fix debian/patches/series file to reflect new patch naming scheme... -2011-12-29 09:57:30 +0100 Mike Gabriel (89fea92) +2011-12-29 09:57:30 +0100 Mike Gabriel (89fea9279) * Add FreeNX patches for nxagent (some with other names compared to FreeNX): - 101_nxagent_set-rgb-path.patch - @@ -8185,563 +8428,563 @@ 109_nxagent_locale-utf8-compound-text.patch - 200_nxagent_unbrand-agent.patch -2011-12-29 09:47:29 +0100 Mike Gabriel (dd287a5) +2011-12-29 09:47:29 +0100 Mike Gabriel (dd287a5c8) * Add man page for nxagent. Fix lintian warning: binary-without-manpage. -2011-12-29 09:42:45 +0100 Mike Gabriel (1f87c87) +2011-12-29 09:42:45 +0100 Mike Gabriel (1f87c87a1) * forgot to commit changelog for last two commits (adding of watch files, change of patch file naming scheme) -2011-12-28 23:18:58 +0100 Mike Gabriel (3c2fe1a) +2011-12-28 23:18:58 +0100 Mike Gabriel (3c2fe1ace) * Change naming scheme of patch files. -2011-12-28 23:15:54 +0100 Mike Gabriel (082c8ae) +2011-12-28 23:15:54 +0100 Mike Gabriel (082c8ae3a) * Add individual watch files for NX components in this source package. -2011-12-28 19:25:43 +0100 Mike Gabriel (13b60f7) +2011-12-28 19:25:43 +0100 Mike Gabriel (13b60f760) * Add lintian-overrides for every package. Override lintian warning: possible-new-upstream-release-without-new-version as there will be new upstream releases of NX subprojects that will not require a version increment of the Debian package. -2011-12-28 19:07:03 +0100 Mike Gabriel (c853e1e) +2011-12-28 19:07:03 +0100 Mike Gabriel (c853e1eb8) * changelog update: new upstream release of nxagent 3.5.0-7 -2011-12-28 18:48:50 +0100 Mike Gabriel (82ab807) +2011-12-28 18:48:50 +0100 Mike Gabriel (82ab807fd) * Merge branch 'nxagent' -2011-12-28 18:46:39 +0100 Mike Gabriel (c29053f) +2011-12-28 18:46:39 +0100 Mike Gabriel (c29053f82) * Imported nxagent-3.5.0-7.tar.gz (tag: nxagent/3.5.0-7) -2011-12-06 14:48:04 +0100 Mike Gabriel (aa16655) +2011-12-06 14:48:04 +0100 Mike Gabriel (aa1665506) * fix for patch 016_nx-x11-install.patch (2) -2011-12-06 14:44:40 +0100 Mike Gabriel (37c5f0e) +2011-12-06 14:44:40 +0100 Mike Gabriel (37c5f0ee8) * fix for patch 016_nx-x11-install.patch -2011-12-05 09:51:35 +0100 Mike Gabriel (3132e1d) +2011-12-05 09:51:35 +0100 Mike Gabriel (3132e1d02) * Add patch 016_nx-x11-install.patch, to allow installation of nx-X11 from Makefile (via make install). -2011-12-05 09:50:16 +0100 Mike Gabriel (4c66f3d) +2011-12-05 09:50:16 +0100 Mike Gabriel (4c66f3d5c) * forgot to add file (015_nxproxy-makefile-uninstall.patch) -2011-12-05 09:42:05 +0100 Mike Gabriel (a2d7774) +2011-12-05 09:42:05 +0100 Mike Gabriel (a2d77744d) * Add install/uninstall stanza to main Makefile (via patch 001_add-main-makefile.patch). -2011-12-05 09:39:08 +0100 Mike Gabriel (f4fac45) +2011-12-05 09:39:08 +0100 Mike Gabriel (f4fac4535) * Add patch: 015_nxproxy-makefile-uninstall.patch. -2011-12-05 09:35:03 +0100 Mike Gabriel (8eb3ea7) +2011-12-05 09:35:03 +0100 Mike Gabriel (8eb3ea78b) * Add patches: 012, 013, 014 - Makefile uninstall stanza patches for nxcomp, nxcompext, nxcompshad. -2011-12-02 11:54:03 +0100 Mike Gabriel (9852dfa) +2011-12-02 11:54:03 +0100 Mike Gabriel (9852dfad0) * fix EOF of pre-build-nx.sh script -2011-11-20 18:12:44 +0100 Mike Gabriel (23dcaef) +2011-11-20 18:12:44 +0100 Mike Gabriel (23dcaefb6) * missing control file changes to build nxauth -2011-11-20 18:07:06 +0100 Mike Gabriel (a690310) +2011-11-20 18:07:06 +0100 Mike Gabriel (a6903100a) * Add lintian overrides for libxcomp*: breaks-without-version. -2011-11-20 18:01:52 +0100 Mike Gabriel (7402df3) +2011-11-20 18:01:52 +0100 Mike Gabriel (7402df3ba) * fix ext. description of nxagent in control file -2011-11-20 17:06:41 +0100 Mike Gabriel (b555775) +2011-11-20 17:06:41 +0100 Mike Gabriel (b55577524) * fix patch 001 -2011-11-20 16:51:27 +0100 Mike Gabriel (5814d15) +2011-11-20 16:51:27 +0100 Mike Gabriel (5814d15bb) * Build nxauth package. -2011-11-20 16:46:36 +0100 Mike Gabriel (4fef9e4) +2011-11-20 16:46:36 +0100 Mike Gabriel (4fef9e4a4) * add forgotten patch files for patch 010 and 011 -2011-11-20 16:45:16 +0100 Mike Gabriel (7b5552f) +2011-11-20 16:45:16 +0100 Mike Gabriel (7b5552f70) * Add patch: 011_add-nxauth-wrapper.patch. -2011-11-20 16:42:28 +0100 Mike Gabriel (369972d) +2011-11-20 16:42:28 +0100 Mike Gabriel (369972db3) * Add patch: 010_nxauth-fix-binary-name-in-man-page.patch. -2011-11-20 16:18:39 +0100 Mike Gabriel (e6fa2ca) +2011-11-20 16:18:39 +0100 Mike Gabriel (e6fa2ca31) * Fix of nxproxy build in main Makefile (modifies 001_add-main-makefile.patch). -2011-11-20 16:15:36 +0100 Mike Gabriel (b3d3ea7) +2011-11-20 16:15:36 +0100 Mike Gabriel (b3d3ea7d8) * main Makefile does not need x-bits set -2011-11-20 15:51:32 +0100 Mike Gabriel (379f32a) +2011-11-20 15:51:32 +0100 Mike Gabriel (379f32a5e) * Add nxproxy man page to nxproxy package. -2011-11-20 15:50:20 +0100 Mike Gabriel (5336186) +2011-11-20 15:50:20 +0100 Mike Gabriel (5336186cf) * Add patch: 009_nxproxy-add-man-page.patch. -2011-11-20 15:41:55 +0100 Mike Gabriel (ed08056) +2011-11-20 15:41:55 +0100 Mike Gabriel (ed08056fd) * fix permission of nxproxy wrapper -2011-11-20 15:40:39 +0100 Mike Gabriel (a84dd07) +2011-11-20 15:40:39 +0100 Mike Gabriel (a84dd07bb) * rename 005_add-nxagent-wrapper.patch -2011-11-20 15:39:31 +0100 Mike Gabriel (5ea24ed) +2011-11-20 15:39:31 +0100 Mike Gabriel (5ea24ed1e) * Add patch: 008_add-nxproxy-wrapper.patch. Build nxproxy package. -2011-11-20 15:36:37 +0100 Mike Gabriel (867c3b9) +2011-11-20 15:36:37 +0100 Mike Gabriel (867c3b978) * Add autoconf as build dependency. -2011-11-20 15:27:49 +0100 Mike Gabriel (63bdc1f) +2011-11-20 15:27:49 +0100 Mike Gabriel (63bdc1f87) * Remove unknown option --with from dh_auto_clean. -2011-11-20 15:26:17 +0100 Mike Gabriel (c0fb3c3) +2011-11-20 15:26:17 +0100 Mike Gabriel (c0fb3c34b) * remove build cruft from nxproxy, adapt patch set 006 -2011-11-20 15:03:19 +0100 Mike Gabriel (41c5c25) +2011-11-20 15:03:19 +0100 Mike Gabriel (41c5c2537) * fix distclean for patch 001_add-main-makefile.patch -2011-11-20 14:56:16 +0100 Mike Gabriel (b026a80) +2011-11-20 14:56:16 +0100 Mike Gabriel (b026a8005) * Add patch: 007_nxcompshad-clean-gch-files.patch. -2011-11-20 14:49:53 +0100 Mike Gabriel (d93577c) +2011-11-20 14:49:53 +0100 Mike Gabriel (d93577c58) * Add patch: 006_remove-configure-files.patch. -2011-11-20 14:43:34 +0100 Mike Gabriel (5489d46) +2011-11-20 14:43:34 +0100 Mike Gabriel (5489d4648) * Disable build of *-dbg packages. -2011-11-19 18:15:36 +0100 Mike Gabriel (70ccae4) +2011-11-19 18:15:36 +0100 Mike Gabriel (70ccae44a) * Fix for lintian issue: extended-description-line-too-long (nxagent). -2011-11-19 18:09:05 +0100 Mike Gabriel (3add2cb) +2011-11-19 18:09:05 +0100 Mike Gabriel (3add2cba4) * Fix for lintian issue: missing-build-dependency quilt (>= 0.46-7~). -2011-11-19 17:54:22 +0100 Mike Gabriel (687e07b) +2011-11-19 17:54:22 +0100 Mike Gabriel (687e07b0c) * chown has to be chmod... stupid error... -2011-11-19 17:50:14 +0100 Mike Gabriel (7fb19af) +2011-11-19 17:50:14 +0100 Mike Gabriel (7fb19af29) * add chown a+x for nxagent wrapper script -2011-11-19 17:49:48 +0100 Mike Gabriel (9da5689) +2011-11-19 17:49:48 +0100 Mike Gabriel (9da568986) * add newline at EOF -2011-11-19 17:44:07 +0100 Mike Gabriel (5a7e3cc) +2011-11-19 17:44:07 +0100 Mike Gabriel (5a7e3cc13) * Add patch: 005_add_nxagent_wrapper.patch. -2011-11-19 17:40:48 +0100 Mike Gabriel (e603345) +2011-11-19 17:40:48 +0100 Mike Gabriel (e60334546) * changelog maintenance -2011-11-19 17:40:33 +0100 Mike Gabriel (1234d1b) +2011-11-19 17:40:33 +0100 Mike Gabriel (1234d1b89) * Add patch: 004_nx-x11-fix-nxcompshad-build.patch. -2011-11-19 17:36:45 +0100 Mike Gabriel (85be77c) +2011-11-19 17:36:45 +0100 Mike Gabriel (85be77cb3) * Add patch: 003_nxcompshad-gcc43.patch -2011-11-19 17:30:04 +0100 Mike Gabriel (f7e6c45) +2011-11-19 17:30:04 +0100 Mike Gabriel (f7e6c45a5) * Add patch: 002_nxcompshad-build-against-nx-x11-only.patch -2011-11-19 17:08:40 +0100 Mike Gabriel (954557e) +2011-11-19 17:08:40 +0100 Mike Gabriel (954557e90) * Add main Makefile via patch: 001_add-main-makefile.patch. -2011-11-19 16:43:25 +0100 Mike Gabriel (4076b41) +2011-11-19 16:43:25 +0100 Mike Gabriel (4076b4132) * Add quilt as build dependency. -2011-11-19 16:10:28 +0100 Mike Gabriel (d031104) +2011-11-19 16:10:28 +0100 Mike Gabriel (d03110473) * add /debian folder -2011-11-19 15:59:43 +0100 Mike Gabriel (65f882e) +2011-11-19 15:59:43 +0100 Mike Gabriel (65f882e05) * Merge branch 'nxproxy' -2011-11-19 15:59:38 +0100 Mike Gabriel (9bfca1c) +2011-11-19 15:59:38 +0100 Mike Gabriel (9bfca1c2d) * Merge branch 'nxcompshad' -2011-11-19 15:59:26 +0100 Mike Gabriel (5e502cb) +2011-11-19 15:59:26 +0100 Mike Gabriel (5e502cbb1) * Merge branch 'nxcompext' -2011-11-19 15:59:16 +0100 Mike Gabriel (a48361b) +2011-11-19 15:59:16 +0100 Mike Gabriel (a48361b11) * Merge branch 'nxcomp' -2011-11-13 09:53:38 +0100 Reinhard Tartler (6dc46fa) +2011-11-13 09:53:38 +0100 Reinhard Tartler (6dc46faed) * Imported nxproxy-3.5.0-1.tar.gz (tag: nxproxy/3.5.0-1, origin/nxproxy, gh-sunweaver/nxproxy) -2011-11-13 09:53:38 +0100 Reinhard Tartler (d83d9f6) +2011-11-13 09:53:38 +0100 Reinhard Tartler (d83d9f6be) * Imported nxproxy-3.4.0-2.tar.gz (tag: nxproxy/3.4.0-2) -2011-11-13 09:53:38 +0100 Reinhard Tartler (7b07a64) +2011-11-13 09:53:38 +0100 Reinhard Tartler (7b07a64ea) * Imported nxproxy-3.3.0-2.tar.gz (tag: nxproxy/3.3.0-2) -2011-11-13 09:53:38 +0100 Reinhard Tartler (131e675) +2011-11-13 09:53:38 +0100 Reinhard Tartler (131e675bd) * Imported nxproxy-3.2.0-1.tar.gz (tag: nxproxy/3.2.0-1) -2011-11-13 09:53:38 +0100 Reinhard Tartler (d588e1f) +2011-11-13 09:53:38 +0100 Reinhard Tartler (d588e1f09) * Imported nxproxy-3.1.0-2.tar.gz (tag: nxproxy/3.1.0-2) -2011-11-13 09:53:38 +0100 Reinhard Tartler (35472e3) +2011-11-13 09:53:38 +0100 Reinhard Tartler (35472e348) * Imported nxproxy-3.0.0-4.tar.gz (tag: nxproxy/3.0.0-4) -2011-11-13 09:53:12 +0100 Reinhard Tartler (bf85c6e) +2011-11-13 09:53:12 +0100 Reinhard Tartler (bf85c6e69) * Imported nxcompshad-3.5.0-2.tar.gz (tag: nxcompshad/3.5.0-2, origin/nxcompshad, gh-sunweaver/nxcompshad) -2011-11-13 09:53:12 +0100 Reinhard Tartler (c70adf7) +2011-11-13 09:53:12 +0100 Reinhard Tartler (c70adf725) * Imported nxcompshad-3.4.0-3.tar.gz (tag: nxcompshad/3.4.0-3) -2011-11-13 09:53:12 +0100 Reinhard Tartler (2208f4f) +2011-11-13 09:53:12 +0100 Reinhard Tartler (2208f4f9e) * Imported nxcompshad-3.4.0-1.tar.gz (tag: nxcompshad/3.4.0-1) -2011-11-13 09:53:12 +0100 Reinhard Tartler (3d8e85c) +2011-11-13 09:53:12 +0100 Reinhard Tartler (3d8e85c47) * Imported nxcompshad-3.3.0-3.tar.gz (tag: nxcompshad/3.3.0-3) -2011-11-13 09:53:12 +0100 Reinhard Tartler (3b44046) +2011-11-13 09:53:12 +0100 Reinhard Tartler (3b4404668) * Imported nxcompshad-3.3.0-2.tar.gz (tag: nxcompshad/3.3.0-2) -2011-11-13 09:53:12 +0100 Reinhard Tartler (9f70213) +2011-11-13 09:53:12 +0100 Reinhard Tartler (9f7021392) * Imported nxcompshad-3.2.0-3.tar.gz (tag: nxcompshad/3.2.0-3) -2011-11-13 09:53:12 +0100 Reinhard Tartler (c7dc0c3) +2011-11-13 09:53:12 +0100 Reinhard Tartler (c7dc0c3cd) * Imported nxcompshad-3.2.0-1.tar.gz (tag: nxcompshad/3.2.0-1) -2011-11-13 09:53:12 +0100 Reinhard Tartler (8fa612d) +2011-11-13 09:53:12 +0100 Reinhard Tartler (8fa612d1a) * Imported nxcompshad-3.1.0-2.tar.gz (tag: nxcompshad/3.1.0-2) -2011-11-13 09:52:38 +0100 Reinhard Tartler (88dace9) +2011-11-13 09:52:38 +0100 Reinhard Tartler (88dace9a9) * Imported nxcompext-3.5.0-1.tar.gz (tag: nxcompext/3.5.0-1, origin/nxcompext, gh-sunweaver/nxcompext) -2011-11-13 09:52:38 +0100 Reinhard Tartler (9573b56) +2011-11-13 09:52:38 +0100 Reinhard Tartler (9573b5669) * Imported nxcompext-3.4.0-1.tar.gz (tag: nxcompext/3.4.0-1) -2011-11-13 09:52:38 +0100 Reinhard Tartler (9ea0691) +2011-11-13 09:52:38 +0100 Reinhard Tartler (9ea069139) * Imported nxcompext-3.3.0-4.tar.gz (tag: nxcompext/3.3.0-4) -2011-11-13 09:52:38 +0100 Reinhard Tartler (f2f6dab) +2011-11-13 09:52:38 +0100 Reinhard Tartler (f2f6dab87) * Imported nxcompext-3.3.0-3.tar.gz (tag: nxcompext/3.3.0-3) -2011-11-13 09:52:37 +0100 Reinhard Tartler (abf03fd) +2011-11-13 09:52:37 +0100 Reinhard Tartler (abf03fd2c) * Imported nxcompext-3.3.0-2.tar.gz (tag: nxcompext/3.3.0-2) -2011-11-13 09:52:37 +0100 Reinhard Tartler (4ad13f4) +2011-11-13 09:52:37 +0100 Reinhard Tartler (4ad13f4ef) * Imported nxcompext-3.2.0-1.tar.gz (tag: nxcompext/3.2.0-1) -2011-11-13 09:52:37 +0100 Reinhard Tartler (42e72ef) +2011-11-13 09:52:37 +0100 Reinhard Tartler (42e72ef5f) * Imported nxcompext-3.1.0-2.tar.gz (tag: nxcompext/3.1.0-2) -2011-11-13 09:27:53 +0100 Reinhard Tartler (232dfc4) +2011-11-13 09:27:53 +0100 Reinhard Tartler (232dfc41d) * Imported nxcomp-3.5.0-2.tar.gz (tag: nxcomp/3.5.0-2, origin/nxcomp, gh-sunweaver/nxcomp) -2011-11-13 09:27:53 +0100 Reinhard Tartler (233de71) +2011-11-13 09:27:53 +0100 Reinhard Tartler (233de71fc) * Imported nxcomp-3.5.0-1.tar.gz (tag: nxcomp/3.5.0-1) -2011-11-13 09:27:53 +0100 Reinhard Tartler (7c9e193) +2011-11-13 09:27:53 +0100 Reinhard Tartler (7c9e193ae) * Imported nxcomp-3.4.0-7.tar.gz (tag: nxcomp/3.4.0-7) -2011-11-13 09:27:53 +0100 Reinhard Tartler (4779616) +2011-11-13 09:27:53 +0100 Reinhard Tartler (477961678) * Imported nxcomp-3.4.0-6.tar.gz (tag: nxcomp/3.4.0-6) -2011-11-13 09:27:52 +0100 Reinhard Tartler (799bf67) +2011-11-13 09:27:52 +0100 Reinhard Tartler (799bf672a) * Imported nxcomp-3.4.0-1.tar.gz (tag: nxcomp/3.4.0-1) -2011-11-13 09:27:52 +0100 Reinhard Tartler (ca416e7) +2011-11-13 09:27:52 +0100 Reinhard Tartler (ca416e797) * Imported nxcomp-3.3.0-4.tar.gz (tag: nxcomp/3.3.0-4) -2011-11-13 09:27:52 +0100 Reinhard Tartler (95ce6b7) +2011-11-13 09:27:52 +0100 Reinhard Tartler (95ce6b74b) * Imported nxcomp-3.3.0-3.tar.gz (tag: nxcomp/3.3.0-3) -2011-11-13 09:27:52 +0100 Reinhard Tartler (920705c) +2011-11-13 09:27:52 +0100 Reinhard Tartler (920705cf7) * Imported nxcomp-3.2.0-7.tar.gz (tag: nxcomp/3.2.0-7) -2011-11-13 09:27:52 +0100 Reinhard Tartler (92239da) +2011-11-13 09:27:52 +0100 Reinhard Tartler (92239dafb) * Imported nxcomp-3.2.0-6.tar.gz (tag: nxcomp/3.2.0-6) -2011-11-13 09:27:52 +0100 Reinhard Tartler (d7a8d67) +2011-11-13 09:27:52 +0100 Reinhard Tartler (d7a8d67d7) * Imported nxcomp-3.1.0-6.tar.gz (tag: nxcomp/3.1.0-6) -2011-11-13 09:27:51 +0100 Reinhard Tartler (3e92412) +2011-11-13 09:27:51 +0100 Reinhard Tartler (3e924126b) * Imported nxcomp-3.1.0-4.tar.gz (tag: nxcomp/3.1.0-4) -2011-10-10 18:03:17 +0200 Reinhard Tartler (9997e13) +2011-10-10 18:03:17 +0200 Reinhard Tartler (9997e13bb) * Merge branch 'nx-X11' -2011-10-10 18:02:52 +0200 Reinhard Tartler (5b4ca0f) +2011-10-10 18:02:52 +0200 Reinhard Tartler (5b4ca0f93) * Merge branch 'nxagent' -2011-10-10 18:02:41 +0200 Reinhard Tartler (e29a112) +2011-10-10 18:02:41 +0200 Reinhard Tartler (e29a11209) * Merge branch 'nxauth' -2011-10-10 17:59:01 +0200 Reinhard Tartler (e01b917) +2011-10-10 17:59:01 +0200 Reinhard Tartler (e01b9177b) * Imported nxagent-3.5.0-5.tar.gz (tag: nxagent/3.5.0-5) -2011-10-10 17:59:00 +0200 Reinhard Tartler (39b738a) +2011-10-10 17:59:00 +0200 Reinhard Tartler (39b738a67) * Imported nxagent-3.5.0-2.tar.gz (tag: nxagent/3.5.0-2) -2011-10-10 17:59:00 +0200 Reinhard Tartler (e6db7e9) +2011-10-10 17:59:00 +0200 Reinhard Tartler (e6db7e936) * Imported nxagent-3.4.0-9.tar.gz (tag: nxagent/3.4.0-9) -2011-10-10 17:58:59 +0200 Reinhard Tartler (b7494f0) +2011-10-10 17:58:59 +0200 Reinhard Tartler (b7494f082) * Imported nxagent-3.4.0-8.tar.gz (tag: nxagent/3.4.0-8) -2011-10-10 17:58:59 +0200 Reinhard Tartler (c078024) +2011-10-10 17:58:59 +0200 Reinhard Tartler (c07802401) * Imported nxagent-3.4.0-5.tar.gz (tag: nxagent/3.4.0-5) -2011-10-10 17:58:58 +0200 Reinhard Tartler (d30ef03) +2011-10-10 17:58:58 +0200 Reinhard Tartler (d30ef0340) * Imported nxagent-3.4.0-3.tar.gz (tag: nxagent/3.4.0-3) -2011-10-10 17:58:57 +0200 Reinhard Tartler (25af86c) +2011-10-10 17:58:57 +0200 Reinhard Tartler (25af86cd3) * Imported nxagent-3.4.0-16.tar.gz (tag: nxagent/3.4.0-16) -2011-10-10 17:58:57 +0200 Reinhard Tartler (e9132da) +2011-10-10 17:58:57 +0200 Reinhard Tartler (e9132da09) * Imported nxagent-3.4.0-11.tar.gz (tag: nxagent/3.4.0-11) -2011-10-10 17:58:56 +0200 Reinhard Tartler (6f5e20b) +2011-10-10 17:58:56 +0200 Reinhard Tartler (6f5e20bc4) * Imported nxagent-3.3.0-9.tar.gz (tag: nxagent/3.3.0-9) -2011-10-10 17:58:56 +0200 Reinhard Tartler (45b970f) +2011-10-10 17:58:56 +0200 Reinhard Tartler (45b970f25) * Imported nxagent-3.3.0-6.tar.gz (tag: nxagent/3.3.0-6) -2011-10-10 17:58:56 +0200 Reinhard Tartler (2291444) +2011-10-10 17:58:56 +0200 Reinhard Tartler (229144470) * Imported nxagent-3.3.0-18.tar.gz (tag: nxagent/3.3.0-18) -2011-10-10 17:58:56 +0200 Reinhard Tartler (fc05e5e) +2011-10-10 17:58:56 +0200 Reinhard Tartler (fc05e5e04) * Imported nxagent-3.3.0-13.tar.gz (tag: nxagent/3.3.0-13) -2011-10-10 17:58:55 +0200 Reinhard Tartler (1a74e03) +2011-10-10 17:58:55 +0200 Reinhard Tartler (1a74e0323) * Imported nxagent-3.3.0-10.tar.gz (tag: nxagent/3.3.0-10) -2011-10-10 17:58:55 +0200 Reinhard Tartler (97fe765) +2011-10-10 17:58:55 +0200 Reinhard Tartler (97fe7650e) * Imported nxagent-3.2.0-8.tar.gz (tag: nxagent/3.2.0-8) -2011-10-10 17:58:55 +0200 Reinhard Tartler (c4e7705) +2011-10-10 17:58:55 +0200 Reinhard Tartler (c4e7705d2) * Imported nxagent-3.2.0-7.tar.gz (tag: nxagent/3.2.0-7) -2011-10-10 17:58:55 +0200 Reinhard Tartler (c998323) +2011-10-10 17:58:55 +0200 Reinhard Tartler (c9983230f) * Imported nxagent-3.2.0-6.tar.gz (tag: nxagent/3.2.0-6) -2011-10-10 17:58:55 +0200 Reinhard Tartler (b791640) +2011-10-10 17:58:55 +0200 Reinhard Tartler (b79164001) * Imported nxagent-3.2.0-5.tar.gz (tag: nxagent/3.2.0-5) -2011-10-10 17:58:31 +0200 Reinhard Tartler (1c25e92) +2011-10-10 17:58:31 +0200 Reinhard Tartler (1c25e92b9) * Imported nxagent-3.2.0-10.tar.gz (tag: nxagent/3.2.0-10) -2011-10-10 17:58:31 +0200 Reinhard Tartler (266b555) +2011-10-10 17:58:31 +0200 Reinhard Tartler (266b55549) * Imported nxagent-3.1.0-7.tar.gz (tag: nxagent/3.1.0-7) -2011-10-10 17:58:31 +0200 Reinhard Tartler (3e7c669) +2011-10-10 17:58:31 +0200 Reinhard Tartler (3e7c6697a) * Imported nxagent-3.1.0-6.tar.gz (tag: nxagent/3.1.0-6) -2011-10-10 17:58:30 +0200 Reinhard Tartler (9e33710) +2011-10-10 17:58:30 +0200 Reinhard Tartler (9e3371021) * Imported nxagent-3.1.0-2.tar.gz (tag: nxagent/3.1.0-2) -2011-10-10 17:57:25 +0200 Reinhard Tartler (edddbe8) +2011-10-10 17:57:25 +0200 Reinhard Tartler (edddbe876) * creating nxagent -2011-10-10 17:51:57 +0200 Reinhard Tartler (caf1bc4) +2011-10-10 17:51:57 +0200 Reinhard Tartler (caf1bc41f) * Imported nxauth-3.5.0-1.tar.gz (tag: nxauth/3.5.0-1) -2011-10-10 17:51:57 +0200 Reinhard Tartler (fea16d7) +2011-10-10 17:51:57 +0200 Reinhard Tartler (fea16d7bb) * Imported nxauth-3.4.0-3.tar.gz (tag: nxauth/3.4.0-3) -2011-10-10 17:51:57 +0200 Reinhard Tartler (d90fd5d) +2011-10-10 17:51:57 +0200 Reinhard Tartler (d90fd5d13) * Imported nxauth-3.4.0-2.tar.gz (tag: nxauth/3.4.0-2) -2011-10-10 17:51:57 +0200 Reinhard Tartler (7881dac) +2011-10-10 17:51:57 +0200 Reinhard Tartler (7881dac52) * Imported nxauth-3.4.0-1.tar.gz (tag: nxauth/3.4.0-1) -2011-10-10 17:51:57 +0200 Reinhard Tartler (c76c078) +2011-10-10 17:51:57 +0200 Reinhard Tartler (c76c07835) * Imported nxauth-3.3.0-1.tar.gz (tag: nxauth/3.3.0-1) -2011-10-10 17:51:57 +0200 Reinhard Tartler (76b9f2d) +2011-10-10 17:51:57 +0200 Reinhard Tartler (76b9f2d91) * Imported nxauth-3.2.0-1.tar.gz (tag: nxauth/3.2.0-1) -2011-10-10 17:51:57 +0200 Reinhard Tartler (9610c1e) +2011-10-10 17:51:57 +0200 Reinhard Tartler (9610c1e72) * Imported nxauth-3.1.0-1.tar.gz (tag: nxauth/3.1.0-1) -2011-10-10 17:47:59 +0200 Reinhard Tartler (15cee47) +2011-10-10 17:47:59 +0200 Reinhard Tartler (15cee47a4) * Imported nx-X11-3.5.0-2.tar.gz (tag: nx-X11/3.5.0-2, origin/nx-X11, gh-sunweaver/nx-X11) -2011-10-10 17:47:52 +0200 Reinhard Tartler (964f539) +2011-10-10 17:47:52 +0200 Reinhard Tartler (964f53964) * Imported nx-X11-3.5.0-1.tar.gz (tag: nx-X11/3.5.0-1) -2011-10-10 17:47:50 +0200 Reinhard Tartler (17bae6b) +2011-10-10 17:47:50 +0200 Reinhard Tartler (17bae6bff) * Imported nx-X11-3.4.0-4.tar.gz (tag: nx-X11/3.4.0-4) -2011-10-10 17:47:47 +0200 Reinhard Tartler (4fceb19) +2011-10-10 17:47:47 +0200 Reinhard Tartler (4fceb197e) * Imported nx-X11-3.4.0-3.tar.gz (tag: nx-X11/3.4.0-3) -2011-10-10 17:47:45 +0200 Reinhard Tartler (3daf6d4) +2011-10-10 17:47:45 +0200 Reinhard Tartler (3daf6d446) * Imported nx-X11-3.4.0-1.tar.gz (tag: nx-X11/3.4.0-1) -2011-10-10 17:47:42 +0200 Reinhard Tartler (5036ffb) +2011-10-10 17:47:42 +0200 Reinhard Tartler (5036ffbe6) * Imported nx-X11-3.3.0-7.tar.gz (tag: nx-X11/3.3.0-7) -2011-10-10 17:47:40 +0200 Reinhard Tartler (bd433c6) +2011-10-10 17:47:40 +0200 Reinhard Tartler (bd433c648) * Imported nx-X11-3.3.0-6.tar.gz (tag: nx-X11/3.3.0-6) -2011-10-10 17:47:37 +0200 Reinhard Tartler (55a9311) +2011-10-10 17:47:37 +0200 Reinhard Tartler (55a9311fb) * Imported nx-X11-3.3.0-5.tar.gz (tag: nx-X11/3.3.0-5) -2011-10-10 17:47:35 +0200 Reinhard Tartler (aefdef6) +2011-10-10 17:47:35 +0200 Reinhard Tartler (aefdef62f) * Imported nx-X11-3.3.0-4.tar.gz (tag: nx-X11/3.3.0-4) -2011-10-10 17:47:32 +0200 Reinhard Tartler (01ed757) +2011-10-10 17:47:32 +0200 Reinhard Tartler (01ed75712) * Imported nx-X11-3.3.0-3.tar.gz (tag: nx-X11/3.3.0-3) -2011-10-10 17:47:30 +0200 Reinhard Tartler (30463b0) +2011-10-10 17:47:30 +0200 Reinhard Tartler (30463b084) * Imported nx-X11-3.2.0-2.tar.gz (tag: nx-X11/3.2.0-2) -2011-10-10 17:47:28 +0200 Reinhard Tartler (713da22) +2011-10-10 17:47:28 +0200 Reinhard Tartler (713da2260) * Imported nx-X11-3.2.0-1.tar.gz (tag: nx-X11/3.2.0-1) -2011-10-10 17:46:43 +0200 Reinhard Tartler (3d1c57d) +2011-10-10 17:46:43 +0200 Reinhard Tartler (3d1c57d5e) * Imported nx-X11-3.1.0-4.tar.gz (tag: nx-X11/3.1.0-4) -2011-10-10 17:46:25 +0200 Reinhard Tartler (844a409) +2011-10-10 17:46:25 +0200 Reinhard Tartler (844a4094f) * Imported nx-X11-3.1.0-3.tar.gz (tag: nx-X11/3.1.0-3) -2011-10-10 17:43:39 +0200 Reinhard Tartler (f4092ab) +2011-10-10 17:43:39 +0200 Reinhard Tartler (f4092abdf) * Imported nx-X11-3.1.0-1.tar.gz (tag: nx-X11/3.1.0-1) -2011-10-10 17:22:20 +0200 Reinhard Tartler (e5c70da) +2011-10-10 17:22:20 +0200 Reinhard Tartler (e5c70dac0) * creating nxauth -2011-10-10 15:28:54 +0200 Reinhard Tartler (a840692) +2011-10-10 15:28:54 +0200 Reinhard Tartler (a840692ed) * creating nx-X11 diff --git a/VERSION b/VERSION index 3c2645490..f1a1688ce 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.99.3 +3.5.99.4 diff --git a/debian/changelog b/debian/changelog index 4223ebb3d..9e2dd7ae8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +nx-libs (2:3.5.99.4-0.1) unstable; urgency=medium + + * Upstream-provided Debian package for nx-libs. + See upstream ChangeLog for recent changes. + + -- Mike Gabriel Fri, 24 Feb 2017 22:19:27 +0000 + nx-libs (2:3.5.99.3-0.1) unstable; urgency=medium * Upstream-provided Debian package for nx-libs. diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index 769367c54..af5fc88f8 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -24,7 +24,7 @@ .\" other dealings in this Software without prior written authorization .\" from The Open Group. .ds q \N'34' -.TH NXAGENT 1 3.6.x +.TH nxagent 1 "Feb 2017" "Version 3.6.x" "NX Agent (Xserver)" .SH NAME nxagent \- nx-X11 Agent (nested Xserver optimized for remote computing) .SH SYNOPSIS diff --git a/nx-libs.spec b/nx-libs.spec index 4779885da..2e3d08466 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -1,7 +1,7 @@ %global _hardened_build 1 Name: nx-libs -Version: 3.5.99.3 +Version: 3.5.99.4 Release: 0.0build1%{?dist} Summary: NX X11 protocol compression libraries diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index 3cf95c992..dd14afa12 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH nxproxy 1 "June 2016" "Version 3.6.x" "NX Proxy" +.TH nxproxy 1 "Feb 2017" "Version 3.6.x" "NX Proxy" .SH NAME nxproxy \- NX Proxy Tool .SH SYNOPSIS -- cgit v1.2.3 From 4c2fe0d97f03e8f325bc63bbacda257f804fae7d Mon Sep 17 00:00:00 2001 From: Bernard Cafarelli Date: Sun, 5 Feb 2017 23:29:41 +0100 Subject: nxproxy: Support communication over stdin. Allow nxcl to use standard ssh instead of nxssh. Fixes ArcticaProject/nx-libs#98. --- nxproxy/Main.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 13 deletions(-) (limited to 'nxproxy') diff --git a/nxproxy/Main.c b/nxproxy/Main.c index ae90990d4..d9fb1ef4f 100644 --- a/nxproxy/Main.c +++ b/nxproxy/Main.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "NX.h" @@ -27,6 +29,8 @@ #undef TEST #undef DEBUG +extern const char *__progname; + /* * Entry point when running nxproxy stand-alone. */ @@ -37,27 +41,74 @@ int main(int argc, const char **argv) char *options = NULL; + char *nx_commfd_str = NULL; + options = getenv("NX_DISPLAY"); - if (NXTransParseCommandLine(argc, argv) < 0) + if ((nx_commfd_str = getenv("NX_COMMFD")) != NULL) { - NXTransCleanup(); - } + errno = 0; + unsigned long int nx_commfd = strtoul(nx_commfd_str, NULL, 10); - if (NXTransParseEnvironment(options, 0) < 0) - { - NXTransCleanup(); + if ((errno) && (0 == nx_commfd)) + { + fprintf(stderr, "%s: NX_COMMFD environment variable's value [%s] is not a file descriptor number. " + "Aborting...\n", + __progname, nx_commfd_str + ); + NXTransCleanup(); + } + else if ((unsigned long int) INT_MAX < nx_commfd) + { + fprintf(stderr, "%s: NX_COMMFD environment variable's value [%lu] is out of range for a file descriptor number. " + "Aborting...\n", + __progname, nx_commfd); + NXTransCleanup(); + } + else { + result = NXTransCreate(nx_commfd, NX_MODE_SERVER, options); + + if (result != 1) + { + fprintf(stderr, "%s: NXTransCreate failed for FD#%lu\n" + "Aborting...", + __progname, nx_commfd); + NXTransCleanup(); + } + + } + + // go into endless loop + + if (result == 1) + { + while (NXTransRunning(NX_FD_ANY)) + result = NXTransContinue(NULL); + } } + else + { - /* - * This should not return... - */ + if (NXTransParseCommandLine(argc, argv) < 0) + { + NXTransCleanup(); + } - #ifdef TEST - fprintf(stderr, "Main: Yielding control to NX entry point.\n"); - #endif + if (NXTransParseEnvironment(options, 0) < 0) + { + NXTransCleanup(); + } - result = NXTransProxy(NX_FD_ANY, NX_MODE_ANY, NX_DISPLAY_ANY); + /* + * This should not return... + */ + + #ifdef TEST + fprintf(stderr, "%s: Yielding control to NX entry point.\n", __progname); + #endif + + result = NXTransProxy(NX_FD_ANY, NX_MODE_ANY, NX_DISPLAY_ANY); + } /* * ...So these should not be called. -- cgit v1.2.3 From 3a2ecb9a5d3b54b07cb3ea54d74f80a0686821db Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 11 Apr 2017 17:01:25 +0200 Subject: release 3.5.99.5 --- ChangeLog | 5233 +++++++++++++--------- VERSION | 2 +- debian/changelog | 7 + debian/copyright | 38 - nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 2 +- nx-libs.spec | 2 +- nxproxy/man/nxproxy.1 | 2 +- 7 files changed, 3235 insertions(+), 2051 deletions(-) (limited to 'nxproxy') diff --git a/ChangeLog b/ChangeLog index afcecb41a..c6e22636b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3370 +1,4576 @@ -2017-02-24 22:22:47 +0000 Mike Gabriel (73cc94686) +2017-04-11 17:01:25 +0200 Mike Gabriel (856b59b) - * release 3.5.99.4 (HEAD -> 3.6.x) + * release 3.5.99.5 (HEAD, release-builds/3.6.x, 3.6.x) -2017-02-24 12:23:51 +0100 Mihai Moldovan (31426a3d2) +2017-04-10 20:54:19 +0000 Mike Gabriel (d6479c9) - * Merge branch 'uli42-fix_#306_#322' into 3.6.x (origin/HEAD, - origin/3.6.x) + * debian/patches: Update 016_nx-X11_install-location.debian.patch + (due to fuzziness). (origin/HEAD, origin/3.6.x) -2017-02-19 00:06:54 +0100 Ulrich Sibiller (3d8575c21) +2017-04-10 20:53:34 +0000 Mike Gabriel (d63b4a5) + + * Regression fix for added libXfont2 API support: + +2017-04-10 16:33:27 +0200 Mihai Moldovan (2d700b1) + + * Merge branch 'sunweaver-pr/createpixmap-alloc-hints-abi-change' + into 3.6.x + +2017-02-22 12:59:07 +0000 Mike Gabriel (8b5bb2c) + + * hw/nxagent/Pixmap.c et al.: Propagate usage_hint through + nxagentCreatePixmap, as well. + (gh-sunweaver/pr/createpixmap-alloc-hints-abi-change, + pr/createpixmap-alloc-hints-abi-change) + +2017-03-11 01:13:58 +0100 Mike Gabriel (560c956) + + * Mesa.patches: Adapt Mesa to CreatePixmap allocation hint ABI bump. + +2017-02-22 14:14:41 +0100 Aaron Plattner (aa50b35) + + * Save pixmap allocation hints into the PixmapRec. + +2017-02-22 13:30:48 +0100 Aaron Plattner (3ef6d51) + + * Add CreatePixmap allocation hints. + +2017-04-10 16:20:51 +0200 Mihai Moldovan (cc24d8b) + + * Merge branch 'sunweaver-pr/switch-to-libXfont2-API' into 3.6.x + +2017-04-10 12:43:33 +0200 Mike Gabriel (c4c5485) + + * nx-libs.spec: Prefer libXfont2-devel on RPM distro versions that + have it.~ (gh-sunweaver/pr/switch-to-libXfont2-API, + pr/switch-to-libXfont2-API) + +2017-04-10 10:09:32 +0000 Mike Gabriel (a5432aa) + + * debian/control: Use B-D libxfont-dev only. Follow libXfont2 + transition on Debian (and alike). + +2017-04-10 10:08:14 +0000 Mike Gabriel (92979a4) + + * Makefile: Tell Xserver build which Xfont API to use (v2 or v1) + depending on what's available in the build env. + +2017-02-09 14:05:57 +0100 Mike Gabriel (f4c80a7) + + * Xserver: Support building against libXfont2 (v2) API and old + libXfont(1) API alike. + +2017-02-16 08:19:40 +0000 Jamey Sharp (f743f9f) + + * SetFontPath: set client->errorValue on failure. + +2017-02-16 08:21:56 +0000 Eamon Walsh (4768662) + + * dix: pass a valid ClientPtr to SetFontPath in all cases. + +2017-02-14 09:17:25 +0100 Mike Gabriel (523009b) + + * hw/nxagent/BitmapUtils.c: Derive from utilbitmap.c in deprecated + libXfont1 and ship as copy-of-code with nxagent. + +2017-02-09 22:31:19 +0000 Mike Gabriel (6a06a6c) + + * dix: Move InitFonts up above screen initialization + +2017-02-09 11:22:41 +0100 Mike Gabriel (03b772b) + + * Xserver/Imakefile: Improve readability by introducing the NULL + variable and adding more line-breaks. + +2017-04-10 16:01:02 +0200 Mike Gabriel (9e2588e) + + * Revert "regression fix for 52872a0: Keep index parameter in + AddScreen() for now. Requires proper ABI backport. (was: + copy+paste error)." + +2017-04-10 15:01:39 +0200 Mihai Moldovan (5421dd4) + + * Merge branch + 'sunweaver-pr/remove-index-from-CloseScreen-ABI-backport' + into 3.6.x + +2017-03-11 00:53:01 +0100 Dave Airlie (93ea74e) + + * xserver: remove index from CloseScreen (API/ABI breakage) + (gh-sunweaver/pr/remove-index-from-CloseScreen-ABI-backport, + pr/remove-index-from-CloseScreen-ABI-backport) + +2017-04-07 16:20:47 +0200 Vadim Troshchinskiy (ab3974f) + + * Merge remote-tracking branch + 'sunweaver-pr/pr/nxproxy-read-from-stdin' into 3.6.x + +2017-02-05 23:29:41 +0100 Bernard Cafarelli (4c2fe0d) + + * nxproxy: Support communication over stdin. Allow nxcl to use + standard ssh instead of nxssh. + (gh-sunweaver/pr/nxproxy-read-from-stdin, + pr/nxproxy-read-from-stdin) + +2017-04-07 13:48:56 +0200 Mike Gabriel (1441b02) + + * nxcomp/Loop.cpp: Fix server/client mode info cerr printing in + PrintProcessInfo(). + +2017-04-07 10:32:28 +0200 Mike Gabriel (dcdbc10) + + * Merge branch 'sunweaver-pr/drop-render-fullcolor-workaround' into + 3.6.x + +2017-03-21 21:25:39 +0100 Mike Gabriel (6c8c950) + + * NXpicturestr_PictSolidFill.h: Drop file and revert db8705. Not an + issue anymore nowadays. + (gh-sunweaver/pr/drop-render-fullcolor-workaround, + sunweaver-pr/drop-render-fullcolor-workaround, + pr/drop-render-fullcolor-workaround) + +2017-04-06 14:09:19 +0200 Erkki Seppälä (c8a4e1e) + + * record: avoid crash when calling RecordFlushReplyBuffer recursively + +2017-04-06 12:17:54 +0200 Mihai Moldovan (0d7b4c3) + + * Merge branch 'sunweaver-pr/mesa-patching-with-quilt' into 3.6.x + +2017-02-20 12:54:14 +0100 Mike Gabriel (2c9effe) + + * Mesa subtree: Add quilt based patch system for bundled Mesa. + (gh-sunweaver/pr/mesa-patching-with-quilt, + pr/mesa-patching-with-quilt) + +2017-04-05 11:19:54 +0200 Mike Gabriel (2767d32) + + * roll-tarball.sh: Fix ChangeLog creation, always create ChangeLog + for the CHECKOUT, not the currently checked out branch. + +2017-04-03 21:44:05 +0200 Mike Gabriel (25d38bf) + + * Merge branch 'uli42-pr/cleanup_keystroke' into 3.6.x + +2017-03-27 22:58:38 +0200 Ulrich Sibiller (ee18cd4) + + * Keystrokes: rename left/up/right/down keystrokes to descriptive + names (uli42-pr/cleanup_keystroke) + +2017-03-27 22:46:47 +0200 Ulrich Sibiller (d28cf55) + + * doc: rework keystroke documentation + +2017-03-27 22:07:51 +0200 Ulrich Sibiller (9f0713c) + + * doc: document debugging keystrokes + +2017-03-23 23:48:46 +0100 Ulrich Sibiller (e3240d6) + + * keystrokes.cfg: remove debug keystrokes + +2017-03-23 23:32:24 +0100 Ulrich Sibiller (bf27d58) + + * Keystroke.c: move some vars to inner scope + +2017-03-23 23:11:32 +0100 Ulrich Sibiller (ba5183f) + + * Init keystrokes at startup and reconnect + +2017-03-23 23:01:09 +0100 Ulrich Sibiller (f12012b) + + * Keystroke.c: avoid use of comparisons on "False" + +2017-03-23 22:54:34 +0100 Ulrich Sibiller (2b9d7d2) + + * Keystroke.c: use Booleans where appropriate + +2017-03-23 22:48:09 +0100 Ulrich Sibiller (076d458) + + * Keystroke.h: improve parse_keystroke_file() + +2017-03-23 22:46:35 +0100 Ulrich Sibiller (79520f9) + + * Keystroke.c: introduce nxagentDumpKeystrokes() + +2017-03-23 22:42:26 +0100 Ulrich Sibiller (a45a348) + + * keystrokes.cfg: add missing keystrokes + +2017-03-23 22:22:05 +0100 Ulrich Sibiller (3c921cc) + + * Keystroke.c/h: completely disable keystrokes that are not active at + compile time + +2017-03-23 22:21:00 +0100 Ulrich Sibiller (811ce49) + + * Keystroke.h: auto-enum keystrokes + +2017-03-23 22:18:16 +0100 Ulrich Sibiller (4adb191) + + * Keystroke.h/Keyboard.h: cleanup mask variables + +2017-03-21 22:33:29 +0100 Ulrich Sibiller (c693df1) + + * Keystroke.c: detect duplicate keystroke definitions + +2017-03-21 22:32:00 +0100 Ulrich Sibiller (40f0339) + + * Keystroke.c: use KEYSTROKE_NOTHING + +2017-03-21 21:52:05 +0100 Ulrich Sibiller (51782cb) + + * Args.c: add two missing options to help message + +2017-04-03 20:52:05 +0200 Mike Gabriel (147371a) + + * Merge branch + 'sunweaver-pr/xinerama-response-swapping-in-RRXineramaWriteMonitor' + into 3.6.x + +2017-03-10 14:16:26 +0100 Michal Srb (f34eff0) + + * xinerama: Swap the response in RRXineramaWriteMonitor + (gh-sunweaver/pr/xinerama-response-swapping-in-RRXineramaWriteMonitor, + sunweaver-pr/xinerama-response-swapping-in-RRXineramaWriteMonitor, + pr/xinerama-response-swapping-in-RRXineramaWriteMonitor) + +2017-04-03 20:39:06 +0200 Mike Gabriel (4e0e7c4) + + * Merge branch 'mikedep333-pr/cygwin-nxcomp-ftbfs' into 3.6.x + +2017-03-29 21:52:25 -0400 Mike DePaulo (1a2bea9) + + * Remove EMX (MS-DOS & OS/2) support + (mikedep333-pr/cygwin-nxcomp-ftbfs) + +2017-03-29 07:19:25 -0400 Mike DePaulo (9958512) + + * Cygwin nxcomp: Use Cygwin un.h + +2017-03-27 16:39:28 +0200 Mike Gabriel (3427582) + + * regression fix for 52872a0: Keep index parameter in AddScreen() for + now. Requires proper ABI backport. (was: copy+paste + error). + +2017-03-27 16:14:30 +0200 Mike Gabriel (d7d2aee) + + * Merge branch 'uli42-pr/libX11-HEAD' into 3.6.x + +2017-02-01 15:02:41 +0100 Arthur Huillet (00405b2) + + * _XDefaultError: set XlibDisplayIOError flag before calling exit + (uli42-pr/libX11-HEAD) + +2017-01-07 16:20:31 +0100 Julien Cristau (8ad49a0) + + * Fix wrong Xfree in XListFonts failure path + +2017-03-26 14:34:48 +0200 Mihai Moldovan (ac03b51) + + * Merge branch 'sunweaver-pr/dix-dispatch-backports' into 3.6.x + +2017-03-11 00:48:03 +0100 Mike Gabriel (c1fc4ba) + + * dix: Remove insane BC hacks + (gh-sunweaver/pr/dix-dispatch-backports, + pr/dix-dispatch-backports) + +2017-03-10 16:48:54 +0100 Mike Gabriel (cb9e50c) + + * Move AddScreen() comment where it actually belongs. Should be done + in X.org, too. + +2017-03-10 16:29:24 +0100 Mike Gabriel (52872a0) + + * dix: Move AddScreen() over into dispatch.c and introduce + init_screen() + +2017-03-22 00:40:55 +0100 Mihai Moldovan (f5e7d55) + + * Merge branch 'sunweaver-pr/various-os-backports' into 3.6.x + +2017-03-20 13:22:50 +0100 Adam Jackson (565421b) + + * os: Remove the useless -x option + (gh-sunweaver/pr/various-os-backports, + pr/various-os-backports) + +2017-03-15 15:46:32 +0000 Keith Packard (a95cfdf) + + * os: FatalError if -displayfd writes fail AND Clear the -displayfd + option after closing the file + +2017-03-15 15:42:10 +0000 Alan Coopersmith (e96e810) + + * Use unique logfile names when starting server with -displayfd + +2017-03-15 15:40:57 +0000 Jon TURNEY (faaba26) + + * os: -displayfd should check ports up to 65535 + +2017-03-15 15:16:37 +0000 Keith Packard (c468be8) + + * os: Use NotifyFd interface for listen descriptors + +2017-03-15 15:05:18 +0000 Jon TURNEY (3be144f) + + * Handle -displayfd and an explicit display number sensibly + +2017-03-15 15:00:27 +0000 Mike Gabriel (506aedb) + + * Xserver/os/utils.c: Add NXAGENT_SERVER specific -nolisten + parameter: ANY. + +2017-03-15 14:56:17 +0000 Kristian Høgsberg (e8bc4c7) + + * os: Add a mechanism to prevent creating any listen sockets + +2017-03-15 14:10:24 +0000 Chase Douglas (89496d9) + + * os: Add -displayfd option + +2017-03-15 11:42:30 +0100 Keith Packard (eb49996) + + * os: Use NotifyFd for ErrorConnMax + +2017-03-15 12:08:46 +0100 Adam Jackson (f5301de) + + * Move SIGUSR1 notification as late as possible. + +2017-02-16 10:54:19 +0000 Adam Jackson (4f76ed1) + + * dix: Extend initial connection handshake for forwarding proxies + +2017-02-16 10:51:40 +0000 Adam Jackson (ed52cb2) + + * dix: Pull client-is-local flag up to the ClientRec + +2017-02-16 10:35:39 +0100 Pauli Nieminen (349b6de) + + * os: always check if client is local when connection is accepted + +2017-02-15 16:42:14 +0100 Rami Ylimäki (239fe3d) + + * os: Add facilities for client ID tracking. + +2017-02-16 15:21:34 +0000 Mike Gabriel (366067b) + + * dix/os: backport various signal handling and smart scheduler + changes from X.org + +2017-02-16 15:04:43 +0000 Keith Packard (f14f738) + + * dix/os: Merge priority computation into SmartScheduleClient + +2017-02-16 10:28:32 +0100 Pauli Nieminen (6c076cf) + + * os: Fix a memory leak + +2017-02-15 14:42:48 +0000 Alan Coopersmith (8996f80) + + * Rework local client id finding code to be more uniform + +2017-02-15 14:18:35 +0000 Alan Coopersmith (6bc37b9) + + * AUDIT messages should contain uid for local accesses (X.org bug + #1997) + +2017-02-15 14:11:46 +0000 Mike Gabriel (0338cbc) + + * LBX clean-up: Drop forgotten passage in Xserver/os/connection.c. + +2017-02-15 13:51:26 +0000 Mike Gabriel (104307d) + + * Xserver/os/: Drop not-used-anymore MNX_TCPCONN macro. + +2017-02-15 10:27:43 +0100 Mike Gabriel (7177caa) + + * Xserver/os/Imakefile: Introduce the NULL variable and line-wrap + various variable definitions for the sake of better + readability. + +2017-02-15 09:41:36 +0100 Adam Jackson (eac0a8f) + + * Don't crash on unconfigured interfaces. (X.org bug #5218, Andrei + Barbu) + +2017-02-14 18:01:17 +0000 Alan Coopersmith (f912357) + + * Set padding bytes to 0 in WriteToClient + +2017-02-14 15:47:10 +0000 Aaron Plattner (2ecd2a0) + + * os: Return BadLength instead of disconnecting BigReq clients + (#4565) + +2017-02-14 15:19:18 +0000 Peter Harris (cbc2d30) + + * Fix overflow of ConnectionOutput->size and ->count + +2017-02-15 08:13:57 +0000 Michel Dänzer (65b6a62) + + * dix: Pass ClientPtr to FlushCallback + +2017-02-14 14:59:51 +0000 Keith Packard (af7c375) + + * Xserver/os/io.c: Bail out early from FlushClient if nothing needs + to be written. + +2017-02-14 13:18:04 +0000 Chris Wilson (645b757) + + * os: Immediately queue initial WriteToClient + +2017-03-15 13:27:12 +0000 Mike Gabriel (0746467) + + * os/xdmcp: Remove dead 'restart' code + +2017-03-19 22:24:59 +0100 Mike Gabriel (b7c389b) + + * Merge branch 'uli42-pr/ignore_caps' into 3.6.x + +2017-03-19 21:59:17 +0100 Ulrich Sibiller (7065e0b) + + * Keystroke.c: ignore CapsLock and NumLock most of the time + (uli42-pr/ignore_caps) + +2017-03-17 20:39:28 +0100 Mihai Moldovan (7fd5d93) + + * Merge branch 'sunweaver-pr/setnotifyfd-ABI' into 3.6.x + +2017-02-24 13:03:30 +0000 Mike Gabriel (f315ae0) + + * os: Initialize NotifyFds earlier in startup + (gh-sunweaver/pr/setnotifyfd-ABI, pr/setnotifyfd-ABI) + +2017-02-09 23:33:44 +0000 Keith Packard (761d74a) + + * os: Implement support for NotifyFd X_NOTIFY_WRITE and removal of + AddEnabledDevices/RemoveEnabledDevices + +2017-02-09 21:28:12 +0000 Fredrik Höglund (6307e6f) + + * Move the code for resetting the DPMS mode in response to input + events, from WaitForSomething to mieqProcessInputEvents. + +2017-02-09 23:35:00 +0000 Mike Gabriel (9b934a4) + + * nxagent: Use SetNotifyFd to receive events. + +2017-02-09 13:45:12 +0100 Keith Packard (86110d6) + + * os: Add NotifyFd interfaces + +2017-02-09 12:32:16 +0000 Mike Gabriel (289e8ce) + + * Xserver/include/list.h: Add list.h from X.org (from X.org commit + 63f83d1). + +2017-02-10 00:22:03 +0100 Keith Packard (9f00084) + + * os/xdmcp: Just send XDMCP keepalive packets once every three minute + +2017-03-13 23:07:19 +0100 Mike Gabriel (6ac805a) + + * Merge branch 'uli42-pr/cleanup_keystroke' into 3.6.x + +2017-03-13 22:19:17 +0100 Ulrich Sibiller (6f4eb15) + + * Update keystroke readme (gh-uli42/pr/cleanup_keystroke) + +2017-03-13 22:07:58 +0100 Ulrich Sibiller (cb40cc4) + + * Keystroke.c: remove unneeded capital keys for default keystrokes + +2017-03-13 22:00:23 +0100 Ulrich Sibiller (abf6242) + + * Keystroke.c: add new keystroke to reread keystroke config + +2017-03-13 21:42:24 +0100 Ulrich Sibiller (aadcac4) + + * Keystroke.c: simplify parse_keystroke_file + +2017-03-13 21:26:31 +0100 Ulrich Sibiller (f97bb3f) + + * Keystroke.c: fix formatting + +2017-03-13 21:19:48 +0100 Ulrich Sibiller (c134b93) + + * Keystroke.c: use an own environment variable for X2Go + +2017-03-13 21:14:20 +0100 Ulrich Sibiller (8f2679a) + + * Keystroke.c: make nxagentKeystrokeFileParsed local + +2017-03-13 20:50:53 +0100 Ulrich Sibiller (3042c50) + + * Keystroke.c: add missing Mod5 modifier + +2017-03-13 20:27:50 +0100 Ulrich Sibiller (57081e5) + + * Keystroke.c: fix code order + +2017-03-13 20:25:15 +0100 Ulrich Sibiller (2c721f4) + + * Keystroke.h: sane struct init + +2017-03-13 20:23:32 +0100 Ulrich Sibiller (d2c8115) + + * Keyboard.c: Introduce separate masks for Alt and Meta + +2017-03-13 20:21:57 +0100 Ulrich Sibiller (5595e3d) + + * Keystroke.c: Fix modifier handling + +2017-03-13 20:20:53 +0100 Ulrich Sibiller (af5a83b) + + * Keystroke.c: more/fixed debug output + +2017-03-13 20:17:51 +0100 Ulrich Sibiller (af8e5e0) + + * Keystroke: whitespace fixes + +2017-03-11 00:21:53 +0100 Ulrich Sibiller (8f7b0b7) + + * Keystroke.c: arrange switch_all_screens and fullscreen close + together + +2017-03-11 00:07:13 +0100 Ulrich Sibiller (8f0d885) + + * Keystroke.c: print keystroke name in TEST mode + +2017-03-10 23:49:49 +0100 Ulrich Sibiller (b39ec4c) + + * Keystroke.c: improve TEST output + +2017-03-10 23:40:17 +0100 Ulrich Sibiller (93a360c) + + * Keystroke.c: add another FIXME + +2017-03-10 23:31:27 +0100 Ulrich Sibiller (25db741) + + * Keystroke.c: Simplify read_binding_from_xmlnode + +2017-03-10 23:30:02 +0100 Ulrich Sibiller (13a7c4a) + + * Keystroke.c: use symbols instead of integers + +2017-03-10 23:29:11 +0100 Ulrich Sibiller (f78e673) + + * Keystroke.c: Boolify read_binding_from_xmlnode + +2017-03-10 23:09:24 +0100 Ulrich Sibiller (c80605a) + + * Keystroke.c: Boolify nxagentCheckSpecialKeystroke + +2017-03-10 23:08:40 +0100 Ulrich Sibiller (ac3794c) + + * Keystroke.c: reorder parse_keystroke_file + +2017-03-10 22:58:27 +0100 Ulrich Sibiller (06c83be) + + * Keystroke.c: handle parsing state in parse_keystroke_file() + +2017-03-10 22:55:37 +0100 Ulrich Sibiller (7804c9c) + + * Keystroke.c: simplify nxagentCheckSpecialKeystroke + +2017-03-10 22:53:09 +0100 Ulrich Sibiller (dfa8bb2) + + * Keystroke.c: fix code formatting + +2017-03-10 22:48:18 +0100 Ulrich Sibiller (7a61c62) + + * Keystroke.c: rework read_binding_from_xmlnode() + +2017-03-10 22:47:18 +0100 Ulrich Sibiller (d8bc491) + + * Keystroke.c: use Bool type where appropriate + +2017-03-10 20:19:19 +0100 Mihai Moldovan (320cece) + + * Merge branch 'uli42-pr/misc_cherries' into 3.6.x + +2017-03-04 01:12:24 +0100 Ulrich Sibiller (ee2a933) + + * Xext: fix compiler warning (gh-uli42/pr/misc_cherries) + +2017-03-04 00:28:01 +0100 Ulrich Sibiller (e021bc2) + + * xfixes: fix compiler warning + +2017-03-04 00:24:12 +0100 Ulrich Sibiller (914f78a) + + * xfixes: fix compiler warnings + +2017-03-04 00:15:08 +0100 Ulrich Sibiller (e79d3ac) + + * render/filter.c: add missing return value + +2017-03-04 00:10:57 +0100 Ulrich Sibiller (a9d4a45) + + * record.c: fix compiler warnings + +2017-03-03 23:52:20 +0100 Ulrich Sibiller (c1ed005) + + * fb: fix compiler warning + +2017-03-03 23:43:50 +0100 Ulrich Sibiller (e17c42e) + + * dix: Fix compiler warning + +2017-03-03 23:32:52 +0100 Ulrich Sibiller (fe887d6) + + * Display.c: remove unused logo code + +2016-12-14 11:50:47 +0100 Ulrich Sibiller (2a6fcfc) + + * Rootless.c: improve debugging output + +2016-12-14 11:50:21 +0100 Ulrich Sibiller (a83022a) + + * Rootless.c: improve malloc failure handling + +2016-12-14 11:49:40 +0100 Ulrich Sibiller (4e54571) + + * Rootless.c: fix possible memleak + +2016-12-13 10:05:40 +0100 Ulrich Sibiller (1b6b76b) + + * Display.c: pid is always 0, remove check + +2016-12-13 02:02:29 +0100 Ulrich Sibiller (35e4146) + + * Window.c: Fix reference before check for null pointer + +2016-12-13 02:00:40 +0100 Ulrich Sibiller (4a1095f) + + * Keyboard.c: Simplify if clause + +2016-12-13 01:56:57 +0100 Ulrich Sibiller (fcb5e8a) + + * Rootless.c: Fix wrongly negated comparisons + +2016-12-13 01:56:10 +0100 Ulrich Sibiller (df0fea7) + + * Args.c: Fix missing parentheses + +2017-03-09 09:22:03 +0100 Mihai Moldovan (dc8477f) + + * nxcomp/ChannelEndPoint.cpp: we're not really testing for a + character, but a pointer. + +2017-03-07 23:53:21 +0100 Mihai Moldovan (d8a4f3b) + + * Merge branch 'uli42-pr/backup_null_rulesfile' into 3.6.x + +2008-12-03 15:06:37 +1000 Peter Hutterer (2794e67) + + * xkb: Allow NULL as rulesFile in XkbSetRulesDflts. + (gh-uli42/pr/backup_null_rulesfile) + +2017-03-07 22:34:09 +0100 Mihai Moldovan (c6f0e6b) + + * Merge branch 'uli42-pr/cve-2017-2624' into 3.6.x + +2017-03-04 16:10:38 +0100 Ulrich Sibiller (22f5426) + + * os: add timingsafe_memcmp to Imake (gh-uli42/pr/cve-2017-2624) + +2017-03-03 22:46:33 +0100 Ulrich Sibiller (65c5d8a) + + * Backport CVE-2017-2624 (timingsafe_memcmp) + +2017-03-03 22:44:58 +0100 Mike Gabriel (05aabb4) + + * Merge branch 'uli42-pr/fix_validatestring' into 3.6.x + (pr/keystrokes-cfg-example) + +2017-03-02 15:38:08 +0100 Ulrich Sibiller (06bb154) + + * replace (DE)ALLOCATE_LOCAL by malloc/free + +2017-03-03 21:46:33 +0100 Mike Gabriel (96e2556) + + * Merge branch 'uli42-pr/remove_allocate_local' into 3.6.x + +2017-03-03 21:44:07 +0100 Ulrich Sibiller (6e8aee4) + + * nxagent: move validateString as inline func to Utils.h + +2017-03-03 21:24:59 +0100 Ulrich Sibiller (19065e7) + + * xkb: add missing const + +2010-01-15 15:32:13 +1000 Peter Hutterer (9e29588) + + * xkb: remove XkbAtomGetString, replace with NameForAtom. + +2011-02-13 21:36:03 -0800 Alan Coopersmith (bdfb521) + + * Replace _XkbDupString with Xstrdup + +2017-02-25 15:47:42 +0100 Ulrich Sibiller (e61e979) + + * nxagent: half number of NameForAtom calls + +2017-03-02 15:38:08 +0100 Ulrich Sibiller (09ef999) + + * replace (DE)ALLOCATE_LOCAL by malloc/free + (gh-uli42/pr/remove_allocate_local) + +2017-03-03 16:21:33 +0100 Mihai Moldovan (89ccf26) + + * Merge branch 'sunweaver-pr/really-enable-MITSHM-in-fboverlay-c' + into 3.6.x + +2017-02-05 23:25:35 +0000 Mike Gabriel (1c7b45d) + + * Xserver/mi/miscrinit.c: Use new shmint.h for making + ShmRegisterFbFuncs() available. + (gh-sunweaver/pr/really-enable-MITSHM-in-fboverlay-c) + +2017-02-05 23:23:52 +0000 Mike Gabriel (269651e) + + * Xserver/fb/fboverlay.c: Define -DMITSHM at build as it is used in + fboverlay.c. + +2017-02-05 23:16:50 +0000 Mike Gabriel (dbfd764) + + * Xserver/Xext/shmint.h: Provide header file exporting + ShmRegisterFunc and ShmRegisterFbFuncs (plus + ShmSetPixmapFormat as a by-product). + +2017-03-03 13:46:38 +0100 Mihai Moldovan (a54f3e0) + + * Merge branch 'sunweaver-pr/fix-unused-libNX_X11-files' into 3.6.x + +2017-02-04 11:09:37 +0100 Mike Gabriel (09cf1bc) + + * libNX_X11: Fully drop loadable i18n module support in libNX_X11. + +2017-02-04 10:55:12 +0100 Mike Gabriel (ba27cae) + + * libNX_X11/lcUTF8.c: Drop not-used X11/lcUniConv/ascii.h. + +2017-02-04 10:52:05 +0100 Mike Gabriel (949f5e0) + + * doc/libNX_X11/lcUniConv: Move over the rather-documentary files + 8bit_tab_to_h.c and cjk_tab_to_h.c to nx-libs's doc/ + folder. + +2017-02-04 10:50:49 +0100 Mike Gabriel (c953941) + + * doc/libNX_X11/lcUniConv: Pull over README from X.org's libX11 to + document the origin and purpose of 8bit_tab_to_h.c and + cjk_tab_to_h.c. + +2017-03-03 13:09:15 +0100 Mike Gabriel (8cdccdc) + + * Merge branch 'sunweaver-pr/happyvalgrind-in-glXQueryVersion' into + 3.6.x + +2017-03-03 11:06:58 +0100 Mike Gabriel (6e77037) + + * Xserver/GL/glx/glxcmd.c: Fix uninitialized xGLXQueryVersionReply. + (gh-sunweaver/pr/happyvalgrind-in-glXQueryVersion) + +2016-09-16 23:58:54 +0000 Mihai Moldovan (7011de1) + + * misc nx-X11/programs/Xserver/randr/: switch to using xreallocarray, + since it has been ported now. + +2016-09-12 02:59:02 +0000 Mihai Moldovan (5413c5e) + + * misc nx-X11/programs/Xserver/{composite,dix,randr}/: switch to + using reallocarray, since it has been ported now. + +2016-08-17 04:51:32 +0000 Mihai Moldovan (cd1dcdb) + + * nx-X11/programs/Xserver/include/os.h: backport xallocarray(). + +2016-08-17 04:34:50 +0000 Mihai Moldovan (d189cb4) + + * + nx-X11/{config/cf/{{Imake,X11}.tmpl,linux.cf},programs/Xserver/{include/os.h,os/{Imakefile,reallocarray.c}}: + backport reallocarray() implementation. + +2016-07-20 02:41:03 +0000 Mihai Moldovan (1a7fc41) + + * misc nx-X11/programs/Xserver/{hw/nxagent,miext,render}/: move code + around so that we can drop + nx-X11/programs/Xserver/render/miglyph.c (and by extension + nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.) + +2016-09-12 02:33:22 +0000 Mihai Moldovan (d5a222b) + + * nx-X11/programs/Xserver/mi/{Imakefile,mibank.{c,h}}: backport + ffaae7c0c69a51a53a76146c79f3630ae197a443. + +2017-03-03 11:42:06 +0100 Mike Gabriel (50c589e) + + * Merge branch + 'sunweaver-pr/happyvalgrind-nxagentResetSignalHandlers' + into 3.6.x + +2017-03-03 11:17:22 +0100 Mike Gabriel (46f9afb) + + * hw/nxagent/Display.c: Fix uninitialized newAction in + nxagentResetSignalHandlers(). + (gh-sunweaver/pr/happyvalgrind-nxagentResetSignalHandlers) + +2017-03-03 11:04:10 +0100 Mike Gabriel (20029db) + + * Merge branch 'uli42-pr/happyvalgrind' into 3.6.x + +2017-02-25 02:17:18 +0100 Ulrich Sibiller (3e315cd) + + * Fix "uninitialised byte(s)" complaints from valgrind + (gh-uli42/pr/happyvalgrind) + +2017-03-02 11:24:18 +0100 Mihai Moldovan (9d41e84) + + * Merge branch 'sunweaver-pr/allow-empty-nx-options-string' into + 3.6.x + +2017-02-05 12:47:57 +0100 Mike Gabriel (ce037f4) + + * nxcomp/Loop.cpp: Allow nx/nx: as DISPLAY variable (i.e. an + empty nx/nx options string. + (gh-sunweaver/pr/allow-empty-nx-options-string) + +2017-02-05 12:41:28 +0100 Mike Gabriel (a4be1b8) + + * nxcomp/Loop.cpp: Ignore, options= nx/nx parameter, if file options + path starts with /dev/, /proc/, or /sys/. + +2017-03-02 11:01:43 +0100 Mihai Moldovan (554a6fa) + + * Merge branch 'sunweaver-pr/constify-atom-name-strings' into 3.6.x + +2017-02-27 13:52:29 +0000 Mike Gabriel (9c3669c) + + * Xserver/dix/atom.c (et al.): Constify atom name strings. + (gh-sunweaver/pr/constify-atom-name-strings) + +2017-03-01 15:19:26 +0100 Mihai Moldovan (f42d36f) + + * Merge branch + 'sunweaver-pr/randr-regression-fix-re-adding-RegisterResourceName-calls' + into 3.6.x + +2017-02-27 11:20:38 +0100 Mike Gabriel (bdc212b) + + * nx-libs.spec: Add BR filesystem for SUSE builds (as it provides + /usr/share/fonts). + +2017-02-14 09:35:32 +0000 Mike Gabriel (f90e92b) + + * nx-libs.spec: Add BR for Fedora/RHEL builds: xorg-x11-font-utils. + +2017-02-09 08:59:48 +0100 Mike Gabriel (2174721) + + * nx-libs.spec: Versioned BR on libXfont-devel (and alike) (>= + 1.4.2). + +2017-02-09 08:59:15 +0100 Mike Gabriel (2556d40) + + * debian/control: Versioned B-D on libXfont (>= 1.4.2). + +2017-02-09 08:55:07 +0100 Tiago Vignatti (ec30a85) + + * dix: use one single function to register fpe fonts + +2017-02-08 13:57:42 +0100 Mike Gabriel (7bf4446) + + * nx-libs.spec: Handle fonts dir symlinking and install + /usr/share/nx/fonts symlink into nxagent bin:pkg. This + change probably needs more fine-tuning for the various + other RPM distros and versions out there. + +2017-02-05 21:35:33 +0000 Mike Gabriel (bd98ba2) + + * For consistency, apply patch from previous commit (630a7c3) to the + original Xserver/dix/dixfonts.c file, although the code is + undef'ed when NXAGENT_SERVER is defined. + +2017-02-05 17:06:55 +0000 Mike Gabriel (d981d93) + + * {dix/,hw/nxagent/NX}dixfont.{c,h}: Support using builtin-fonts. + Makes dependency on X11's misc fonts package obsolete. + +2017-02-05 21:04:46 +0000 Mike Gabriel (d8eac7c) + + * Xserver/dix/main.c: ErrorF requires a string to end with an EOL + char. + +2017-02-05 19:34:33 +0000 Mike Gabriel (7866430) + + * debian/nx-x11-common.{links,dirs}: Make sure /usr/share/fonts/X11 + are reachable for nxagent (via placing a symlink to + /usr/share/nx/fonts). + +2017-02-05 20:19:49 +0000 Mike Gabriel (6537f7e) + + * Xserver/hw/nxagent/Font.c: Drop references to + /usr/NX/share/fonts/base as default font path, entirely. + +2017-02-05 20:18:13 +0000 Mike Gabriel (b11dd91) + + * Xserver/hw/nxagent/Font.c: Change (alternative) default font path + order to make font path search compliant with latest FHS + for X11 fonts (though, prefer /usr/share/nx/fonts as + default path). + +2017-02-05 19:54:40 +0000 Mike Gabriel (b816d36) + + * Xserver/hw/nxagent/Font.c: Drop NXAGENT_ALTERNATE_FONT_PATH_4 + (pointing to /usr/NX/share/fonts/base) entirely. + +2017-02-05 19:19:44 +0000 Mike Gabriel (2161ede) + + * nx-X11/config/cf/X11.tmpl: Set a more appropriate font directory + (recommended: /usr/{,local/}share/nx/fonts). + +2017-02-06 15:33:35 +0100 Mike Gabriel (628281e) + + * debian/patches: Update/rebase + 016_nx-X11_install-location.debian.patch. + +2017-02-06 14:30:03 +0100 Mike Gabriel (398e238) + + * nx-libs.spec: Drop non-shipped-anymore rgb(.txt) file from list of + to-be-installed files. + +2017-02-06 15:20:18 +0100 Mike Gabriel (41c79bf) + + * debian/nxagent.*: Drop conffile /etc/nxagent/rgb utilizing + dpkg-maintscript-helper. + +2017-02-06 15:19:47 +0100 Mike Gabriel (7e99ae3) + + * Xserver/os/oscolor.c: Follow X.org in dropping the rgb.txt file + entirely. Content of that file is now hard-coded. + +2017-02-24 22:22:47 +0000 Mike Gabriel (095ba65) + + * release 3.5.99.4 + +2017-02-19 00:06:54 +0100 Ulrich Sibiller (1d24554) + + * dix: fix incomplete commit + +2017-02-15 09:59:00 +0100 Mike Gabriel (52c3c80) + + * Naming change: Security*Access -> Dix*Access + +2017-02-17 12:43:06 +0000 Mike Gabriel (efc0dae) + + * Switch from using libNX_X11's deprecated XKeycodeToKeysym() + function to using XGetKeyboardMapping(). + +2017-02-09 14:05:32 +0100 Mathieu Bérard (e704480) + + * The smart scheduler is not optional. + +2017-02-08 16:33:40 +0100 Mike Gabriel (f781b8e) + + * Makefile: Fix flawed uninstall-* targets. Spotted by Ionic while + reviewing the nxagent RPATH changeset. Thanks! + +2017-02-08 16:31:00 +0100 Mike Gabriel (29fee5b) + + * debian/patches: Update comment header of + 016_nx-X11_install-location.debian.patch. + +2017-02-04 19:02:16 +0100 Mike Gabriel (d16caa7) + + * debian/patches: Update 016_nx-X11_install-location.debian.patch. + Adapt path to recent upstream changes. + +2017-02-04 19:00:00 +0100 Mike Gabriel (0a7ef09) + + * Load libNX_X11 / faked libX11 via RPATH setting rather than + fidgeting with LD_LIBRARY_PATH in the nxagent wrapper + script. + +2017-02-08 15:03:58 +0100 Mike Gabriel (6777fac) + + * Makefile: Allow longer names for variables that we want to allow + distro maintainers to override. + +2017-02-04 18:54:21 +0100 Mike Gabriel (14e4005) + + * Makefile: Actively set/override USRLIBDIR and SHLIBDIR when calling + Xserver's make process. + +2017-02-04 18:53:25 +0100 Mike Gabriel (5d3c4dd) + + * debian/rules: Don't manually override SHLIBDIR via the + dh_auto_build call. The default in the main Makefile + should work fine. + +2017-02-04 18:52:56 +0100 Mike Gabriel (cfb097a) + + * nx-libs.spec: Don't manually override SHLIBDIR via the .spec file. + The default in the main Makefile should work fine. + +2017-02-04 18:52:04 +0100 Mike Gabriel (1e1f124) + + * Makefile: Align variable names USRLIBDIR, SHLIBDIR (and NX_DIR) + with nx-X11 internal naming schemes (and use + /usr//nx/X11 rather than /usr//nx-X11). + +2017-02-08 11:06:17 +0100 Mike Gabriel (af11c31) + + * nx-X11/include/Xos_r.h: Drop one _POSIX_REENTRANT_FUNCTIONS macro + block, where offenders AIXV3, AIXV4 and __osf__ are gone + now. + +2017-02-04 16:25:13 +0100 Daniel Stone (bf1b3c6) + + * dix: remove staggeringly broken vendor workarounds + +2016-11-15 22:03:39 +0100 Mike Gabriel (8c1a21b) + + * drop platform support: unifdef sgi. + +2016-11-15 21:51:55 +0100 Mike Gabriel (5c3776d) + + * drop platform support: unifdef QNX. + +2016-11-15 21:41:57 +0100 Mike Gabriel (29401f2) + + * drop platform support: unifdef DGUX. + +2016-11-15 21:32:46 +0100 Mike Gabriel (0a9f9a9) + + * drop platform support: unifdef __osf__. + +2016-11-15 21:20:22 +0100 Mike Gabriel (cc1350a) + + * drop platform support: unifdef AIXV3, AIXV4 (and AIXrt, AIX386). + +2016-11-15 20:59:35 +0100 Mike Gabriel (f6dcf2f) + + * drop platform support: unifdef hpux and __hppa__. + +2016-11-15 19:20:13 +0100 Mike Gabriel (19edfab) + + * drop platform support: unifdef Lynx. + +2016-11-15 18:41:52 +0100 Mike Gabriel (0f9a11a) + + * drop platform support: unifdef __UNIXOS2__. + +2017-02-08 21:43:45 +0100 Ulrich Sibiller (f22e873) + + * Screen.c: clean up superfluous whitespace + +2017-02-08 21:13:38 +0100 Ulrich Sibiller (baf7a92) + + * Screen.c: Ensure that an output is unused before destroying it + +2017-02-05 19:16:54 +0000 Mike Gabriel (da82328) + + * nx-X11/config/cf/X11.tmpl: Fix DefaultRGBDatabase path to + $(USRDATADIR)/rgb (not $(LIBDIR)/rgb). + +2017-02-04 15:41:18 +0100 Mike Gabriel (ce153d4) + + * debian/copyright{,.in}: Adopt from Debian's upload candidate, being + DEP-5 compliant and up-to-date for 3.5.99.3. + +2017-02-27 13:11:33 +0100 Mike Gabriel (5e68c12) + + * Merge branch 'sunweaver-pr/support-builtin-fonts' into 3.6.x + +2017-02-27 11:20:38 +0100 Mike Gabriel (3e8d98f) + + * nx-libs.spec: Add BR filesystem for SUSE builds (as it provides + /usr/share/fonts). (gh-sunweaver/pr/support-builtin-fonts, + pr/support-builtin-fonts) + +2017-02-14 09:35:32 +0000 Mike Gabriel (b981dd1) + + * nx-libs.spec: Add BR for Fedora/RHEL builds: xorg-x11-font-utils. + +2017-02-09 08:59:48 +0100 Mike Gabriel (6c9e3eb) + + * nx-libs.spec: Versioned BR on libXfont-devel (and alike) (>= + 1.4.2). + +2017-02-09 08:59:15 +0100 Mike Gabriel (6fd7243) + + * debian/control: Versioned B-D on libXfont (>= 1.4.2). + +2017-02-09 08:55:07 +0100 Tiago Vignatti (cb760f1) + + * dix: use one single function to register fpe fonts + +2017-02-08 13:57:42 +0100 Mike Gabriel (8992549) + + * nx-libs.spec: Handle fonts dir symlinking and install + /usr/share/nx/fonts symlink into nxagent bin:pkg. This + change probably needs more fine-tuning for the various + other RPM distros and versions out there. + +2017-02-05 21:35:33 +0000 Mike Gabriel (2ba23b3) + + * For consistency, apply patch from previous commit (630a7c3) to the + original Xserver/dix/dixfonts.c file, although the code is + undef'ed when NXAGENT_SERVER is defined. + +2017-02-05 17:06:55 +0000 Mike Gabriel (ed40c3d) + + * {dix/,hw/nxagent/NX}dixfont.{c,h}: Support using builtin-fonts. + Makes dependency on X11's misc fonts package obsolete. + +2017-02-05 21:04:46 +0000 Mike Gabriel (82a7f72) + + * Xserver/dix/main.c: ErrorF requires a string to end with an EOL + char. + +2017-02-05 19:34:33 +0000 Mike Gabriel (8383b19) + + * debian/nx-x11-common.{links,dirs}: Make sure /usr/share/fonts/X11 + are reachable for nxagent (via placing a symlink to + /usr/share/nx/fonts). + +2017-02-05 20:19:49 +0000 Mike Gabriel (18794d2) + + * Xserver/hw/nxagent/Font.c: Drop references to + /usr/NX/share/fonts/base as default font path, entirely. + +2017-02-05 20:18:13 +0000 Mike Gabriel (7e3bb3f) + + * Xserver/hw/nxagent/Font.c: Change (alternative) default font path + order to make font path search compliant with latest FHS + for X11 fonts (though, prefer /usr/share/nx/fonts as + default path). + +2017-02-05 19:54:40 +0000 Mike Gabriel (66d9b3e) + + * Xserver/hw/nxagent/Font.c: Drop NXAGENT_ALTERNATE_FONT_PATH_4 + (pointing to /usr/NX/share/fonts/base) entirely. + +2017-02-05 19:19:44 +0000 Mike Gabriel (5585464) + + * nx-X11/config/cf/X11.tmpl: Set a more appropriate font directory + (recommended: /usr/{,local/}share/nx/fonts). + +2017-02-27 04:08:51 +0100 Mihai Moldovan (0a5d26d) + + * Merge branch 'sunweaver-pr/hard-code-rgb-colors' into 3.6.x + +2017-02-06 15:33:35 +0100 Mike Gabriel (fff8755) + + * debian/patches: Update/rebase + 016_nx-X11_install-location.debian.patch. + (gh-sunweaver/pr/hard-code-rgb-colors) + +2017-02-06 14:30:03 +0100 Mike Gabriel (0b34475) + + * nx-libs.spec: Drop non-shipped-anymore rgb(.txt) file from list of + to-be-installed files. + +2017-02-06 15:20:18 +0100 Mike Gabriel (744e288) + + * debian/nxagent.*: Drop conffile /etc/nxagent/rgb utilizing + dpkg-maintscript-helper. + +2017-02-06 15:19:47 +0100 Mike Gabriel (f6a1140) + + * Xserver/os/oscolor.c: Follow X.org in dropping the rgb.txt file + entirely. Content of that file is now hard-coded. + +2017-02-24 22:22:47 +0000 Mike Gabriel (e1f2902) + + * release 3.5.99.4 (tag: 3.5.99.4, origin/release-builds/3.6.x) + +2017-02-24 12:23:51 +0100 Mihai Moldovan (31426a3) + + * Merge branch 'uli42-fix_#306_#322' into 3.6.x + +2017-02-19 00:06:54 +0100 Ulrich Sibiller (3d8575c) * dix: fix incomplete commit -2017-02-20 10:33:52 +0100 Mihai Moldovan (3c322ffbb) +2017-02-20 10:33:52 +0100 Mihai Moldovan (3c322ff) * Merge branch 'sunweaver-pr/security-acl-naming-change' into 3.6.x -2017-02-15 09:59:00 +0100 Mike Gabriel (104a3e9e2) +2017-02-15 09:59:00 +0100 Mike Gabriel (104a3e9) * Naming change: Security*Access -> Dix*Access - (gh-sunweaver/pr/security-acl-naming-change, - pr/security-acl-naming-change) + (gh-sunweaver/pr/security-acl-naming-change) -2017-02-20 10:21:01 +0100 Mike Gabriel (c79f2d289) +2017-02-20 10:21:01 +0100 Mike Gabriel (c79f2d2) * Merge branch 'sunweaver-pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym' into 3.6.x -2017-02-17 12:43:06 +0000 Mike Gabriel (38ac74d6f) +2017-02-17 12:43:06 +0000 Mike Gabriel (38ac74d) * Switch from using libNX_X11's deprecated XKeycodeToKeysym() function to using XGetKeyboardMapping(). - (gh-sunweaver/pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym, - sunweaver-pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym, - pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym) + (gh-sunweaver/pr/use-xgetkeyboardMapping-instead-of-deprecated-xkeycodetokeysym) -2017-02-18 10:24:21 +0100 Mihai Moldovan (73ec915bc) +2017-02-18 10:24:21 +0100 Mihai Moldovan (73ec915) * Merge branch 'sunweaver-pr/smart-scheduler-is-not-optional' into 3.6.x -2017-02-09 14:05:32 +0100 Mathieu Bérard (6884e6a5b) +2017-02-09 14:05:32 +0100 Mathieu Bérard (6884e6a) * The smart scheduler is not optional. (gh-sunweaver/pr/smart-scheduler-is-not-optional, pr/smart-scheduler-is-not-optional) -2017-02-10 00:47:32 +0100 Mihai Moldovan (0a7df0770) +2017-02-10 00:47:32 +0100 Mihai Moldovan (0a7df07) * Merge branch 'sunweaver-pr/use-rpath-for-nxagent' into 3.6.x -2017-02-08 16:33:40 +0100 Mike Gabriel (99c130f15) +2017-02-08 16:33:40 +0100 Mike Gabriel (99c130f) * Makefile: Fix flawed uninstall-* targets. Spotted by Ionic while reviewing the nxagent RPATH changeset. Thanks! - (gh-sunweaver/pr/use-rpath-for-nxagent, - pr/use-rpath-for-nxagent) + (gh-sunweaver/pr/use-rpath-for-nxagent) -2017-02-08 16:31:00 +0100 Mike Gabriel (52760b6e8) +2017-02-08 16:31:00 +0100 Mike Gabriel (52760b6) * debian/patches: Update comment header of 016_nx-X11_install-location.debian.patch. -2017-02-04 19:02:16 +0100 Mike Gabriel (a474b9f93) +2017-02-04 19:02:16 +0100 Mike Gabriel (a474b9f) * debian/patches: Update 016_nx-X11_install-location.debian.patch. Adapt path to recent upstream changes. -2017-02-04 19:00:00 +0100 Mike Gabriel (ba620a054) +2017-02-04 19:00:00 +0100 Mike Gabriel (ba620a0) * Load libNX_X11 / faked libX11 via RPATH setting rather than fidgeting with LD_LIBRARY_PATH in the nxagent wrapper script. -2017-02-08 15:03:58 +0100 Mike Gabriel (9d1da072c) +2017-02-08 15:03:58 +0100 Mike Gabriel (9d1da07) * Makefile: Allow longer names for variables that we want to allow distro maintainers to override. -2017-02-04 18:54:21 +0100 Mike Gabriel (4c4d3dfba) +2017-02-04 18:54:21 +0100 Mike Gabriel (4c4d3df) * Makefile: Actively set/override USRLIBDIR and SHLIBDIR when calling Xserver's make process. -2017-02-04 18:53:25 +0100 Mike Gabriel (4a01be659) +2017-02-04 18:53:25 +0100 Mike Gabriel (4a01be6) * debian/rules: Don't manually override SHLIBDIR via the dh_auto_build call. The default in the main Makefile should work fine. -2017-02-04 18:52:56 +0100 Mike Gabriel (0ae1fd5d3) +2017-02-04 18:52:56 +0100 Mike Gabriel (0ae1fd5) * nx-libs.spec: Don't manually override SHLIBDIR via the .spec file. The default in the main Makefile should work fine. -2017-02-04 18:52:04 +0100 Mike Gabriel (c45cab1ba) +2017-02-04 18:52:04 +0100 Mike Gabriel (c45cab1) * Makefile: Align variable names USRLIBDIR, SHLIBDIR (and NX_DIR) with nx-X11 internal naming schemes (and use /usr//nx/X11 rather than /usr//nx-X11). -2017-02-09 22:01:31 +0100 Mihai Moldovan (0a314adfa) +2017-02-09 22:01:31 +0100 Mihai Moldovan (0a314ad) * Merge branch 'sunweaver-pr/drop-support-for-ancient-platforms' into 3.6.x -2017-02-08 11:06:17 +0100 Mike Gabriel (029bae127) +2017-02-08 11:06:17 +0100 Mike Gabriel (029bae1) * nx-X11/include/Xos_r.h: Drop one _POSIX_REENTRANT_FUNCTIONS macro block, where offenders AIXV3, AIXV4 and __osf__ are gone - now. (gh-sunweaver/pr/drop-support-for-ancient-platforms, - pr/drop-support-for-ancient-platforms) + now. (gh-sunweaver/pr/drop-support-for-ancient-platforms) -2017-02-04 16:25:13 +0100 Daniel Stone (7dae94814) +2017-02-04 16:25:13 +0100 Daniel Stone (7dae948) * dix: remove staggeringly broken vendor workarounds -2016-11-15 22:03:39 +0100 Mike Gabriel (2d45d8d80) +2016-11-15 22:03:39 +0100 Mike Gabriel (2d45d8d) * drop platform support: unifdef sgi. -2016-11-15 21:51:55 +0100 Mike Gabriel (c6250a864) +2016-11-15 21:51:55 +0100 Mike Gabriel (c6250a8) * drop platform support: unifdef QNX. -2016-11-15 21:41:57 +0100 Mike Gabriel (754e48ac0) +2016-11-15 21:41:57 +0100 Mike Gabriel (754e48a) * drop platform support: unifdef DGUX. -2016-11-15 21:32:46 +0100 Mike Gabriel (a9c30796d) +2016-11-15 21:32:46 +0100 Mike Gabriel (a9c3079) * drop platform support: unifdef __osf__. -2016-11-15 21:20:22 +0100 Mike Gabriel (4b178918b) +2016-11-15 21:20:22 +0100 Mike Gabriel (4b17891) * drop platform support: unifdef AIXV3, AIXV4 (and AIXrt, AIX386). -2016-11-15 20:59:35 +0100 Mike Gabriel (184c5d778) +2016-11-15 20:59:35 +0100 Mike Gabriel (184c5d7) * drop platform support: unifdef hpux and __hppa__. -2016-11-15 19:20:13 +0100 Mike Gabriel (ace255eda) +2016-11-15 19:20:13 +0100 Mike Gabriel (ace255e) * drop platform support: unifdef Lynx. -2016-11-15 18:41:52 +0100 Mike Gabriel (d12f95241) +2016-11-15 18:41:52 +0100 Mike Gabriel (d12f952) * drop platform support: unifdef __UNIXOS2__. -2017-02-08 22:34:53 +0100 Mike Gabriel (86a6a340f) +2017-02-08 22:34:53 +0100 Mike Gabriel (86a6a34) * Merge branch 'uli42-pr/fix_#293' into 3.6.x -2017-02-08 21:43:45 +0100 Ulrich Sibiller (3790a28fe) +2017-02-08 21:43:45 +0100 Ulrich Sibiller (3790a28) - * Screen.c: clean up superfluous whitespace - (gh-sunweaver/uli42-pr/fix_#293, uli42-pr/fix_#293) + * Screen.c: clean up superfluous whitespace (gh-uli42/pr/fix_#293, + gh-sunweaver/uli42-pr/fix_#293) -2017-02-08 21:13:38 +0100 Ulrich Sibiller (184c07e24) +2017-02-08 21:13:38 +0100 Ulrich Sibiller (184c07e) * Screen.c: Ensure that an output is unused before destroying it -2017-02-06 21:57:50 +0100 Mihai Moldovan (083051f66) +2017-02-06 21:57:50 +0100 Mihai Moldovan (083051f) * Merge branch 'sunweaver-pr/fix-DefaultRGBDatabase-path' into 3.6.x -2017-02-05 19:16:54 +0000 Mike Gabriel (34889920c) +2017-02-05 19:16:54 +0000 Mike Gabriel (3488992) * nx-X11/config/cf/X11.tmpl: Fix DefaultRGBDatabase path to $(USRDATADIR)/rgb (not $(LIBDIR)/rgb). - (gh-sunweaver/pr/fix-DefaultRGBDatabase-path, - pr/fix-DefaultRGBDatabase-path) + (gh-sunweaver/pr/fix-DefaultRGBDatabase-path) -2017-02-04 15:41:18 +0100 Mike Gabriel (d6f475f67) +2017-02-04 15:41:18 +0100 Mike Gabriel (d6f475f) * debian/copyright{,.in}: Adopt from Debian's upload candidate, being DEP-5 compliant and up-to-date for 3.5.99.3. -2017-02-03 14:58:06 +0100 Mike Gabriel (1cd73ccb7) +2017-02-04 15:22:20 +0100 Mike Gabriel (ff6126f) + + * Xserver/randr: Regression fix introduced by c2b1f48. Re-introduce + RegisterResourceName() calls after each + CreateNewResourceType() call. + (gh-sunweaver/pr/randr-regression-fix-re-adding-RegisterResourceName-calls) + +2017-02-03 14:58:06 +0100 Mike Gabriel (1cd73cc) * Makefile: Don't create superfluous symlink for libX11.so -> ../libNX_X11.so. The libNX_X11.so is only required at build time, so need to use it for faking libX11.so in nxagent. -2017-02-03 14:40:19 +0100 Mike Gabriel (b0d28c8a6) +2017-02-03 14:40:19 +0100 Mike Gabriel (b0d28c8) * debian/changelog: Cosmetic fix, restoring correct version number for 3.5.99.2 release stanza. -2017-01-12 10:23:02 +0100 Mike Gabriel (93447eb2b) +2017-01-12 10:23:02 +0100 Mike Gabriel (93447eb) * Merge branch 'opoplawski-symlink' into 3.6.x (gh-sunweaver/pr/no-extra-mode-freeing-in-nxagentAdjustRandRXinerama) -2017-01-05 16:43:17 -0700 Orion Poplawski (f92820948) +2017-01-05 16:43:17 -0700 Orion Poplawski (f928209) - * Be consistent with macros (opoplawski-symlink) + * Be consistent with macros -2017-01-05 16:35:34 -0700 Orion Poplawski (c392bc0a8) +2017-01-05 16:35:34 -0700 Orion Poplawski (c392bc0) * Use Obsoletes instead of Conflicts. Drop unneeded %{?_isa} versions -2017-01-12 10:21:51 +0100 Mike Gabriel (42b136811) +2017-01-12 10:21:51 +0100 Mike Gabriel (42b1368) * Merge branch 'opoplawski-fedora' into 3.6.x -2017-01-11 15:19:24 -0700 Orion Poplawski (c9ab60e89) +2017-01-11 15:19:24 -0700 Orion Poplawski (c9ab60e) * Install missing libNX_X11.so.6 symlink - fixes gh-287 -2017-01-05 16:43:17 -0700 Orion Poplawski (bdcc867e2) +2017-01-05 16:43:17 -0700 Orion Poplawski (bdcc867) - * Be consistent with macros (opoplawski-fedora) + * Be consistent with macros -2017-01-05 16:35:34 -0700 Orion Poplawski (13f3bdc00) +2017-01-05 16:35:34 -0700 Orion Poplawski (13f3bdc) * Use Obsoletes instead of Conflicts. Drop unneeded %{?_isa} versions -2016-12-22 20:12:53 +0100 Mike Gabriel (7d845e7f4) +2016-12-22 20:12:53 +0100 Mike Gabriel (7d845e7) * hw/nxagent/Init.c: Amend artifact in license header. -2016-12-22 15:30:07 +0100 Mike Gabriel (9c0d52807) +2016-12-22 15:30:07 +0100 Mike Gabriel (9c0d528) * helper scripts: Add license headers to files. -2016-12-20 10:33:48 +0100 Mike Gabriel (b425f071e) +2016-12-20 10:33:48 +0100 Mike Gabriel (b425f07) * nxcomp: Fix artifacts in copyright headers. -2016-12-20 10:27:07 +0100 Mike Gabriel (8a8ec60cc) +2016-12-20 10:27:07 +0100 Mike Gabriel (8a8ec60) * nxcompext: Drop folder with .gitignore file. nxcompext has been moved into nxagent DDX. -2016-12-20 09:04:11 +0100 Mike Gabriel (02546c560) +2016-12-20 09:04:11 +0100 Mike Gabriel (02546c5) * roll-tarballs.sh: Adapt to recent changes in nx-libs, keep legacy support for older 3.6.x and 3.5.x releases. -2016-12-19 15:03:09 +0100 Mike Gabriel (9acd13e50) +2016-12-19 15:03:09 +0100 Mike Gabriel (9acd13e) - * release 3.5.99.3 (tag: 3.5.99.3, origin/release-builds/3.6.x, - release-builds/3.6.x) + * release 3.5.99.3 (tag: 3.5.99.3) -2016-12-14 13:32:23 +0100 Mike Gabriel (8be276d27) +2016-12-14 13:32:23 +0100 Mike Gabriel (8be276d) * Merge branch 'theqvd-fix-loopback-bind' into 3.6.x -2016-12-13 12:00:43 +0100 Vadim Troshchinskiy (920f423a5) +2016-12-13 12:00:43 +0100 Vadim Troshchinskiy (920f423) * Make nxagent only bind to loopback when requested - (theqvd-fix-loopback-bind) -2016-12-14 10:57:39 +0100 Mike Gabriel (e466a9387) +2016-12-14 10:57:39 +0100 Mike Gabriel (e466a93) * Merge branch 'theqvd-fix-accept-host-message' into 3.6.x -2016-12-13 12:19:09 +0100 Vadim Troshchinskiy (77188865e) +2016-12-13 12:19:09 +0100 Vadim Troshchinskiy (7718886) * Fix reversed logic in acceptHost setting - (theqvd-fix-accept-host-message) -2016-12-10 21:49:10 +0100 Mike Gabriel (2b8f59261) +2016-12-10 21:49:10 +0100 Mike Gabriel (2b8f592) * Merge branch 'uli42-pr/improve_xinerama_debug' into 3.6.x -2016-12-07 21:50:40 +0100 Ulrich Sibiller (6f3fb5248) +2016-12-07 21:50:40 +0100 Ulrich Sibiller (6f3fb52) * Screen.c: more debug output formatting improvements - (uli42-pr/improve_xinerama_debug) + (gh-uli42/pr/improve_xinerama_debug, + gh-uli42/pr/cherry_picks) -2016-12-07 21:17:26 +0100 Ulrich Sibiller (e14309892) +2016-12-07 21:17:26 +0100 Ulrich Sibiller (e143098) * Screen.c: fix uninitalized variable -2016-12-07 21:15:59 +0100 Ulrich Sibiller (ce76009d2) +2016-12-07 21:15:59 +0100 Ulrich Sibiller (ce76009) * Screen.c: fix compile warnings in DEBUG mode -2016-12-07 21:42:03 +0100 Ulrich Sibiller (6882b08d8) +2016-12-07 21:42:03 +0100 Ulrich Sibiller (6882b08) * Screen.c: fix formatting -2016-12-07 20:18:09 +0100 Ulrich Sibiller (c806956c2) +2016-12-07 20:18:09 +0100 Ulrich Sibiller (c806956) * Screen.c: improve debugging output -2016-12-05 10:26:28 +0000 Mike Gabriel (5bdb2fcdf) +2016-12-05 10:26:28 +0000 Mike Gabriel (5bdb2fc) * debian/control: B-D alternatively on libxfont1-dev or libxfont-dev. Fix FTBFS on Debian stretch which has libxfont2-dev as default now. -2016-12-04 21:45:33 +0100 Mike Gabriel (c893ad65c) +2016-12-04 21:45:33 +0100 Mike Gabriel (c893ad6) * Merge branch 'sunweaver-pr/drop-glx-ansic' into 3.6.x -2016-11-02 20:30:07 +0100 Mike Gabriel (4e33fd4be) +2016-11-02 20:30:07 +0100 Mike Gabriel (4e33fd4) * Mesa: Convert some files with MSDOS EOL style to Unix EOL style. - (gh-sunweaver/pr/drop-glx-ansic, - sunweaver-pr/drop-glx-ansic, pr/drop-glx-ansic) + (gh-sunweaver/pr/drop-glx-ansic) -2016-11-01 21:30:22 +0100 Kristian Høgsberg (4146d1aa7) +2016-11-01 21:30:22 +0100 Kristian Høgsberg (4146d1a) * Drop xf86glx.h, so we can finally drop Xserver/GL/include/ entirely. -2016-10-31 15:06:37 +0100 Kristian Høgsberg (cee997dac) +2016-10-31 15:06:37 +0100 Kristian Høgsberg (cee997d) * Drop glx_ansic.h wrapper and call malloc, realloc, free and str-funcs directly. -2016-12-04 21:14:24 +0100 Mike Gabriel (b38d5b97d) +2016-12-04 21:14:24 +0100 Mike Gabriel (b38d5b9) * Merge branch 'sunweaver-pr/extmod-xfree86loader-cleanup' into 3.6.x -2016-10-29 11:28:02 +0200 Eric Anholt (508d2deae) +2016-10-29 11:28:02 +0200 Eric Anholt (508d2de) * Remove libcwrapper usage from xorg server modules. The libcwrapper is not used in nxagent. - (gh-sunweaver/pr/extmod-xfree86loader-cleanup, - sunweaver-pr/extmod-xfree86loader-cleanup, - pr/extmod-xfree86loader-cleanup) + (gh-sunweaver/pr/extmod-xfree86loader-cleanup) -2016-12-04 21:09:52 +0100 Mike Gabriel (62f8e50e7) +2016-12-04 21:09:52 +0100 Mike Gabriel (62f8e50) * Merge branch 'uli42-pr/compilation_fixes_and_debug_improvements' into 3.6.x -2016-12-03 23:31:26 +0100 Ulrich Sibiller (b0106e75a) +2016-12-03 23:31:26 +0100 Ulrich Sibiller (b0106e7) * slightly improve rrxinerama debug output + (gh-uli42/pr/compilation_fixes_and_debug_improvements) -2016-12-03 23:06:32 +0100 Ulrich Sibiller (c5e06d408) +2016-12-03 23:06:32 +0100 Ulrich Sibiller (c5e06d4) * Fix compilation warnings -2016-11-30 08:13:54 +0100 Mike Gabriel (a0a429cc7) +2016-11-30 08:13:54 +0100 Mike Gabriel (a0a429c) * Update auto-generated debian/copyright.in. -2016-11-18 00:07:19 +0100 Mike Gabriel (cb8af80ae) +2016-11-18 00:07:19 +0100 Mike Gabriel (cb8af80) * .gitignore: Don't ignore myself. -2016-11-18 00:06:30 +0100 Mike Gabriel (edeca4aff) +2016-11-18 00:06:30 +0100 Mike Gabriel (edeca4a) * Merge branch 'uli42-pr/gitignore' into 3.6.x -2016-11-03 23:53:46 +0100 Ulrich Sibiller (7993d28f1) +2016-11-03 23:53:46 +0100 Ulrich Sibiller (7993d28) - * add .gitignore files + * add .gitignore files (gh-uli42/pr/gitignore) -2016-11-17 20:49:53 +0100 Mike Gabriel (1f6070437) +2016-11-17 20:49:53 +0100 Mike Gabriel (1f60704) * Merge branch 'uli42-pr/remove_xlibi18n' into 3.6.x -2016-11-04 00:25:25 +0100 Ulrich Sibiller (de4eca171) +2016-11-04 00:25:25 +0100 Ulrich Sibiller (de4eca1) - * LibX11: drop unused xlibi18n + * LibX11: drop unused xlibi18n (gh-uli42/pr/remove_xlibi18n) -2016-11-15 17:06:18 +0100 Mike Gabriel (cb8bcbec8) +2016-11-15 17:06:18 +0100 Mike Gabriel (cb8bcbe) * Merge branch 'sunweaver-pr/testscripts-file-headers' into 3.6.x -2016-11-07 12:32:09 +0100 Mike Gabriel (00725f16a) +2016-11-07 12:32:09 +0100 Mike Gabriel (00725f1) * testscripts: Use non-NoMachine file headers for our testscripts. - (gh-sunweaver/pr/testscripts-file-headers, - pr/testscripts-file-headers) + (gh-sunweaver/pr/testscripts-file-headers) -2016-11-15 17:02:11 +0100 Mike Gabriel (91d06723b) +2016-11-15 17:02:11 +0100 Mike Gabriel (91d0672) * New helper script: regenerate-symbol-docs.sh. Plus update symbols usage of libNX_X11 and nxcompext in nxagent, nxcompext and libNX_X11. -2016-11-15 16:42:39 +0100 Mike Gabriel (8c5a1b071) +2016-11-15 16:42:39 +0100 Mike Gabriel (8c5a1b0) * Merge branch 'sunweaver-pr/move-nxcompext-into-Xserver' into 3.6.x -2016-11-09 16:45:47 +0100 Mike Gabriel (9ad0aae5d) +2016-11-09 16:45:47 +0100 Mike Gabriel (9ad0aae) * Xserver/Imakefile: Some whitespace fixes. (gh-sunweaver/pr/move-nxcompext-into-Xserver) -2016-11-03 00:19:26 +0100 Mike Gabriel (80b5de3f5) +2016-11-03 00:19:26 +0100 Mike Gabriel (80b5de3) * nxcompext: Move code into Xserver subtree, as nxcompext requires Xserver includes at build time. -2016-11-03 08:30:49 +0100 Mike Gabriel (cae394b45) +2016-11-03 08:30:49 +0100 Mike Gabriel (cae394b) * Xserver/hw/nxagent/Imakefile: Introduce the NULL variable. -2016-11-08 08:00:44 +0100 Mihai Moldovan (b1d3f2ca5) +2016-11-08 08:00:44 +0100 Mihai Moldovan (b1d3f2c) * Merge branch 'uli42-pr/keyboard_fixes' into arctica-3.6.x -2016-10-27 01:00:23 +0200 Ulrich Sibiller (2f2ade61a) +2016-10-27 01:00:23 +0200 Ulrich Sibiller (2f2ade6) * Keyboard.c: evdev is only existing on Linux + (gh-uli42/pr/keyboard_fixes) -2006-10-02 20:58:33 +0300 Daniel Stone (926e90abc) +2006-10-02 20:58:33 +0300 Daniel Stone (926e90a) * xkb: remove the world's most staggeringly broken vendor workaround -2016-10-26 11:01:57 +0200 Ulrich Sibiller (08ed062c4) +2016-10-26 11:01:57 +0200 Ulrich Sibiller (08ed062) * Keyboard.c: move variable to inner scope -2016-10-26 10:39:37 +0200 Ulrich Sibiller (d37f9f311) +2016-10-26 10:39:37 +0200 Ulrich Sibiller (d37f9f3) * Reconnect.c: simplify code by using strndup -2016-10-25 23:40:13 +0200 Ulrich Sibiller (e52799d5c) +2016-10-25 23:40:13 +0200 Ulrich Sibiller (e52799d) * Keyboard.c: replace malloc/strcpy by str(n)dup -2016-10-25 22:59:35 +0200 Ulrich Sibiller (718c5b9f1) +2016-10-25 22:59:35 +0200 Ulrich Sibiller (718c5b9) * Keyboard.c: more whitespace/formatting fixes -2016-10-25 22:53:39 +0200 Ulrich Sibiller (b5cc3c94e) +2016-10-25 22:53:39 +0200 Ulrich Sibiller (b5cc3c9) * Keyboard.c: improve keyboard file creation -2016-10-25 22:53:07 +0200 Ulrich Sibiller (52848b785) +2016-10-25 22:53:07 +0200 Ulrich Sibiller (52848b7) * Keyboard.c: use NULL instead of 0 -2016-10-25 22:52:43 +0200 Ulrich Sibiller (3ea601bcb) +2016-10-25 22:52:43 +0200 Ulrich Sibiller (3ea601b) * Keyboard.c: remove superfluous whitespace -2016-10-25 21:50:11 +0200 Ulrich Sibiller (2901aca36) +2016-10-25 21:50:11 +0200 Ulrich Sibiller (2901aca) * Keyboard.c: Fix wrong error msg prefix -2016-10-25 21:41:11 +0200 Ulrich Sibiller (2f7f39b49) +2016-10-25 21:41:11 +0200 Ulrich Sibiller (2f7f39b) * Keyboard.c: Fix and simplify keyboard config file handling -2016-10-25 21:40:10 +0200 Ulrich Sibiller (8793e362b) +2016-10-25 21:40:10 +0200 Ulrich Sibiller (8793e36) * Improve DEBUG/TEST output regarding keyboard stuff -2016-10-25 21:39:24 +0200 Ulrich Sibiller (e3ac55bc2) +2016-10-25 21:39:24 +0200 Ulrich Sibiller (e3ac55b) * Drop unused define NXAGENT_KEYMAP_DIR_FILE -2016-11-05 05:20:31 +0000 Mihai Moldovan (7b79e8d83) +2016-11-05 05:20:31 +0000 Mihai Moldovan (7b79e8d) * Makefile: fix up a9b145d4. -2016-11-05 05:18:06 +0000 Mihai Moldovan (c7e01938d) +2016-11-05 05:18:06 +0000 Mihai Moldovan (c7e0193) * nx-X11/lib/X11/Imakefile: essentially revert 5a90a63. -2016-11-04 14:19:07 +0100 Vadim Troshchinskiy (e5091e002) +2016-11-04 14:19:07 +0100 Vadim Troshchinskiy (e5091e0) * Added sample slave agent and test script -2016-11-03 22:51:56 +0100 Mihai Moldovan (53d304ef7) +2016-11-03 22:51:56 +0100 Mihai Moldovan (53d304e) * Merge branch 'sunweaver-pr/drop-fbmmx' into arctica-3.6.x -2016-10-29 14:23:58 +0200 Mike Gabriel (f5c5cb10f) +2016-10-29 14:23:58 +0200 Mike Gabriel (f5c5cb1) * Xserver/fb: Drop fbmmx.[ch] files and code passages wrapped-in by USE_MMX macro. (gh-sunweaver/pr/drop-fbmmx) -2016-10-29 14:23:25 +0200 Mike Gabriel (89e1457d1) +2016-10-29 14:23:25 +0200 Mike Gabriel (89e1457) * Xserver/fb/Imakefile: Introduce NULL variable. -2016-11-03 09:36:23 +0100 Mike Gabriel (d12b77543) +2016-11-03 09:36:23 +0100 Mike Gabriel (d12b775) * Merge branch 'uli42-pr/libX11_xtrans_silence_compiler_warnings' into 3.6.x -2016-11-02 23:57:43 +0100 Ulrich Sibiller (47fab08aa) +2016-11-02 23:57:43 +0100 Ulrich Sibiller (47fab08) * xtrans: fix const warnings for SocketConnectConnInfo + (gh-uli42/pr/libX11_xtrans_silence_compiler_warnings) -2016-11-02 23:55:23 +0100 Ulrich Sibiller (882c034c3) +2016-11-02 23:55:23 +0100 Ulrich Sibiller (882c034) * xtrans: silence compiler warning regarding is_numeric -2016-11-02 23:37:30 +0100 Ulrich Sibiller (90612d25c) +2016-11-02 23:37:30 +0100 Ulrich Sibiller (90612d2) * libX11 + Xserver: fix missing define warning -2016-11-02 23:36:50 +0100 Ulrich Sibiller (2631603b6) +2016-11-02 23:36:50 +0100 Ulrich Sibiller (2631603) * xtrans: Fix compile warning -2016-11-02 23:14:52 +0100 Ulrich Sibiller (5d06f46e5) +2016-11-02 23:14:52 +0100 Ulrich Sibiller (5d06f46) * xtrans: fix compilation warnings because of missing XTRANS_SEND_FDS -2016-11-02 19:59:23 +0100 Mike Gabriel (8dc0d18c1) +2016-11-02 19:59:23 +0100 Mike Gabriel (8dc0d18) * debian/libnx-x11-6.symbols: Update after upgrade of xtrans library files. -2016-11-02 19:50:24 +0100 Mike Gabriel (107e72b03) +2016-11-02 19:50:24 +0100 Mike Gabriel (107e72b) * Merge branch 'uli42-pr/upgrade_xtrans' into 3.6.x -2016-11-02 11:48:23 +0100 Ulrich Sibiller (6a186b921) +2016-11-02 11:48:23 +0100 Ulrich Sibiller (6a186b9) * Whitespace fixes -2016-10-31 02:29:18 +0100 Ulrich Sibiller (e65b106a8) +2016-10-31 02:29:18 +0100 Ulrich Sibiller (e65b106) * Xtrans: update to Xorg/xtrans upstream (1.3.5+) -2016-10-13 21:53:17 +0200 Ulrich Sibiller (793d587b4) +2016-10-13 21:53:17 +0200 Ulrich Sibiller (793d587) * Remove __UNIXOS2__ references -2016-05-18 12:38:02 -0400 Adam Jackson (603fe2554) +2016-05-18 12:38:02 -0400 Adam Jackson (603fe25) * remove CLTS code -2016-10-13 19:08:37 +0200 Ulrich Sibiller (247e1f72e) +2016-10-13 19:08:37 +0200 Ulrich Sibiller (247e1f7) * use %p in format strings -2016-10-13 00:51:03 +0200 Ulrich Sibiller (c3f43e832) +2016-10-13 00:51:03 +0200 Ulrich Sibiller (c3f43e8) * replace PRMSG by prmsg -2016-10-13 00:35:04 +0200 Ulrich Sibiller (c4b775f6d) +2016-10-13 00:35:04 +0200 Ulrich Sibiller (c4b775f) * align license headers with Xorg/xtrans upstream -2016-10-13 00:31:51 +0200 Ulrich Sibiller (6957b3daa) +2016-10-13 00:31:51 +0200 Ulrich Sibiller (6957b3d) * move helper functions to file end -2008-02-10 19:04:40 -0800 Jeremy Huddleston (f686bc3eb) +2008-02-10 19:04:40 -0800 Jeremy Huddleston (f686bc3) * Fixed #ifdef checks that were using i386 to use __i386__ -2016-10-13 00:16:30 +0200 Ulrich Sibiller (64d51869f) +2016-10-13 00:16:30 +0200 Ulrich Sibiller (64d5186) * whitespace cleanup -2008-08-07 10:32:11 -0400 Adam Jackson (e5b4532ab) +2008-08-07 10:32:11 -0400 Adam Jackson (e5b4532) * Drastically simplify TRANS_OPEN_MAX. -2016-10-12 22:28:41 +0200 Ulrich Sibiller (0ca6e5999) +2016-10-12 22:28:41 +0200 Ulrich Sibiller (0ca6e59) * undef __QNX__ -2016-10-12 22:27:34 +0200 Ulrich Sibiller (4ab02b27c) +2016-10-12 22:27:34 +0200 Ulrich Sibiller (4ab02b2) * undef Lynx -2016-10-12 22:47:36 +0200 Ulrich Sibiller (89cea600a) +2016-10-12 22:47:36 +0200 Ulrich Sibiller (89cea60) * undef AIXV3 -2016-10-12 22:44:21 +0200 Ulrich Sibiller (eb4ee6c32) +2016-10-12 22:44:21 +0200 Ulrich Sibiller (eb4ee6c) * undef hpux -2016-10-12 22:24:09 +0200 Ulrich Sibiller (175a3416e) +2016-10-12 22:24:09 +0200 Ulrich Sibiller (175a341) * undef __UNIXOS2__ -2016-10-12 22:05:26 +0200 Ulrich Sibiller (97d651fcf) +2016-10-12 22:05:26 +0200 Ulrich Sibiller (97d651f) * Remove OS2PIPECONN transport -2016-10-12 21:33:00 +0200 Ulrich Sibiller (0cbc89221) +2016-10-12 21:33:00 +0200 Ulrich Sibiller (0cbc892) * Remove unused TLI ("STREAMSCONN") code -2016-10-12 21:06:36 +0200 Ulrich Sibiller (b5bfd3a49) +2016-10-12 21:06:36 +0200 Ulrich Sibiller (b5bfd3a) * remove DECnet support -2016-11-02 19:38:08 +0100 Mike Gabriel (a9b145d46) +2016-11-02 19:38:08 +0100 Mike Gabriel (a9b145d) * Makefile: Make sure libNX_X11.so.6.2 does not get installed as symlink but as actual file. (Follow-up for 5a90a63). -2016-11-02 17:54:24 +0100 Mike Gabriel (1d1d1fc21) +2016-11-02 17:54:24 +0100 Mike Gabriel (1d1d1fc) * Merge branch 'pr/unused_files' into 3.6.x -2016-10-30 19:05:56 +0100 Ulrich Sibiller (7d884049b) +2016-10-30 19:05:56 +0100 Ulrich Sibiller (7d88404) * remove unused mkks.sh (pr/unused_files) -2016-10-30 19:02:36 +0100 Ulrich Sibiller (bac5ce7b5) +2016-10-30 19:02:36 +0100 Ulrich Sibiller (bac5ce7) * remove unused jump_* files from libX11 -2016-10-30 18:54:04 +0100 Ulrich Sibiller (331497b88) +2016-10-30 18:54:04 +0100 Ulrich Sibiller (331497b) * drop unused xtest1.frags -2016-10-30 18:48:31 +0100 Ulrich Sibiller (6b9ce7da4) +2016-10-30 18:48:31 +0100 Ulrich Sibiller (6b9ce7d) * remove unused fb24_32.h -2016-10-30 18:47:04 +0100 Ulrich Sibiller (a29a2b656) +2016-10-30 18:47:04 +0100 Ulrich Sibiller (a29a2b6) * remove unused registry.h -2016-10-30 18:43:38 +0100 Ulrich Sibiller (89f9212ef) +2016-10-30 18:43:38 +0100 Ulrich Sibiller (89f9212) * remove unused XInput.h -2016-10-30 18:40:10 +0100 Ulrich Sibiller (881979bd1) +2016-10-30 18:40:10 +0100 Ulrich Sibiller (881979b) * Remove unused Xv and XvMC headers -2016-10-30 18:01:11 +0100 Ulrich Sibiller (ba87cf406) +2016-10-30 18:01:11 +0100 Ulrich Sibiller (ba87cf4) * drop unused glu.h -2016-10-30 17:58:59 +0100 Ulrich Sibiller (903d5ce8a) +2016-10-30 17:58:59 +0100 Ulrich Sibiller (903d5ce) * drop ap_keysym.h -2016-10-30 17:55:53 +0100 Ulrich Sibiller (1832ab62f) +2016-10-30 17:55:53 +0100 Ulrich Sibiller (1832ab6) * remove unused registry file -2016-10-30 17:54:46 +0100 Ulrich Sibiller (b7daac272) +2016-10-30 17:54:46 +0100 Ulrich Sibiller (b7daac2) * remove *-def.cpp -2016-10-29 23:26:05 +0200 Ulrich Sibiller (4271b9ebd) +2016-10-29 23:26:05 +0200 Ulrich Sibiller (4271b9e) * nxcomp: remove unused Utils.cpp -2016-10-29 22:52:53 +0200 Ulrich Sibiller (96c9aafd6) +2016-10-29 22:52:53 +0200 Ulrich Sibiller (96c9aaf) * Imake: drop DoLoadableServer, MakeDllModules and IHaveModules -2016-10-29 11:18:41 +0200 Mike Gabriel (8dab7c21d) +2016-10-29 11:18:41 +0200 Mike Gabriel (8dab7c2) * Remove extmod from nx-X11/programs/Xserver/Xext/. -2016-11-02 17:53:15 +0100 Mike Gabriel (6eb8d3ec6) +2016-11-02 17:53:15 +0100 Mike Gabriel (6eb8d3e) * Merge branch 'uli42-pr/add_libX11_links' into 3.6.x -2016-10-28 23:38:17 +0200 Ulrich Sibiller (5a90a638f) +2016-10-28 23:38:17 +0200 Ulrich Sibiller (5a90a63) * libX11/Imakefile: handle libX11 links -2016-10-28 23:37:17 +0200 Ulrich Sibiller (f1d420baa) +2016-10-28 23:37:17 +0200 Ulrich Sibiller (f1d420b) * libX11/Imakefile: add missing dependencies on ks_tables.h -2016-10-31 12:44:52 +0100 Mike Gabriel (4c59a3c58) +2016-10-31 12:44:52 +0100 Mike Gabriel (4c59a3c) * Merge branch 'sunweaver-pr/clean-up-old-vcs-comments' into 3.6.x -2016-10-29 15:30:20 +0200 Mike Gabriel (fcf61d341) +2016-10-29 15:30:20 +0200 Mike Gabriel (fcf61d3) * Imakefile cleanup: Delete all ancient Vcs comments stemming from SVN times of X.org and XFree86. -2016-10-30 23:52:44 +0100 Mike Gabriel (6b3080d54) +2016-10-30 23:52:44 +0100 Mike Gabriel (6b3080d) * Merge branch 'sunweaver-pr/drop-mfb-maskbits-h' into 3.6.x -2016-10-30 21:36:53 +0100 Mike Gabriel (b99c78721) +2016-10-30 21:36:53 +0100 Mike Gabriel (b99c787) * Xserver/Imakefile: Drop references to already removed afb code. (gh-sunweaver/pr/drop-mfb-maskbits-h) -2016-10-30 21:36:03 +0100 Mike Gabriel (65e25bd47) +2016-10-30 21:36:03 +0100 Mike Gabriel (65e25bd) * Xserver/Imakefile: Drop all references to building already removed cfb* implementations. -2016-10-30 20:16:53 +0100 Adam Jackson (cc0350202) +2016-10-30 20:16:53 +0100 Adam Jackson (cc03502) * Death to mfb (removing last remnants from NX code). -2016-10-30 18:31:54 +0100 Adam Jackson (3c0e426f0) +2016-10-30 18:31:54 +0100 Adam Jackson (3c0e426) * Disinfect mi/ of mfb. -2016-10-30 14:32:04 +0100 Mike Gabriel (23c66f400) +2016-10-30 14:32:04 +0100 Mike Gabriel (23c66f4) * Merge branch 'sunweaver-pr/drop-nxlibint-h' into 3.6.x -2016-10-30 13:11:38 +0100 Mike Gabriel (1ddbe39ad) +2016-10-30 13:11:38 +0100 Mike Gabriel (1ddbe39) * nxcompext: Drop (nowadays) no-op file NXlibint.h. (gh-sunweaver/pr/drop-nxlibint-h) -2016-10-30 14:25:57 +0100 Mike Gabriel (23ad270b5) +2016-10-30 14:25:57 +0100 Mike Gabriel (23ad270) * Merge branch 'uli42-misc_fixes' into 3.6.x -2016-10-30 13:46:11 +0100 Ulrich Sibiller (16947012d) +2016-10-30 13:46:11 +0100 Ulrich Sibiller (1694701) * nxagent.keyboard: add quotes -2016-10-30 13:45:33 +0100 Ulrich Sibiller (903cc0657) +2016-10-30 13:45:33 +0100 Ulrich Sibiller (903cc06) * Imakefile: remove references to non-existing subdirs -2016-10-30 02:32:35 +0200 Ulrich Sibiller (162a627c4) +2016-10-30 02:32:35 +0200 Ulrich Sibiller (162a627) * saver.c: fix unused variable warnings -2016-10-29 10:32:51 +0200 Mike Gabriel (a375d178f) +2016-10-29 10:32:51 +0200 Mike Gabriel (a375d17) * Merge branch 'sunweaver-pr/build-includes-robustness' into 3.6.x + (gh-uli42/3.6.x) -2016-10-28 15:19:10 +0200 Mike Gabriel (2f2a5a920) +2016-10-28 15:19:10 +0200 Mike Gabriel (2f2a5a9) * Imake.rules: Make BuildIncludes{,Top}() more robust in case people attempt providing path names instead of file names via srclist. (gh-sunweaver/pr/build-includes-robustness) -2016-10-29 10:30:27 +0200 Mike Gabriel (ecd335fa6) +2016-10-29 10:30:27 +0200 Mike Gabriel (ecd335f) * Merge branch 'uli42-pr/remove_xf86' into 3.6.x -2016-10-28 01:05:03 +0200 Ulrich Sibiller (4aeed7ad9) +2016-10-28 01:05:03 +0200 Ulrich Sibiller (4aeed7a) * remove hw/xfree86 altogether -2016-10-28 00:30:25 +0200 Ulrich Sibiller (6c7f9cdaa) +2016-10-28 00:30:25 +0200 Ulrich Sibiller (6c7f9cd) * remove xf86Version.h and xf86Date.h -2016-10-28 14:51:52 +0200 Mike Gabriel (4cdcd9145) +2016-10-28 14:51:52 +0200 Mike Gabriel (4cdcd91) * debian/patches: Rebase 102_xserver-xext_set-securitypolicy-path.debian.patch. (pr/harmonize-xkb-defaults) -2016-10-28 14:48:25 +0200 Mike Gabriel (c9da511cf) +2016-10-28 14:48:25 +0200 Mike Gabriel (c9da511) * Merge branch 'theqvd-slave-channel' into 3.6.x -2016-10-24 13:27:52 +0200 Vadim Troshchinskiy (c7eac1f95) +2016-10-24 13:27:52 +0200 Vadim Troshchinskiy (c7eac1f) * Add description of NX_SLAVE_CMD to man and help (theqvd-slave-channel) -2016-10-18 09:19:28 +0200 Vadim Troshchinskiy (30af52eb3) +2016-10-18 09:19:28 +0200 Vadim Troshchinskiy (30af52e) * Slave channel implementation -2016-10-28 05:42:02 +0200 Mihai Moldovan (a5de79181) +2016-10-28 05:42:02 +0200 Mihai Moldovan (a5de791) * Merge branch 'uli42-pr/backup_memleak' into arctica-3.6.x -2016-10-25 21:30:15 +0200 Emilio Pozuelo Monfort (8d1126e97) +2016-10-25 21:30:15 +0200 Emilio Pozuelo Monfort (8d1126e) * Plug a memory leak -2016-10-20 22:56:41 +0200 Mike Gabriel (5d4a7e071) +2016-10-20 22:56:41 +0200 Mike Gabriel (5d4a7e0) * debian/rules: Re-enable (+pie) hardening flags again when building .deb packages. -2016-10-20 10:31:24 +0200 Mike Gabriel (61b8d44f1) +2016-10-20 10:31:24 +0200 Mike Gabriel (61b8d44) * Merge branch 'uli42-pr/fix_compile_warnings' into 3.6.x -2016-10-20 00:15:20 +0200 Ulrich Sibiller (50eb5e4a9) +2016-10-20 00:15:20 +0200 Ulrich Sibiller (50eb5e4) * sendexev.c: Fix return of unitialized variable -2011-05-24 18:33:17 +0200 Cyril Brulebois (151e0b16d) +2011-05-24 18:33:17 +0200 Cyril Brulebois (151e0b1) * xfixes: Remove unused variable. -2006-02-14 08:11:41 +0000 Benjamin Herrenschmidt (c26621610) +2006-02-14 08:11:41 +0000 Benjamin Herrenschmidt (c266216) * Remove useless line of code that contained a bug and triggered a gcc warning. This variable will be overriden before being used anyway. (Bugzilla #5595) -2009-01-11 08:25:17 +0100 Julien Cristau (4f99f854c) +2009-01-11 08:25:17 +0100 Julien Cristau (4f99f85) * dix: fix cast from pointer to integer -2014-12-09 09:30:57 -0800 Keith Packard (e3e4062c3) +2014-12-09 09:30:57 -0800 Keith Packard (e3e4062) * dbe: Call to DDX SwapBuffers requires address of int, not unsigned int [CVE-2014-8097 pt. 2] -2016-10-19 21:58:06 +0200 Ulrich Sibiller (01eaab831) +2016-10-19 21:58:06 +0200 Ulrich Sibiller (01eaab8) * LRGB.c: Fix label defined but not used -2016-06-04 17:19:59 +0200 walter harms (ddc5ed4c9) +2016-06-04 17:19:59 +0200 walter harms (ddc5ed4) * Fixes: warning: variable 'req' set but not,used -2016-04-26 16:31:27 +0200 walter harms (21405f62b) +2016-04-26 16:31:27 +0200 walter harms (21405f6) * fix: warning: pointer targets in passing argument 2 of '_XSend' differ in signedness [-Wpointer-sign] -2016-04-26 16:34:11 +0200 walter harms (3f9ebf33d) +2016-04-26 16:34:11 +0200 walter harms (3f9ebf3) * no need to check args for Xfree() -2016-04-26 16:23:46 +0200 walter harms (897b8b28b) +2016-04-26 16:23:46 +0200 walter harms (897b8b2) * remove stray extern -2016-10-16 02:15:13 +0200 Ulrich Sibiller (2c59fbe30) +2016-10-16 02:15:13 +0200 Ulrich Sibiller (2c59fbe) * Fix warnings in XlibInt.c -2016-10-16 00:41:11 +0200 Ulrich Sibiller (0a28292ec) +2016-10-16 00:41:11 +0200 Ulrich Sibiller (0a28292) * xkb.c: fix 'assignment makes integer from pointer without a cast' -2016-10-16 00:19:47 +0200 Ulrich Sibiller (057ddde08) +2016-10-16 00:19:47 +0200 Ulrich Sibiller (057ddde) * xkmread.c: use _X_UNUSED to avoid compiler warning when result is not needed -2016-10-16 00:07:21 +0200 Ulrich Sibiller (33b5911f2) +2016-10-16 00:07:21 +0200 Ulrich Sibiller (33b5911) * xcmisc.c: remove HAVE_STDINT -2016-10-16 00:02:41 +0200 Ulrich Sibiller (c180a2147) +2016-10-16 00:02:41 +0200 Ulrich Sibiller (c180a21) * security.c: fix compiler warnings -2016-10-15 23:01:59 +0200 Ulrich Sibiller (185fbdaf9) +2016-10-15 23:01:59 +0200 Ulrich Sibiller (185fbda) * Loop.cpp: Fix output of SetCore() -2016-10-15 22:02:06 +0200 Ulrich Sibiller (d238db344) +2016-10-15 22:02:06 +0200 Ulrich Sibiller (d238db3) * Window.c: Fix function assignment warning -2016-10-15 21:45:30 +0200 Ulrich Sibiller (81a7c6cf4) +2016-10-15 21:45:30 +0200 Ulrich Sibiller (81a7c6c) * Display.c: remove unused variable -2016-10-15 21:42:54 +0200 Ulrich Sibiller (54b7561f9) +2016-10-15 21:42:54 +0200 Ulrich Sibiller (54b7561) * Colormap.c: add cast to avoid warning -2016-10-15 21:41:03 +0200 Ulrich Sibiller (3c5621c37) +2016-10-15 21:41:03 +0200 Ulrich Sibiller (3c5621c) * Args.c: fix string format warning -2016-10-15 18:21:48 +0200 Ulrich Sibiller (e3c9bc392) +2016-10-15 18:21:48 +0200 Ulrich Sibiller (e3c9bc3) * imLcIm.c: Fix unused variables -2016-10-15 18:03:18 +0200 Ulrich Sibiller (babaf67c9) +2016-10-15 18:03:18 +0200 Ulrich Sibiller (babaf67) * Pending.c: Fix compilation warning -2016-10-15 17:51:11 +0200 Ulrich Sibiller (ae8ec6b14) +2016-10-15 17:51:11 +0200 Ulrich Sibiller (ae8ec6b) * Fix libX11 implicit declaration warnings -2016-10-20 10:08:14 +0200 Mike Gabriel (da01dc8da) +2016-10-20 10:08:14 +0200 Mike Gabriel (da01dc8) * Drop nx-X11/lib/X11/libX11.elist. Not needed for anything nowadays. Probably never was needed in nx-X11. -2016-10-20 09:58:37 +0200 Mike Gabriel (44c76cacf) +2016-10-20 09:58:37 +0200 Mike Gabriel (44c76ca) * debian/libnx-x11-6.symbols: Update symbols list. -2016-10-20 09:52:45 +0200 Mike Gabriel (a559592dc) +2016-10-20 09:52:45 +0200 Mike Gabriel (a559592) * XKeysymDB: ... got removed. -2016-10-19 22:15:01 +0200 Mike Gabriel (70ac75f4a) +2016-10-19 22:15:01 +0200 Mike Gabriel (70ac75f) * Merge branch 'uli42-pr/libX11_further_backports' into 3.6.x -2016-09-25 21:25:25 +0200 Tobias Stoeckmann (70e9d346f) +2016-09-25 21:25:25 +0200 Tobias Stoeckmann (70e9d34) * Validation of server responses in XGetImage() -2016-09-25 21:22:57 +0200 Tobias Stoeckmann (b17557f9f) +2016-09-25 21:22:57 +0200 Tobias Stoeckmann (b17557f) * The validation of server responses avoids out of boundary accesses. -2016-02-06 14:18:32 -0800 Alan Coopersmith (68e3ee67c) +2016-02-06 14:18:32 -0800 Alan Coopersmith (68e3ee6) * xcms: use size_t for pointer offsets passed to strncmp -2016-02-06 13:32:44 -0800 Alan Coopersmith (8d8d5cfd8) +2016-02-06 13:32:44 -0800 Alan Coopersmith (8d8d5cf) * xcms: use unsigned indexes when looping through unsigned values -2016-02-06 13:01:25 -0800 Alan Coopersmith (327d2cc60) +2016-02-06 13:01:25 -0800 Alan Coopersmith (327d2cc) * xcms: use size_t for strlen/sizeof values instead of converting to int & back -2015-03-26 07:52:58 +0100 Dominik Muth (de4047722) +2015-03-26 07:52:58 +0100 Dominik Muth (de40477) * Xlib.h: Fix macros imitating C functions. -2016-01-21 11:54:19 +0100 Olivier Fourdan (a3759f323) +2016-01-21 11:54:19 +0100 Olivier Fourdan (a3759f3) * XKB: fix XkbGetKeyboardByName with Xming server -2015-12-19 18:03:41 -0800 Alan Coopersmith (50192b720) +2015-12-19 18:03:41 -0800 Alan Coopersmith (50192b7) * lcPubWrap: replace malloc(strlen) + strcpy with strdup -2015-12-19 10:21:04 -0800 Alan Coopersmith (7a1fc1759) +2015-12-19 10:21:04 -0800 Alan Coopersmith (7a1fc17) * XlcDL.c: reduce code duplication -2015-12-19 10:19:25 -0800 Alan Coopersmith (c9ebd122f) +2015-12-19 10:19:25 -0800 Alan Coopersmith (c9ebd12) * XlcDL.c: replace strcpy+strcat sequences with snprintf -2015-12-19 10:05:42 -0800 Alan Coopersmith (2874fd14b) +2015-12-19 10:05:42 -0800 Alan Coopersmith (2874fd1) * XDefaultOMIF: Remove comments referring to ancient Sun bug ids -2015-12-19 10:00:22 -0800 Alan Coopersmith (d980be3c2) +2015-12-19 10:00:22 -0800 Alan Coopersmith (d980be3) * XDefaultOMIF: additional code simplification -2015-12-19 09:46:31 -0800 Alan Coopersmith (c00196d2d) +2015-12-19 09:46:31 -0800 Alan Coopersmith (c00196d) * XDefaultOMIF: replace strlen+Xmalloc+strcpy with strdup -2015-12-19 09:20:55 -0800 Alan Coopersmith (f7254c69f) +2015-12-19 09:20:55 -0800 Alan Coopersmith (f7254c6) * Use strdup instead of Xmalloc+strcpy in _XDefaultOpenIM -2015-12-04 22:20:53 -0800 Alan Coopersmith (b912a4042) +2015-12-04 22:20:53 -0800 Alan Coopersmith (b912a40) * Delete #if 0 hunks of code -2015-12-03 23:38:07 -0800 Alan Coopersmith (9dec6c18b) +2015-12-03 23:38:07 -0800 Alan Coopersmith (9dec6c1) * Bug 93183: _XDefaultOpenIM memory leaks in out-of-memory error paths -2015-12-03 23:19:48 -0800 Alan Coopersmith (8d6d95d74) +2015-12-03 23:19:48 -0800 Alan Coopersmith (8d6d95d) * Bug 93184: read_EncodingInfo invalid free -2015-11-28 13:18:11 -0800 Alan Coopersmith (8339e6803) +2015-11-28 13:18:11 -0800 Alan Coopersmith (8339e68) * Remove unused definition of XCONN_CHECK_FREQ -2015-09-27 18:38:32 -0700 Alan Coopersmith (f857c70f8) +2015-09-27 18:38:32 -0700 Alan Coopersmith (f857c70) * Get rid of some extraneous ; at the end of C source lines -2015-07-19 10:22:45 +0200 Thomas Klausner (fc524ddbb) +2015-07-19 10:22:45 +0200 Thomas Klausner (fc524dd) * Do not return() after exit(). -2015-05-18 14:49:01 +0100 Ross Burton (1445735ef) +2015-05-18 14:49:01 +0100 Ross Burton (1445735) * Add missing NULL checks to ICWrap -2015-06-04 20:51:17 -0700 Alan Coopersmith (39dd37d57) +2015-06-04 20:51:17 -0700 Alan Coopersmith (39dd37d) * Replace Xmalloc+memset pairs with Xcalloc calls -2015-06-04 19:07:12 -0700 Bhavi Dhingra (a402ed016) +2015-06-04 19:07:12 -0700 Bhavi Dhingra (a402ed0) * omGeneric.c: Correct the parameter usage of sizeof -2015-05-19 12:30:22 +1000 Peter Hutterer (73f2d66e0) +2015-05-19 12:30:22 +1000 Peter Hutterer (73f2d66) * Fix three "use of uninitialized variable" coverity warnings -2015-05-18 07:55:17 +1000 Peter Hutterer (e14489988) +2015-05-18 07:55:17 +1000 Peter Hutterer (e144899) * Fix potential memory leak -2015-02-03 13:23:50 -0500 Ran Benita (8e3e7bb77) +2015-02-03 13:23:50 -0500 Ran Benita (8e3e7bb) * compose: fix the description of modifiers in compose sequences -2014-07-11 10:34:08 -0700 Alan Coopersmith (0f1fa85fe) +2014-07-11 10:34:08 -0700 Alan Coopersmith (0f1fa85) * Use C99 named initializers to fill in events passed to XSendEvent -2014-07-06 11:13:49 -0700 Alan Coopersmith (f20f91ee8) +2014-07-06 11:13:49 -0700 Alan Coopersmith (f20f91e) * Fix validation of ctrls parameter to XkbGetPerClientControls() -2014-07-06 10:54:57 -0700 Alan Coopersmith (37b8d6883) +2014-07-06 10:54:57 -0700 Alan Coopersmith (37b8d68) * Fix map->num_types check in XkbAddKeyType() -2014-06-07 12:03:17 +0200 walter harms (aa7053b3e) +2014-06-07 12:03:17 +0200 walter harms (aa7053b) * lcDefConv.c: fix use before check -2014-06-07 11:54:34 +0200 walter harms (dd6dc2ddf) +2014-06-07 11:54:34 +0200 walter harms (dd6dc2d) * rm redundant null checks -2014-06-07 15:17:27 +0200 walter harms (a98260726) +2014-06-07 15:17:27 +0200 walter harms (a982607) * libX11: rm redundante NULL checks -2014-06-06 22:53:05 +0200 walter harms (1ff696123) +2014-06-06 22:53:05 +0200 walter harms (1ff6961) * Remove more redundant null checks before Xfree() -2014-06-05 18:37:40 +0200 walter harms (fc26b97ea) +2014-06-05 18:37:40 +0200 walter harms (fc26b97) * Remove redundant null checks before free -2014-06-04 17:12:31 +0200 walter harms (191d1575f) +2014-06-04 17:12:31 +0200 walter harms (191d157) * libX11/lcUTF8.c fix: dereferenced before check -2014-06-04 17:10:20 +0200 walter harms (861fe5aee) +2014-06-04 17:10:20 +0200 walter harms (861fe5a) * libX11/XKBNames.c fix: dereferenced before check -2014-06-04 17:08:12 +0200 walter harms (e7528f581) +2014-06-04 17:08:12 +0200 walter harms (e7528f5) * libX11/lcGenConv.c fix: dereferenced before check -2014-05-09 18:21:05 -0400 Owen W. Taylor (afc7138f9) +2014-05-09 18:21:05 -0400 Owen W. Taylor (afc7138) * Fix XNextRequest() after direct usage of XCB -2014-02-11 13:26:16 +0200 Ran Benita (88d496598) +2014-02-11 13:26:16 +0200 Ran Benita (88d4965) * Remove dead USE_OWN_COMPOSE-protected code -2014-02-06 13:48:08 -0800 Alan Coopersmith (3e8df1a2e) +2014-02-06 13:48:08 -0800 Alan Coopersmith (3e8df1a) * Fix typos in Xrm.c comments -2013-12-26 09:26:13 -0800 Alan Coopersmith (101419b10) +2013-12-26 09:26:13 -0800 Alan Coopersmith (101419b) * _XkbReadGeomOverlay: check for NULL first, then use pointer -2013-12-26 09:22:49 -0800 Alan Coopersmith (1b0df5da6) +2013-12-26 09:22:49 -0800 Alan Coopersmith (1b0df5d) * XkbSelectEventDetails: remove unnecessary assignments -2010-10-07 18:46:08 +0100 Jon TURNEY (4fad46e9c) +2010-10-07 18:46:08 +0100 Jon TURNEY (4fad46e) * Don't try so hard to find a matching font with the given encoding -2013-12-02 21:51:27 -0800 Alan Coopersmith (f45ac4ae3) +2013-12-02 21:51:27 -0800 Alan Coopersmith (f45ac4a) * unifdef -UISC -2013-11-16 20:21:54 -0800 Alan Coopersmith (35dc4784b) +2013-11-16 20:21:54 -0800 Alan Coopersmith (35dc478) * Drop X_LOCALE fallback for OS'es without setlocale() -2013-08-24 17:27:43 -0700 Alan Coopersmith (f04e1a6d1) +2013-08-24 17:27:43 -0700 Alan Coopersmith (f04e1a6) * Bug 68413 - [Bisected]Error in `xterm': realloc(): invalid next size -2013-08-16 21:04:02 -0700 Alan Coopersmith (ba86b7a2e) +2013-08-16 21:04:02 -0700 Alan Coopersmith (ba86b7a) * Stop checking for HAVE_DIX_CONFIG_H on the client side -2013-08-16 18:27:28 -0700 Alan Coopersmith (2824899d2) +2013-08-16 18:27:28 -0700 Alan Coopersmith (2824899) * Rearrange some variable declarations & initializations in XKB -2013-08-11 13:29:33 -0700 Alan Coopersmith (3c5880e72) +2013-08-11 13:29:33 -0700 Alan Coopersmith (3c5880e) * Reindent XKB code to X.Org standard style -2013-08-16 18:14:14 -0700 Alan Coopersmith (3cd822526) +2013-08-16 18:14:14 -0700 Alan Coopersmith (3cd8225) * Fix overflow checks in _XkbReadKeySyms when key_sym_map is already created -2013-08-11 17:02:21 -0700 Alan Coopersmith (c22524d30) +2013-08-11 17:02:21 -0700 Alan Coopersmith (c22524d) * Remove long unused udcInf.c -2013-08-11 00:07:33 -0700 Alan Coopersmith (26256188b) +2013-08-11 00:07:33 -0700 Alan Coopersmith (2625618) * Remove unnecessary casts of pointers to (char *) in calls to Xfree() -2013-08-10 23:57:55 -0700 Alan Coopersmith (d33cf0446) +2013-08-10 23:57:55 -0700 Alan Coopersmith (d33cf04) * Don't cast sizeof() results to unsigned when passing to Xmalloc/Xcalloc -2013-08-10 23:51:08 -0700 Alan Coopersmith (c161df4fe) +2013-08-10 23:51:08 -0700 Alan Coopersmith (c161df4) * Remove even more casts of return values from Xmalloc/Xrealloc -2013-08-10 23:05:13 -0700 Alan Coopersmith (5d6cda4f6) +2013-08-10 23:05:13 -0700 Alan Coopersmith (5d6cda4) * xlibi18n: fix argsize argument to _XlcParsePath -2013-08-10 22:32:42 -0700 Alan Coopersmith (069c1f4d5) +2013-08-10 22:32:42 -0700 Alan Coopersmith (069c1f4) * i18n modules: Fix some const cast warnings -2013-08-10 22:21:54 -0700 Alan Coopersmith (d8358c6ef) +2013-08-10 22:21:54 -0700 Alan Coopersmith (d8358c6) * xlibi18n: Fix a bunch of const cast warnings -2013-08-10 22:18:00 -0700 Alan Coopersmith (e667b9054) +2013-08-10 22:18:00 -0700 Alan Coopersmith (e667b90) * Fix const handling in XSetLocaleModifiers -2013-08-10 21:46:37 -0700 Alan Coopersmith (d2671c285) +2013-08-10 21:46:37 -0700 Alan Coopersmith (d2671c2) * Constify lc_name argument to _XlcLocaleDirName() & _XlcLocaleLibDirName() -2013-08-10 13:37:53 -0700 Alan Coopersmith (22377a799) +2013-08-10 13:37:53 -0700 Alan Coopersmith (22377a7) * init_om: remove unneeded extra copy of string to local buffer -2013-08-10 12:34:53 -0700 Alan Coopersmith (92591316d) +2013-08-10 12:34:53 -0700 Alan Coopersmith (9259131) * Delete unused XKB_INSURE_SIZE macro from XKBlibint.h -2013-08-10 12:19:17 -0700 Alan Coopersmith (be32fbb31) +2013-08-10 12:19:17 -0700 Alan Coopersmith (be32fbb) * miRegionOp(): ensure region size is not updated if realloc fails -2013-08-10 12:19:17 -0700 Alan Coopersmith (ad51fbdb4) +2013-08-10 12:19:17 -0700 Alan Coopersmith (ad51fbd) * miRegionCopy(): handle realloc failure better -2013-08-10 11:27:22 -0700 Alan Coopersmith (105cd4711) +2013-08-10 11:27:22 -0700 Alan Coopersmith (105cd47) * Avoid memory leak/corruption if realloc fails in Xregion.h:MEMCHECK macro -2013-08-10 12:07:51 -0700 Alan Coopersmith (180991ce2) +2013-08-10 12:07:51 -0700 Alan Coopersmith (180991c) * Avoid memory leak/corruption if realloc fails in imLcPrs.c:parseline() -2013-08-10 12:30:39 -0700 Alan Coopersmith (7156a20bc) +2013-08-10 12:30:39 -0700 Alan Coopersmith (7156a20) * lcDB.c: ensure buffer size is updated correctly if realloc fails -2013-08-10 11:07:47 -0700 Alan Coopersmith (0574a55eb) +2013-08-10 11:07:47 -0700 Alan Coopersmith (0574a55) * Avoid memory leak/corruption if realloc fails in XlcDL.c:resolve_object() -2013-08-09 23:33:03 -0700 Alan Coopersmith (a6d9409b0) +2013-08-09 23:33:03 -0700 Alan Coopersmith (a6d9409) * omGeneric.c: convert sprintf calls to snprintf -2013-08-09 23:30:30 -0700 Alan Coopersmith (d03ab1de0) +2013-08-09 23:30:30 -0700 Alan Coopersmith (d03ab1d) * ximcp/imRm.c: convert sprintf calls to snprintf -2013-08-09 23:02:12 -0700 Alan Coopersmith (a1b0fdb2c) +2013-08-09 23:02:12 -0700 Alan Coopersmith (a1b0fdb2) * xlibi18n: convert sprintf calls to snprintf -2013-08-09 23:02:12 -0700 Alan Coopersmith (bde3d8b14) +2013-08-09 23:02:12 -0700 Alan Coopersmith (bde3d8b) * lcfile: skip over any null entries in args list -2013-08-09 22:00:09 -0700 Alan Coopersmith (7bca34528) +2013-08-09 22:00:09 -0700 Alan Coopersmith (7bca345) * Fix file leak on malloc error in XlcDL.c:resolve_object() -2012-12-18 15:28:05 +0000 ISHIKAWA,chiaki (ce482d4fd) +2012-12-18 15:28:05 +0000 ISHIKAWA,chiaki (ce482d4) * Fix bogus timestamp generated by XIM -2011-06-16 17:28:39 +0200 Egbert Eich (ed53aca1d) +2011-06-16 17:28:39 +0200 Egbert Eich (ed53aca) * XIM: Fix race on focus change: set 'FABRICATED' only when keyev filters in place. -2013-07-27 01:03:18 -0700 Alan Coopersmith (adcf3894a) +2013-07-27 01:03:18 -0700 Alan Coopersmith (adcf389) * omGeneric: remove space between struct name & member name -2013-07-23 22:11:34 -0700 Alan Coopersmith (6d64c4164) +2013-07-23 22:11:34 -0700 Alan Coopersmith (6d64c41) * XSetModifierMapping: Use Data instead of GetReqExtra -2013-06-09 11:13:42 -0700 Kees Cook (ea8239650) +2013-06-09 11:13:42 -0700 Kees Cook (ea82396) * libX11: check size of GetReqExtra after XFlush -2013-06-25 22:35:29 +0200 Thomas Klausner (39c6e5aa8) +2013-06-25 22:35:29 +0200 Thomas Klausner (39c6e5a) * Tighten out-of-range comparisons. -2013-06-25 18:34:32 +0200 Thomas Klausner (ac3d26251) +2013-06-25 18:34:32 +0200 Thomas Klausner (ac3d262) * Fix out-of-range comparison in _XF86BigfontQueryFont -2013-06-25 18:33:56 +0200 Thomas Klausner (61fdf93ef) +2013-06-25 18:33:56 +0200 Thomas Klausner (61fdf93) * Check for symbol existence with #ifdef, not #if -2013-06-25 18:31:32 +0200 Thomas Klausner (d122d7545) +2013-06-25 18:31:32 +0200 Thomas Klausner (d122d75) * Stop truncating source to destination length if it is larger. -2013-06-24 23:02:05 -0700 Alan Coopersmith (88edf8083) +2013-06-24 23:02:05 -0700 Alan Coopersmith (88edf80) * Require ANSI C89 pre-processor, drop pre-C89 token pasting support -2016-10-08 00:20:48 +0200 Ulrich Sibiller (7f98ab03b) +2016-10-08 00:20:48 +0200 Ulrich Sibiller (7f98ab0) * update Xfuncproto.h -2016-10-07 23:46:05 +0200 Ulrich Sibiller (e2e45b2b3) +2016-10-07 23:46:05 +0200 Ulrich Sibiller (e2e45b2) * Align files with upstream libX11-1.6.0 -2012-12-16 17:44:42 -0800 Alan Coopersmith (878040bf0) +2012-12-16 17:44:42 -0800 Alan Coopersmith (878040b) * Tell clang not to report -Wpadded warnings on public headers we can't fix -2010-09-08 10:44:23 -0400 Adam Jackson (9b5f99c37) +2010-09-08 10:44:23 -0400 Adam Jackson (9b5f99c) * Zero buffer data in BufAlloc() -2011-01-31 14:02:10 +0200 Erkki Seppälä (13fe4d475) +2011-01-31 14:02:10 +0200 Erkki Seppälä (13fe4d4) * GetProp: Zero-initialized error so its resourceID field is initialized -2013-03-01 18:37:37 -0800 Alan Coopersmith (7992a9873) +2013-03-01 18:37:37 -0800 Alan Coopersmith (7992a98) * integer overflow in ReadInFile() in Xrm.c [CVE-2013-1981 7/13] -2011-01-31 14:01:58 +0200 Erkki Seppälä (78b0ca2fe) +2011-01-31 14:01:58 +0200 Erkki Seppälä (78b0ca2) * ximcp/imRmAttr: Handle leaking colormap_ret -2011-02-21 15:56:54 +0100 Samuel Thibault (b00312f5d) +2011-02-21 15:56:54 +0100 Samuel Thibault (b00312f) * Fix status reporting for braille patterns -2016-10-07 22:16:24 +0200 Ulrich Sibiller (a2fded2e3) +2016-10-07 22:16:24 +0200 Ulrich Sibiller (a2fded2) * Revert incomplete "Fix status reporting for braille patterns" -2010-09-03 23:11:53 -0700 Alan Coopersmith (bd43a0640) +2010-09-03 23:11:53 -0700 Alan Coopersmith (bd43a06) * Sun's copyrights are now owned by Oracle -2016-10-07 21:16:39 +0200 Ulrich Sibiller (5dbcf1987) +2016-10-07 21:16:39 +0200 Ulrich Sibiller (5dbcf19) * Assume size_t is always available, since it was defined in C89 -2016-10-07 21:00:20 +0200 Ulrich Sibiller (1078f9770) +2016-10-07 21:00:20 +0200 Ulrich Sibiller (1078f97) * rename xf86bigfstr.h to xf86bigfproto.h -2013-06-02 11:49:54 -0700 Thomas Klausner (e03d8c215) +2013-06-02 11:49:54 -0700 Thomas Klausner (e03d8c2) * cmsMath.c: Add missing stdio header for printf(3) in DEBUG build. -2013-05-17 15:26:21 -0700 Niveditha Rau (26f7239a0) +2013-05-17 15:26:21 -0700 Niveditha Rau (26f7239) * Make sure internal headers include required headers -2013-05-16 23:05:36 -0700 Alan Coopersmith (71fb99cb4) +2013-05-16 23:05:36 -0700 Alan Coopersmith (71fb99c) * Free fs->properties in XF86BigfontQueryFont overflow error path -2013-05-23 20:39:46 +0200 Julien Cristau (78ed23330) +2013-05-23 20:39:46 +0200 Julien Cristau (78ed233) * xkb: fix off-by-one in _XkbReadGetNamesReply and _XkbReadVirtualModMap -2016-10-06 23:34:06 +0200 Ulrich Sibiller (082e83130) +2016-10-06 23:34:06 +0200 Ulrich Sibiller (082e831) * Revert "Add a couple fixups for the security patches" -2013-03-07 23:46:05 -0800 Alan Coopersmith (e15023b2a) +2013-03-07 23:46:05 -0800 Alan Coopersmith (e15023b) * Remove more unnecessary casts from Xmalloc/calloc calls -2013-03-16 18:30:56 -0700 Alan Coopersmith (47d0ea1ba) +2013-03-16 18:30:56 -0700 Alan Coopersmith (47d0ea1) * Move big request comment in XOpenDisplay to the right place -2013-03-08 22:33:28 -0800 Alan Coopersmith (4988e9bd9) +2013-03-08 22:33:28 -0800 Alan Coopersmith (4988e9b) * Fix very weird indenting in nx-X11/lib/X11/GetFProp.c -2013-03-08 15:37:33 -0800 Alan Coopersmith (001aeb55b) +2013-03-08 15:37:33 -0800 Alan Coopersmith (001aeb5) * XAllocClassHint: Assume calloc sets pointers in allocated memory to NULL -2013-03-08 17:13:09 -0800 Alan Coopersmith (7ddc5b90f) +2013-03-08 17:13:09 -0800 Alan Coopersmith (7ddc5b9) * _xudc_code_to_glyph: check for NULL pointer *before* writing to it, not after -2013-03-01 18:10:27 -0800 Alan Coopersmith (e18ccaaae) +2013-03-01 18:10:27 -0800 Alan Coopersmith (e18ccaa) * Assume size_t is always available, since it was defined in C89 -2013-03-01 18:09:07 -0800 Alan Coopersmith (2393e1acd) +2013-03-01 18:09:07 -0800 Alan Coopersmith (2393e1a) * unifdef XKB_IN_SERVER -2013-02-16 10:42:23 -0800 Alan Coopersmith (d31b81c10) +2013-02-16 10:42:23 -0800 Alan Coopersmith (d31b81c) * Convert more sprintf calls to snprintf -2013-02-15 23:43:12 -0800 Alan Coopersmith (d43f4c398) +2013-02-15 23:43:12 -0800 Alan Coopersmith (d43f4c3) * XKeysymToString: move variable declarations to the scope of their usage -2013-02-15 23:34:40 -0800 Alan Coopersmith (5e0584c43) +2013-02-15 23:34:40 -0800 Alan Coopersmith (5e0584c) * Preserve constness in casting arguments through the Data*() routines -2013-02-15 23:25:38 -0800 Alan Coopersmith (d91c145a4) +2013-02-15 23:25:38 -0800 Alan Coopersmith (d91c145) * XStringToKeysym: preserve constness when casting off unsignedness for strcmp -2013-02-15 23:14:40 -0800 Alan Coopersmith (641704516) +2013-02-15 23:14:40 -0800 Alan Coopersmith (6417045) * XRebindKeysym: Drop unnecessary const-removing cast -2013-02-15 22:45:19 -0800 Alan Coopersmith (5608b67f2) +2013-02-15 22:45:19 -0800 Alan Coopersmith (5608b67) * cmsColNm.c: maintain constness of arguments to qsort helper function -2012-12-26 22:57:39 -0800 Alan Coopersmith (19275f9e1) +2012-12-26 22:57:39 -0800 Alan Coopersmith (19275f9) * Remove unused DECnet ("DNETCONN") code from Xlib -2012-12-26 22:56:38 -0800 Alan Coopersmith (acceb2cf6) +2012-12-26 22:56:38 -0800 Alan Coopersmith (acceb2c) * Remove unused TLI ("STREAMSCONN") code from Xlib -2011-05-20 18:25:24 +0200 Egbert Eich (53e2e92e3) +2011-05-20 18:25:24 +0200 Egbert Eich (53e2e92) * Don't hard code path to Xcms.txt file. -2012-10-22 13:54:11 -0500 Yaakov Selkowitz (11d6dac92) +2012-10-22 13:54:11 -0500 Yaakov Selkowitz (11d6dac) * XIM: remove Private and Public macros -2012-06-29 23:08:04 -0700 Alan Coopersmith (97b9864ea) +2012-06-29 23:08:04 -0700 Alan Coopersmith (97b9864) * Convert XCreate{Pix,Bit}map...Data to use C99 designated initializers -2012-06-29 22:57:13 -0700 Alan Coopersmith (7a8721b8a) +2012-06-29 22:57:13 -0700 Alan Coopersmith (7a8721b) * XCreate{Pix,Bit}map...Data: Free pixmap in error path if XCreateGC fails -2010-12-22 15:14:05 +0000 Philipp Reh (c86806148) +2010-12-22 15:14:05 +0000 Philipp Reh (c868061) * Events: Store event cookie when dequeuing event -2011-05-03 09:32:53 -0700 Jeremy Huddleston (5062342d4) +2011-05-03 09:32:53 -0700 Jeremy Huddleston (5062342) * clang analyzer: Don't warn about Xmalloc(0) -2011-05-08 09:08:07 -0700 Jeremy Huddleston (c19cda6d6) +2011-05-08 09:08:07 -0700 Jeremy Huddleston (c19cda6) * Silence clang static analysis warnings for SetReqLen -2011-05-17 20:49:59 -0700 Alan Coopersmith (c300a430d) +2011-05-17 20:49:59 -0700 Alan Coopersmith (c300a43) * Fix man page and comment references to use XFreeModifiermap (lowercase map) -2011-10-10 14:09:17 -0700 Jeremy Huddleston (f3bbb81c4) +2011-10-10 14:09:17 -0700 Jeremy Huddleston (f3bbb81) * Mark XKeycodeToKeysym as _X_DEPRECATED -2011-10-10 16:40:52 +0200 Bodo Graumann (cc4d5260e) +2011-10-10 16:40:52 +0200 Bodo Graumann (cc4d526) * libX11: Fixing modifier key range in Xutil.h (Bug #21910) -2011-10-27 13:24:10 +1000 Peter Hutterer (3bf350742) +2011-10-27 13:24:10 +1000 Peter Hutterer (3bf3507) * Switch GetEmptyReq and GetResReq to call _XGetRequest -2011-10-14 14:51:06 +1000 Peter Hutterer (3597915f6) +2011-10-14 14:51:06 +1000 Peter Hutterer (3597915) * include: Add GetReqSized() for request buffers of specific size -2011-10-27 13:53:22 +1000 Peter Hutterer (3155b9bb2) +2011-10-27 13:53:22 +1000 Peter Hutterer (3155b9b) * Use GetReqSized for GetReq and GetReqExtra -2011-01-31 14:01:59 +0200 Erkki Seppälä (79cb50e4c) +2011-01-31 14:01:59 +0200 Erkki Seppälä (79cb50e) * ximcp/imRmAttr: Handle leaking missing_list -2011-01-31 14:02:01 +0200 Erkki Seppälä (44e472068) +2011-01-31 14:02:01 +0200 Erkki Seppälä (44e4720) * ximcp/imRm: Handle leaking colormap_ret -2011-01-31 14:02:14 +0200 Erkki Seppälä (89dc7ccfb) +2011-01-31 14:02:14 +0200 Erkki Seppälä (89dc7cc) * ximcp/imTrX: Handle failing XGetWindowProperty -2011-01-31 14:02:15 +0200 Erkki Seppälä (81422098f) +2011-01-31 14:02:15 +0200 Erkki Seppälä (8142209) * ximcp/imLckup: Handle negative return value from _Xlcwctomb -2011-01-31 14:02:13 +0200 Ander Conselvan de Oliveira (a8598e062) +2011-01-31 14:02:13 +0200 Ander Conselvan de Oliveira (a8598e0) * lc/def/lcDefConv: Use Xcalloc to avoid use of uninitialized memory -2011-02-21 15:56:54 +0100 Samuel Thibault (93a4f5c47) +2011-02-21 15:56:54 +0100 Samuel Thibault (93a4f5c) * Fix status reporting for braille patterns -2011-02-21 21:54:17 +0100 Samuel Thibault (2cca621e3) +2011-02-21 21:54:17 +0100 Samuel Thibault (2cca621) * Make the Local XIM request key releases for braille -2011-01-10 16:22:45 +0200 Erkki Seppälä (e4815126b) +2011-01-10 16:22:45 +0200 Erkki Seppälä (e481512) * im/ximcp: release modifiermap before returning -2011-04-12 20:50:42 -0700 Alan Coopersmith (018d938aa) +2011-04-12 20:50:42 -0700 Alan Coopersmith (018d938) * Fix "attrinute" typo in comments in ximcp -2011-03-24 16:24:29 +0200 Ander Conselvan de Oliveira (4aa79f1f1) +2011-03-24 16:24:29 +0200 Ander Conselvan de Oliveira (4aa79f1) * Fix leaks in _XimEncodingNegotiation error paths. -2011-03-24 19:36:56 +0200 Ander Conselvan de Oliveira (3720ed7bf) +2011-03-24 19:36:56 +0200 Ander Conselvan de Oliveira (3720ed7) * Fix memory leaks on _XimProtoCreateIC error paths. -2011-03-24 19:48:44 +0200 Ander Conselvan de Oliveira (b7cc762ba) +2011-03-24 19:48:44 +0200 Ander Conselvan de Oliveira (b7cc762) * Fix memory leaks on _XimWriteCachedDefaultTree error paths. -2011-03-24 19:52:05 +0200 Ander Conselvan de Oliveira (7024f3d90) +2011-03-24 19:52:05 +0200 Ander Conselvan de Oliveira (7024f3d) * Fix memory leak on _XimCommitRecv error path. -2011-03-24 19:55:33 +0200 Ander Conselvan de Oliveira (60840dc31) +2011-03-24 19:55:33 +0200 Ander Conselvan de Oliveira (60840dc) * Fix memory leaks on _XimCbDispatch error path. -2011-03-24 20:40:41 +0200 Ander Conselvan de Oliveira (9fa1e98dd) +2011-03-24 20:40:41 +0200 Ander Conselvan de Oliveira (9fa1e98) * om: Fix memory leak on read_EncodingInfo error path. -2011-03-25 16:06:15 +0200 Ander Conselvan de Oliveira (748cf8946) +2011-03-25 16:06:15 +0200 Ander Conselvan de Oliveira (748cf89) * om: Fix potential memory leak in init_om. -2011-03-25 14:47:35 +0200 Ander Conselvan de Oliveira (6fe8d44ca) +2011-03-25 14:47:35 +0200 Ander Conselvan de Oliveira (6fe8d44) * om: Fix memory leaks on get_font_name error paths. -2011-10-09 02:26:45 -0700 Jeremy Huddleston (73a2898af) +2011-10-09 02:26:45 -0700 Jeremy Huddleston (73a2898) * Fix potential uninitialized variable access in _XimMakeICAttrIDList -2011-10-09 17:56:45 +0200 Yann Droneaud (bec22fe97) +2011-10-09 17:56:45 +0200 Yann Droneaud (bec22fe) * Return name instead of value in XGetIMValues() and XSetIMValues() -2011-10-11 17:27:59 +0200 Yann Droneaud (cded3305d) +2011-10-11 17:27:59 +0200 Yann Droneaud (cded330) * Return name instead of False in XSetICValues() -2011-10-14 17:39:21 -0700 Xue Wei (8d1e05940) +2011-10-14 17:39:21 -0700 Xue Wei (8d1e059) * mbtocs should not truncate input -2011-10-14 17:53:00 -0700 Alan Coopersmith (2f49f62a8) +2011-10-14 17:53:00 -0700 Alan Coopersmith (2f49f62) * Fix "nomal" -> "normal" typo in several comments -2011-11-08 20:18:09 +0000 Andreas Wettstein (4ef27790b) +2011-11-08 20:18:09 +0000 Andreas Wettstein (4ef2779) * XIM: Allow modifier releases in compose sequences (#26705) -2011-02-21 17:27:38 +0100 Samuel Thibault (b8b885daf) +2011-02-21 17:27:38 +0100 Samuel Thibault (b8b885d) * Match braille patterns with compose tree -2012-04-30 16:36:47 +1000 Peter Hutterer (79a5330db) +2012-04-30 16:36:47 +1000 Peter Hutterer (79a5330) * Typo fix -2012-03-15 22:03:21 -0700 Alan Coopersmith (4c7f0af73) +2012-03-15 22:03:21 -0700 Alan Coopersmith (4c7f0af) * Remove "register" qualifier that annoys Solaris Studio compiler -2012-03-04 02:00:13 -0800 Keith Packard (3d37513eb) +2012-03-04 02:00:13 -0800 Keith Packard (3d37513) * Block for other threads in _XUserLockDisplay -2011-02-20 17:09:43 +0200 Marko Myllynen (e8e91b69e) +2011-02-20 17:09:43 +0200 Marko Myllynen (e8e91b6) * Provide translation from XK_permille (ad5) to Unicode (U2030) -2012-01-01 21:04:52 +0000 Ryan Pavlik (fd7157723) +2012-01-01 21:04:52 +0000 Ryan Pavlik (fd71577) * Use pthreads on MinGW also -2011-12-14 02:17:55 -0500 Kusanagi Kouichi (5eb1147cc) +2011-12-14 02:17:55 -0500 Kusanagi Kouichi (5eb1147) * XQueryColors: Split a request into multiple requests if necessary -2011-11-29 23:56:57 -0800 Alan Coopersmith (30d4454e3) +2011-11-29 23:56:57 -0800 Alan Coopersmith (30d4454) * Reject negative string counts in copy_string_list -2011-11-09 21:00:36 -0800 Alan Coopersmith (0f089824e) +2011-11-09 21:00:36 -0800 Alan Coopersmith (0f08982) * XlcSL.c: convert old-style function definitions to ANSI C89 style -2011-10-17 09:45:15 +1000 Peter Hutterer (02dad70a8) +2011-10-17 09:45:15 +1000 Peter Hutterer (02dad70) * Add _XGetRequest as substitute for GetReq/GetReqExtra -2011-10-13 07:58:02 +0900 Choe Hwanjin (1871ff031) +2011-10-13 07:58:02 +0900 Choe Hwanjin (1871ff0) * XIM: Make Xim handle NEED_SYNC_REPLY flag -2011-05-04 15:34:31 -0700 Jeremy Huddleston (7efa7da59) +2011-05-04 15:34:31 -0700 Jeremy Huddleston (7efa7da) * XKB: XkbComputeSectionBounds: Check correct bounds in default switch-case -2011-05-04 11:35:31 -0700 Jeremy Huddleston (1d806a555) +2011-05-04 11:35:31 -0700 Jeremy Huddleston (1d806a5) * Dead code removal -2011-04-21 16:21:04 -0700 Alan Coopersmith (8127b17dc) +2011-04-21 16:21:04 -0700 Alan Coopersmith (8127b17) * Delete special case code to append "/sparcv9" to i18n module path -2011-04-12 22:30:45 -0700 Alan Coopersmith (dde00b2f6) +2011-04-12 22:30:45 -0700 Alan Coopersmith (dde00b2) * Convert malloc(strlen()); strcpy() sets to strdup -2011-04-12 21:27:45 -0700 Alan Coopersmith (7d7224d85) +2011-04-12 21:27:45 -0700 Alan Coopersmith (7d7224d) * Replace Xmalloc+bzero pairs with Xcalloc calls -2011-03-24 19:42:36 +0200 Ander Conselvan de Oliveira (369c95668) +2011-03-24 19:42:36 +0200 Ander Conselvan de Oliveira (369c956) * Fix memory leaks on _XimGetAttributeID error paths. -2011-03-30 15:06:10 +0300 Ander Conselvan de Oliveira (f50e651e8) +2011-03-30 15:06:10 +0300 Ander Conselvan de Oliveira (f50e651) * xcms: Fix memory leaks on LINEAR_RGB_InitSCCData error path. -2011-03-30 15:19:28 +0300 Ander Conselvan de Oliveira (fefb909a0) +2011-03-30 15:19:28 +0300 Ander Conselvan de Oliveira (fefb909) * xcms: Fix error on LINEAR_RGB_InitSCCData error path. -2011-03-24 14:17:44 +0200 Ander Conselvan de Oliveira (dce81504f) +2011-03-24 14:17:44 +0200 Ander Conselvan de Oliveira (dce8150) * FSWrap: fix potential leak in copy_string_list -2011-03-23 14:36:22 +0200 Ander Conselvan de Oliveira (0f7148695) +2011-03-23 14:36:22 +0200 Ander Conselvan de Oliveira (0f71486) * Fix memory leak with broken bitmap files in XReadBitmapFileData -2011-03-21 14:49:37 +0000 Harshula Jayasuriya (417e04111) +2011-03-21 14:49:37 +0000 Harshula Jayasuriya (417e041) * Add #define XK_SINHALA -2011-01-18 15:58:20 +0200 Erkki Seppälä (29ad23b98) +2011-01-18 15:58:20 +0200 Erkki Seppälä (29ad23b) * xkb: XkbPropertyPtr determined allocation success from wrong variables -2011-01-10 16:37:22 +0200 Erkki Seppälä (bbeee4fd1) +2011-01-10 16:37:22 +0200 Erkki Seppälä (bbeee4f) * keyBind: Use Xcalloc to initialize allocated _XKeytrans -2011-02-11 14:49:17 -0800 Alan Coopersmith (2618bd3fc) +2011-02-11 14:49:17 -0800 Alan Coopersmith (2618bd3) * Clean up memory when first XCreateRegion succeeds and second fails -2011-02-03 17:08:57 +0200 Erkki Seppälä (07fae919a) +2011-02-03 17:08:57 +0200 Erkki Seppälä (07fae91) * cmsProp: don't deal with uninitialized values, fail instead -2011-01-31 14:02:07 +0200 Ander Conselvan de Oliveira (ae4e7538e) +2011-01-31 14:02:07 +0200 Ander Conselvan de Oliveira (ae4e753) * xcms/LRGB: don't double-free property_return -2011-02-02 08:58:45 -0800 Alan Coopersmith (26270ab1c) +2011-02-02 08:58:45 -0800 Alan Coopersmith (26270ab) * Xrm.c: ReadInFile: refactor fstat error handling -2011-02-02 08:56:00 -0800 Alan Coopersmith (563318af9) +2011-02-02 08:56:00 -0800 Alan Coopersmith (563318a) * Expand GetSizeOfFile() macro at the one place it's called -2011-01-31 14:01:57 +0200 Erkki Seppälä (20470a83e) +2011-01-31 14:01:57 +0200 Erkki Seppälä (20470a8) * XlibInt: Use strncpy+zero termination instead of strcpy to enforce buffer size -2011-01-31 14:02:16 +0200 Erkki Seppälä (7576f5f15) +2011-01-31 14:02:16 +0200 Erkki Seppälä (7576f5f) * xlibi18n/lcFile: Removed superfluous check for NULL target_dir -2011-01-31 14:02:12 +0200 Ander Conselvan de Oliveira (698270c47) +2011-01-31 14:02:12 +0200 Ander Conselvan de Oliveira (698270c) * XlibInt: info_list->watch_data was reallocated, but result was discarded -2011-02-01 11:07:25 +0200 Ander Conselvan de Oliveira (7482afcaa) +2011-02-01 11:07:25 +0200 Ander Conselvan de Oliveira (7482afc) * xcms/LRGB: Add a label for freeing property_return. -2011-01-31 14:02:08 +0200 Ander Conselvan de Oliveira (8f5a56474) +2011-01-31 14:02:08 +0200 Ander Conselvan de Oliveira (8f5a564) * xcms/LRGB: Fix potential resource leak. -2011-01-31 14:02:05 +0200 Erkki Seppälä (afd1d4eb5) +2011-01-31 14:02:05 +0200 Erkki Seppälä (afd1d4e) * Xrm: NEWTABLE had a memory leak after a memory allocation error -2011-01-31 14:02:03 +0200 Erkki Seppälä (1ac1b691d) +2011-01-31 14:02:03 +0200 Erkki Seppälä (1ac1b69) * ImUtil: Handle a memory leak in one early return branch -2011-01-31 14:01:56 +0200 Erkki Seppälä (52d2c3558) +2011-01-31 14:01:56 +0200 Erkki Seppälä (52d2c35) * xlibi18n/lcGeneric: Initialize uninitialized local variable -2011-01-31 14:01:54 +0200 Erkki Seppälä (865043ea0) +2011-01-31 14:01:54 +0200 Erkki Seppälä (865043e) * xcmx/cmxColNm: Removed unused assignments to pBuf (in two functions) -2011-02-01 12:30:56 +0200 Alan Coopersmith (54550ebb2) +2011-02-01 12:30:56 +0200 Alan Coopersmith (54550eb) * XDefaultOMIF.c: Fix memory leaks in get_font_name -2011-01-18 12:49:48 +0200 Erkki Seppälä (b7694b0b5) +2011-01-18 12:49:48 +0200 Erkki Seppälä (b7694b0) * Comparing array against NULL is not useful "&xkb->server->vmods != NULL" -2011-01-12 15:51:11 +0200 Erkki Seppälä (3147ddbf4) +2011-01-12 15:51:11 +0200 Erkki Seppälä (3147ddb) * Variable "entry" tracked as NULL was dereferenced. -2011-01-27 09:54:00 +0200 Erkki Seppälä (e17558786) +2011-01-27 09:54:00 +0200 Erkki Seppälä (e175587) * Dereferencing possibly NULL "str" in call to function "memcpy" (Deref assumed on the basis of 'nonnull' parameter attribute.) -2011-01-10 16:17:47 +0200 Erkki Seppälä (8aacb3fab) +2011-01-10 16:17:47 +0200 Erkki Seppälä (8aacb3f) * Using freed pointer "e" -2011-01-03 12:25:28 -0500 Pauli Nieminen (1a72bc414) +2011-01-03 12:25:28 -0500 Pauli Nieminen (1a72bc4) * Initialize event type -2010-06-04 13:20:17 -0700 Alan Coopersmith (8ff526111) +2010-06-04 13:20:17 -0700 Alan Coopersmith (8ff5261) * LINEAR_RGB_InitSCCData: When malloc fails, don't try to free unallocated bits -2010-07-09 18:13:13 +0100 Daniel Stone (93b55eeec) +2010-07-09 18:13:13 +0100 Daniel Stone (93b55ee) * XStringToKeysym: Cope with 0x1234cafe-style input -2010-07-08 16:49:51 +0100 Daniel Stone (b414bc2c6) +2010-07-08 16:49:51 +0100 Daniel Stone (b414bc2) * XStringToKeysym: Check strdup() return value -2010-06-15 18:49:43 +0100 Daniel Stone (c1b175d3d) +2010-06-15 18:49:43 +0100 Daniel Stone (c1b175d) * Delete now-redundant XKeysymDB -2010-06-15 18:47:37 +0100 Daniel Stone (f0b87f3de) +2010-06-15 18:47:37 +0100 Daniel Stone (f0b87f3) * XStringToKeysym: Special case for XF86 keysyms -2016-10-14 16:49:08 +0200 Mike Gabriel (6c303d9e4) +2016-10-14 16:49:08 +0200 Mike Gabriel (6c303d9) * debian/rules: Don't use -pie -fPIE at build time for 3.5.99.2 as it causes nxagent to segfault. Investigating the reasons behind it is in process... -2016-10-14 02:31:38 +0000 Mihai Moldovan (75e080800) +2016-10-14 02:31:38 +0000 Mihai Moldovan (75e0808) * nx-X11/programs/Xserver/GL/glx/Imakefile: typo fix, leading to glcontextmodes.c not being compiled. -2016-10-13 14:10:28 +0200 Mike Gabriel (29e29342e) +2016-10-13 14:10:28 +0200 Mike Gabriel (29e2934) * release 3.5.99.2 (tag: 3.5.99.2) -2016-10-13 15:05:37 +0200 Mike Gabriel (64aa45a61) +2016-10-13 15:05:37 +0200 Mike Gabriel (64aa45a) * debian/*.triggers: Call ldconfig via a trigger for all shared libraries. -2016-10-13 15:05:31 +0200 Mike Gabriel (440c675c2) +2016-10-13 15:05:31 +0200 Mike Gabriel (440c675) * debian/rules: Don't modify/create post{inst,rm} scripts during dh_makeshlibs. This avoids adding ldconfig calls to such scripts. -2016-10-13 14:45:37 +0200 Mike Gabriel (bd25086c3) +2016-10-13 14:45:37 +0200 Mike Gabriel (bd25086) * hw/nxagent/{Clipboard|Events}.c: Typo fix in error messages. -2016-10-13 14:44:27 +0200 Mike Gabriel (d2fb76d8b) +2016-10-13 14:44:27 +0200 Mike Gabriel (d2fb76d) * nxcomp/{Client|}Proxy.cpp: Typo fix in error messages. -2016-10-13 14:17:55 +0200 Mike Gabriel (0006fc04b) +2016-10-13 14:17:55 +0200 Mike Gabriel (0006fc0) * debian/libnx-x11-6.symbols: Update symbols for new backports in libNX_X11 API. -2016-10-07 21:19:07 +0200 Ulrich Sibiller (97c26978b) +2016-10-07 21:19:07 +0200 Ulrich Sibiller (97c2697) * Pending.c: conditionally include stdio.h -2016-10-10 01:00:38 +0200 Ulrich Sibiller (0bf52dc99) +2016-10-10 01:00:38 +0200 Ulrich Sibiller (0bf52dc) * nxcomp: Fix typo in usage message. -2016-10-13 14:02:51 +0200 Mike Gabriel (133c91f73) +2016-10-13 14:02:51 +0200 Mike Gabriel (133c91f) * Merge branch 'uli42-pr/libX11_debian_backports' into 3.6.x -2013-05-21 21:54:55 +0200 Julien Cristau (a9f623f0a) +2013-05-21 21:54:55 +0200 Julien Cristau (a9f623f) * Add a couple fixups for the security patches -2013-05-08 19:33:09 +0200 Matthieu Herrb (838108c29) +2013-05-08 19:33:09 +0200 Matthieu Herrb (838108c) * XListFontsWithInfo: Re-decrement flist[0] before calling free() on it. -2013-03-31 12:22:35 -0700 Alan Coopersmith (dc749a457) +2013-03-31 12:22:35 -0700 Alan Coopersmith (dc749a4) * _XkbReadGetMapReply: reject maxKeyCodes smaller than the minKeyCode -2013-03-16 10:03:13 -0700 Alan Coopersmith (37f8d3eb8) +2013-03-16 10:03:13 -0700 Alan Coopersmith (37f8d3e) * Use calloc in XOpenDisplay to initialize structs containing pointers -2013-03-02 12:39:58 -0800 Alan Coopersmith (e386187e9) +2013-03-02 12:39:58 -0800 Alan Coopersmith (e386187) * Unbounded recursion in _XimParseStringFile() when parsing include files [CVE-2013-2004 2/2] -2013-03-02 12:01:39 -0800 Alan Coopersmith (bddfee4a9) +2013-03-02 12:01:39 -0800 Alan Coopersmith (bddfee4) * Unbounded recursion in GetDatabase() when parsing include files [CVE-2013-2004 1/2] -2013-03-02 15:08:21 -0800 Alan Coopersmith (dbc117193) +2013-03-02 15:08:21 -0800 Alan Coopersmith (dbc1171) * Avoid overflows in XListExtensions() [CVE-2013-1997 15/15] -2013-03-02 15:08:21 -0800 Alan Coopersmith (77edd88e1) +2013-03-02 15:08:21 -0800 Alan Coopersmith (77edd88) * Avoid overflows in XGetFontPath() [CVE-2013-1997 14/15] -2013-03-02 15:08:21 -0800 Alan Coopersmith (f6c5069ac) +2013-03-02 15:08:21 -0800 Alan Coopersmith (f6c5069) * Avoid overflows in XListFonts() [CVE-2013-1997 13/15] -2013-03-02 11:25:25 -0800 Alan Coopersmith (0284afb80) +2013-03-02 11:25:25 -0800 Alan Coopersmith (0284afb) * unvalidated length in _XimXGetReadData() [CVE-2013-1997 12/15] -2013-03-02 11:11:08 -0800 Alan Coopersmith (0bf09b4bb) +2013-03-02 11:11:08 -0800 Alan Coopersmith (0bf09b4) * unvalidated index/length in _XkbReadGetNamesReply() [CVE-2013-1997 11/15] -2013-03-02 11:01:04 -0800 Alan Coopersmith (e6d8856ef) +2013-03-02 11:01:04 -0800 Alan Coopersmith (e6d8856) * unvalidated index in _XkbReadVirtualModMap() [CVE-2013-1997 10/15] -2013-03-02 11:04:44 -0800 Alan Coopersmith (e27df8070) +2013-03-02 11:04:44 -0800 Alan Coopersmith (e27df80) * unvalidated index in _XkbReadExplicitComponents() [CVE-2013-1997 9/15] -2013-03-02 10:51:51 -0800 Alan Coopersmith (7564bf7ef) +2013-03-02 10:51:51 -0800 Alan Coopersmith (7564bf7) * unvalidated index in _XkbReadModifierMap() [CVE-2013-1997 8/15] -2013-03-02 10:39:21 -0800 Alan Coopersmith (8f2c05082) +2013-03-02 10:39:21 -0800 Alan Coopersmith (8f2c050) * unvalidated index in _XkbReadKeyBehaviors() [CVE-2013-1997 7/15] -2013-03-02 09:40:22 -0800 Alan Coopersmith (4c19cd0c7) +2013-03-02 09:40:22 -0800 Alan Coopersmith (4c19cd0) * unvalidated index in _XkbReadKeyActions() [CVE-2013-1997 6/15] -2013-03-02 09:28:33 -0800 Alan Coopersmith (5dae1d3f4) +2013-03-02 09:28:33 -0800 Alan Coopersmith (5dae1d3) * unvalidated index in _XkbReadKeySyms() [CVE-2013-1997 5/15] -2013-03-02 09:18:26 -0800 Alan Coopersmith (e6fbdea84) +2013-03-02 09:18:26 -0800 Alan Coopersmith (e6fbdea) * unvalidated indexes in _XkbReadGetGeometryReply() [CVE-2013-1997 4/15] -2013-03-02 09:12:47 -0800 Alan Coopersmith (0445730b1) +2013-03-02 09:12:47 -0800 Alan Coopersmith (0445730) * unvalidated indexes in _XkbReadGeomShapes() [CVE-2013-1997 3/15] -2013-03-01 22:49:01 -0800 Alan Coopersmith (b06952603) +2013-03-01 22:49:01 -0800 Alan Coopersmith (b069526) * unvalidated index in _XkbReadGetDeviceInfoReply() [CVE-2013-1997 2/15] -2013-03-01 19:30:09 -0800 Alan Coopersmith (2a1fbb181) +2013-03-01 19:30:09 -0800 Alan Coopersmith (2a1fbb1) * unvalidated lengths in XAllocColorCells() [CVE-2013-1997 1/15] -2013-03-09 11:04:37 -0800 Alan Coopersmith (e03f3922a) +2013-03-09 11:04:37 -0800 Alan Coopersmith (e03f392) * Make XGetWindowProperty() always initialize returned values -2013-03-02 13:03:55 -0800 Alan Coopersmith (b20710586) +2013-03-02 13:03:55 -0800 Alan Coopersmith (b207105) * Move repeated #ifdef magic to find PATH_MAX into a common header -2013-03-02 16:56:16 -0800 Alan Coopersmith (05b72b8da) +2013-03-02 16:56:16 -0800 Alan Coopersmith (05b72b8) * Convert more _XEatData callers to _XEatDataWords -2013-03-02 15:08:21 -0800 Alan Coopersmith (306ca006a) +2013-03-02 15:08:21 -0800 Alan Coopersmith (306ca00) * integer overflow in XGetModifierMapping() [CVE-2013-1981 13/13] -2013-03-02 15:08:21 -0800 Alan Coopersmith (748af521e) +2013-03-02 15:08:21 -0800 Alan Coopersmith (748af52) * integer overflow in XGetPointerMapping() & XGetKeyboardMapping() [CVE-2013-1981 12/13] -2013-03-02 15:08:21 -0800 Alan Coopersmith (9501bce22) +2013-03-02 15:08:21 -0800 Alan Coopersmith (9501bce) * integer overflow in XGetImage() [CVE-2013-1981 11/13] -2013-03-08 22:25:35 -0800 Alan Coopersmith (361d36770) +2013-03-08 22:25:35 -0800 Alan Coopersmith (361d367) * integer overflow in XGetWindowProperty() [CVE-2013-1981 10/13] -2013-03-02 13:18:48 -0800 Alan Coopersmith (25172302a) +2013-03-02 13:18:48 -0800 Alan Coopersmith (2517230) * integer overflows in TransFileName() [CVE-2013-1981 9/13] -2013-03-01 18:37:37 -0800 Alan Coopersmith (8468165ae) +2013-03-01 18:37:37 -0800 Alan Coopersmith (8468165) * integer truncation in _XimParseStringFile() [CVE-2013-1981 8/13] -2013-03-01 18:37:37 -0800 Alan Coopersmith (00d7a2e5b) +2013-03-01 18:37:37 -0800 Alan Coopersmith (00d7a2e) * integer overflow in ReadInFile() in Xrm.c [CVE-2013-1981 7/13] -2013-03-02 11:44:19 -0800 Alan Coopersmith (0349af114) +2013-03-02 11:44:19 -0800 Alan Coopersmith (0349af1) * Integer overflows in stringSectionSize() cause buffer overflow in ReadColornameDB() [CVE-2013-1981 6/13] -2013-03-01 22:49:01 -0800 Alan Coopersmith (8673bf071) +2013-03-01 22:49:01 -0800 Alan Coopersmith (8673bf0) * integer overflow in XListHosts() [CVE-2013-1981 5/13] -2013-03-01 22:49:01 -0800 Alan Coopersmith (7d18bbe93) +2013-03-01 22:49:01 -0800 Alan Coopersmith (7d18bbe) * integer overflow in XGetMotionEvents() [CVE-2013-1981 4/13] -2013-03-01 22:49:01 -0800 Alan Coopersmith (29779559c) +2013-03-01 22:49:01 -0800 Alan Coopersmith (2977955) * integer overflow in XListFontsWithInfo() [CVE-2013-1981 3/13] -2013-03-01 21:05:27 -0800 Alan Coopersmith (dda0c652f) +2013-03-01 21:05:27 -0800 Alan Coopersmith (dda0c65) * integer overflow in _XF86BigfontQueryFont() [CVE-2013-1981 2/13] -2013-03-01 21:05:27 -0800 Alan Coopersmith (de2d3cb6b) +2013-03-01 21:05:27 -0800 Alan Coopersmith (de2d3cb) * integer overflow in _XQueryFont() on 32-bit platforms [CVE-2013-1981 1/13] -2013-01-22 10:03:00 -0500 Nickolai Zeldovich (e8ada07fa) +2013-01-22 10:03:00 -0500 Nickolai Zeldovich (e8ada07) * XListFontsWithInfo: avoid accessing realloc'ed memory -2011-02-11 14:20:24 -0800 Alan Coopersmith (290f94aea) +2011-02-11 14:20:24 -0800 Alan Coopersmith (290f94a) * ximcp: Prevent memory leak & double free if multiple %L in string -2011-01-31 14:02:06 +0200 Erkki Seppälä (936154728) +2011-01-31 14:02:06 +0200 Erkki Seppälä (9361547) * Xrm: Handle the extremely unlikely situation of fstat failing -2016-10-12 08:32:04 +0200 Mike Gabriel (051d521f6) +2016-10-12 08:32:04 +0200 Mike Gabriel (051d521) * Merge branch 'uli42-pr/upgrade_libX11' into 3.6.x -2016-10-09 17:49:20 +0200 Ulrich Sibiller (b8de7bf65) +2016-10-09 17:49:20 +0200 Ulrich Sibiller (b8de7bf) * Use both __APPLE__ and __DARWIN__ defines -2015-04-15 10:16:18 +0200 Karl Tomlinson (01865335b) +2015-04-15 10:16:18 +0200 Karl Tomlinson (0186533) * MakeBigReq: don't move the last word, already handled by Data32 (X.Org CVE-2013-7439). -2013-04-19 14:30:40 -0700 Alan Coopersmith (670b8ef64) +2013-04-19 14:30:40 -0700 Alan Coopersmith (670b8ef) * Give GNU & Solaris Studio compilers hints about XEatData branches -2011-12-13 19:58:30 -0800 Alan Coopersmith (6165dafda) +2011-12-13 19:58:30 -0800 Alan Coopersmith (6165daf) * makekeys: move buf declaration from global to main to silence gcc -Wshadow -2011-09-22 18:44:13 -0400 Derek Buitenhuis (62e5b0ff8) +2011-09-22 18:44:13 -0400 Derek Buitenhuis (62e5b0f) * makekeys: Fix build/target word size mismatch when cross-compiling -2016-08-27 03:24:22 +0200 Ulrich Sibiller (0bcb4bba2) +2016-08-27 03:24:22 +0200 Ulrich Sibiller (0bcb4bb) * adapt Imakefile to call makekeys correctly after update -2010-06-15 18:48:48 +0100 Daniel Stone (c98265ab4) +2010-06-15 18:48:48 +0100 Daniel Stone (c98265a) * makekeys: Scan vendor keysyms as well as core -2009-03-17 15:42:19 -0700 Alan Coopersmith (70327993a) +2009-03-17 15:42:19 -0700 Alan Coopersmith (7032799) * When makekeys fails to find a good hash, print error instead of divide-by-zero -2008-10-25 09:13:08 -0400 James Cloos (f57365400) +2008-10-25 09:13:08 -0400 James Cloos (f573654) * Increase size of working arrays in the makekeys utility program. -2016-08-27 02:24:46 +0200 Ulrich Sibiller (9a3096a2a) +2016-08-27 02:24:46 +0200 Ulrich Sibiller (9a3096a) * Update keysym includes -2016-08-27 02:13:27 +0200 Ulrich Sibiller (1baa27d09) +2016-08-27 02:13:27 +0200 Ulrich Sibiller (1baa27d) * update files from modules dir of libX11 1.3.4 -2016-08-27 02:13:02 +0200 Ulrich Sibiller (da3e7fd28) +2016-08-27 02:13:02 +0200 Ulrich Sibiller (da3e7fd) * Xutil.h: Fix wrong include path -2016-08-27 01:44:41 +0200 Ulrich Sibiller (d3ae0b2c9) +2016-08-27 01:44:41 +0200 Ulrich Sibiller (d3ae0b2) * replace {x11,xim}trans.c links by libX11 1.3.4 solution -2016-08-27 01:22:46 +0200 Ulrich Sibiller (385dc2b07) +2016-08-27 01:22:46 +0200 Ulrich Sibiller (385dc2b) * update xlibi18n files to libX11 1.3.4 -2016-08-27 01:00:43 +0200 Ulrich Sibiller (e868fbbfd) +2016-08-27 01:00:43 +0200 Ulrich Sibiller (e868fbb) * update xcms files to libX11 1.3.4 -2016-08-27 00:37:53 +0200 Ulrich Sibiller (274929053) +2016-08-27 00:37:53 +0200 Ulrich Sibiller (2749290) * Update some missing files to libX11 1.3.4 -2016-08-27 00:31:05 +0200 Ulrich Sibiller (8a5f30fb1) +2016-08-27 00:31:05 +0200 Ulrich Sibiller (8a5f30f) * Add (Free|Get)EventData.c from libX11 1.3.4 -2016-08-27 00:16:07 +0200 Ulrich Sibiller (efa70b0cf) +2016-08-27 00:16:07 +0200 Ulrich Sibiller (efa70b0) * remove more NEED_REPLIES/EVENTS -2016-08-27 00:24:37 +0200 Ulrich Sibiller (0079db696) +2016-08-27 00:24:37 +0200 Ulrich Sibiller (0079db6) * Purge more remaining VCS refs -2016-08-27 00:04:03 +0200 Ulrich Sibiller (af1f7cee0) +2016-08-27 00:04:03 +0200 Ulrich Sibiller (af1f7ce) * Lift XKB*.c to libX11 1.3.4 -2016-08-25 21:43:53 +0200 Ulrich Sibiller (3e75c816d) +2016-08-25 21:43:53 +0200 Ulrich Sibiller (3e75c81) * XlibInt.c: shorten one ifdef -2016-08-24 16:52:58 +0200 Ulrich Sibiller (a497ebf88) +2016-08-24 16:52:58 +0200 Ulrich Sibiller (a497ebf) * update X.h and Xproto.h because of GenericEvent -2016-08-03 19:19:58 +0200 Ulrich Sibiller (22652155f) +2016-08-03 19:19:58 +0200 Ulrich Sibiller (2265215) * set USE_XCB define to 0 to prevent compiler complaints -2016-08-02 01:06:35 +0200 Ulrich Sibiller (e51b961a7) +2016-08-02 01:06:35 +0200 Ulrich Sibiller (e51b961) * Remove CRAY support -2016-08-02 01:23:54 +0200 Ulrich Sibiller (35270a3d9) +2016-08-02 01:23:54 +0200 Ulrich Sibiller (35270a3) * adapt include files to libX11 1.3.4 -2016-08-02 00:51:13 +0200 Ulrich Sibiller (7b0bdde5c) +2016-08-02 00:51:13 +0200 Ulrich Sibiller (7b0bdde) * update makekeys.c to libX11 1.3.4 (+ fix) -2016-08-01 23:54:34 +0200 Ulrich Sibiller (b4571a8ff) +2016-08-01 23:54:34 +0200 Ulrich Sibiller (b4571a8) * update lcUniConv subdir to libX11 1.3.4 -2016-07-29 00:44:38 +0200 Ulrich Sibiller (687d44b6e) +2016-07-29 00:44:38 +0200 Ulrich Sibiller (687d44b) * update src files *[ch] to libX11 1.3.4 -2016-07-26 23:19:36 +0200 Ulrich Sibiller (ea24f0b0e) +2016-07-26 23:19:36 +0200 Ulrich Sibiller (ea24f0b) * add XLOCALELIBDIR -2016-07-26 23:18:33 +0200 Ulrich Sibiller (ef5565f8e) +2016-07-26 23:18:33 +0200 Ulrich Sibiller (ef5565f) * improve header guards -2016-07-26 00:34:34 +0200 Ulrich Sibiller (593073142) +2016-07-26 00:34:34 +0200 Ulrich Sibiller (5930731) * update all files with NX relevant changes to libX11 1.3.4 -2016-08-24 16:41:42 +0200 Ulrich Sibiller (a053df0a7) +2016-08-24 16:41:42 +0200 Ulrich Sibiller (a053df0) * fix wrong include in XlibInt.c -2016-10-08 21:31:17 +0200 Mike Gabriel (6dce607ba) +2016-10-08 21:31:17 +0200 Mike Gabriel (6dce607) * Merge branch 'uli42-pr/decouple-xserver' into 3.6.x -2016-10-08 00:40:36 +0200 Ulrich Sibiller (b0622729a) +2016-10-08 00:40:36 +0200 Ulrich Sibiller (b062272) * xserver: add missing xkbfile.h -2016-10-07 13:12:39 +0200 Vadim Troshchinskiyddd (f55852c2e) +2016-10-07 13:12:39 +0200 Vadim Troshchinskiyddd (f55852c) * Fix nxproxy hostname parsing. -2016-10-07 13:58:57 +0200 Vadim Troshchinskiy (85f5fdfd2) +2016-10-07 13:58:57 +0200 Vadim Troshchinskiy (85f5fdf) * Check if unixPath is NULL before accessing it; this fixes crashing of nxagent when TEST is enabled. -2016-10-07 21:38:18 +0200 Mike Gabriel (3039a34cb) +2016-10-07 21:38:18 +0200 Mike Gabriel (3039a34) * Merge branch 'uli42-pr/decouple-xserver' into 3.6.x -2016-10-04 21:24:56 +0200 Ulrich Sibiller (736a2333e) +2016-10-04 21:24:56 +0200 Ulrich Sibiller (736a233) * xserver: adapt xkbsrc includes syntax to match upstream -2015-02-17 14:40:27 +1000 Dave Airlie (a2a7482f2) +2015-02-17 14:40:27 +1000 Dave Airlie (a2a7482) * os/access: fix regression in server interpreted auth -2014-10-22 14:24:55 -0700 Keith Packard (a11629656) +2014-10-22 14:24:55 -0700 Keith Packard (a116296) * os: Eliminate uninitialized value warnings from access.c -2014-12-09 09:31:00 -0800 Keith Packard (057cdafdc) +2014-12-09 09:31:00 -0800 Keith Packard (057cdaf) * dix: GetHosts bounds check using wrong pointer value [CVE-2014-8092 pt. 6] -2008-06-13 21:59:09 -0400 Eamon Walsh (da5da2091) +2008-06-13 21:59:09 -0400 Eamon Walsh (da5da20) * Fix multiple warnings in os/xdmauth.c. -2016-09-26 23:00:04 +0200 Ulrich Sibiller (b60f66bb9) +2016-09-26 23:00:04 +0200 Ulrich Sibiller (b60f66b) * replace transport.c link by xstrans.c -2016-09-26 22:20:45 +0200 Ulrich Sibiller (2a5364d5f) +2016-09-26 22:20:45 +0200 Ulrich Sibiller (2a5364d) * xserver: drop XKBSRV_NEED_FILE_FUNCS -2016-09-26 21:32:05 +0200 Ulrich Sibiller (7c5d836c2) +2016-09-26 21:32:05 +0200 Ulrich Sibiller (7c5d836) * xserver: remove define XKB_IN_SERVER -2016-09-26 21:12:23 +0200 Ulrich Sibiller (2fdb1add0) +2016-09-26 21:12:23 +0200 Ulrich Sibiller (2fdb1ad) * xserver: use own copy of XKBgeom.h header -2016-09-26 21:09:36 +0200 Ulrich Sibiller (2c31ce2f2) +2016-09-26 21:09:36 +0200 Ulrich Sibiller (2c31ce2) * xserver: use own copy of XKBrules.h header -2016-09-26 21:05:32 +0200 Ulrich Sibiller (e60184393) +2016-09-26 21:05:32 +0200 Ulrich Sibiller (e601843) * xserver: use own copy of XKBrules.h header -2016-09-26 21:03:02 +0200 Ulrich Sibiller (3b8819087) +2016-09-26 21:03:02 +0200 Ulrich Sibiller (3b88190) * xserver: use own copy of XKBstr.h header -2016-09-26 20:43:23 +0200 Ulrich Sibiller (3739a9b30) +2016-09-26 20:43:23 +0200 Ulrich Sibiller (3739a9b) * xserver: use own copy of XKBsrv.h header -2016-09-21 20:54:53 +0200 Ulrich Sibiller (f0c0ff41b) +2016-09-21 20:54:53 +0200 Ulrich Sibiller (f0c0ff4) * copy files from libX11 to xserver dir -2016-10-06 13:04:25 +0200 Mike Gabriel (168c063dc) +2016-10-06 13:04:25 +0200 Mike Gabriel (168c063) * run-nxproxy2nxagent-over-network: Improve comment that describes script usage. Fix commented-out NX_HOST assignment. -2016-10-06 12:59:52 +0200 Mike Gabriel (834f13fa1) +2016-10-06 12:59:52 +0200 Mike Gabriel (834f13f) * testscripts: Rename run-nxagent and run-nxagent-over-sockets. -2016-10-06 12:59:25 +0200 Mike Gabriel (cd0da096a) +2016-10-06 12:59:25 +0200 Mike Gabriel (cd0da09) * run-nxproxy2nxagent-over-network: New test script that tests nxproxy/nxagent connectivity between networked hosts. -2016-10-01 20:22:18 +0200 Mike Gabriel (3e59f165f) +2016-10-01 20:22:18 +0200 Mike Gabriel (3e59f16) * Merge branch 'sunweaver-pr/update-X11s-XKeysymDB' into 3.6.x -2011-03-22 11:28:56 +1000 Peter Hutterer (5dcf0d573) +2011-03-22 11:28:56 +1000 Peter Hutterer (5dcf0d5) * Add XF86TouchpadOn and XF86TouchpadOff to keysymdb (gh-sunweaver/pr/update-X11s-XKeysymDB) -2016-08-25 00:52:51 +0200 Mike Gabriel (34cb7b558) +2016-08-25 00:52:51 +0200 Mike Gabriel (34cb7b5) * lib/X11/XKeysymDB: Update to last version found in X.org (between 1.3.5 and 1.3.6). -2016-10-01 20:20:18 +0200 Mike Gabriel (5d52d21bc) +2016-10-01 20:20:18 +0200 Mike Gabriel (5d52d21) * Merge branch 'sunweaver-pr/use-gccmakedep' into 3.6.x -2016-10-01 12:04:54 +0200 Mike Gabriel (b1603713e) +2016-10-01 12:04:54 +0200 Mike Gabriel (b160371) * Imake.tmpl: Use gccmakedep instead of makedepend. (gh-sunweaver/pr/use-gccmakedep) -2016-10-01 20:16:39 +0200 Mike Gabriel (e3ea74823) +2016-10-01 20:16:39 +0200 Mike Gabriel (e3ea748) * Merge branch 'sunweaver-pr/fix-protoheader-mess' into 3.6.x -2016-10-01 11:28:50 +0200 Mike Gabriel (3698cf27b) +2016-10-01 11:28:50 +0200 Mike Gabriel (3698cf2) * include/extensions/damageproto.h: Use nx-X11's xfixesproto.h and damagewire.h instead of X.org's. - (gh-sunweaver/pr/fix-protoheader-mess, - pr/fix-protoheader-mess) + (gh-sunweaver/pr/fix-protoheader-mess) -2016-10-01 11:25:29 +0200 Mike Gabriel (9acfa3b28) +2016-10-01 11:25:29 +0200 Mike Gabriel (9acfa3b) * randrproto: It was discovered that nx-libs shipped two different version of randr.h and randrproto.h. This commit leaves the newer file versions in the package and let's the build process use those everywhere. -2016-10-01 11:00:01 +0200 Mike Gabriel (f4f0b4490) +2016-10-01 11:00:01 +0200 Mike Gabriel (f4f0b44) * nx-X11: Enable -Wpedantic as default CFLAG. This is to detect redefined typedefs when building nxagent. -2016-10-01 10:53:37 +0200 Mike Gabriel (b50b0af97) +2016-10-01 10:53:37 +0200 Mike Gabriel (b50b0af) * hw/nxagent/X11/include/Xrandr_nxagent.h: Reduce injected libXrandr(_nxagent) header file, so that it only contains the XRRScreenChangeNotifyEvent typedef. -2016-09-29 20:58:15 +0200 Ulrich Sibiller (485805235) +2016-09-29 20:58:15 +0200 Ulrich Sibiller (4858052) * nx-libs.spec: Fix warning because of double reference to nxproxy.1.gz. -2016-09-29 20:28:59 +0200 Ulrich Sibiller (ce31b9c97) +2016-09-29 20:28:59 +0200 Ulrich Sibiller (ce31b9c) * Fix FTBFS with gcc 4.4 -2016-10-01 10:29:48 +0200 Mike Gabriel (a788c6856) +2016-10-01 10:29:48 +0200 Mike Gabriel (a788c68) * Makefile: Adapt install target to the new situation where we fake X11 headers in .build-export. This fixes FTBFS during file installation into .deb and .rpm packages. -2016-09-29 08:40:05 -0400 Mike DePaulo (5c2a8cdc9) +2016-09-29 08:40:05 -0400 Mike DePaulo (5c2a8cd) * Merge pull request #203 from mikedep333/issue-202 -2016-09-25 08:28:29 -0400 Mike DePaulo (cf435b3bc) +2016-09-25 08:28:29 -0400 Mike DePaulo (cf435b3) * nx-libs.spec: Add BuildRequires: imake -2016-09-24 23:59:02 +0200 Mike Gabriel (049bf681e) +2016-09-24 23:59:02 +0200 Mike Gabriel (049bf68) * Merge branch 'uli42-pr/improve_include_path_handling' into 3.6.x -2016-09-24 23:44:09 +0200 Ulrich Sibiller (97a5cec70) +2016-09-24 23:44:09 +0200 Ulrich Sibiller (97a5cec) * Revert "Fix wrong include" -2016-09-24 23:43:01 +0200 Ulrich Sibiller (c061022a9) +2016-09-24 23:43:01 +0200 Ulrich Sibiller (c061022) * whitespace cleanup -2016-09-24 23:41:55 +0200 Ulrich Sibiller (35e8c02d9) +2016-09-24 23:41:55 +0200 Ulrich Sibiller (35e8c02) * ensure that headers references use nx-X11 files if existing -2016-09-22 08:41:24 +0200 Mike Gabriel (a906bf0f2) +2016-09-22 08:41:24 +0200 Mike Gabriel (a906bf0) * Merge branch 'uli42-remove-misc' into 3.6.x -2016-09-21 18:37:10 +0200 Ulrich Sibiller (09d5e073a) +2016-09-21 18:37:10 +0200 Ulrich Sibiller (09d5e07) * remove misc dir -2016-09-21 18:28:22 +0200 Ulrich Sibiller (8d4d2bc20) +2016-09-21 18:28:22 +0200 Ulrich Sibiller (8d4d2bc) * move xkblib to xserver -2016-09-13 15:45:03 +0200 Mike Gabriel (43f135be0) +2016-09-13 15:45:03 +0200 Mike Gabriel (43f135b) * release 3.5.99.1 (tag: 3.5.99.1) -2016-08-26 12:49:28 +0200 Mike Gabriel (60e88a0b1) +2016-08-26 12:49:28 +0200 Mike Gabriel (60e88a0) * nxcomp/Loop.cpp: We have PrintVersionInfo(), why not use it? Use endl instead of \n for EOLs when streaming application's preamble to stderr. -2016-08-26 12:40:49 +0200 Mike Gabriel (01ebcfa35) +2016-08-26 12:40:49 +0200 Mike Gabriel (01ebcfa) * nxcomp/Loop.cpp: Mention DXPC copyright holders on application (i.e. nxproxy) start-up. -2016-08-24 16:29:46 +0200 Mike Gabriel (efa309add) +2016-08-24 16:29:46 +0200 Mike Gabriel (efa309a) * nxcomp/Loop.cpp: We have GetCopyrightInfo() in Misc.cpp, so why not use it? Also: point to ArcticaProject/nx-libs namespace on Github for further information. -2016-08-24 16:17:24 +0200 Mike Gabriel (3520015b4) +2016-08-24 16:17:24 +0200 Mike Gabriel (3520015) * hw/nxagent/Init.c: Fix copy+paste flaw when re-arranging copyright information as display by nxagent. -2016-08-24 16:13:52 +0200 Mike Gabriel (e2011608f) +2016-08-24 16:13:52 +0200 Mike Gabriel (e201160) * nxcomp/Misc.cpp: Display new list of copyright holders when launching nxproxy / nxagent. -2016-08-24 16:11:04 +0200 Mike Gabriel (8fc2e80bc) +2016-08-24 16:11:04 +0200 Mike Gabriel (8fc2e80) * nxcomp/*.c: Update copyright headers, use new list of copyright holders like for the .cpp files. -2016-08-24 16:08:41 +0200 Mike Gabriel (ed5d920f6) +2016-08-24 16:08:41 +0200 Mike Gabriel (ed5d920) * nxcomp/Loop.cpp: Refer to Github namespace of Arctica Project as location to search for software updates. -2016-08-24 15:59:36 +0200 Mike Gabriel (0ea971b9e) +2016-08-24 15:59:36 +0200 Mike Gabriel (0ea971b) * Merge branch 'uli42-fix_x2go_952' into 3.6.x -2016-08-21 13:12:23 +0200 Ulrich Sibiller (2d450e383) +2016-08-21 13:12:23 +0200 Ulrich Sibiller (2d450e3) * Fix pasting the clipboard directly after session start. -2016-07-28 13:21:29 +0200 Mike Gabriel (46fef3150) +2016-07-28 13:21:29 +0200 Mike Gabriel (46fef31) * nxagent.1 man page: Some layout fixes for string options with well-defined expected selections of values. -2016-07-28 13:20:38 +0200 Mike Gabriel (e9a3734ae) +2016-07-28 13:20:38 +0200 Mike Gabriel (e9a3734) * hw/nxagent/Display.c: Fix comment where the meaning of the "bypass" reconnectchecks parameter value is explained. -2016-07-28 12:59:37 +0200 Mike Gabriel (bff330577) +2016-07-28 12:59:37 +0200 Mike Gabriel (bff3305) * nxagent.1 man page: Add explanation about the new reconnectchecks nx/nx option. -2016-07-28 12:16:23 +0200 Mike Gabriel (aadf3175c) +2016-07-28 12:16:23 +0200 Mike Gabriel (aadf317) * hw/nxagent/Args.c: Follow-up fix for PR #183: expect reconnectchecks=bypass instead of =none. -2016-07-28 12:14:22 +0200 Mike Gabriel (443b52723) +2016-07-28 12:14:22 +0200 Mike Gabriel (443b527) * Merge branch 'Ionic-feature/reconnect-checks' into 3.6.x -2016-07-03 23:52:43 +0000 Mihai Moldovan (64a83d1e0) +2016-07-03 23:52:43 +0000 Mihai Moldovan (64a83d1) * nx-X11/programs/Xserver/hw/nxagent/Display.c: add FIXME comment to nxagentCheckForColormapsCompatibility(). - (Ionic-feature/reconnect-checks) + (gh-Ionic/feature/reconnect-checks) -2016-07-03 23:52:06 +0000 Mihai Moldovan (5ec7e48ac) +2016-07-03 23:52:06 +0000 Mihai Moldovan (5ec7e48) * nx-X11/programs/Xserver/hw/nxagent/Display.c: add FIXME comment to nxagentInitAndCheckVisuals(). -2016-07-09 03:28:27 +0000 Mihai Moldovan (e61c8c85c) +2016-07-09 03:28:27 +0000 Mihai Moldovan (e61c8c8) * nx-X11/programs/Xserver/hw/nxagent/Display.c: split up nxagentCheckForPixmapFormatsCompatibility() and nxagentInitPixmapFormats(). -2016-06-29 02:13:03 +0000 Mihai Moldovan (661827149) +2016-06-29 02:13:03 +0000 Mihai Moldovan (6618271) * nx-X11/programs/Xserver/hw/nxagent/Display.c: use new ReconnectTolerance nxagentOption value in nxagentCheckForPixmapFormatsCompatibility() and modify behavior based on this value. -2016-06-28 23:54:17 +0000 Mihai Moldovan (bb9b50bfc) +2016-06-28 23:54:17 +0000 Mihai Moldovan (bb9b50b) * nx-X11/programs/Xserver/hw/nxagent/Display.c: use new ReconnectTolerance nxagentOption value in nxagentCheckForDepthsCompatibility() and modify behavior based on this value. -2016-06-28 23:51:14 +0000 Mihai Moldovan (6effea543) +2016-06-28 23:51:14 +0000 Mihai Moldovan (6effea5) * nx-X11/programs/Xserver/hw/nxagent/Display.c: use new ReconnectTolerance nxagentOption in nxagentCheckForDefaultDepthCompatibility() and modify behavior based on this value. -2016-07-02 21:49:10 +0000 Mihai Moldovan (29be5cc07) +2016-07-02 21:49:10 +0000 Mihai Moldovan (29be5cc) * {nx-X11/programs/Xserver/hw/nxagent/{Args.c,Options.{c,h}},nxcomp/{Loop,Misc}.cpp}: add tolerancechecks parameter as an nx/nx option and ReconnectTolerance as an nxagentOption. -2016-07-27 13:05:27 +0200 Mike Gabriel (e1c85caac) +2016-07-27 13:05:27 +0200 Mike Gabriel (e1c85ca) * Merge branch 'uli42-3.6.x' into 3.6.x -2016-07-26 23:25:26 +0200 Ulrich Sibiller (9a4bb50af) +2016-07-26 23:25:26 +0200 Ulrich Sibiller (9a4bb50) * Fix wrong include -2016-07-06 10:38:25 +0200 Mike Gabriel (470611e02) +2016-07-06 10:38:25 +0200 Mike Gabriel (470611e) - * release 3.5.99.0 (tag: 3.5.99.0) + * release 3.5.99.0 (tag: 3.5.99.0, gh-Ionic/3.6.x) -2016-07-06 10:02:37 +0200 Mike Gabriel (961fa2a0e) +2016-07-06 10:02:37 +0200 Mike Gabriel (961fa2a) * README.md: Add build howto for openSUSE based RPMs. -2016-07-06 10:02:16 +0200 Mike Gabriel (b41369f27) +2016-07-06 10:02:16 +0200 Mike Gabriel (b41369f) * README.md: Status update of listed 3.6.x features. -2016-07-06 08:29:38 +0200 Mike Gabriel (98922f7b1) +2016-07-06 08:29:38 +0200 Mike Gabriel (98922f7) * make-changelog.sh: Ship simple script for updating the upstream ChangeLog file from Git history. -2016-07-06 01:14:56 +0200 Mike Gabriel (9b50e0088) +2016-07-06 01:14:56 +0200 Mike Gabriel (9b50e00) * Merge branch 'sunweaver-pr/update-license-files' into 3.6.x -2016-07-05 16:32:57 +0200 Mike Gabriel (6144b615d) +2016-07-05 16:32:57 +0200 Mike Gabriel (6144b61) * VCS info lines: Remove ancient X.org / XFree86 VCS info line from - code files. + code files. (gh-sunweaver/pr/update-license-files) -2016-07-05 16:22:51 +0200 Mike Gabriel (51c3d42f3) +2016-07-05 16:22:51 +0200 Mike Gabriel (51c3d42) * Per-file copyright notices: Update copyright information in file headers that NoMachine placed there own copyright statement in. -2016-07-05 13:44:32 +0200 Mike Gabriel (3c79d5cf4) +2016-07-05 13:44:32 +0200 Mike Gabriel (3c79d5c) * LICENSE files: Update copyright holders, FSF address and various other minor things. -2016-07-06 00:40:36 +0200 Mike Gabriel (5cbc93678) +2016-07-06 00:40:36 +0200 Mike Gabriel (5cbc936) * nxproxy.1 man page: Another rendering flaw fixed. -2016-07-06 00:25:06 +0200 Mike Gabriel (8ec78a0c3) +2016-07-06 00:25:06 +0200 Mike Gabriel (8ec78a0) * debian/*.doc-base: Add .doc-base files for bin:packages containing documentation. -2016-07-06 00:07:11 +0200 Ulrich Sibiller (196d38f96) +2016-07-06 00:07:11 +0200 Ulrich Sibiller (196d38f) * Xserver/dix/events.c: Drop unused i variable from TryClientEvents. -2016-07-06 00:04:05 +0200 Mike Gabriel (0369bf5e9) +2016-07-06 00:04:05 +0200 Mike Gabriel (0369bf5) * nxproxy.1 man page: Fix a typo + a rendering error. Detected by lintian. -2016-07-05 23:47:49 +0200 Mike Gabriel (67f937c4a) +2016-07-05 23:47:49 +0200 Mike Gabriel (67f937c) * debian/rules: Enable -fPIE / -pie hardening support for nxagent and nxproxy. -2016-07-05 22:56:01 +0200 Ulrich Sibiller (d7655e15a) +2016-07-05 22:56:01 +0200 Ulrich Sibiller (d7655e1) * Merge pull request #180 from uli42/pr/remove_need_events_replies -2016-07-04 21:11:21 +0200 Ulrich Sibiller (fa6519947) +2016-07-04 21:11:21 +0200 Ulrich Sibiller (fa65199) * remove unreferenced NEED_EVENTS/NEED_REPLIES -2016-07-05 22:23:27 +0200 Mike Gabriel (ff0d46e0b) +2016-07-05 22:23:27 +0200 Mike Gabriel (ff0d46e) * bin/nxauth: Remove deprecated wrapper script "nxauth". -2016-07-05 22:18:40 +0200 Mike Gabriel (f397f3a42) +2016-07-05 22:18:40 +0200 Mike Gabriel (f397f3a) * debian/nxagent.docs: whitespace only -2016-07-05 22:17:51 +0200 Mike Gabriel (754d33d81) +2016-07-05 22:17:51 +0200 Mike Gabriel (754d33d) * README.keystrokes: Move from base folder to doc/nxagent/. -2016-07-05 21:58:42 +0200 Mike Gabriel (a39c5c155) +2016-07-05 21:58:42 +0200 Mike Gabriel (a39c5c1) * nx-libs.spec: Adapt RPM packaging to doc files having been moved around. -2016-07-05 21:57:45 +0200 Mike Gabriel (cd9a6b9dd) +2016-07-05 21:57:45 +0200 Mike Gabriel (cd9a6b9) * debian/libxcomp3.docs: Install libxcomp3 documentation files into bin:package. -2016-07-05 21:48:27 +0200 Mike Gabriel (3ec3f6162) +2016-07-05 21:48:27 +0200 Mike Gabriel (3ec3f61) * debian/nxproxy.docs: Fix FTBFS due to missing documentation files (moved out of the way with recent commits). -2016-07-05 21:47:28 +0200 Mike Gabriel (2555bd5ac) +2016-07-05 21:47:28 +0200 Mike Gabriel (2555bd5) * documentation: Move README-VALGRIND out of doc/_attic_/ folder to doc/nxproxy/. -2016-07-05 13:34:26 +0200 Mike Gabriel (381706aa2) +2016-07-05 13:34:26 +0200 Mike Gabriel (381706a) * Merge branch 'sunweaver-pr/no-more-type-casting-in-writetoclient' into 3.6.x -2016-07-04 00:28:47 +0200 Alan Coopersmith (f6a1bda2d) +2016-07-04 00:28:47 +0200 Alan Coopersmith (f6a1bda) * Remove unneccesary casts from WriteToClient calls + (gh-sunweaver/pr/no-more-type-casting-in-writetoclient) -2016-07-04 00:21:45 +0200 Kristian Høgsberg (ff81a5269) +2016-07-04 00:21:45 +0200 Kristian Høgsberg (ff81a52) * Make WriteToClient take a const void * like any decent IO write function. -2016-07-05 13:25:48 +0200 Mike Gabriel (06a97857a) +2016-07-05 13:25:48 +0200 Mike Gabriel (06a9785) * nxcomp/Misc.cpp: The clipboard nx/nx option is a string option, not int. -2016-07-05 13:25:17 +0200 Mike Gabriel (7e18fdf6e) +2016-07-05 13:25:17 +0200 Mike Gabriel (7e18fdf) * Xserver.man: Drop original and old Xserver man page. Relevant parts have now been added to nxagent.1 man page. -2016-07-05 13:24:16 +0200 Mike Gabriel (ebb2026a7) +2016-07-05 13:24:16 +0200 Mike Gabriel (ebb2026) * man pages: Greatly improve man pages nxagent.1 and nxproxy.1. -2016-07-05 10:47:55 +0200 Mike Gabriel (ee0282207) +2016-07-05 10:47:55 +0200 Mike Gabriel (ee02822) * File permission fixes: No executable bit on Imakefile files, *.c and *.h files. -2016-07-05 10:41:55 +0200 Mike Gabriel (5214930a1) +2016-07-05 10:41:55 +0200 Mike Gabriel (5214930) * X2Go remnants: Drop x2goagent.1 man page. Shipped in X2Go Server sources nowadays. -2016-07-05 10:41:24 +0200 Mike Gabriel (40179398d) +2016-07-05 10:41:24 +0200 Mike Gabriel (4017939) * nxcomp licensing: Move README.on-retroactive-DXPC-license to doc/nxcomp/ folder. -2016-07-05 10:40:11 +0200 Mike Gabriel (b38f01092) +2016-07-05 10:40:11 +0200 Mike Gabriel (b38f010) * NoMachine documentation files: Move to doc/_attic_/ folder. -2016-07-05 10:33:08 +0200 Mike Gabriel (d38ccd197) +2016-07-05 10:33:08 +0200 Mike Gabriel (d38ccd1) * LICENSE files: Have a main LICENSE file and one for nxcomp in the project's base folder. -2016-07-05 10:28:40 +0200 Mike Gabriel (cc4fdf6f0) +2016-07-05 10:28:40 +0200 Mike Gabriel (cc4fdf6) * X.org 6.9 documentation files: Move into doc/_attic_/. -2016-07-05 10:26:34 +0200 Mike Gabriel (4ad29435c) +2016-07-05 10:26:34 +0200 Mike Gabriel (4ad2943) * Drop multiple COPYING files contaning the GPL-2 license text. -2016-07-05 10:16:00 +0200 Mike Gabriel (d14cc5361) +2016-07-05 10:16:00 +0200 Mike Gabriel (d14cc53) * doc/_attic_/: Introduce an "_attic_" folder. Move diffs between NoMachine's nx-X11 3.5 and X.org 6.9 here. -2016-07-05 10:15:12 +0200 Mike Gabriel (74a52dd35) +2016-07-05 10:15:12 +0200 Mike Gabriel (74a52dd) * doc/ folder: Have one sub-folder per nx-libs component. -2016-07-05 10:11:19 +0200 Mike Gabriel (74edd6e73) +2016-07-05 10:11:19 +0200 Mike Gabriel (74edd6e) * test scripts: Move to top folder "testscripts/" in source tree. -2016-07-05 10:08:03 +0200 Mike Gabriel (aa4210715) +2016-07-05 10:08:03 +0200 Mike Gabriel (aa42107) * Merge branch 'sunweaver-pr/rpm-packaging-updates' into 3.6.x -2016-07-05 09:54:47 +0200 Mike Gabriel (058ae3e76) +2016-07-05 09:54:47 +0200 Mike Gabriel (058ae3e) * nx-libs.spec: Add Conflicts: fields for removed shared library - bin:packages. + bin:packages. (gh-sunweaver/pr/rpm-packaging-updates) -2016-07-04 16:34:38 +0200 Mike Gabriel (1910142cf) +2016-07-04 16:34:38 +0200 Mike Gabriel (1910142) * nx-libs.spec: Let libNX_X11-6 and libNX_X11-devel conflict with deprecated libXau6 and libXau-devel. -2016-07-04 16:31:18 +0200 Mike Gabriel (6dded30a7) +2016-07-04 16:31:18 +0200 Mike Gabriel (6dded30) * nx-libs.spec: Let nxagent conflict with nxauth, which is not provided anymore. -2016-07-04 16:27:34 +0200 Mike Gabriel (59eab0a82) +2016-07-04 16:27:34 +0200 Mike Gabriel (59eab0a) * nx-libs.spec: Add correct Obsoletes:/Provides: fields for lib* bin:packages. -2016-07-04 15:32:58 +0200 Mike Gabriel (5c65e9b40) +2016-07-04 15:32:58 +0200 Mike Gabriel (5c65e9b) * nx-libs.spec: Fix various issues since last testing the RPM builds of nx-libs: -2016-07-05 09:46:45 +0200 Mike Gabriel (a1a7b1aab) +2016-07-05 09:46:45 +0200 Mike Gabriel (a1a7b1a) * debian/control: Add some hard and exact-versioned dependencies for our bin:packages. Assure that no old share lib packages with the same set of symbols remain on the system when upgrading. -2016-07-05 09:10:28 +0200 Mike Gabriel (bf08b9960) +2016-07-05 09:10:28 +0200 Mike Gabriel (bf08b99) * Merge branch 'sunweaver-pr/writeeventstoclients-no-sequencenumber' into 3.6.x -2016-07-03 22:52:13 +0200 Jamey Sharp (cb0089bad) +2016-07-03 22:52:13 +0200 Jamey Sharp (cb0089b) * Set event sequence number in WriteEventsToClient instead of at callers. + (gh-sunweaver/pr/writeeventstoclients-no-sequencenumber) -2016-07-03 22:06:43 +0200 Jamey Sharp (9ea88717d) +2016-07-03 22:06:43 +0200 Jamey Sharp (9ea8871) * Make WriteEventsToClient/WriteToClient no-op on fake or dead clients. -2016-07-05 08:34:17 +0200 Mike Gabriel (320a8cc0c) +2016-07-05 08:34:17 +0200 Mike Gabriel (320a8cc) * Merge branch 'sunweaver-pr/silencing-compiler-warnings' into 3.6.x -2016-07-05 08:16:09 +0200 Tomas Carnecky (b15fc63f4) +2016-07-05 08:16:09 +0200 Tomas Carnecky (b15fc63) * Replace INITARGS with void + (gh-sunweaver/pr/silencing-compiler-warnings) -2016-06-29 15:07:16 +0200 Mike Gabriel (f0af82cbb) +2016-06-29 15:07:16 +0200 Mike Gabriel (f0af82c) * nx-X11/lib/X11/XKBMisc.c: Avoid warning about maybe non-assigned variables (mask, newMask). -2016-06-29 15:02:00 +0200 Daniel Stone (d60297e41) +2016-06-29 15:02:00 +0200 Daniel Stone (d60297e) * Remove INITARGS braindamage, change to void; add XkbExtensionInit prototype to xkb.h. Explicitly initialise nTypes in xkb.c. -2016-06-29 14:58:47 +0200 Keith Packard (ecaf4df7f) +2016-06-29 14:58:47 +0200 Keith Packard (ecaf4df) * Xserver/Xext/xres.c: Drop unused REQUEST macro call (for xXResQueryVersionReq). -2016-06-29 14:28:49 +0200 Mike Gabriel (894993501) +2016-06-29 14:28:49 +0200 Mike Gabriel (8949935) * Xserver: Post-REGION-macros-to-inline-funcs clean-up. -2016-06-29 14:17:53 +0200 Mike Gabriel (8df1a67b6) +2016-06-29 14:17:53 +0200 Mike Gabriel (8df1a67) * Xserver/mi/mizerarc.c: Initialize oddPtrs as NULL before using it (in miZeroPolyArc). -2016-06-29 14:14:15 +0200 Mike Gabriel (c08d0308d) +2016-06-29 14:14:15 +0200 Mike Gabriel (c08d030) * Xserver/mi/miarc.c: Initialize dashRemaining with 0 before using it. -2016-06-29 14:09:52 +0200 Mike Gabriel (a8fd16ce6) +2016-06-29 14:09:52 +0200 Mike Gabriel (a8fd16c) * Xserver/os/xdmauth.c: Avoid compiler warnings due to -Wswitch being enabled. Use if statement rather than switch. -2016-06-29 14:05:12 +0200 Mike Gabriel (141316af0) +2016-06-29 14:05:12 +0200 Mike Gabriel (141316a) * Xserver/os/log.c: Make sure strlcpy is defined in log.c. Immitate what is done in X.org. -2016-06-29 13:57:05 +0200 Adam Jackson (f46af7de8) +2016-06-29 13:57:05 +0200 Adam Jackson (f46af7d) * Restore compression of duplicate log file entries. -2016-06-29 13:45:20 +0200 Keith Packard (b5cceb740) +2016-06-29 13:45:20 +0200 Keith Packard (b5cceb7) * os: Make sure that writing our pid to the lock file actually worked -2016-06-29 13:35:06 +0200 Mike Gabriel (bad0e8bdd) +2016-06-29 13:35:06 +0200 Mike Gabriel (bad0e8b) * Xserver/os/connection.c: Drop unused variable 'restore_trans_conn' from ClientAuthorized(). -2016-06-29 13:33:51 +0200 Mike Gabriel (00ebfaf53) +2016-06-29 13:33:51 +0200 Mike Gabriel (00ebfaf) * Xserver/os/connection.c: Only define XSERV_t, TRANS_SERVER and TRANS_REOPEN if not yet defined. -2016-06-29 13:30:08 +0200 Mike Gabriel (b34b47ed5) +2016-06-29 13:30:08 +0200 Mike Gabriel (b34b47e) * nx-X11/lib/X11/imTrX.c: Fix warning ‘len’ may be used uninitialized in this function (_XimRead). -2016-06-29 13:28:23 +0200 Mike Gabriel (eddd4876b) +2016-06-29 13:28:23 +0200 Mike Gabriel (eddd487) * nx-X11/lib/X11/imInsClbk.c: Fix warning 'right-hand operand of comma expression has no effect' in _XimFilterPropertyNotify. -2016-06-29 13:24:38 +0200 Mike Gabriel (3569ac171) +2016-06-29 13:24:38 +0200 Mike Gabriel (3569ac1) * nx-X11/lib/X11/lcFile.c: Drop conditional always evaluating as True. -2016-06-29 13:20:30 +0200 Mike Gabriel (365fa4f3e) +2016-06-29 13:20:30 +0200 Mike Gabriel (365fa4f) * nx-X11/lib/X11/XKBMisc.c: Drop conditional always evaluating as True. -2016-06-29 13:17:04 +0200 Mike Gabriel (ed61433e1) +2016-06-29 13:17:04 +0200 Mike Gabriel (ed61433) * nx-X11/lib/X11/LiHosts.c: Drop unused variable (in XListHosts). -2016-06-29 13:10:08 +0200 Mike Gabriel (5e2e760d3) +2016-06-29 13:10:08 +0200 Mike Gabriel (5e2e760) * Avoid 'siAddr' maybe being used uninitialized in XAddHost and XRemoveHost. -2016-06-29 12:53:21 +0200 Mike Gabriel (35dbbd7e4) +2016-06-29 12:53:21 +0200 Mike Gabriel (35dbbd7) * hw/nxagent/Exrensions.c: Post-RandR 1.5 update fix. Properly set rrProvider hook functions to NULL. -2016-06-29 12:50:14 +0200 Mike Gabriel (e02bdf929) +2016-06-29 12:50:14 +0200 Mike Gabriel (e02bdf9) * hw/nxagent/Args.c: Fix fprintf placeholder (%u -> %lu). -2016-06-29 12:45:45 +0200 Adam Jackson (7e21611db) +2016-06-29 12:45:45 +0200 Adam Jackson (7e21611) * Remove fbpseudocolor -2016-06-29 12:37:22 +0200 Cyril Brulebois (3a54da8bc) +2016-06-29 12:37:22 +0200 Cyril Brulebois (3a54da8) * fb: Mark some variables as unused. -2016-06-29 12:38:31 +0200 Jeremy Huddleston (b91099b97) +2016-06-29 12:38:31 +0200 Jeremy Huddleston (b91099b) * Add _X_UNUSED attribute to designate unused variables and silence warnings -2016-06-29 12:18:52 +0200 Mike Gabriel (cef6d723c) +2016-06-29 12:18:52 +0200 Mike Gabriel (cef6d72) * Xserver/composite/compint.h: Disable debugging in Copmosite extension. -2016-06-29 12:07:26 +0200 Mike Gabriel (f364bacf8) +2016-06-29 12:07:26 +0200 Mike Gabriel (f364bac) * Xserver/xfixes/region.c: Don't declare and set PictureScreenPtr ps (in ProcXFixesSetPictureClipRegion). Variable is not used. -2016-07-05 08:09:24 +0200 Mike Gabriel (854f3fa49) +2016-07-05 08:09:24 +0200 Mike Gabriel (854f3fa) * Merge branch 'sunweaver-pr/proxy-to-proxy-over-unix-socket' into 3.6.x -2016-06-15 16:44:28 +0200 Mike Gabriel (5a22f2ec1) +2016-06-15 16:44:28 +0200 Mike Gabriel (5a22f2e) * test scripts: Add test scripts for testing Unix file socket support (i.e. proxy2proxy and proxy2agent sessions via Unix file sockets). + (gh-sunweaver/pr/proxy-to-proxy-over-unix-socket) -2016-06-15 10:29:12 +0200 Mike Gabriel (c6e956512) +2016-06-15 10:29:12 +0200 Mike Gabriel (c6e9565) * nxcomp/Loop.cpp: Add Unix file socket support for proxy <-> proxy connection. -2015-06-02 14:55:40 +0200 Salvador Fandino (b23dcd101) +2015-06-02 14:55:40 +0200 Salvador Fandino (b23dcd1) * merge code paths depending on acceptHost being "" -2015-06-02 15:35:50 +0200 Salvador Fandino (f706d774b) +2015-06-02 15:35:50 +0200 Salvador Fandino (f706d77) * remove now unused function ParseListenOption -2015-06-02 13:25:34 +0200 Salvador Fandino (c92a102ba) +2015-06-02 13:25:34 +0200 Salvador Fandino (c92a102) * rewrite WaitForRemote to build on top of ListenConnectionTCP -2015-06-02 12:54:15 +0200 Salvador Fandino (28736a888) +2015-06-02 12:54:15 +0200 Salvador Fandino (28736a8) * remove unused listenHost parameter -2015-06-02 12:34:20 +0200 Salvador Fandino (d6edd7c97) +2015-06-02 12:34:20 +0200 Salvador Fandino (d6edd7c) * Remove work around for OS/X that was doing nothing -2015-06-02 12:30:49 +0200 Salvador Fandino (d2e8551ef) +2015-06-02 12:30:49 +0200 Salvador Fandino (d2e8551) * Simplify ParseListenOption -2015-06-02 10:31:53 +0200 Salvador Fandino (5ea2d901b) +2015-06-02 10:31:53 +0200 Salvador Fandino (5ea2d90) * rewrite SetupUnixSocket to use ListenConnectionUnix -2015-06-01 17:52:33 +0200 Salvador Fandino (c5a2cf82f) +2015-06-01 17:52:33 +0200 Salvador Fandino (c5a2cf8) * Rework SetupTcpSocket to use ListenConnectionTCP -2016-07-04 22:55:23 +0200 Mike Gabriel (e0edae04d) +2016-07-04 22:55:23 +0200 Mike Gabriel (e0edae0) * Merge branch 'sunweaver-pr/xerrordb-from-xorg' into 3.6.x -2016-06-28 20:30:42 +0200 Mike Gabriel (1bd2463a2) +2016-06-28 20:30:42 +0200 Mike Gabriel (1bd2463) * libNX_X11 data files: Install libNX_X11 related data files. + (gh-sunweaver/pr/xerrordb-from-xorg) -2016-07-04 16:37:55 +0200 Mike Gabriel (27b0b5723) +2016-07-04 16:37:55 +0200 Mike Gabriel (27b0b57) * Merge branch 'sunweaver-pr/type-safe-swapping' into 3.6.x -2016-06-29 01:36:31 +0200 Mike Gabriel (286d83260) +2016-06-29 01:36:31 +0200 Mike Gabriel (286d832) * Use internal temp variable for swap macros. Make swaps/swapl type safe (introducing wrong_size check at build time). + (gh-sunweaver/pr/type-safe-swapping) -2016-06-15 16:46:10 +0200 Mike Gabriel (d1d859dfd) +2016-06-15 16:46:10 +0200 Mike Gabriel (d1d859d) * test scripts: Update copyright headers. -2016-06-15 16:42:25 +0200 Mike Gabriel (b767ca5c3) +2016-06-15 16:42:25 +0200 Mike Gabriel (b767ca5) * test scripts: Rename run-nxproxy2nxproxy-test -> run-nxproxy2nxproxy. -2016-07-02 14:11:38 +0200 Mike Gabriel (1dbd3c888) +2016-07-02 14:11:38 +0200 Mike Gabriel (1dbd3c8) * Merge branch 'sunweaver-pr/backport-Xorg-memory-handling' into 3.6.x -2016-06-27 12:53:03 +0200 Mike Gabriel (e85808245) +2016-06-27 12:53:03 +0200 Mike Gabriel (e858082) * debian/patches: Refresh patches after changes in upstream code. + (gh-sunweaver/pr/backport-Xorg-memory-handling) -2016-06-28 16:55:26 +0200 Mike Gabriel (40e398409) +2016-06-28 16:55:26 +0200 Mike Gabriel (40e3984) * nx-X11/include/extensions/XKBsrv.h: Different memory handling when built with Xserver and with Xlib. -2016-06-27 12:12:31 +0200 Mike Gabriel (f779b2e3c) +2016-06-27 12:12:31 +0200 Mike Gabriel (f779b2e) * os: Remove deprecated malloc/free wrappers, clean {X,XNF}{alloc,calloc,realloc,free,strdup} from pre-C89 baggage -2016-06-27 11:51:31 +0200 Mike Gabriel (ce40aec08) +2016-06-27 11:51:31 +0200 Mike Gabriel (ce40aec) * nx-X11/programs/Xserver: Drop {X,x}calloc() macros, use calloc() instead. -2016-06-26 02:08:32 +0200 Mike Gabriel (74a5450bc) +2016-06-26 02:08:32 +0200 Mike Gabriel (74a5450) * nx-X11/programs/Xserver: Drop {X,x}realloc() macros, use realloc() instead. -2016-06-26 01:51:18 +0200 Mike Gabriel (2646fc254) +2016-06-26 01:51:18 +0200 Mike Gabriel (2646fc2) * nx-X11/programs/Xserver: Drop {X,x}alloc() macros, use malloc() instead. -2016-06-26 01:38:22 +0200 Mike Gabriel (acf87144d) +2016-06-26 01:38:22 +0200 Mike Gabriel (acf8714) * nx-X11/programs/Xserver: Drop {X,x}free() macros, use free() instead. -2016-07-02 13:53:16 +0200 Mike Gabriel (279d37127) +2016-07-02 13:53:16 +0200 Mike Gabriel (279d371) * Merge branch 'sunweaver-pr/protocols-version-h' into 3.6.x -2016-06-28 12:07:10 +0200 Mike Gabriel (487870fff) +2016-06-28 12:07:10 +0200 Mike Gabriel (487870f) * Xserver/include/protocol-versions.h: Switch to having an Xserver-specific header file containing all use protocol - versions. + versions. (gh-sunweaver/pr/protocols-version-h) -2016-06-28 12:06:50 +0200 Mike Gabriel (a08e2323e) +2016-06-28 12:06:50 +0200 Mike Gabriel (a08e232) * Xserver Imakefiles: Make sure NXAGENT_SERVER is defined for all extensions. -2016-07-01 16:08:55 +0200 Mike Gabriel (dd5f5b56b) +2016-07-01 16:08:55 +0200 Mike Gabriel (dd5f5b5) * Merge branch 'sunweaver-pr/ld-loading-libX11-hack' into 3.6.x -2016-06-30 23:50:12 +0200 Mike Gabriel (5934d03ef) +2016-06-30 23:50:12 +0200 Mike Gabriel (5934d03) * Rework nxagent and nxproxy wrapper scripts. + (gh-sunweaver/pr/ld-loading-libX11-hack) -2016-07-01 16:00:04 +0200 Mike Gabriel (da7261cfe) +2016-07-01 16:00:04 +0200 Mike Gabriel (da7261c) * Merge branch 'uli42-pr/drop_libNX_Xext' into 3.6.x -2016-07-01 13:54:11 +0200 Ulrich Sibiller (1cd7e35cb) +2016-07-01 13:54:11 +0200 Ulrich Sibiller (1cd7e35) * finally drop libNX_Xext -2016-07-01 13:54:10 +0200 Ulrich Sibiller (e78c5bc3c) +2016-07-01 13:54:10 +0200 Ulrich Sibiller (e78c5bc) * remove shm code from libNX_Xext -2016-07-01 00:55:53 +0200 Ulrich Sibiller (232c7ad91) +2016-07-01 00:55:53 +0200 Ulrich Sibiller (232c7ad) * avoid conflicts when mixing own includes with upstream includes -2016-07-01 00:05:30 +0200 Ulrich Sibiller (e77e37ff0) +2016-07-01 00:05:30 +0200 Ulrich Sibiller (e77e37f) * remove XShape code from libNX_Xext -2016-07-01 15:48:55 +0200 Mike Gabriel (2f19f2f66) +2016-07-01 15:48:55 +0200 Mike Gabriel (2f19f2f) * Merge branch 'sunweaver-pr/libXau-cleanup' into 3.6.x -2016-06-23 10:46:48 +0200 Mike Gabriel (204545286) +2016-06-23 10:46:48 +0200 Mike Gabriel (2045452) * nxagent Xserver: Drop Kerberos code. Not used in nxagent. + (gh-sunweaver/pr/libXau-cleanup) -2016-06-23 10:31:42 +0200 Mike Gabriel (26bf48bab) +2016-06-23 10:31:42 +0200 Mike Gabriel (26bf48b) * library-cleanup: Don't build libNX_Xau anymore. Use system's libXau shared library. -2016-06-23 10:27:37 +0200 Mike Gabriel (b214c73b5) +2016-06-23 10:27:37 +0200 Mike Gabriel (b214c73) * nxauth: Drop nxauth tool completely, xauth can be successfully used with nxagent / nxproxy instead. -2016-07-01 14:02:52 +0200 Mike Gabriel (a3a295288) +2016-07-01 14:02:52 +0200 Mike Gabriel (a3a2952) * Merge branch 'sunweaver-pr/debian-packaging-updates' into 3.6.x -2016-07-01 00:00:29 +0200 Mike Gabriel (12ca29bf5) +2016-07-01 00:00:29 +0200 Mike Gabriel (12ca29b) * debian/*.dirs: Don't create directories in the Debian package. All handled well by the upstream Makefile. + (gh-sunweaver/pr/debian-packaging-updates) -2016-06-23 21:33:23 +0200 Mike Gabriel (2d016f826) +2016-06-23 21:33:23 +0200 Mike Gabriel (2d016f8) * roll-tarball.sh: Move out of debian/ folder into project's base folder. -2016-06-23 21:28:42 +0200 Mike Gabriel (82a8d595d) +2016-06-23 21:28:42 +0200 Mike Gabriel (82a8d59) * debian/libxcompext3.symbols: Add symbols file for libXcompext3. -2016-06-23 21:13:20 +0200 Mike Gabriel (ba5f32cda) +2016-06-23 21:13:20 +0200 Mike Gabriel (ba5f32c) * nx-X11/extras/Mesa/src/mesa/shader/arbprogparse.c: Fix typo (grammer -> grammar). -2016-06-23 21:09:19 +0200 Mike Gabriel (7d66941ae) +2016-06-23 21:09:19 +0200 Mike Gabriel (7d66941) * debian/rules: Use buildflags.mk from dpkg-dev. Enable bindnow hardening flag. -2016-06-23 21:08:47 +0200 Mike Gabriel (56f776ced) +2016-06-23 21:08:47 +0200 Mike Gabriel (56f776c) * debian/control: Versioned B-D: dpkg-dev (>= 1.16.1.1). -2016-06-23 15:45:33 +0200 Mike Gabriel (2a2d7f0e2) +2016-06-23 15:45:33 +0200 Mike Gabriel (2a2d7f0) * debian/control: Remove all Pre-Depends: fields from all bin:pkgs. -2016-06-22 12:14:00 +0200 Mike Gabriel (9663b1ce2) +2016-06-22 12:14:00 +0200 Mike Gabriel (9663b1c) * debian/control: Bump Standards: to 3.9.8. (Various changes were needed). -2016-06-22 12:13:23 +0200 Mike Gabriel (87ce9b4b0) +2016-06-22 12:13:23 +0200 Mike Gabriel (87ce9b4) * debian/{control,compat}: Bump to DH compat level 9. -2016-06-22 12:08:49 +0200 Mike Gabriel (2e1ec6181) +2016-06-22 12:08:49 +0200 Mike Gabriel (2e1ec61) * debian/control: Use my DD address in Uploaders: field. -2016-06-22 12:08:35 +0200 Mike Gabriel (24ff7db2b) +2016-06-22 12:08:35 +0200 Mike Gabriel (24ff7db) * debian/changelog: Suppress warnings from lintian about -0 revision in version string. -2016-06-22 10:26:15 +0200 Mike Gabriel (b4d7b9989) +2016-06-22 10:26:15 +0200 Mike Gabriel (b4d7b99) * debian/control: Drop various not-used-anymore libNX_* related packages. Add B:/R: to libnx-x11-{6,dev,6-dbg) to uninstall those package when upgrading to nx-libs 3.6.x. -2016-06-22 10:12:33 +0200 Mike Gabriel (6b423eefd) +2016-06-22 10:12:33 +0200 Mike Gabriel (6b423ee) * roll-tarball.sh: Don't ship doc/X11-symbols/ in the lite (proxy-only) tarball derived from the nx-libs code tree. -2016-06-22 10:10:49 +0200 Mike Gabriel (908b930c9) +2016-06-22 10:10:49 +0200 Mike Gabriel (908b930) * debian/rules: Don't attempt at removing $(CURDIR)/.preserve/. Not needed anymore since we removed the CODE-REDUCTION_* hacks from debian/rules. -2016-06-22 10:09:17 +0200 Mike Gabriel (593e15ca1) +2016-06-22 10:09:17 +0200 Mike Gabriel (593e15c) * debian/*: Drop non-multi-arch support (i.e. Debian squeeze, Ubuntu 10.04 and earlier). -2016-06-22 10:04:16 +0200 Mike Gabriel (3983b111a) +2016-06-22 10:04:16 +0200 Mike Gabriel (3983b11) * debian/*: Drop not-use-anymore CODE-REDUCTION_* files. -2016-07-01 13:46:26 +0200 Mike Gabriel (8307d4f33) +2016-07-01 13:46:26 +0200 Mike Gabriel (8307d4f) * Merge branch 'sunweaver-pr/define-default-source-not-bsd+svid-source' into 3.6.x -2016-06-23 20:52:27 +0200 Mike Gabriel (da4410cce) +2016-06-23 20:52:27 +0200 Mike Gabriel (da4410c) * build flags: Use -D_DEFAULT_SOURCE instead of deprecated -D_BSD_SOURCE and -D_SVID_SOURCE. + (gh-sunweaver/pr/define-default-source-not-bsd+svid-source) -2016-07-01 13:13:48 +0200 Mike Gabriel (4b3081c48) +2016-07-01 13:13:48 +0200 Mike Gabriel (4b3081c) * Merge branch 'sunweaver-pr/drop-really-old-X10-API-code' into 3.6.x -2016-06-23 09:58:54 +0200 Mike Gabriel (f0bf303c8) +2016-06-23 09:58:54 +0200 Mike Gabriel (f0bf303) * nx-X11/lib/X10: Drop really ancient X10 API code. Not used within - nxagent. + nxagent. (gh-sunweaver/pr/drop-really-old-X10-API-code) -2016-07-01 13:10:06 +0200 Mike Gabriel (b666a3776) +2016-07-01 13:10:06 +0200 Mike Gabriel (b666a37) * Merge branch 'sunweaver-pr/properly-apply-optflags-at-buildtime' into 3.6.x -2016-06-23 14:27:15 +0200 Mike Gabriel (d650a0b47) +2016-06-23 14:27:15 +0200 Mike Gabriel (d650a0b) * OPTFLAGS: Properly propagate build option flags to nxcomp{,ext,shad} and the nx-X11 build scripts. + (gh-sunweaver/pr/properly-apply-optflags-at-buildtime) -2016-06-23 09:58:54 +0200 Mike Gabriel (4693c3203) +2016-06-23 09:58:54 +0200 Mike Gabriel (4693c32) * nx-X11/lib/X10: Drop really ancient X10 API code. Not used within nxagent. -2016-06-23 14:27:15 +0200 Mike Gabriel (a1e9abc78) +2016-06-23 14:27:15 +0200 Mike Gabriel (a1e9abc) * OPTFLAGS: Properly propagate build option flags to nxcomp{,ext,shad} and the nx-X11 build scripts. -2016-06-30 22:41:00 +0200 Mike Gabriel (4cbfc5f98) +2016-06-30 22:41:00 +0200 Mike Gabriel (4cbfc5f) * debian/libnx-x11-6.symbols: Update symbols (added: _XEatDataWords@Base 3.5.99.0, _XGetRequest@Base 3.5.99.0). -2016-06-30 15:41:03 +0200 Mike Gabriel (ba10ceffc) +2016-06-30 15:41:03 +0200 Mike Gabriel (ba10cef) * Merge branch 'sunweaver-pr/drop-embedded-imake-and-makedepend' into 3.6.x -2016-06-22 13:22:06 +0200 Mike Gabriel (298744e94) +2016-06-22 13:22:06 +0200 Mike Gabriel (298744e) * nx-X11/Makefile: Drop build support for World.Win32 and World.OS2. Not our target platforms. + (gh-sunweaver/pr/drop-embedded-imake-and-makedepend) -2016-06-22 12:41:50 +0200 Mike Gabriel (2f3d394e8) +2016-06-22 12:41:50 +0200 Mike Gabriel (2f3d394) * nx-X11/config/{imake,makedepend}: Use system-wide available imake and makedepend tools. -2016-06-30 00:26:37 +0200 Mike Gabriel (5b36f6443) +2016-06-30 00:26:37 +0200 Mike Gabriel (5b36f64) * Merge branch 'sunweaver-pr/backport-xgetrequest-and-xeatdatawords' into 3.6.x -2016-06-29 21:44:08 +0200 Ulrich Sibiller (bd2650ca0) +2016-06-29 21:44:08 +0200 Ulrich Sibiller (bd2650c) * Port _XEatDataWords + (gh-sunweaver/pr/backport-xgetrequest-and-xeatdatawords) -2016-06-29 21:25:24 +0200 Ulrich Sibiller (36d0fac77) +2016-06-29 21:25:24 +0200 Ulrich Sibiller (36d0fac) * Backport of _XGetRequest() -2016-06-29 11:21:09 +0200 Mike Gabriel (3314c24a7) +2016-06-29 11:21:09 +0200 Mike Gabriel (3314c24) * Merge branch 'sunweaver-pr/drop-x2goagent' into 3.6.x -2016-06-22 08:16:35 +0200 Mike Gabriel (c355dc91d) +2016-06-22 08:16:35 +0200 Mike Gabriel (c355dc9) * Makefile,debian/*,nx-libs.spec,: Drop references to X2Go Project, esp. drop x2goagent. + (gh-sunweaver/pr/drop-x2goagent) -2016-06-29 11:13:34 +0200 Mike Gabriel (b9fb7a05a) +2016-06-29 11:13:34 +0200 Mike Gabriel (b9fb7a0) * Merge branch 'sunweaver-pr/libnx-xext-drop-unused-extensions' into 3.6.x -2016-06-28 12:20:00 +0000 Mike Gabriel (f051b7a2d) +2016-06-28 12:20:00 +0000 Mike Gabriel (f051b7a) * libNX_Xext: Drop unused extensions: DPMS, XTestExt1, XSync, XSecurity. + (gh-sunweaver/pr/libnx-xext-drop-unused-extensions) -2016-06-28 12:13:27 +0000 Mike Gabriel (e9857d5ea) +2016-06-28 12:13:27 +0000 Mike Gabriel (e9857d5) * nx-X11/lib/Xext/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-06-28 12:05:01 +0000 Mike Gabriel (d595125a1) +2016-06-28 12:05:01 +0000 Mike Gabriel (d595125) * fix wrong bin:package for Xext proto headers: Move dpmsstr.h and securstr.h from Xext devel package into proto header package. -2016-06-28 11:43:06 +0000 Mike Gabriel (3ded4a2d6) +2016-06-28 11:43:06 +0000 Mike Gabriel (3ded4a2) * Fix linking order hack in nxagent. + (gh-sunweaver/pr/linking-order-fix) -2016-06-15 16:42:58 +0200 Mike Gabriel (b83a14843) +2016-06-15 16:42:58 +0200 Mike Gabriel (b83a148) * test scripts: Add run-nxagent test script. -2016-06-25 01:35:40 +0200 Mihai Moldovan (975511c87) +2016-06-25 01:35:40 +0200 Mihai Moldovan (975511c) * Merge branch 'sunweaver-pr/hw-nxagent-drop-duplicate-Xserver-code_disable-Xserver-code-and-include-in-nxagent' into arctica-3.6.x -2016-05-02 12:14:14 +0200 Mike Gabriel (a5befd4e2) +2016-05-02 12:14:14 +0200 Mike Gabriel (a5befd4) * hw/nxagent: Drop code referring to the following removed Xserver extensions: XAPPGROUP, LBX, XEVIE. + (gh-sunweaver/pr/hw-nxagent-drop-duplicate-Xserver-code_disable-Xserver-code-and-include-in-nxagent) -2016-05-02 11:29:53 +0200 Mike Gabriel (3bdcd1727) +2016-05-02 11:29:53 +0200 Mike Gabriel (3bdcd17) * hw/nxagent/NX*.c: Amend re-introduced nxagent warnings by fixing the corresponding code section in files included from "somewhere" in nx-X11/programs/Xserver/. -2016-05-01 23:02:20 +0200 Mike Gabriel (a5c7b248e) +2016-05-01 23:02:20 +0200 Mike Gabriel (a5c7b24) * hw/nxagent/NXdixfonts.c: Shrink file, drop duplicate code that can identically be found in dix/dixfonts.c. Also remove NX'ish code from dix/dixfonts.c. -2016-05-01 21:58:22 +0200 Mike Gabriel (2ba500864) +2016-05-01 21:58:22 +0200 Mike Gabriel (2ba5008) * hw/nxagent/NXdispatch.c: Shrink file, drop duplicate code that can identically be found in dix/dispatch.c. -2016-04-26 05:59:56 +0200 Mike Gabriel (a43461335) +2016-04-26 05:59:56 +0200 Mike Gabriel (a434613) * hw/nxagent/NXproperty.c: Shrink file, drop duplicate code that can identically be found in dix/property.c. -2016-04-11 14:53:15 +0200 Mike Gabriel (c6f86b3b2) +2016-04-11 14:53:15 +0200 Mike Gabriel (c6f86b3) * hw/nxagent/NXshm.c: Shrink file, drop duplicate code that can identically be found in Xext/shm.c. -2016-04-10 01:57:57 +0200 Mike Gabriel (51e4ed0fc) +2016-04-10 01:57:57 +0200 Mike Gabriel (51e4ed0) * hw/nxagent/NXxvdisp.c: Shrink file, drop duplicate code that can identically be found in Xext/xvdisp.c. -2016-04-18 13:02:34 +0200 Mike Gabriel (add881931) +2016-04-18 13:02:34 +0200 Mike Gabriel (add8819) * hw/nxagent/NXevents.c: Shrink file, drop duplicate code that can identically be found in dix/events.c. -2016-04-18 08:19:05 +0200 Mike Gabriel (0571ece6a) +2016-04-18 08:19:05 +0200 Mike Gabriel (0571ece) * hw/nxagent/NXglyph.c: Shrink file, drop duplicate code that can identically be found in render/glyph.c. -2016-04-18 08:10:08 +0200 Mike Gabriel (12130a4d9) +2016-04-18 08:10:08 +0200 Mike Gabriel (12130a4) * hw/nxagent/NXglyphcurs.c: Shrink file, drop duplicate code that can identically be found in dix/glyphcurs.c. -2016-04-13 15:29:32 +0200 Mike Gabriel (a64855879) +2016-04-13 15:29:32 +0200 Mike Gabriel (a648558) * hw/nxagent/NXrender.c: Shrink file, drop duplicate code that can identically be found in render/render.c. -2016-04-13 15:28:33 +0200 Mike Gabriel (778e83a3c) +2016-04-13 15:28:33 +0200 Mike Gabriel (778e83a) * hw/nxagent/NX{glyphstr,picturestr}.h: Don't ship the complete header files in nxagent's code base. Rather replace structures we need modified only. -2016-04-13 11:33:33 +0200 Mike Gabriel (de03d6227) +2016-04-13 11:33:33 +0200 Mike Gabriel (de03d62) * NXrenderint.h: Move into subfolder X11/include/ and rename to Xrender_nxagent.h. (Like we have done with all other non-public Xlib related header files that are required for building nxagent. -2016-04-11 16:37:00 +0200 Mike Gabriel (ab6bb890e) +2016-04-11 16:37:00 +0200 Mike Gabriel (ab6bb89) * hw/nxagent/NXresource.c: Shrink file, drop duplicate code that can identically be found in dix/resource.c. -2016-04-11 13:46:36 +0200 Mike Gabriel (1384776fd) +2016-04-11 13:46:36 +0200 Mike Gabriel (1384776) * Xserver/dix/window.c: Don't reintroduce build warnings with previous commit due to now-unnecessary assignements of pScreen pointers. -2016-04-11 13:41:11 +0200 Mike Gabriel (4690d6b71) +2016-04-11 13:41:11 +0200 Mike Gabriel (4690d6b) * hw/nxagent/NXwindow.c: Shrink file, drop duplicate code that can identically be found in dix/window.c. -2016-04-10 02:45:24 +0200 Mike Gabriel (e60f281aa) +2016-04-10 02:45:24 +0200 Mike Gabriel (e60f281) * hw/nxagent/NXglxext.c: Shrink file, drop duplicate code that can identically be found in GL/glx/glxext.c. -2016-04-10 02:37:19 +0200 Mike Gabriel (b4e2ec709) +2016-04-10 02:37:19 +0200 Mike Gabriel (b4e2ec7) * Xserver/GL/glx/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-04-09 00:36:40 +0200 Mike Gabriel (0c29f81f1) +2016-04-09 00:36:40 +0200 Mike Gabriel (0c29f81) * hw/nxagent/NXpicture.c: Shrink file, drop duplicate code that can identically be found in render/picture.c. -2016-04-08 13:53:36 +0200 Mike Gabriel (809fed649) +2016-04-08 13:53:36 +0200 Mike Gabriel (809fed6) * hw/nxagent/NXmiexpose.c: Shrink file, drop duplicate code that can identically be found in mi/miexpose.c. -2016-04-08 13:52:59 +0200 Mike Gabriel (69ac98165) +2016-04-08 13:52:59 +0200 Mike Gabriel (69ac981) * hw/nxagent/Pixmaps.h: Make RESTYPE well-defined by adding resource.h to includes. -2016-04-08 10:01:30 +0200 Mike Gabriel (5088a6d13) +2016-04-08 10:01:30 +0200 Mike Gabriel (5088a6d) * Xserver/mi/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-04-08 09:45:32 +0200 Mike Gabriel (ae1a218d1) +2016-04-08 09:45:32 +0200 Mike Gabriel (ae1a218) * hw/nxagent/NXmiglyph.c: Shrink file, drop code that can be identically found in render/miglyph.c. -2016-04-08 09:38:20 +0200 Mike Gabriel (500544f82) +2016-04-08 09:38:20 +0200 Mike Gabriel (500544f) * hw/nxagent/NXmitrap.c: Shrink file, drop duplicate code that can identically be found in render/mitrap.c. -2016-04-08 09:26:12 +0200 Mike Gabriel (8fab4afbb) +2016-04-08 09:26:12 +0200 Mike Gabriel (8fab4af) * hw/nxagent/NXmiwindow.c: Drop complete file. -2016-04-07 12:22:51 +0200 Mike Gabriel (148f75067) +2016-04-07 12:22:51 +0200 Mike Gabriel (148f750) * hw/nxagent/NXdamage.c: Shrink file, drop duplicate code that can identically be found in miext/damage/damage.c. -2016-04-07 09:36:18 +0200 Mike Gabriel (fd31518f4) +2016-04-07 09:36:18 +0200 Mike Gabriel (fd31518) * NXcomposite.h: Move fake header file NXcomposite.h to hw/nxagent/X11/include/ and drop all symbols that are not explicitly used by nxagent. -2016-04-07 00:54:44 +0200 Mike Gabriel (28acdaff7) +2016-04-07 00:54:44 +0200 Mike Gabriel (28acdaf) * Xserver/hw/nxagent: Drop NXcompositeext.h, it is a duplicate of nx-X11/include/extensions/composite.h. -2016-04-06 23:31:52 +0200 Mike Gabriel (ca1e85710) +2016-04-06 23:31:52 +0200 Mike Gabriel (ca1e857) * hw/nxagent/NXextension.c: Shrink file, drop duplicate code that is indentically found in dix/extension.c. -2016-04-06 23:18:07 +0200 Mike Gabriel (5d1604616) +2016-04-06 23:18:07 +0200 Mike Gabriel (5d16046) * Xserver/dix/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-06-25 00:38:01 +0200 Mike Gabriel (9df153668) +2016-06-25 00:38:01 +0200 Mike Gabriel (9df1536) * Merge branch 'uli42-pr/run_xinerama_without_debug_output' into 3.6.x -2016-06-24 21:22:01 +0200 Ulrich Sibiller (b7d7ff3e4) +2016-06-24 21:22:01 +0200 Ulrich Sibiller (b7d7ff3) * libX11: Extend Event functions to handle IOErrors -2016-06-25 00:31:35 +0200 Ulrich Sibiller (e079b0b35) +2016-06-25 00:31:35 +0200 Ulrich Sibiller (e079b0b) * Screen.c: fix RRGetInfo call + (gh-uli42/pr/run_xinerama_without_debug_output, + gh-uli42/pr/run_xinerama_without_debug_outout) -2016-06-25 00:31:05 +0200 Ulrich Sibiller (cec31e2f0) +2016-06-25 00:31:05 +0200 Ulrich Sibiller (cec31e2) * Xinerama: undef debug/test flags -2016-06-25 00:17:10 +0200 Mike Gabriel (9c1275f58) +2016-06-25 00:17:10 +0200 Mike Gabriel (9c1275f) * Merge branch 'uli42-pr/fix-crash-in-XPeekEvent' into 3.6.x -2016-06-24 21:22:01 +0200 Ulrich Sibiller (5ee04c24c) +2016-06-24 21:22:01 +0200 Ulrich Sibiller (5ee04c2) * libX11: Extend Event functions to handle IOErrors -2016-06-21 04:12:07 +0200 Mike Gabriel (17f3e3bc5) +2016-06-21 04:12:07 +0200 Mike Gabriel (17f3e3b) * Merge branch 'sunweaver-pr/xrandr-extension-upgrade-1.5' into 3.6.x -2016-06-20 17:21:33 +0200 Mike Gabriel (4c8fc6be8) +2016-06-20 17:21:33 +0200 Mike Gabriel (4c8fc6b) * debian/patches: Update 102_xserver-xext_set-securitypolicy-path.debian.patch. + (gh-sunweaver/pr/xrandr-extension-upgrade-1.5) -2016-06-20 11:10:06 +0200 Mike Gabriel (c2b1f489d) +2016-06-20 11:10:06 +0200 Mike Gabriel (c2b1f48) * Backport RANDR proto version 1.5 to nx-X11's Xserver. -2016-06-20 15:53:20 +0200 Mike Gabriel (2e5b98986) +2016-06-20 15:53:20 +0200 Mike Gabriel (2e5b989) * Move matrix operations from X server to pixman 0.13.2. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). -2016-06-20 15:51:55 +0200 Mike Gabriel (36e17bdc6) +2016-06-20 15:51:55 +0200 Mike Gabriel (36e17bd) * [render] Split out filter finding from filter setting. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). -2016-06-20 15:50:05 +0200 Mike Gabriel (3f4e503d6) +2016-06-20 15:50:05 +0200 Mike Gabriel (3f4e503) * nx-libs.spec, debian/control: versioned B-R / B-D: pixman-1 (>= 0.13.2). -2016-06-20 15:43:35 +0200 Mike Gabriel (f9dbc64f0) +2016-06-20 15:43:35 +0200 Mike Gabriel (f9dbc64) * Move matrix operations from X server to pixman 0.13.2, handle RandR transform matrices in floating point. -2016-06-20 15:36:52 +0200 Mike Gabriel (6859815ec) +2016-06-20 15:36:52 +0200 Mike Gabriel (6859815) * Call pScreen->ConstrainCursorHarder from the position update path -2016-06-20 15:29:28 +0200 Mike Gabriel (a60c22f45) +2016-06-20 15:29:28 +0200 Mike Gabriel (a60c22f) * dix/randr: add a hooks into screen to (a) replace scanout pixmap and (b) for additional cursor confinement -2016-06-20 13:25:23 +0200 Mike Gabriel (19ebd7722) +2016-06-20 13:25:23 +0200 Mike Gabriel (19ebd77) * include: add version_compare helper function -2016-06-20 13:19:08 +0200 Mike Gabriel (21c3d20fb) +2016-06-20 13:19:08 +0200 Mike Gabriel (21c3d20) * [render] Split out filter finding from filter setting. -2016-06-20 12:21:39 +0200 Mike Gabriel (e38388174) +2016-06-20 12:21:39 +0200 Mike Gabriel (e383881) * debian/patches-pending-evaluation: Adapt fix-icon-and-clipboard.patch to removal of the WindowTable array. -2016-06-20 16:51:59 +0200 Mike Gabriel (8c7d7bed9) +2016-06-20 16:51:59 +0200 Mike Gabriel (8c7d7be) * hw/nxagent/NXresource.c: remove caching of drawables and graphics contexts. The security checks simply bypass the cached @@ -3372,2590 +4578,2597 @@ nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). -2016-06-20 16:45:38 +0200 Mike Gabriel (e6f2f6427) +2016-06-20 16:45:38 +0200 Mike Gabriel (e6f2f64) * dix: remove caching of drawables and graphics contexts. The security checks simply bypass the cached values so they are unused. -2016-06-20 16:47:28 +0200 Mike Gabriel (274598651) +2016-06-20 16:47:28 +0200 Mike Gabriel (2745986) * Xserver/dix/events.c: Don't declare and assign unused pScreen. -2016-06-20 12:18:53 +0200 Mike Gabriel (c61bb8cc5) +2016-06-20 12:18:53 +0200 Mike Gabriel (c61bb8c) * Move each screen's root-window pointer into ScreenRec. -2016-06-20 11:16:08 +0200 Mike Gabriel (590862d39) +2016-06-20 11:16:08 +0200 Mike Gabriel (590862d) * Centralize declaration of ConnectionInfo. -2016-06-20 11:21:46 +0200 Mike Gabriel (560fd4e5f) +2016-06-20 11:21:46 +0200 Mike Gabriel (560fd4e) * nxagent/hw/NXextension.c: Allow CloseDownProc to be NULL. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). -2016-06-20 11:12:11 +0200 Mike Gabriel (4aec11346) +2016-06-20 11:12:11 +0200 Mike Gabriel (4aec113) * Allow CloseDownProc to be NULL. -2016-06-07 10:26:58 +0200 Mike Gabriel (e440ea768) +2016-06-07 10:26:58 +0200 Mike Gabriel (e440ea7) * randr extension: Convert to Xorg coding style. -2016-06-07 10:26:12 +0200 Mike Gabriel (7f7c96c7c) +2016-06-07 10:26:12 +0200 Mike Gabriel (7f7c96c) * Copy x-indent.sh and x-indent-all.sh from xorg/util/modular. -2016-06-07 10:14:50 +0200 Mike Gabriel (b943cfe2a) +2016-06-07 10:14:50 +0200 Mike Gabriel (b943cfe) * Drop trailing whitespaces (randr extension) -2016-05-31 16:12:15 +0200 Adam Jackson (e2b0f279e) +2016-05-31 16:12:15 +0200 Adam Jackson (e2b0f27) * randr: Remove mirandr -2016-05-31 16:11:40 +0200 Mike Gabriel (6343fa664) +2016-05-31 16:11:40 +0200 Mike Gabriel (6343fa6) * Xserver/randr/Imakefile: Serialize parameters and make Imakefile changes more trackable. -2016-06-21 03:56:29 +0200 Mike Gabriel (3db9a757f) +2016-06-21 03:56:29 +0200 Mike Gabriel (3db9a75) * hw/nxagent/Handlers.c: Regression fix since 6051dec. Close unclosed '#ifdef TEST'. -2016-06-18 19:50:10 +0200 Mike Gabriel (9de3d26ef) +2016-06-18 19:50:10 +0200 Mike Gabriel (9de3d26) * hw/nxagent/Options.h: Grammar fix in comment. -2016-06-10 01:05:58 +0200 Mike Gabriel (d13049403) +2016-06-10 01:05:58 +0200 Mike Gabriel (d130494) * Properly enable/disable Xinerama support in nxagent via cmdline options provider in Xserver/os/utils.c. -2016-06-09 16:24:10 +0200 Mike Gabriel (059f03188) +2016-06-09 16:24:10 +0200 Mike Gabriel (059f031) * noRRXineramaExtension: Make Boolean configurable via new cmdline switch (+|-rrxinerama). -2016-06-17 01:45:40 +0000 Mihai Moldovan (4d6d3c567) +2016-06-17 01:45:40 +0000 Mihai Moldovan (4d6d3c5) * {nx-X11/programs/Xserver/hw/nxagent/{{Args,Handlers,Image,Options}.c,Options.h},nxcomp/{Loop,Misc}.cpp}: add configurable sleep delay if session is suspended. -2016-06-13 01:56:07 +0200 Mike Gabriel (04d2fe3ae) +2016-06-13 01:56:07 +0200 Mike Gabriel (04d2fe3) * nxagentReversePointerMap: Don't assume Xevent.xbutton.button is always greater than zero. We have seen Xevent.xbutton.button being set to AnyButton (equaling 0). -2016-05-27 15:52:50 +0000 Mihai Moldovan (129cc6afd) +2016-05-27 15:52:50 +0000 Mihai Moldovan (129cc6a) * nx-X11/programs/Xserver/hw/nxagent/Handlers.h: fix stack smashing related to different data type sizes between Xserver and Xlib. -2016-06-21 03:56:29 +0200 Mike Gabriel (9013a24da) +2016-06-21 03:56:29 +0200 Mike Gabriel (9013a24) * hw/nxagent/Handlers.c: Regression fix since 6051dec. Close unclosed '#ifdef TEST'. -2016-06-18 19:50:10 +0200 Mike Gabriel (d5cc12c2a) +2016-06-18 19:50:10 +0200 Mike Gabriel (d5cc12c) * hw/nxagent/Options.h: Grammar fix in comment. -2016-06-18 19:46:28 +0200 Mike Gabriel (c31ae1eed) +2016-06-18 19:46:28 +0200 Mike Gabriel (c31ae1e) * Merge branch 'sunweaver-pr/rrxinerama-vs-panoramix-with-disable-support' into 3.6.x -2016-06-10 01:05:58 +0200 Mike Gabriel (4b4a6a35c) +2016-06-10 01:05:58 +0200 Mike Gabriel (4b4a6a3) * Properly enable/disable Xinerama support in nxagent via cmdline options provider in Xserver/os/utils.c. + (gh-sunweaver/pr/rrxinerama-vs-panoramix-with-disable-support) -2016-06-09 16:24:10 +0200 Mike Gabriel (3f8aa38fe) +2016-06-09 16:24:10 +0200 Mike Gabriel (3f8aa38) * noRRXineramaExtension: Make Boolean configurable via new cmdline switch (+|-rrxinerama). -2016-06-18 09:27:39 +0200 Mike Gabriel (2dd1a1fe6) +2016-06-18 09:27:39 +0200 Mike Gabriel (2dd1a1f) * Merge branch 'Ionic-feature/configurablesleep' into 3.6.x -2016-06-17 01:45:40 +0000 Mihai Moldovan (6051dec4a) +2016-06-17 01:45:40 +0000 Mihai Moldovan (6051dec) * {nx-X11/programs/Xserver/hw/nxagent/{{Args,Handlers,Image,Options}.c,Options.h},nxcomp/{Loop,Misc}.cpp}: add configurable sleep delay if session is suspended. + (gh-Ionic/feature/configurablesleep) -2016-06-15 00:39:04 +0200 Mike Gabriel (3dea5a88c) +2016-06-15 00:39:04 +0200 Mike Gabriel (3dea5a8) * Merge branch 'sunweaver-pr/nxagentReversePointerMapping-negative-index' into 3.6.x -2016-06-13 01:56:07 +0200 Mike Gabriel (5e17d05aa) +2016-06-13 01:56:07 +0200 Mike Gabriel (5e17d05) * nxagentReversePointerMap: Don't assume Xevent.xbutton.button is always greater than zero. We have seen Xevent.xbutton.button being set to AnyButton (equaling 0). (gh-sunweaver/pr/nxagentReversePointerMapping-negative-index) -2016-06-13 21:07:38 +0200 Mike Gabriel (61d0fbea7) +2016-06-13 21:07:38 +0200 Mike Gabriel (61d0fbe) * Merge branch 'Ionic-bugfix/Xserver-Xlib-type-mismatch' into 3.6.x -2016-05-27 15:52:50 +0000 Mihai Moldovan (639a2c36f) +2016-05-27 15:52:50 +0000 Mihai Moldovan (639a2c3) * nx-X11/programs/Xserver/hw/nxagent/Handlers.h: fix stack smashing related to different data type sizes between Xserver and - Xlib. + Xlib. (gh-Ionic/bugfix/Xserver-Xlib-type-mismatch) -2016-06-13 13:13:55 +0200 Mike Gabriel (35613d1dc) +2016-06-13 13:13:55 +0200 Mike Gabriel (35613d1) * Merge branch 'sunweaver-pr/nxcomp+ext+shad-system-wide-headers' into 3.6.x -2016-04-06 22:09:31 +0200 Mike Gabriel (f5eff9bc0) +2016-04-06 22:09:31 +0200 Mike Gabriel (f5eff9b) * nx-X11/programs/Xserver: Include nxcomp{,ext,shad} headers like one would do with system-wide shared libraries. (gh-sunweaver/pr/nxcomp+ext+shad-system-wide-headers) -2016-04-05 14:29:02 +0200 Mike Gabriel (2f706cbeb) +2016-04-05 14:29:02 +0200 Mike Gabriel (2f706cb) * nxcomp/Makefile.in: Only install MD5.h, NX.h, NXalert.h, NXpack.h, NXproto.h and NXvars.h as publicly available header files. -2016-04-05 14:20:24 +0200 Mike Gabriel (f55249dc6) +2016-04-05 14:20:24 +0200 Mike Gabriel (f55249d) * nxcomshad/Makefile.in: Only install Shadow.h as publicly available header file. -2016-06-09 16:26:51 +0200 Mike Gabriel (734da2139) +2016-06-09 16:26:51 +0200 Mike Gabriel (734da21) * hw/nxagent/Args.c: Fix syntax errors for builds using -UPANORAMIX. -2016-06-03 14:58:02 +0200 Mike Gabriel (4998e62c4) +2016-06-03 14:58:02 +0200 Mike Gabriel (4998e62) * nx-X11/programs/Xserver/Imakefile: Don't overlink nxagent. Linking against libXrandr and libXtst is not necessary for nxagent. -2016-06-03 14:42:54 +0200 Mike Gabriel (15440cad7) +2016-06-03 14:42:54 +0200 Mike Gabriel (15440ca) * nx-X11/config/cf/lnxLib.tmpl requires post-library removal cleanup: Drop references to dropped X11 extension client libraries. -2016-06-01 21:57:36 +0200 Mihai Moldovan (3d5433833) +2016-06-01 21:57:36 +0200 Mihai Moldovan (3d54338) * Merge branch 'sunweaver-pr/xserver-drop-outdated-xext-extensions' into arctica-3.6.x -2016-04-26 23:44:55 +0200 Mike Gabriel (b2145323c) +2016-04-26 23:44:55 +0200 Mike Gabriel (b214532) * XTRAP: Drop all Xserver code blocks that relate to removed XTRAP extension. (gh-sunweaver/pr/xserver-drop-outdated-xext-extensions) -2016-04-19 12:04:57 +0200 Mike Gabriel (8c1d16dae) +2016-04-19 12:04:57 +0200 Mike Gabriel (8c1d16d) * XFreeXDGA: Drop all Xserver code blocks that relate to removed XFreeXDGA extension. -2016-04-19 12:02:12 +0200 Mike Gabriel (2ff2c92bb) +2016-04-19 12:02:12 +0200 Mike Gabriel (2ff2c92) * XF86MISC: Drop all Xserver code blocks that relate to removed XF86MISC extension. -2016-04-19 11:58:37 +0200 Mike Gabriel (004f8f896) +2016-04-19 11:58:37 +0200 Mike Gabriel (004f8f8) * MITMISC: Drop all Xserver code blocks that relate to removed MITMISC extension. -2016-04-19 11:56:20 +0200 Mike Gabriel (e14231443) +2016-04-19 11:56:20 +0200 Mike Gabriel (e142314) * XF86VIDMODE: Drop all Xserver code blocks that relate to removed XF86VIDMODE extension. -2016-04-19 11:53:59 +0200 Mike Gabriel (74a1e4e83) +2016-04-19 11:53:59 +0200 Mike Gabriel (74a1e4e) * MULTIBUFFER: Drop all Xserver code blocks that relate to removed MULTIBUFFER extension. -2016-04-19 11:52:13 +0200 Mike Gabriel (2f0d2d388) +2016-04-19 11:52:13 +0200 Mike Gabriel (2f0d2d3) * LBX: Drop all Xserver code blocks that relate to removed LBX extension. -2016-04-19 11:36:27 +0200 Mike Gabriel (e80842cc4) +2016-04-19 11:36:27 +0200 Mike Gabriel (e80842c) * EVI: Drop all Xserver code blocks that relate to removed EVI extension. -2016-04-19 11:34:20 +0200 Mike Gabriel (25ffbbb22) +2016-04-19 11:34:20 +0200 Mike Gabriel (25ffbbb) * FONTCACHE: Drop all Xserver code blocks that relate to removed FONTCACHE extension. -2016-04-19 11:02:14 +0200 Mike Gabriel (3aedac174) +2016-04-19 11:02:14 +0200 Mike Gabriel (3aedac1) * XEVIE: Drop all Xserver code blocks that relate to removed XEVIE extension. -2016-04-19 11:31:48 +0200 Mike Gabriel (cd39f1393) +2016-04-19 11:31:48 +0200 Mike Gabriel (cd39f13) * XFree86DGA: Drop all Xserver code blocks that relate to removed XFree86DGA extension. -2016-04-19 11:07:49 +0200 Mike Gabriel (a25c0de09) +2016-04-19 11:07:49 +0200 Mike Gabriel (a25c0de) * TOGCUP: Drop all Xserver code blocks that relate to removed TOGCUP extension. -2016-04-19 11:05:41 +0200 Mike Gabriel (683415dfe) +2016-04-19 11:05:41 +0200 Mike Gabriel (683415d) * XAPPGROUP: Drop all Xserver code blocks that relate to removed XAPPGROUP extension. -2016-03-01 20:55:27 +0000 Mike Gabriel (9bc6ff269) +2016-03-01 20:55:27 +0000 Mike Gabriel (9bc6ff2) * Drop X11 extensions not shipped with recent X.Org server versions anymore: -2016-05-31 12:44:02 +0200 Nito Martinez (c646808bc) +2016-05-31 12:44:02 +0200 Nito Martinez (c646808) * Fix debugging function for Loop.cpp. getDebugSpec was replaced by << operand in ChannelEndPoint.{h|cpp}, fixes #130 -2016-05-31 12:12:39 +0200 Mike Gabriel (e3051f7a7) +2016-05-31 12:12:39 +0200 Mike Gabriel (e3051f7) * Merge branch 'nitomartinez-3.6.x' into 3.6.x (origin/3713346f) -2016-05-30 16:10:32 +0000 Mihai Moldovan (36c3613a7) +2016-05-30 16:10:32 +0000 Mihai Moldovan (36c3613) * nx-X11/programs/Xserver/{hw/nxagent/NX,render/}picture.c: add and use new function ReduceCompositeOp(). -2016-04-09 19:41:48 +0000 Mihai Moldovan (62aac6950) +2016-04-09 19:41:48 +0000 Mihai Moldovan (62aac69) * nx-X11/programs/Xserver/composite/Imakefile: add new file to SRCS and OBJS and define -DNXAGENT_SERVER while building the Composite extension to disable some code that depends upon a newer X.Org architecture. -2016-04-09 19:40:24 +0000 Mihai Moldovan (7d2dd2aac) +2016-04-09 19:40:24 +0000 Mihai Moldovan (7d2dd2a) * misc nx-X11/{programs/Xserver/composite,include/extensions}: update to Composite 0.4 - with changes where neccessary and rough edges. -2016-04-09 19:38:12 +0000 Mihai Moldovan (fe3fa5ef3) +2016-04-09 19:38:12 +0000 Mihai Moldovan (fe3fa5e) * nx-X11/programs/Xserver/{dix/{colormap.c,window.c},hw/nxagent/NXwindow.c,include/{colormap,window{,str}}.h}: backport features needed for Composite 0.4. -2016-05-31 12:09:23 +0200 Mike Gabriel (4a9c1b946) +2016-05-31 12:09:23 +0200 Mike Gabriel (4a9c1b9) * Merge branch 'Ionic-feature/composite-update' into 3.6.x -2016-05-31 11:23:40 +0200 Nito Martinez (035995a8c) +2016-05-31 11:23:40 +0200 Nito Martinez (035995a) * display version number in nxcomp log, fixes #127 -2016-05-30 16:10:32 +0000 Mihai Moldovan (cad9f4ef8) +2016-05-30 16:10:32 +0000 Mihai Moldovan (cad9f4e) * nx-X11/programs/Xserver/{hw/nxagent/NX,render/}picture.c: add and use new function ReduceCompositeOp(). + (gh-Ionic/feature/composite-update) -2016-04-09 19:41:48 +0000 Mihai Moldovan (dd9eb3adf) +2016-04-09 19:41:48 +0000 Mihai Moldovan (dd9eb3a) * nx-X11/programs/Xserver/composite/Imakefile: add new file to SRCS and OBJS and define -DNXAGENT_SERVER while building the Composite extension to disable some code that depends upon a newer X.Org architecture. -2016-04-09 19:40:24 +0000 Mihai Moldovan (be824bc8d) +2016-04-09 19:40:24 +0000 Mihai Moldovan (be824bc) * misc nx-X11/{programs/Xserver/composite,include/extensions}: update to Composite 0.4 - with changes where neccessary and rough edges. -2016-04-09 19:38:12 +0000 Mihai Moldovan (f7cff021e) +2016-04-09 19:38:12 +0000 Mihai Moldovan (f7cff02) * nx-X11/programs/Xserver/{dix/{colormap.c,window.c},hw/nxagent/NXwindow.c,include/{colormap,window{,str}}.h}: backport features needed for Composite 0.4. -2016-05-13 06:19:21 +0200 Mihai Moldovan (aba2a534f) +2016-05-13 06:19:21 +0200 Mihai Moldovan (aba2a53) * Merge branch 'sunweaver-pr/nxagent-no-compiler-warnings' into arctica-3.6.x -2016-05-03 19:42:46 +0200 Mike Gabriel (52dc49607) +2016-05-03 19:42:46 +0200 Mike Gabriel (52dc496) * hw/nxagent/Display.c: Avoid incompatible pointer type. (gh-sunweaver/pr/nxagent-no-compiler-warnings) -2016-05-03 19:28:48 +0200 Mike Gabriel (a0e5589ed) +2016-05-03 19:28:48 +0200 Mike Gabriel (a0e5589) * hw/nxagent/Display.c: Define Pixmap from XlibPixmap before including Icons.h (which includes hw/nxagent/X11/include/xpm_nxagent.h). -2016-05-03 17:49:54 +0200 Mike Gabriel (e79fe3b9a) +2016-05-03 17:49:54 +0200 Mike Gabriel (e79fe3b) * hw/nxagent/Holder.c: Define Pixmap from XlibPixmap before including hw/nxagent/X11/include/xpm_nxagent.h. -2016-04-19 10:43:40 +0200 Mihai Moldovan (b91135b0c) +2016-04-19 10:43:40 +0200 Mihai Moldovan (b91135b) * hw/nxagent/Events.c: Avoid '#endif #ifdef DEBUG' blocks. -2016-03-22 01:11:55 +0100 Mike Gabriel (c2de5f198) +2016-03-22 01:11:55 +0100 Mike Gabriel (c2de5f1) * hw/nxagent/NXmiexpose.c: Initialize all items of the newValues[] array. -2016-03-21 22:49:25 +0100 Mike Gabriel (021023202) +2016-03-21 22:49:25 +0100 Mike Gabriel (0210232) * hw/nxagent/Keystroke.c: Fix warning: pointer type mismatch in conditional expression. -2016-03-21 22:37:38 +0100 Mike Gabriel (00059798d) +2016-03-21 22:37:38 +0100 Mike Gabriel (0005979) * hw/nxagent/Window.c: Initialize tmp_mask and attributes.event_mask with NoEventMask. -2016-03-21 22:22:07 +0100 Mike Gabriel (7251ef492) +2016-03-21 22:22:07 +0100 Mike Gabriel (7251ef4) * hw/nxagent/Colormap.c: Don't declare and assign flexibility variable if not used later on. -2016-03-21 16:36:38 +0100 Mike Gabriel (634484bb3) +2016-03-21 16:36:38 +0100 Mike Gabriel (634484b) * hw/nxagent/GCOps.c: Don't declare and assign oldDstxyValue if not used later on. -2016-03-21 16:36:15 +0100 Mike Gabriel (e8042c9ff) +2016-03-21 16:36:15 +0100 Mike Gabriel (e8042c9) * hw/nxagent/GC.c: Don't declare and assign flexibility variable if not used later on. -2016-03-21 16:32:41 +0100 Mike Gabriel (7876d1f28) +2016-03-21 16:32:41 +0100 Mike Gabriel (7876d1f) * hw/nxagent/Events.c: Only declare and assign message_data and box variables if compiled with -DTEST / -DDEBUG (plus drop commented out code). -2016-03-21 16:31:49 +0100 Mike Gabriel (30cd3a6c2) +2016-03-21 16:31:49 +0100 Mike Gabriel (30cd3a6) * hw/nxagent/Display.c: Don't declare and assign packMethod / packQuality if not used later on. -2016-03-21 16:14:00 +0100 Mike Gabriel (ab196f3a1) +2016-03-21 16:14:00 +0100 Mike Gabriel (ab196f3) * hw/nxagent/NXrender.c: Don't declare and assign the colors variable, if not used later on. -2016-03-21 16:11:46 +0100 Mike Gabriel (ce8fb1f93) +2016-03-21 16:11:46 +0100 Mike Gabriel (ce8fb1f) * HAVE_STDINT_H: Always include . -2016-05-02 15:38:30 +0200 Mike Gabriel (e3e451629) +2016-05-02 15:38:30 +0200 Mike Gabriel (e3e4516) * hw/nxagent/NXdixfonts.c: Fix implicit declaration for register_fpe_functions(). -2016-03-21 15:54:24 +0100 Mike Gabriel (fb832b01e) +2016-03-21 15:54:24 +0100 Mike Gabriel (fb832b0) * Adapt API for MakeAtom() and CopyISOLatin1Lowered to latest changes in X.org. -2016-03-21 14:18:42 +0100 Mike Gabriel (5e6b72dc7) +2016-03-21 14:18:42 +0100 Mike Gabriel (5e6b72d) * hw/nxagent/NXdixfonts.c: Don't include . No symbol needed from that header file. -2016-03-21 11:55:31 +0100 Mike Gabriel (23d3821f0) +2016-03-21 11:55:31 +0100 Mike Gabriel (23d3821) * hw/nxagent/NXpicture.c: Don't declare anything in empty function nxagentReconnectPictFormat. -2016-03-21 11:54:55 +0100 Mike Gabriel (292d88d07) +2016-03-21 11:54:55 +0100 Mike Gabriel (292d88d) * hw/nxagent/NXglyphcurs.c: Don't declare and set gcval, if not being used later on. -2016-03-21 09:48:11 +0100 Mike Gabriel (182569bf6) +2016-03-21 09:48:11 +0100 Mike Gabriel (182569b) * hw/nxagent/Keyboard.c: The ret variable is only used later on when compiled with -DTEST. -2016-03-21 09:47:29 +0100 Mike Gabriel (66f889542) +2016-03-21 09:47:29 +0100 Mike Gabriel (66f8895) * hw/nxagent/Handlers.c: Don't declare and assign result variable if not used later on. -2016-03-21 09:43:02 +0100 Mike Gabriel (fc393174c) +2016-03-21 09:43:02 +0100 Mike Gabriel (fc39317) * hw/nxagent/Keyboard.c: Don't declare and set XkbDescPtr xkb if not used later on. -2016-03-21 09:41:16 +0100 Mike Gabriel (eb682184c) +2016-03-21 09:41:16 +0100 Mike Gabriel (eb68218) * hw/nxagent/*.c: Drop various declarations of unused ScreenPtr pScreen. -2016-03-18 16:46:34 +0100 Mike Gabriel (b5b7a2d26) +2016-03-18 16:46:34 +0100 Mike Gabriel (b5b7a2d) * hw/nxagent/Screen.c: Cast proper types before handing values over to fprintf(). -2016-03-18 16:45:59 +0100 Mike Gabriel (ab50f84b5) +2016-03-18 16:45:59 +0100 Mike Gabriel (ab50f84) * hw/nxagent/Screen.c: Drop various unused variables. -2016-03-18 16:35:43 +0100 Mike Gabriel (ef287b54f) +2016-03-18 16:35:43 +0100 Mike Gabriel (ef287b5) * hw/nxagent/Screen.h: Provide prototype for nxagentAdjustRandRXinerama(). Avoid implicit-declaration compiler warning. -2016-03-18 16:34:43 +0100 Mike Gabriel (72386e171) +2016-03-18 16:34:43 +0100 Mike Gabriel (72386e1) * hw/nxagent/Screen.c: Correctly use already defined MIN/MAX macros. -2016-03-18 16:27:09 +0100 Mike Gabriel (7d3d47f1f) +2016-03-18 16:27:09 +0100 Mike Gabriel (7d3d47f) * hw/nxagent/Window.c: Don't declare "XWindowChanges changes;" and later not use it. -2016-03-18 16:17:30 +0100 Mike Gabriel (5ea2457ef) +2016-03-18 16:17:30 +0100 Mike Gabriel (5ea2457) * hw/nxagent/Pixmap.c: pBool pointer is only required when compiled in -DTEST mode. -2016-03-18 16:15:29 +0100 Mike Gabriel (08d384841) +2016-03-18 16:15:29 +0100 Mike Gabriel (08d3848) * hw/nxagent/Extension.c: Don't declare pRandRScrPriv without using it later on. -2016-03-18 16:08:45 +0100 Mike Gabriel (802f58163) +2016-03-18 16:08:45 +0100 Mike Gabriel (802f581) * hw/nxagent/Rootless.c: Type cast type Atom to type long unsigned int before handing it over to %lu in fprintf(). -2016-03-18 16:06:59 +0100 Mike Gabriel (c206a0c69) +2016-03-18 16:06:59 +0100 Mike Gabriel (c206a0c) * hw/nxagent/Splash.c: Drop unused variable declaration "XPoint m[12];". -2016-03-18 16:05:01 +0100 Mike Gabriel (5bbdbfce2) +2016-03-18 16:05:01 +0100 Mike Gabriel (5bbdbfc) * hw/nxagent/Clipboard.c: The result variable is only needed when combiled with -DDEBUG. -2016-03-18 15:59:58 +0100 Mike Gabriel (f3f0a6b4b) +2016-03-18 15:59:58 +0100 Mike Gabriel (f3f0a6b) * hw/nxagent/Drawable.c: RegionNumRects returns int, not long int anymore. -2016-03-18 13:06:30 +0100 Mike Gabriel (120204631) +2016-03-18 13:06:30 +0100 Mike Gabriel (1202046) * Add REGION_ macros for source compatibility with existing drivers. -2016-03-18 13:05:05 +0100 Mike Gabriel (b0e69fe35) +2016-03-18 13:05:05 +0100 Mike Gabriel (b0e69fe) * Change region implementation names to eliminate the 'mi' prefix -2016-03-18 04:49:09 +0100 Keith Packard (288136514) +2016-03-18 04:49:09 +0100 Keith Packard (2881365) * Move mi/miregion.c to dix/region.c -2016-03-18 05:13:43 +0100 Mike Gabriel (d9e7f6ae4) +2016-03-18 05:13:43 +0100 Mike Gabriel (d9e7f6a) * pixman-devel: Build against shared library pkg-config(pixman-1). -2016-03-18 05:11:40 +0100 Mike Gabriel (4a8d6eca3) +2016-03-18 05:11:40 +0100 Mike Gabriel (4a8d6ec) * Change region implementation from macros to inline functions. -2016-03-16 11:11:43 +0100 Mike Gabriel (63f1fff8f) +2016-03-16 11:11:43 +0100 Mike Gabriel (63f1fff) * Rename region macros to eliminate screen argument -2016-03-04 16:12:12 +0100 Mike Gabriel (28ba87780) +2016-03-04 16:12:12 +0100 Mike Gabriel (28ba877) * gcc: Build using -std=c99 instead of -ansi. -2016-03-16 11:08:49 +0100 Mike Gabriel (101c895e6) +2016-03-16 11:08:49 +0100 Mike Gabriel (101c895) * fix-patch-whitepspace: Copy script from X.Org's xserver Git repo. -2016-03-16 08:05:01 +0100 Mike Gabriel (eaa19eb55) +2016-03-16 08:05:01 +0100 Mike Gabriel (eaa19eb) * NXwindow.c: Don't set w and h, not used later on. -2016-03-22 14:23:12 +0100 Mike Gabriel (6c6b6b962) +2016-03-22 14:23:12 +0100 Mike Gabriel (6c6b6b9) * lib/Imakefile: Drop $(XINERAMADIR) from nx-X11/lib/Imakefile. (gh-sunweaver/3.6.x) -2016-04-27 14:00:57 +0200 Mike Gabriel (2137ee7e2) +2016-04-27 14:00:57 +0200 Mike Gabriel (2137ee7) * Merge branch 'sunweaver-pr/nxcomp-unix-sockets-for-channels' into 3.6.x -2016-04-20 16:22:56 +0200 Salvador Fandino (3713346f3) +2016-04-20 16:22:56 +0200 Salvador Fandino (3713346) * Provide support for channel endpoints being UNIX file sockets in addition to being TCP/IP sockets. (gh-sunweaver/pr/nxcomp-unix-sockets-for-channels) -2016-04-27 13:56:55 +0200 Mike Gabriel (b326eda73) +2016-04-27 13:56:55 +0200 Mike Gabriel (b326eda) * nxcomp: Rephrase comment in previous commit. -2016-04-27 13:54:56 +0200 Mike Gabriel (416fc186b) +2016-04-27 13:54:56 +0200 Mike Gabriel (416fc18) * Merge branch 'fcarvajaldev-3.6.x-nxcomp-amend-compiler-warnings' into 3.6.x -2016-04-25 12:53:00 +0200 Fernando Carvajal (a436cba04) +2016-04-25 12:53:00 +0200 Fernando Carvajal (a436cba) * Clean up compiler warnings in nxcomp -2016-04-26 22:35:00 +0200 Mihai Moldovan (12104a232) +2016-04-26 22:35:00 +0200 Mihai Moldovan (12104a2) * Merge branch 'sunweaver-pr/libxrender-cleanup' into arctica-3.6.x -2015-06-25 05:37:03 +0200 Mike Gabriel (ebcb6a6e1) +2015-06-25 05:37:03 +0200 Mike Gabriel (ebcb6a6) * library-cleanup: Don't build libNX_Xrender anymore. Use system's libXrender shared library. (gh-sunweaver/pr/libxrender-cleanup) -2016-04-20 16:16:40 +0200 Mike Gabriel (5729783db) +2016-04-20 16:16:40 +0200 Mike Gabriel (5729783) * Merge branch 'theqvd-fix-for-112' into 3.6.x -2016-04-20 15:46:16 +0200 Salvador Fandino (7d053959f) +2016-04-20 15:46:16 +0200 Salvador Fandino (7d05395) * Fix copyright notice in nxcomp/Version.c -2016-04-19 10:47:43 +0200 Mike Gabriel (03b652112) +2016-04-19 10:47:43 +0200 Mike Gabriel (03b6521) * Merge branch 'fcarvajaldev-3.6.x-remove-old-proto-compat' into 3.6.x -2016-04-15 09:49:09 +0200 Fernando Carvajal (5c4952410) +2016-04-15 09:49:09 +0200 Fernando Carvajal (5c49524) * Remove TextCompressor class and files from nxcomp -2016-04-14 17:10:07 +0200 Fernando Carvajal (00464aea0) +2016-04-14 17:10:07 +0200 Fernando Carvajal (00464ae) * Add testing doc for nxcomp drop-old-proto-compat -2016-04-12 16:03:37 +0200 Fernando Carvajal (134648169) +2016-04-12 16:03:37 +0200 Fernando Carvajal (1346481) * Remove obsolete compatibility files from nxcomp -2016-04-12 11:52:22 +0200 Fernando Carvajal (a9be6f591) +2016-04-12 11:52:22 +0200 Fernando Carvajal (a9be6f5) * Remove compatibility code for nxcomp before 3.5.0 -2016-03-22 20:03:42 +0100 Mike Gabriel (2ffe52c5e) +2016-03-22 20:03:42 +0100 Mike Gabriel (2ffe52c) * nxcomp: Properly define NX*Version(void) prototypes in NX.h. -2016-03-17 16:46:13 +0100 Mike Gabriel (af923fba3) +2016-03-17 16:46:13 +0100 Mike Gabriel (af923fb) * debian/patches/401_nxcomp_bigrequests-and-genericevent-extensions.full+lite.patch: Move into debian/patches-pending-evaluation/. -2016-03-15 10:49:25 +0100 Mike Gabriel (156814860) +2016-03-15 10:49:25 +0100 Mike Gabriel (1568148) * doc: Collect data on what libX11 symbols are used by nx-X11, nx-Xserver and nxagent. -2016-03-02 09:33:13 +0100 Nito Martinez (b8c5f677c) +2016-03-02 09:33:13 +0100 Nito Martinez (b8c5f67) * Rename file for windows environments, Fixes #96 -2016-02-26 08:14:28 +0100 Mike Gabriel (abd6cf1bd) +2016-02-26 08:14:28 +0100 Mike Gabriel (abd6cf1) * rename original NX patches, so that we can see the patched file's name in the patch file name. -2016-01-19 05:59:51 +0100 Mike Gabriel (2eb85d140) +2016-01-19 05:59:51 +0100 Mike Gabriel (2eb85d1) * README.md: Update open / completed tasks regarding 3.6.x and 3.7.x releases. -2016-01-19 04:55:01 +0100 Mike Gabriel (e3539ec58) +2016-01-19 04:55:01 +0100 Mike Gabriel (e3539ec) * README.md: Update release dates for 3.6.x and 3.7.x (as earlier discussed with Salve from TheQVD). -2016-01-19 04:50:57 +0100 Mike Gabriel (125f03110) +2016-01-19 04:50:57 +0100 Mike Gabriel (125f031) * Merge branch 'mikedep333-README.md' into 3.6.x -2016-01-18 22:37:46 -0500 Mike DePaulo (0239ba72b) +2016-01-18 22:37:46 -0500 Mike DePaulo (0239ba7) * README.md: Add debuild instructions -2016-01-18 21:49:03 -0500 Mike DePaulo (474e9c0ba) +2016-01-18 21:49:03 -0500 Mike DePaulo (474e9c0) * README.md: Update signature -2016-01-09 22:26:34 +0100 Mike Gabriel (72801f6d5) +2016-01-09 22:26:34 +0100 Mike Gabriel (72801f6) * Merge pull request #68 from mikedep333/mock-build-instructions -2016-01-02 07:30:02 +0100 Mike Gabriel (e794be341) +2016-01-02 07:30:02 +0100 Mike Gabriel (e794be3) * debian/nx-x11proto-xinerama-dev.install.in: Install PANORAMIX extension header files into its own nx-x11proto bin:package. (more Xinerama clean-up, fix FTBFS during dh_install). -2016-01-01 12:27:14 -0500 Mike DePaulo (b7657cfba) +2016-01-01 12:27:14 -0500 Mike DePaulo (b7657cf) * nx-libs.spec: FTBFS Fixes (more libNX_Xinerama cleanup) -2016-01-01 12:01:43 -0500 Mike DePaulo (0428db4db) +2016-01-01 12:01:43 -0500 Mike DePaulo (0428db4) * nx-libs.spec: Misc FTBFS fixes for %files due to recent library changes -2016-01-01 11:32:25 -0500 Mike DePaulo (7f5480dd7) +2016-01-01 11:32:25 -0500 Mike DePaulo (7f5480d) * Fedora/EPEL: Add the implicit build dependencies also -2016-01-01 11:21:47 -0500 Mike DePaulo (1330c4125) +2016-01-01 11:21:47 -0500 Mike DePaulo (1330c41) * Fedora/EPEL: Fix FTBFS due to missing libXpm -2016-01-01 16:26:50 +0100 Mike Gabriel (3ba31659e) +2016-01-01 16:26:50 +0100 Mike Gabriel (3ba3165) * Fix c4a3889. Add forgotten file nx-X11/programs/Xserver/Xinerama_nxagent.h. -2016-01-01 16:08:05 +0100 Mike Gabriel (12b4a0e7a) +2016-01-01 16:08:05 +0100 Mike Gabriel (12b4a0e) * nx-libs.spec: Re-add erroneously removed (during rebasing) BR libXdamage-devel. -2016-01-01 09:52:26 -0500 Mike DePaulo (daace15e2) +2016-01-01 09:52:26 -0500 Mike DePaulo (daace15) * Add instructions for building using Mock under Fedora/EPEL -2015-12-30 19:25:08 +0100 Mike Gabriel (fa497ac95) +2015-12-30 19:25:08 +0100 Mike Gabriel (fa497ac) * nxcomp: Make nxcomp/nxproxy aware of nxagent's xinerama option in the $DISPLAY variable. -2015-05-23 09:28:57 -0400 Mike DePaulo (6da41e6f6) +2015-05-23 09:28:57 -0400 Mike DePaulo (6da41e6) * Complete changes from commit 0d56c45 in NXpicturestr.h (i.e. add a missing comment). (Fixes ArcticaProject/nx-libs#38). -2015-12-30 00:06:58 +0100 Mike Gabriel (1391c0ad7) +2015-12-30 00:06:58 +0100 Mike Gabriel (1391c0a) * Merge branch 'sunweaver-pr/xinerama-xrandr' into 3.6.x -2015-10-08 22:25:09 +0200 Ulrich Sibiller (c4a388937) +2015-10-08 22:25:09 +0200 Ulrich Sibiller (c4a3889) * Xinerama: do not cut off at outer edges (gh-sunweaver/pr/xinerama-xrandr) -2015-10-07 20:45:14 +0200 Mike Gabriel (4ba8df855) +2015-10-07 20:45:14 +0200 Mike Gabriel (4ba8df8) * Xserver globals.h: Make PanoramiXExtensionDisabledHack globally available. -2015-10-07 20:44:19 +0200 Mike Gabriel (d49b0625e) +2015-10-07 20:44:19 +0200 Mike Gabriel (d49b062) * Xserver help: Document -disablexineramaextension cmdline option. -2015-10-07 21:33:55 +0200 Mike Gabriel (522cf0089) +2015-10-07 21:33:55 +0200 Mike Gabriel (522cf00) * X2Go Agent: Add x2goagent.features file that informs X2Go clients about the new RandR based Xinerama feature. -2015-10-07 20:51:12 +0200 Mike Gabriel (0297567cd) +2015-10-07 20:51:12 +0200 Mike Gabriel (0297567) * Provide support for re-enabling Xinerama on session resumptions. -2015-10-07 17:24:01 +0200 Mike Gabriel (f40792c43) +2015-10-07 17:24:01 +0200 Mike Gabriel (f40792c) * Initialize XRandR based Xinerama extension properly when session is started with "-geometry fullscreen". -2015-10-07 17:23:13 +0200 Mike Gabriel (e7e2f164b) +2015-10-07 17:23:13 +0200 Mike Gabriel (e7e2f16) * Only declare nxagentRandRCrtcSet if RANDR_12_INTERFACE is defined. -2015-10-07 15:17:59 +0200 Mike Gabriel (f1eafeaa4) +2015-10-07 15:17:59 +0200 Mike Gabriel (f1eafea) * Screen.c: Rename NX_USE_MODE_PREFIX to NXAGENT_RANDR_MODE_PREFIX, fix unclosed comment. -2015-10-06 22:53:16 +0200 Ulrich Sibiller (9b87a384e) +2015-10-06 22:53:16 +0200 Ulrich Sibiller (9b87a38) * Screen.c: restructure xinerama code, much shorter now -2015-10-06 22:32:12 +0200 Ulrich Sibiller (359f48dd7) +2015-10-06 22:32:12 +0200 Ulrich Sibiller (359f48d) * Screen.c: Fix freeing of unsued modes -2015-10-06 22:30:39 +0200 Ulrich Sibiller (76a203410) +2015-10-06 22:30:39 +0200 Ulrich Sibiller (76a2034) * Screen.c: improve comments and DEBUG output -2015-10-06 22:27:10 +0200 Ulrich Sibiller (8b0e2af36) +2015-10-06 22:27:10 +0200 Ulrich Sibiller (8b0e2af) * rrmode.c: add debug output -2015-05-02 21:53:25 +0200 Ulrich Sibiller (c6482d24f) +2015-05-02 21:53:25 +0200 Ulrich Sibiller (c6482d2) * Reimplement xinerama via randr in nxagent (not libNX_Xinerama). (Fixes ArcticaProject/nx-libs#23). -2015-05-05 10:24:24 +0200 Mike Gabriel (2d776b14f) +2015-05-05 10:24:24 +0200 Mike Gabriel (2d776b1) * library clean-up: Don't build libNX_Xinerama anymore. Use system's libXinerama shared library. (Fixes ArcticaProject/nx-libs#49). -2015-12-29 22:34:04 +0100 Mike Gabriel (e4763fb48) +2015-12-29 22:34:04 +0100 Mike Gabriel (e4763fb) * debian/rules: Don't strips symbols from not-build-anymore libNX_Xtst.so. -2015-06-21 18:12:11 +0200 Mike Gabriel (bd592c2e7) +2015-06-21 18:12:11 +0200 Mike Gabriel (bd592c2) * library clean-up: Don't build libNX_Xtst anymore. Use system's libXtst shared library. (Fixes ArcticaProject/nx-libs#32). -2015-12-29 17:34:36 +0100 Mike Gabriel (b768e8124) +2015-12-29 17:34:36 +0100 Mike Gabriel (b768e81) * Fix for too overall Xdamage and Xrandr client lib removal: Bring back the nx-x11proto-{randr,damage} header files and use those at compile time. -2015-12-29 17:27:47 +0100 Mike Gabriel (9618380bd) +2015-12-29 17:27:47 +0100 Mike Gabriel (9618380) * X11/nx-X11 clear-up: More places where we need to explicitly distinguish between X11 and nx-X11 namespace regarding header include paths. -2015-12-29 17:28:54 +0100 Mike Gabriel (eafc94f16) +2015-12-29 17:28:54 +0100 Mike Gabriel (eafc94f) * nx-X11/lib/X11/Marcos.c: white-space cleanup (EOL blanks). -2015-12-28 22:32:52 +0100 Mike Gabriel (b7f155654) +2015-12-28 22:32:52 +0100 Mike Gabriel (b7f1556) * pointer typedef in Xdefs.h: also catch Xdefs.h include in include/misc.h, make undoing the FIXME more obvious. -2015-12-28 21:33:30 +0100 Mike Gabriel (7eab400ab) +2015-12-28 21:33:30 +0100 Mike Gabriel (7eab400) * libray clean (Xfixes): Provide a fake libXfixes.h header from latest X.Org, that includes headers from our Xlib version. This avoids FTBFS caused by type redefinitions and should really be a temporary measure. -2015-12-28 21:31:58 +0100 Mike Gabriel (f63641b13) +2015-12-28 21:31:58 +0100 Mike Gabriel (f63641b) * Xrandr_nxagent.h: When faking Xrandr.h, we better include our own Xfuncproto.h. -2015-12-28 20:47:49 +0100 Mike Gabriel (cc43e2bf6) +2015-12-28 20:47:49 +0100 Mike Gabriel (cc43e2b) * nxcompshad/X11/include/Xdamage_nxcompshad.h: Update FIXME statement. Work-around needs to persist until libX11 from X.Org gets used by nxagent. -2015-12-28 19:09:42 +0100 Mike Gabriel (6217812c8) +2015-12-28 19:09:42 +0100 Mike Gabriel (6217812) * library clean-up: Don't build libNX_Xfixes anymore. Use system's libXfixes shared library. -2015-12-28 19:55:38 +0100 Mike Gabriel (27e06a5e2) +2015-12-28 19:55:38 +0100 Mike Gabriel (27e06a5) * library clean-up: Don't build libNX_Xcomposite anymore. Use system's libXcomposite shared library. -2015-12-28 15:53:09 +0100 Mike Gabriel (96e1f867d) +2015-12-28 15:53:09 +0100 Mike Gabriel (96e1f86) * pointer typedef in Xdefs.h: Define pointer type for building against older Xlib versions that still expect the pointer type to exist (e.g. Ubuntu <= 14.04, Debian <= 7.0). -2015-12-28 13:17:21 +0100 Mike Gabriel (ca0f639a4) +2015-12-28 13:17:21 +0100 Mike Gabriel (ca0f639) * Merge branch 'sunweaver-pr/NX-include-path' into 3.6.x -2015-07-08 16:16:40 +0200 Mike Gabriel (433d81865) +2015-07-08 16:16:40 +0200 Mike Gabriel (433d818) * Clear header file namespace separation ( vs. ). -2015-12-28 13:08:47 +0100 Mike Gabriel (f58006d93) +2015-12-28 13:08:47 +0100 Mike Gabriel (f58006d) * Merge branch 'sunweaver-pr/dixfont-fix' into 3.6.x -2015-06-23 15:04:16 +0200 Mike Gabriel (aea71067d) +2015-06-23 15:04:16 +0200 Mike Gabriel (aea7106) * On realloc failure, free font_path_string instead of leaking it -2015-12-28 13:03:52 +0100 Mike Gabriel (edce25213) +2015-12-28 13:03:52 +0100 Mike Gabriel (edce252) * Merge branch 'sunweaver-pr/change-pointer-into-void' into 3.6.x -2015-06-22 09:36:08 +0200 Keith Packard (68dd0b52e) +2015-06-22 09:36:08 +0200 Keith Packard (68dd0b5) * Replace 'pointer' type with 'void *' -2015-10-07 17:28:27 +0200 Mike Gabriel (e9f44221b) +2015-10-07 17:28:27 +0200 Mike Gabriel (e9f4422) * Drop all references to printver.c. Not provided in source tree anymore. -2015-10-06 17:12:16 +0200 Mike Gabriel (e0b8f3eef) +2015-10-06 17:12:16 +0200 Mike Gabriel (e0b8f3e) * Re-add -sync option back to nxagent to allow synchronous debugging of the nxagent DDX. -2015-09-28 09:57:12 +0200 Mike Gabriel (81d92cd0f) +2015-09-28 09:57:12 +0200 Mike Gabriel (81d92cd) * Xinerama symlinking: Create / remove folder containing Xinerama sylinks on installation/upgrade and removal. -2015-09-28 08:15:52 +0200 Mike Gabriel (45983d130) +2015-09-28 08:15:52 +0200 Mike Gabriel (45983d1) * Xinerama symlinking: Attach Xinerama symlinking to nxagent bin:package (and not libnx-xinerama1). -2015-09-28 08:10:59 +0200 Mike Gabriel (0382b4018) +2015-09-28 08:10:59 +0200 Mike Gabriel (0382b40) * debian/changelog: Drop unnecessary "~build1" from version string -2015-09-28 07:59:12 +0200 Mike Gabriel (ca990cf0a) +2015-09-28 07:59:12 +0200 Mike Gabriel (ca990cf) * Merge pull request #64 from uli42/pr/add_pkgconfig -2015-09-28 07:53:57 +0200 Mike Gabriel (f9653af3b) +2015-09-28 07:53:57 +0200 Mike Gabriel (f9653af) * Merge branch 'uli42-pr/backported_fixes' into 3.6.x -2015-09-23 12:15:06 +0200 Mike Gabriel (3a022e35c) +2015-09-23 12:15:06 +0200 Mike Gabriel (3a022e3) * debian/libnx-xinerama1.postinst.in: Enforce symlink creation for Xinerama support. -2015-09-22 15:02:22 +0200 Mike Gabriel (899f865cf) +2015-09-22 15:02:22 +0200 Mike Gabriel (899f865) * Revert "debian/libnx-xinerama1.*: fix faulty logic when creating symlinks." -2015-07-17 18:13:00 +0200 Mihai Moldovan (9b126b852) +2015-07-17 18:13:00 +0200 Mihai Moldovan (9b126b8) * nx-libs.spec: add xkeyboard-config to nxagent's Requires. -2015-07-17 17:57:24 +0200 Mihai Moldovan (3a1226ea6) +2015-07-17 17:57:24 +0200 Mihai Moldovan (3a1226e) * debian/control: add xkb-data to nxagent's Recommends. -2015-07-17 17:48:44 +0200 Mihai Moldovan (2aa853530) +2015-07-17 17:48:44 +0200 Mihai Moldovan (2aa8535) * debian/roll-tarballs.sh: more quotes, more curly braces, replace cd with pushd and pop. -2015-07-15 09:30:29 +0200 Mike Gabriel (c36501b53) +2015-07-15 09:30:29 +0200 Mike Gabriel (c36501b) * roll-tarball.sh: more quotes (follow-up for previous commit), drop debug code -2015-07-14 20:39:58 +0200 Mike Gabriel (99a7271e3) +2015-07-14 20:39:58 +0200 Mike Gabriel (99a7271) * roll-tarball.sh: Make sure symlinked files are included in tarballs. -2015-07-14 15:14:55 +0200 Mike Gabriel (0897c062e) +2015-07-14 15:14:55 +0200 Mike Gabriel (0897c06) * nx-libs.spec: Install nxcomp{,ext,shad}.pc into the corresponding development packages. -2015-07-14 14:46:42 +0200 Mike Gabriel (2cc179223) +2015-07-14 14:46:42 +0200 Mike Gabriel (2cc1792) * debian/libxcomp{,ext,shad}-dev.install.in: Install nxcomp{,ext,shad}.pc file into the corresponding development packages. -2015-07-14 14:43:34 +0200 Mike Gabriel (eb5f07ccd) +2015-07-14 14:43:34 +0200 Mike Gabriel (eb5f07c) * nxcomp{,ext,shad}/Makefile.in: Create pkgconfigdir before putting files in it. -2015-07-14 01:39:17 +0200 Mike Gabriel (bc35168fb) +2015-07-14 01:39:17 +0200 Mike Gabriel (bc35168) * nxcomp{,shad,ext}: Remove nxcomp*.pc file on clean and distclean. -2015-07-14 01:26:33 +0200 Mike Gabriel (eee7cb4fb) +2015-07-14 01:26:33 +0200 Mike Gabriel (eee7cb4) * Makefile: Also remove nxversion.def on distclean. -2015-07-12 01:52:29 +0200 Ulrich Sibiller (708cf86a5) +2015-07-12 01:52:29 +0200 Ulrich Sibiller (708cf86) * Add pkg-config support to nxcomp, nxcompext and nxcompshad -2015-07-04 06:46:29 +0200 Mihai Moldovan (8c0a6161d) +2015-07-04 06:46:29 +0200 Mihai Moldovan (8c0a616) * debian/changelog: sync with master/3.5.0.x branch. -2015-06-29 03:40:58 +0200 Mihai Moldovan (34670f8ab) +2015-06-29 03:40:58 +0200 Mihai Moldovan (34670f8) * debian/changelog: sync with master/3.5.0.x branch. -2015-06-28 01:50:00 -0400 Mike DePaulo (a1dfd145d) +2015-06-28 01:50:00 -0400 Mike DePaulo (a1dfd14) * Correct nxproxy manpage also: --help -> -help -2015-06-28 01:33:49 -0400 Mike DePaulo (d8132cbfe) +2015-06-28 01:33:49 -0400 Mike DePaulo (d8132cb) * Correct manpages: --help -> -help -2015-06-23 16:24:56 +0200 Mike Gabriel (5720842b6) +2015-06-23 16:24:56 +0200 Mike Gabriel (5720842) * library clean-up: No autotools cruft in nx-libs. -2015-06-25 05:04:12 +0200 Mike Gabriel (8365e22bb) +2015-06-25 05:04:12 +0200 Mike Gabriel (8365e22) * doc/examples/run-nxproxy2nxproxy-test: Create NX_COOKIE dynamically using the mcookie tool. -2015-05-28 14:52:24 +0200 Mike Gabriel (7dc263333) +2015-05-28 14:52:24 +0200 Mike Gabriel (7dc2633) * COPYING: Replace content with GPL-2 license text, because that is the overall (i.e., strictest) license we have to deal with in nx-libs. -2015-05-28 14:50:05 +0200 Mike Gabriel (c68dad542) +2015-05-28 14:50:05 +0200 Mike Gabriel (c68dad5) * debian/roll-tarball.sh: Auto-generate ChangeLog from Git history. -2015-05-28 14:49:40 +0200 Mike Gabriel (ce5337799) +2015-05-28 14:49:40 +0200 Mike Gabriel (ce53377) * debian/roll-tarball.sh: Rename README.md to README.NX-Development before moving it into doc/ folder. -2015-05-28 14:33:08 +0200 Mike Gabriel (122fd234c) +2015-05-28 14:33:08 +0200 Mike Gabriel (122fd23) * debian/roll-tarball.sh: Prevent several files/folders from ending up in nx-libs-lite tarball. -2015-05-28 13:33:43 +0200 Mike Gabriel (2d50be9da) +2015-05-28 13:33:43 +0200 Mike Gabriel (2d50be9) * debian/roll-tarball.sh: Support tarring up the HEAD of the current branch. -2015-05-28 13:29:27 +0200 Mike Gabriel (51a679ac2) +2015-05-28 13:29:27 +0200 Mike Gabriel (51a679a) * debian/roll-tarball.sh: Allow patch files names having a dash next to the four digits (i.e., 1234-.). -2015-06-23 16:09:50 +0200 Emanuele Giaquinta (931d24cc2) +2015-06-23 16:09:50 +0200 Emanuele Giaquinta (931d24c) * Fix alpha premultiplication in XRenderParseColor. -2015-05-27 12:34:12 +0200 Mike Gabriel (6deaaf50f) +2015-05-27 12:34:12 +0200 Mike Gabriel (6deaaf5) * library clean-up: Drop libXx86{misc,vm,dga} libraries. Not needed by nx-libs. -2015-05-27 10:20:29 +0200 Mike Gabriel (fe0065c55) +2015-05-27 10:20:29 +0200 Mike Gabriel (fe0065c) * library clean-up: Drop nx-X11/lib/Xxf86rush and references to libglide{2,3}. Unused in nx-libs. -2015-05-27 09:48:26 +0200 Mike Gabriel (018c51293) +2015-05-27 09:48:26 +0200 Mike Gabriel (018c512) * nx-X11/config/cf: Drop build-logic for all hardware drivers. -2015-05-27 08:38:11 +0200 Mike Gabriel (17334df9b) +2015-05-27 08:38:11 +0200 Mike Gabriel (17334df) * nx-X11/config/cf: Drop unnecessary xf86site.def, xf86.tmpl, xfree86.cf. -2015-05-27 08:26:40 +0200 Mike Gabriel (8dd6d2fe7) +2015-05-27 08:26:40 +0200 Mike Gabriel (8dd6d2f) * nx-X11/config/cf/Imakefile: Don't list non-present-anymore imake configuration files. -2015-06-20 17:47:39 +0200 Mike Gabriel (32b44398a) +2015-06-20 17:47:39 +0200 Mike Gabriel (32b4439) * libgl clean-up, fix-up commit -2015-06-20 17:35:00 +0200 Mike DePaulo (d7108d206) +2015-06-20 17:35:00 +0200 Mike DePaulo (d7108d2) * README.md: typo fix -2015-06-20 11:34:04 +0200 Henning Heinold (2699d60f6) +2015-06-20 11:34:04 +0200 Henning Heinold (2699d60) * remove libxkbui, looks like it is not used anywhere -2015-06-19 23:58:49 +0200 Mike Gabriel (f1778d0c2) +2015-06-19 23:58:49 +0200 Mike Gabriel (f1778d0) * debian/control: Add Breaks:/Replaces: for qvd-libxcomp3 and qvd-nxproxy. -2015-05-27 08:10:38 +0200 Mike Gabriel (858b9bc2a) +2015-05-27 08:10:38 +0200 Mike Gabriel (858b9bc) * imake clean-up: Enforce build of Mesa GLX extension. Drop all other GLX build methods (built-in DRI drivers, etc.). -2015-05-26 16:44:49 +0200 Mike Gabriel (0887e3ad5) +2015-05-26 16:44:49 +0200 Mike Gabriel (0887e3a) * Drop unused / untested Xserver GLX extension support / build logic. -2015-05-26 16:22:40 +0200 Mike Gabriel (d877b46dd) +2015-05-26 16:22:40 +0200 Mike Gabriel (d877b46) * Drop nx-X11/lib/GL and move Imakefile.inc include files into Xserver code tree. -2015-06-16 22:43:21 +0200 Mihai Moldovan (8f4138457) +2015-06-16 22:43:21 +0200 Mihai Moldovan (8f41384) * nxcomp/Loop.cpp: tiny whitespace fix. No functional change. -2015-05-20 15:47:45 +0200 Vadim Troshchinskiy (8d9e8f70b) +2015-05-20 15:47:45 +0200 Vadim Troshchinskiy (8d9e8f7) * Fix negotiation in stage 10 error -2015-09-26 00:28:14 +0200 Ulrich Sibiller (1fe33b710) +2015-09-26 00:28:14 +0200 Ulrich Sibiller (1fe33b7) * use xfree instead of free for xalloced data + (gh-uli42/pr/backported_fixes) -2015-09-23 12:15:06 +0200 Mike Gabriel (da6b89f7e) +2015-09-23 12:15:06 +0200 Mike Gabriel (da6b89f) * debian/libnx-xinerama1.postinst.in: Enforce symlink creation for Xinerama support. -2015-09-22 15:02:22 +0200 Mike Gabriel (4db753eb7) +2015-09-22 15:02:22 +0200 Mike Gabriel (4db753e) * Revert "debian/libnx-xinerama1.*: fix faulty logic when creating symlinks." -2015-08-26 01:06:28 +0200 Ulrich Sibiller (f8772b6fc) +2015-08-26 01:06:28 +0200 Ulrich Sibiller (f8772b6) * adapt pkgconfigdir in nxcompshad -2015-08-26 01:02:34 +0200 Ulrich Sibiller (96a1c5edf) +2015-08-26 01:02:34 +0200 Ulrich Sibiller (96a1c5e) * Fix "Makefile.in seems to ignore the --datarootdir setting" warning -2015-08-26 00:29:14 +0200 Ulrich Sibiller (6615de8dd) +2015-08-26 00:29:14 +0200 Ulrich Sibiller (6615de8) * create pkgcnfig dir before copying anything -2015-07-17 18:13:00 +0200 Mihai Moldovan (edeb4e196) +2015-07-17 18:13:00 +0200 Mihai Moldovan (edeb4e1) * nx-libs.spec: add xkeyboard-config to nxagent's Requires. -2015-07-17 17:57:24 +0200 Mihai Moldovan (813d0cf13) +2015-07-17 17:57:24 +0200 Mihai Moldovan (813d0cf) * debian/control: add xkb-data to nxagent's Recommends. -2015-07-17 17:48:44 +0200 Mihai Moldovan (0606ec814) +2015-07-17 17:48:44 +0200 Mihai Moldovan (0606ec8) * debian/roll-tarballs.sh: more quotes, more curly braces, replace cd with pushd and pop. -2015-07-15 09:30:29 +0200 Mike Gabriel (01ad7dad4) +2015-07-15 09:30:29 +0200 Mike Gabriel (01ad7da) * roll-tarball.sh: more quotes (follow-up for previous commit), drop debug code -2015-07-14 20:39:58 +0200 Mike Gabriel (c2761fb7c) +2015-07-14 20:39:58 +0200 Mike Gabriel (c2761fb) * roll-tarball.sh: Make sure symlinked files are included in tarballs. -2015-07-14 15:14:55 +0200 Mike Gabriel (c1d502e1c) +2015-07-14 15:14:55 +0200 Mike Gabriel (c1d502e) * nx-libs.spec: Install nxcomp{,ext,shad}.pc into the corresponding development packages. -2015-07-14 14:46:42 +0200 Mike Gabriel (931050cbe) +2015-07-14 14:46:42 +0200 Mike Gabriel (931050c) * debian/libxcomp{,ext,shad}-dev.install.in: Install nxcomp{,ext,shad}.pc file into the corresponding development packages. -2015-07-14 14:43:34 +0200 Mike Gabriel (ee0ed871a) +2015-07-14 14:43:34 +0200 Mike Gabriel (ee0ed87) * nxcomp{,ext,shad}/Makefile.in: Create pkgconfigdir before putting files in it. -2015-07-14 01:39:17 +0200 Mike Gabriel (39ae81788) +2015-07-14 01:39:17 +0200 Mike Gabriel (39ae817) * nxcomp{,shad,ext}: Remove nxcomp*.pc file on clean and distclean. -2015-07-14 01:26:33 +0200 Mike Gabriel (5eecadb53) +2015-07-14 01:26:33 +0200 Mike Gabriel (5eecadb) * Makefile: Also remove nxversion.def on distclean. -2015-07-14 00:04:01 +0200 Mike Gabriel (e5fbb11b2) +2015-07-14 00:04:01 +0200 Mike Gabriel (e5fbb11) * Merge branch 'uli42-pr/add_pkgconfig' into 3.6.x -2015-07-12 01:52:29 +0200 Ulrich Sibiller (00cec4924) +2015-07-12 01:52:29 +0200 Ulrich Sibiller (00cec49) * Add pkg-config support to nxcomp, nxcompext and nxcompshad -2015-07-04 06:46:29 +0200 Mihai Moldovan (f4c07c077) +2015-07-04 06:46:29 +0200 Mihai Moldovan (f4c07c0) * debian/changelog: sync with master/3.5.0.x branch. -2015-07-03 17:07:30 +0200 Mihai Moldovan (ca19c342c) +2015-07-03 17:07:30 +0200 Mihai Moldovan (ca19c34) * Merge branch 'uli42-pr/backported_fixes' into arctica-3.6.x -2009-02-13 10:23:28 +0100 Peter Åstrand (d08869832) +2009-02-13 10:23:28 +0100 Peter Åstrand (d088698) * Backport: xserver: Avoid sending uninitialized padding data over the network -2015-06-29 04:13:59 +0200 Mihai Moldovan (61013ec4f) +2015-06-29 04:13:59 +0200 Mihai Moldovan (61013ec) * Merge branch 'sunweaver-pr/no-autotools-cruft' into arctica-3.6.x -2015-06-29 03:40:58 +0200 Mihai Moldovan (fa0286ed6) +2015-06-29 03:40:58 +0200 Mihai Moldovan (fa0286e) * debian/changelog: sync with master/3.5.0.x branch. -2015-06-28 01:50:00 -0400 Mike DePaulo (779d54645) +2015-06-28 01:50:00 -0400 Mike DePaulo (779d546) * Correct nxproxy manpage also: --help -> -help -2015-06-28 01:33:49 -0400 Mike DePaulo (12acd909b) +2015-06-28 01:33:49 -0400 Mike DePaulo (12acd90) * Correct manpages: --help -> -help -2015-06-23 16:24:56 +0200 Mike Gabriel (a28be4aa9) +2015-06-23 16:24:56 +0200 Mike Gabriel (a28be4a) * library clean-up: No autotools cruft in nx-libs. -2015-06-25 05:04:12 +0200 Mike Gabriel (e7f3187ee) +2015-06-25 05:04:12 +0200 Mike Gabriel (e7f3187) * doc/examples/run-nxproxy2nxproxy-test: Create NX_COOKIE dynamically using the mcookie tool. -2015-06-23 16:39:33 +0200 Mihai Moldovan (32bbe01dd) +2015-06-23 16:39:33 +0200 Mihai Moldovan (32bbe01) * Merge branch 'sunweaver-pr/roll-tarball-fixes' into arctica-3.6.x -2015-05-28 14:52:24 +0200 Mike Gabriel (5af9863e7) +2015-05-28 14:52:24 +0200 Mike Gabriel (5af9863) * COPYING: Replace content with GPL-2 license text, because that is the overall (i.e., strictest) license we have to deal with in nx-libs. -2015-05-28 14:50:05 +0200 Mike Gabriel (438f3df14) +2015-05-28 14:50:05 +0200 Mike Gabriel (438f3df) * debian/roll-tarball.sh: Auto-generate ChangeLog from Git history. -2015-05-28 14:49:40 +0200 Mike Gabriel (7e1effbe7) +2015-05-28 14:49:40 +0200 Mike Gabriel (7e1effb) * debian/roll-tarball.sh: Rename README.md to README.NX-Development before moving it into doc/ folder. -2015-05-28 14:33:08 +0200 Mike Gabriel (47afc48ea) +2015-05-28 14:33:08 +0200 Mike Gabriel (47afc48) * debian/roll-tarball.sh: Prevent several files/folders from ending up in nx-libs-lite tarball. -2015-05-28 13:33:43 +0200 Mike Gabriel (895ee3b3b) +2015-05-28 13:33:43 +0200 Mike Gabriel (895ee3b) * debian/roll-tarball.sh: Support tarring up the HEAD of the current branch. -2015-05-28 13:29:27 +0200 Mike Gabriel (701471e8e) +2015-05-28 13:29:27 +0200 Mike Gabriel (701471e) * debian/roll-tarball.sh: Allow patch files names having a dash next to the four digits (i.e., 1234-.). -2015-06-23 16:14:41 +0200 Mike Gabriel (ce9ea5448) +2015-06-23 16:14:41 +0200 Mike Gabriel (ce9ea54) * Merge branch 'pr/anti-aliasing-rgba-crash' into 3.6.x -2015-06-23 16:09:50 +0200 Emanuele Giaquinta (ffc87da60) +2015-06-23 16:09:50 +0200 Emanuele Giaquinta (ffc87da) * Fix alpha premultiplication in XRenderParseColor. -2015-06-23 02:30:02 +0200 Mihai Moldovan (8cf9283bd) +2015-06-23 02:30:02 +0200 Mihai Moldovan (8cf9283) * Merge branch 'sunweaver-pr/libXx86FOO-cleanup' into arctica-3.6.x -2015-05-27 12:34:12 +0200 Mike Gabriel (06d389a0c) +2015-05-27 12:34:12 +0200 Mike Gabriel (06d389a) * library clean-up: Drop libXx86{misc,vm,dga} libraries. Not needed by nx-libs. (gh-sunweaver/pr/libXx86FOO-cleanup) -2015-06-22 03:38:46 +0200 Mihai Moldovan (e7dfbd511) +2015-06-22 03:38:46 +0200 Mihai Moldovan (e7dfbd5) * Merge branch 'sunweaver-pr/libxf86rush-cleanup' into arctica-3.6.x -2015-05-27 10:20:29 +0200 Mike Gabriel (5365f9059) +2015-05-27 10:20:29 +0200 Mike Gabriel (5365f90) * library clean-up: Drop nx-X11/lib/Xxf86rush and references to libglide{2,3}. Unused in nx-libs. (gh-sunweaver/pr/libxf86rush-cleanup) -2015-06-21 10:50:31 +0200 Mihai Moldovan (fb2a4e4c5) +2015-06-21 10:50:31 +0200 Mihai Moldovan (fb2a4e4) * Merge branch 'sunweaver-pr/hw-driver-cleanup' into arctica-3.6.x -2015-05-27 09:48:26 +0200 Mike Gabriel (26091f4bd) +2015-05-27 09:48:26 +0200 Mike Gabriel (26091f4) * nx-X11/config/cf: Drop build-logic for all hardware drivers. (gh-sunweaver/pr/hw-driver-cleanup) -2015-05-27 08:38:11 +0200 Mike Gabriel (ae443bd5b) +2015-05-27 08:38:11 +0200 Mike Gabriel (ae443bd) * nx-X11/config/cf: Drop unnecessary xf86site.def, xf86.tmpl, xfree86.cf. -2015-05-27 08:26:40 +0200 Mike Gabriel (c0662d6de) +2015-05-27 08:26:40 +0200 Mike Gabriel (c0662d6) * nx-X11/config/cf/Imakefile: Don't list non-present-anymore imake configuration files. -2015-06-20 17:47:39 +0200 Mike Gabriel (cc92f77e9) +2015-06-20 17:47:39 +0200 Mike Gabriel (cc92f77) * libgl clean-up, fix-up commit -2015-06-20 17:35:00 +0200 Mike DePaulo (88ab5a34f) +2015-06-20 17:35:00 +0200 Mike DePaulo (88ab5a3) * README.md: typo fix -2015-06-20 14:39:56 +0200 Mike Gabriel (905c74da3) +2015-06-20 14:39:56 +0200 Mike Gabriel (905c74d) * Merge pull request #52 from woglinde/3.6.x -2015-06-20 11:34:04 +0200 Henning Heinold (a287e9dbe) +2015-06-20 11:34:04 +0200 Henning Heinold (a287e9d) * remove libxkbui, looks like it is not used anywhere -2015-06-19 23:58:49 +0200 Mike Gabriel (4674a4ae4) +2015-06-19 23:58:49 +0200 Mike Gabriel (4674a4a) * debian/control: Add Breaks:/Replaces: for qvd-libxcomp3 and qvd-nxproxy. -2015-06-16 23:58:50 +0200 Mihai Moldovan (51b60ea7a) +2015-06-16 23:58:50 +0200 Mihai Moldovan (51b60ea) * Merge branch 'sunweaver-pr/libglx-cleanup' into arctica-3.6.x -2015-05-27 08:10:38 +0200 Mike Gabriel (5cd80d272) +2015-05-27 08:10:38 +0200 Mike Gabriel (5cd80d2) * imake clean-up: Enforce build of Mesa GLX extension. Drop all other GLX build methods (built-in DRI drivers, etc.). (gh-sunweaver/pr/libglx-cleanup) -2015-05-26 16:44:49 +0200 Mike Gabriel (73fa89991) +2015-05-26 16:44:49 +0200 Mike Gabriel (73fa899) * Drop unused / untested Xserver GLX extension support / build logic. -2015-05-26 16:22:40 +0200 Mike Gabriel (cb4a2d732) +2015-05-26 16:22:40 +0200 Mike Gabriel (cb4a2d7) * Drop nx-X11/lib/GL and move Imakefile.inc include files into Xserver code tree. -2015-06-16 22:43:21 +0200 Mihai Moldovan (5a64974cc) +2015-06-16 22:43:21 +0200 Mihai Moldovan (5a64974) * nxcomp/Loop.cpp: tiny whitespace fix. No functional change. -2015-06-16 10:41:12 +0200 Mike Gabriel (d8f3aa414) +2015-06-16 10:41:12 +0200 Mike Gabriel (d8f3aa4) * Merge pull request #28 from theqvd/3.6.x -2009-05-28 14:43:27 -0700 Keith Packard (cf660f485) +2009-05-28 14:43:27 -0700 Keith Packard (cf660f4) * Backport: Make RANDR 'set' timestamps follow client specified time. Bug 21987. -2012-06-21 18:42:46 -0700 Keith Packard (9dbd74793) +2012-06-21 18:42:46 -0700 Keith Packard (9dbd747) * Backport: randr: Clean up compiler warnings about unused and shadowing variables -2012-06-29 13:33:58 -0700 Aaron Plattner (9e2ac01a4) +2012-06-29 13:33:58 -0700 Aaron Plattner (9e2ac01) * Backport: randr: Fix REQUEST vs. REQUEST_SIZE_MATCH mismatch -2012-07-09 19:12:42 -0700 Alan Coopersmith (bd5754f94) +2012-07-09 19:12:42 -0700 Alan Coopersmith (bd5754f) * Backport: ProcRRGetScreenInfo: swap configTimestamp as well -2012-07-14 11:21:15 -0700 Alan Coopersmith (0fc419314) +2012-07-14 11:21:15 -0700 Alan Coopersmith (0fc4193) * Backport: RRModeCreate: plug memory leak of newModes if AddResource fails -2009-05-22 09:54:38 +0200 Julien Cristau (faddfbec6) +2009-05-22 09:54:38 +0200 Julien Cristau (faddfbe) * Backport: randr: fix server crash in RRGetScreenInfo -2010-12-17 16:09:35 +0200 Tiago Vignatti (da678db0e) +2010-12-17 16:09:35 +0200 Tiago Vignatti (da678db) * Backport: randr: check for virtual size limits before set crtc -2009-09-17 18:14:37 -0700 Keith Packard (2aeb76719) +2009-09-17 18:14:37 -0700 Keith Packard (2aeb767) * Backport: Free randr crtc and output pointer arrays -2008-09-10 13:11:09 +0800 Keith Packard (f45476100) +2008-09-10 13:11:09 +0800 Keith Packard (f454761) * Backport: Drop a reference to user mode after create -2012-07-09 19:12:42 -0700 Jaroslav Šmíd (8fd0b52f2) +2012-07-09 19:12:42 -0700 Jaroslav Šmíd (8fd0b52) * Backport: Bug 51375: Xorg doesn't set status for RRGetOutputInfo -2015-06-02 21:54:12 +0200 Mihai Moldovan (b5d78278d) +2015-06-02 21:54:12 +0200 Mihai Moldovan (b5d7827) * Merge branch 'sunweaver-pr/libxres-cleanup' into arctica-3.6.x -2015-06-02 21:12:05 +0200 Mihai Moldovan (167d09ed7) +2015-06-02 21:12:05 +0200 Mihai Moldovan (167d09e) * debian/changelog: sync with master/3.5.0.x branch. -2015-05-26 12:30:48 +0200 Mike Gabriel (6a74e671a) +2015-05-26 12:30:48 +0200 Mike Gabriel (6a74e67) * library clean-up: Don't compile (i.e., remove) libNX_Xres.a anymore. It is not used anywhere. (gh-sunweaver/pr/libxres-cleanup) -2015-05-31 17:21:10 +0200 Mike Gabriel (01b142ddf) +2015-05-31 17:21:10 +0200 Mike Gabriel (01b142d) * Update README.md: Move more release goals to 3.6.x. -2015-05-31 17:15:24 +0200 Mike Gabriel (dddffb760) +2015-05-31 17:15:24 +0200 Mike Gabriel (dddffb7) * Merge pull request #46 from ArcticaProject/pr/Xext-cve-fixes -2015-05-31 16:50:39 +0200 Mike Gabriel (11b26436b) +2015-05-31 16:50:39 +0200 Mike Gabriel (11b2643) * Merge pull request #45 from ArcticaProject/pr/dix-cve-fixes -2014-01-26 19:23:17 -0800 Alan Coopersmith (d1ca2119a) +2014-01-26 19:23:17 -0800 Alan Coopersmith (d1ca211) * Xv: unvalidated lengths in XVideo extension swapped procs - [CVE-2014-8099] (origin/pr/Xext-cve-fixes) + [CVE-2014-8099] (origin/pr/Xext-cve-fixes, + gh-Ionic/pr/Xext-cve-fixes) -2015-05-01 13:09:24 +0200 Keith Packard (2db01a9a2) +2015-05-01 13:09:24 +0200 Keith Packard (2db01a9) * dix: Allow zero-height PutImage requests (fix for X.Org's - CVE-2015-3418). (origin/pr/dix-cve-fixes) + CVE-2015-3418). (origin/pr/dix-cve-fixes, + gh-Ionic/pr/dix-cve-fixes) -2014-01-22 21:11:16 -0800 Alan Coopersmith (8623faa42) +2014-01-22 21:11:16 -0800 Alan Coopersmith (8623faa) * dix: integer overflow in ProcPutImage() [CVE-2014-8092 1/4] -2015-02-08 20:01:27 -0500 Mike DePaulo (c2298e075) +2015-02-08 20:01:27 -0500 Mike DePaulo (c2298e0) * Avoid use-after-free in dix/dixfonts.c: doImageText() [CVE-2013-4396] from xorg/Xserver http://lists.x.org/archives/xorg-announce/2013-October/002332.html -2015-05-29 11:15:19 +0200 Mike Gabriel (4ed85e8ef) +2015-05-29 11:15:19 +0200 Mike Gabriel (4ed85e8) * nxcomp/README.on-retroactive-DXPC-license: Some layout and interpunctuation fixes. -2015-05-28 22:36:59 +0200 Mihai Moldovan (5bc91ad49) +2015-05-28 22:36:59 +0200 Mihai Moldovan (5bc91ad) * nxcomp/Misc.cpp: fix build failure introduced in 1f44331574bdbe4069d13e4c26df18094b49e658. -2015-05-26 16:51:38 +0200 Mihai Moldovan (beb08f96c) +2015-05-26 16:51:38 +0200 Mihai Moldovan (beb08f9) * Merge branch 'sunweaver-pr/DXPC-re-license-retroactively' into arctica-3.6.x -2015-05-26 10:31:46 +0200 Mike Gabriel (e364fde72) +2015-05-26 10:31:46 +0200 Mike Gabriel (e364fde) * Merge pull request #36 from ArcticaProject/pr/render-cve-fixes -2015-05-21 12:25:13 +0200 Mike Gabriel (1f4433157) +2015-05-21 12:25:13 +0200 Mike Gabriel (1f44331) * Document retroactive re-licensing of the original DXPC code (closes #30). -2015-05-25 23:23:22 +0200 Mihai Moldovan (230852e0e) +2015-05-25 23:23:22 +0200 Mihai Moldovan (230852e) * Merge branch 'sunweaver-pr/libxrandr-cleanup' into arctica-3.6.x -2014-01-26 19:51:29 -0800 Alan Coopersmith (a0c90ad34) +2014-01-26 19:51:29 -0800 Alan Coopersmith (a0c90ad) * render: unvalidated lengths in Render extn. swapped procs - [CVE-2014-8100 2/2] (origin/pr/render-cve-fixes) + [CVE-2014-8100 2/2] (origin/pr/render-cve-fixes, + gh-Ionic/pr/render-cve-fixes) -2014-10-28 10:30:04 +0100 Julien Cristau (e469cff02) +2014-10-28 10:30:04 +0100 Julien Cristau (e469cff) * render: check request size before reading it [CVE-2014-8100 1/2] -2015-05-22 00:58:38 +0200 Mihai Moldovan (608ee9928) +2015-05-22 00:58:38 +0200 Mihai Moldovan (608ee99) * README.md: replace simple link with a text link, capitalization. -2015-05-22 00:43:53 +0200 Mihai Moldovan (7846638a8) +2015-05-22 00:43:53 +0200 Mihai Moldovan (7846638) * Merge branch 'nitomartinez-qindel-readme' into arctica-3.6.x -2015-05-21 21:43:30 +0200 Nito Martinez (900b0cc2d) +2015-05-21 21:43:30 +0200 Nito Martinez (900b0cc) * Update the Qindel Company name (Qindel is without u ;-)) -2015-05-20 15:47:45 +0200 Vadim Troshchinskiy (f982cbc85) +2015-05-20 15:47:45 +0200 Vadim Troshchinskiy (f982cbc) * Fix negotiation in stage 10 error -2015-05-20 11:30:05 +0200 Mike Gabriel (a6185abd9) +2015-05-20 11:30:05 +0200 Mike Gabriel (a6185ab) * hw/nxagent clean-up: Drop NXrandr.{c|h} client lib copy-of-code from nxagent hardware driver. -2015-05-01 15:57:02 +0200 Mike Gabriel (e9dcab679) +2015-05-01 15:57:02 +0200 Mike Gabriel (e9dcab6) * library clean-up: Don't build libNX_Xrandr anymore. Use system's libXrandr shared library. -2015-05-16 15:54:37 +0200 Mike Gabriel (24903c921) +2015-05-16 15:54:37 +0200 Mike Gabriel (24903c9) * README.md: mark the iOS support for nxproxy/nxcomp as completed. -2015-05-16 15:15:41 +0200 Mike Gabriel (657acf98a) +2015-05-16 15:15:41 +0200 Mike Gabriel (657acf9) * Merge pull request #26 from nitomartinez/fix_developer_debugging -2015-05-16 15:12:19 +0200 Mike Gabriel (91ac79ecc) +2015-05-16 15:12:19 +0200 Mike Gabriel (91ac79e) * Merge pull request #25 from nitomartinez/nxtranscleanup_for_reconnect -2015-05-15 22:40:05 +0200 Nito Martinez (cf4ed917e) +2015-05-15 22:40:05 +0200 Nito Martinez (cf4ed91) * This patch is some code fixes to debug some debuging macro usage in the NX code. -2015-05-15 17:06:00 +0200 Mihai Moldovan (ab96962b1) +2015-05-15 17:06:00 +0200 Mihai Moldovan (ab96962) * README.md: reword a few sections, whitespace fixes. -2015-05-15 16:34:27 +0200 Mike Gabriel (8512c700a) +2015-05-15 16:34:27 +0200 Mike Gabriel (8512c70) * README.md: grammar fix -2015-05-15 16:33:20 +0200 Mike Gabriel (d73351532) +2015-05-15 16:33:20 +0200 Mike Gabriel (d733515) * README.md: phase 2 release series will be 3.7.0.x -2015-05-15 16:26:58 +0200 Mike Gabriel (50c3f5628) +2015-05-15 16:26:58 +0200 Mike Gabriel (50c3f56) * update README.md with newest plans for nx-libs 3.6.x -2015-05-15 15:20:52 +0200 Nito Martinez (4fefe352c) +2015-05-15 15:20:52 +0200 Nito Martinez (4fefe35) * This patch allows to cleanup the nxcomp resources to allow for a second connection inside the same process, instead of a new process as is the nxproxy case. -2015-05-12 06:07:45 +0200 Mihai Moldovan (f7295831a) +2015-05-12 06:07:45 +0200 Mihai Moldovan (f729583) * Merge branch 'sunweaver-pr/libxdamage-cleanup' into arctica-3.6.x -2015-05-05 01:23:04 +0200 Mihai Moldovan (027f593fc) +2015-05-05 01:23:04 +0200 Mihai Moldovan (027f593) * debian/changelog: merge with master branch. -2015-05-05 01:22:41 +0200 Mihai Moldovan (998527ce5) +2015-05-05 01:22:41 +0200 Mihai Moldovan (998527c) * debian/changelog: add entry for last change. -2015-05-05 01:22:18 +0200 Mihai Moldovan (b77b26f4a) +2015-05-05 01:22:18 +0200 Mihai Moldovan (b77b26f) * debian/libnx-xinerama1.*: fix faulty logic when creating symlinks. -2015-05-05 01:23:04 +0200 Mihai Moldovan (b573cbba9) +2015-05-05 01:23:04 +0200 Mihai Moldovan (b573cbb) * debian/changelog: merge with master branch. -2015-05-05 01:22:41 +0200 Mihai Moldovan (fca264fd0) +2015-05-05 01:22:41 +0200 Mihai Moldovan (fca264f) * debian/changelog: add entry for last change. -2015-05-05 01:22:18 +0200 Mihai Moldovan (06f36d0f0) +2015-05-05 01:22:18 +0200 Mihai Moldovan (06f36d0) * debian/libnx-xinerama1.*: fix faulty logic when creating symlinks. -2015-05-01 16:16:30 -0400 Mike DePaulo (c9d81fc38) +2015-05-01 16:16:30 -0400 Mike DePaulo (c9d81fc) * Merge pull request #20 from sunweaver/pr/fix-CVE-2015-3418 -2015-04-27 16:08:06 +0200 Mike Gabriel (06aa41671) +2015-04-27 16:08:06 +0200 Mike Gabriel (06aa416) * library clean-up: Don't build libNX_Xdamage anymore. Use system's libXdamage shared library. (Fixes ArcticaProject/nx-libs#6, X2GoBTS#826). -2015-05-01 13:09:24 +0200 Keith Packard (dba779d9f) +2015-05-01 13:09:24 +0200 Keith Packard (dba779d) * dix: Allow zero-height PutImage requests (fix for X.Org's CVE-2015-3418). -2015-04-30 15:51:48 +0200 Mihai Moldovan (7ccbb073f) +2015-04-30 15:51:48 +0200 Mihai Moldovan (7ccbb07) * debian/changelog: sync with 3.5.0.x branch. -2015-04-30 15:14:24 +0200 Mihai Moldovan (e6e323a22) +2015-04-30 15:14:24 +0200 Mihai Moldovan (e6e323a) * nx-libs.spec: actually create libXinerama.so.1 symlink during build phase. -2015-04-30 14:43:04 +0200 Mihai Moldovan (e59561387) +2015-04-30 14:43:04 +0200 Mihai Moldovan (e595613) * debian/changelog: correctly sync with 3.5.0.x branch. Add latest entries. -2015-04-30 14:25:25 +0200 Mihai Moldovan (a9bc7bdb6) +2015-04-30 14:25:25 +0200 Mihai Moldovan (a9bc7bd) * debian/libnx-xinerama1.*: move Xinerama dir back to nx-x11-common. Only delete known files. Fixes RPM build failures. -2015-04-29 08:04:44 +0200 Mike Gabriel (7a6b40a11) +2015-04-29 08:04:44 +0200 Mike Gabriel (7a6b40a) * Merge pull request #19 from ArcticaProject/PR-ionic/libXinerama_symlink_to_libnx-xinerama1 -2015-04-28 23:00:43 +0200 Mihai Moldovan (83983e944) +2015-04-28 23:00:43 +0200 Mihai Moldovan (83983e9) * libnx-xinerama1: also create libXinerama symlink in postinst (and remove in prerm.) -2015-04-28 05:15:19 +0200 Mihai Moldovan (7b7ba9441) +2015-04-28 05:15:19 +0200 Mihai Moldovan (7b7ba94) * Merge branch 'sunweaver-pr/imake-cleanup-nonpresent-buildlogic' into arctica-3.6.x -2015-04-22 00:37:47 +0200 Mike Gabriel (662a89545) +2015-04-22 00:37:47 +0200 Mike Gabriel (662a895) * imake cleanup: Drop references to X11 build-logic that is not present in nx-X11. -2015-04-21 10:57:56 +0200 Mike Gabriel (c189f6efc) +2015-04-21 10:57:56 +0200 Mike Gabriel (c189f6e) * imake cleanup: Break up multiple vars into invidual lines to ease further work on patches / pull requests. -2015-04-27 16:10:26 +0200 Mike Gabriel (cbf4e4dbe) +2015-04-27 16:10:26 +0200 Mike Gabriel (cbf4e4d) * COPYING: Add Arctica Project to copyright holders. -2015-04-27 02:56:07 +0200 Mihai Moldovan (99ef17f90) +2015-04-27 02:56:07 +0200 Mihai Moldovan (99ef17f) * debian/changelog: merge with 3.5.0.x branch. -2015-04-27 02:45:10 +0200 Mihai Moldovan (f717a7e81) +2015-04-27 02:45:10 +0200 Mihai Moldovan (f717a7e) * README.keystrokes: remove accidentally copied Dokuwiki syntax. -2015-04-27 02:02:15 +0200 Mihai Moldovan (380a4df0f) +2015-04-27 02:02:15 +0200 Mihai Moldovan (380a4df) * etc/keystrokes.cfg: fix whitespace errors. -2015-04-27 02:00:43 +0200 Mihai Moldovan (a430b4a87) +2015-04-27 02:00:43 +0200 Mihai Moldovan (a430b4a) * README.keystrokes: add documentation for branding behavior. -2015-04-27 01:59:53 +0200 Mihai Moldovan (1c0f42d30) +2015-04-27 01:59:53 +0200 Mihai Moldovan (1c0f42d) * README.keystrokes: copy actions documentation from the wiki. -2015-04-26 23:49:06 +0200 Mihai Moldovan (347e97335) +2015-04-26 23:49:06 +0200 Mihai Moldovan (347e973) * debian/roll-tarballs.sh: don't escape last newline of a multiline command. -2015-04-26 23:48:02 +0200 Mihai Moldovan (21a556b37) +2015-04-26 23:48:02 +0200 Mihai Moldovan (21a556b) * debian/roll-tarballs.sh: use more curly braces. -2015-04-26 23:47:33 +0200 Mihai Moldovan (cf9181918) +2015-04-26 23:47:33 +0200 Mihai Moldovan (cf91819) * debian/roll-tarballs.sh: convert tabs to spaces. -2015-04-26 23:45:42 +0200 Mihai Moldovan (e68c36625) +2015-04-26 23:45:42 +0200 Mihai Moldovan (e68c366) * debian/roll-tarballs.sh: use more quotes. -2015-04-26 16:35:14 +0200 Mike Gabriel (f2fd79416) +2015-04-26 16:35:14 +0200 Mike Gabriel (f2fd794) * libXcompshad underlinking problem: Fix undefined reference to 'XShmQueryVersion', 'XShmDetach', 'XShmCreateImage', 'XShmAttach', and 'XShmGetImage'. -2015-04-26 16:11:57 +0200 Mike Gabriel (4a3a4737f) +2015-04-26 16:11:57 +0200 Mike Gabriel (4a3a473) * Fix underlinking issues for libNX_X{composite,damage,fixes}. -2015-04-26 15:41:46 +0200 Mike Gabriel (305ac7889) +2015-04-26 15:41:46 +0200 Mike Gabriel (305ac78) * libX11 underlinking problem: Fix undefined reference to 'XdmcpWrap' (by linking against X.Org'x libXdmcp). -2015-04-26 15:12:39 +0200 Mike Gabriel (f46b43261) +2015-04-26 15:12:39 +0200 Mike Gabriel (f46b432) * libX11 underlinking problem: Fix undefined reference to 'dlopen' and 'dlsym'. (Fixes: X2GoBTS#853). -2015-04-23 13:29:10 +0200 Mihai Moldovan (2b159e18d) +2015-04-23 13:29:10 +0200 Mihai Moldovan (2b159e1) * Merge branch 'sunweaver-pr/xbitmaps-cleanup' into arctica-3.6.x -2015-04-21 10:42:47 +0200 Mike Gabriel (e69b7d1ec) +2015-04-21 10:42:47 +0200 Mike Gabriel (e69b7d1) * xbitmaps cleanup: The headers are not required at build time for NX. -2015-04-22 22:48:54 +0200 Mihai Moldovan (825af1835) +2015-04-22 22:48:54 +0200 Mihai Moldovan (825af18) * Merge branch 'sunweaver-pr/libxdmcp-cleanup' into arctica-3.6.x -2015-04-05 18:07:53 +0200 Mike Gabriel (49fc383a4) +2015-04-05 18:07:53 +0200 Mike Gabriel (49fc383) * library clean-up: Don't build libNX_Xdmcp anymore. Use system's libXdmcp shared library. -2015-04-22 22:41:14 +0200 Mike Gabriel (a5bb88824) +2015-04-22 22:41:14 +0200 Mike Gabriel (a5bb888) * nx-libs.spec: Drop packaging of libNX_Xpm*, in RPM packages there is no such concept for transitional/dummy packages as know from Debian/Ubuntu. -2015-04-22 22:39:14 +0200 Mike Gabriel (294d91223) +2015-04-22 22:39:14 +0200 Mike Gabriel (294d912) * debian/control: Typo fix (Meas -> Mesa). -2015-04-22 08:38:21 +0200 Mihai Moldovan (b964406ba) +2015-04-22 08:38:21 +0200 Mihai Moldovan (b964406) * Merge branch 'sunweaver-pr/libxfont-cleanup' into arctica-3.6.x -2015-04-14 09:24:55 +0200 Mike Gabriel (70b77a0fc) +2015-04-14 09:24:55 +0200 Mike Gabriel (70b77a0) * library clean-up: Don't build and link libXfont.a anymore. Use system's libXfont shared library and link dynamically. - (origin/pr/libxfont-cleanup) + (origin/pr/libxfont-cleanup, gh-Ionic/pr/libxfont-cleanup) -2015-04-21 15:28:25 +0200 Mike Gabriel (a77ca871c) +2015-04-21 15:28:25 +0200 Mike Gabriel (a77ca87) * fix for Xcursor clean-up (422fe90) -2015-04-17 00:12:52 +0200 Mike Gabriel (a20e77b7c) +2015-04-17 00:12:52 +0200 Mike Gabriel (a20e77b) * imake cleanup (nx-X11/programs/Xserver/Imakefile): Drop build rules for XF86Server and XorgServer. -2015-04-16 18:30:39 -0400 Mike DePaulo (8b1577599) +2015-04-16 18:30:39 -0400 Mike DePaulo (8b15775) * Merge pull request #12 from sunweaver/pr/arch-cleanup.CRAY -2015-04-16 22:12:45 +0200 Mihai Moldovan (0d9217127) +2015-04-16 22:12:45 +0200 Mihai Moldovan (0d92171) * Merge branch 'sunweaver-pr/xcursor-cleanup' into arctica-3.6.x -2015-04-08 21:52:51 +0200 Mike Gabriel (422fe9071) +2015-04-08 21:52:51 +0200 Mike Gabriel (422fe90) * library clean-up: Drop nx-X11/lib/Xcursor. Not used at build time. -2015-04-16 18:03:18 +0200 Mihai Moldovan (cfc0202b4) +2015-04-16 18:03:18 +0200 Mihai Moldovan (cfc0202) * Merge branch 'sunweaver-pr/nxupgradeagent-cleanup' into arctica-3.6.x -2015-04-14 09:42:35 +0200 Mike Gabriel (a5f71f084) +2015-04-14 09:42:35 +0200 Mike Gabriel (a5f71f0) * NXAGENT_UPGRADE code cleanup: -2015-04-15 10:16:18 +0200 Karl Tomlinson (ac9fbaabd) +2015-04-15 10:16:18 +0200 Karl Tomlinson (ac9fbaa) * MakeBigReq: don't move the last word, already handled by Data32 (X.Org CVE-2013-7439). -2015-04-15 09:58:01 +0200 Mike Gabriel (bad677992) +2015-04-15 09:58:01 +0200 Mike Gabriel (bad6779) * old-arch cleanup: Drop CRAY support (i.e., drop code related to CRAY, _CRAY, WORD64, WORD64ALIGN, MUSTCOPY, UNSIGNEDBITFIELDS definitions). -2015-04-15 12:37:30 +0200 Mike Gabriel (fad840cfe) +2015-04-15 12:37:30 +0200 Mike Gabriel (fad840c) * test script: doc/examples/run-nxproxy2nxproxy-test -2015-04-13 15:48:07 +0200 Mike Gabriel (097562b8b) +2015-04-13 15:48:07 +0200 Mike Gabriel (097562b) * drop: nx-X11/config/util/ (not needed at build time). -2015-04-13 15:39:36 +0200 Mike Gabriel (a8dad09a5) +2015-04-13 15:39:36 +0200 Mike Gabriel (a8dad09) * imake clean-up: nx-X11/config/Imakefile (drop BuildDPSLibrary related build-logic). -2015-04-11 17:38:02 +0200 Mike Gabriel (2f4d7dbb4) +2015-04-11 17:38:02 +0200 Mike Gabriel (2f4d7db) * fix for libXpm4-cleanup -2015-04-05 22:31:33 +0200 Mike Gabriel (d97b0ca93) +2015-04-05 22:31:33 +0200 Mike Gabriel (d97b0ca) * fix for ebe00df38f264ef71dac3c73d416a74685c8cbd2 (removal of DmxLibrary) -2015-04-05 20:58:58 +0200 Mihai Moldovan (bb23f7a3d) +2015-04-05 20:58:58 +0200 Mihai Moldovan (bb23f7a) * Merge branch 'feature/other-Xserver-cleanup' into arctica-3.6.x -2015-03-04 14:08:50 +0100 Mike Gabriel (d280fa15e) +2015-03-04 14:08:50 +0100 Mike Gabriel (d280fa1) * imake clean: Remove (probably incomplete) support for NXZaurusXServer, NXiPAQXServer. -2015-03-04 13:56:53 +0100 Mike Gabriel (6db94c3e1) +2015-03-04 13:56:53 +0100 Mike Gabriel (6db94c3) * imake cleanup: nx-X11/programs/Xserver/Imakefile (drop non-provided Xserver variants) -2015-03-04 13:43:54 +0100 Mike Gabriel (05d208351) +2015-03-04 13:43:54 +0100 Mike Gabriel (05d2083) * imake cleanup: nx-X11/programs/Imakefile (reduce to minimal). -2015-03-04 13:34:21 +0100 Mike Gabriel (78ac4396a) +2015-03-04 13:34:21 +0100 Mike Gabriel (78ac439) * imake cleanup: Drop all references to BuildFontServer. -2015-03-04 13:29:02 +0100 Mike Gabriel (f5f280417) +2015-03-04 13:29:02 +0100 Mike Gabriel (f5f2804) * imake cleanup: Drop all references to XprtServer and BuildXprint*. -2015-03-04 08:35:50 +0100 Mike Gabriel (ebe00df38) +2015-03-04 08:35:50 +0100 Mike Gabriel (ebe00df) * imake cleanup: Drop all references to XdmxServer and BuildXdmx*. -2015-03-03 12:30:51 +0100 Mike Gabriel (b1fc73ad4) +2015-03-03 12:30:51 +0100 Mike Gabriel (b1fc73a) * imake cleanup: Drop all references to XVirtualFramebufferServer. -2015-03-03 12:13:59 +0100 Mike Gabriel (6471f66c9) +2015-03-03 12:13:59 +0100 Mike Gabriel (6471f66) * imake cleanup: Drop all references to XNestServer. -2015-03-03 12:09:06 +0100 Mike Gabriel (9c46d3ddb) +2015-03-03 12:09:06 +0100 Mike Gabriel (9c46d3d) * imake cleanup: Drop all references to XWinServer. -2015-03-29 08:03:13 +0200 Mihai Moldovan (8ed8a43d2) +2015-03-29 08:03:13 +0200 Mihai Moldovan (8ed8a43) * nx-X11: add more NULL guards to TEST and DEBUG sections of Render.c. -2015-03-29 08:02:43 +0200 Mihai Moldovan (ab4e5bf66) +2015-03-29 08:02:43 +0200 Mihai Moldovan (ab4e5bf) * debian/changelog: sync with 3.5.0.x branch. -2015-03-29 04:53:52 +0200 Mihai Moldovan (f1ab3f27b) +2015-03-29 04:53:52 +0200 Mihai Moldovan (f1ab3f2) * nx-X11: fix typo in previous commit. -2015-03-29 04:26:10 +0200 Mihai Moldovan (0d56c45a7) +2015-03-29 04:26:10 +0200 Mihai Moldovan (0d56c45) * nx-X11: handle source pictures (those without a Drawable surface) gracefully. -2015-03-26 00:41:45 +0100 Mihai Moldovan (68be7d1c8) +2015-03-26 00:41:45 +0100 Mihai Moldovan (68be7d1) * debian/changelog: sync with 3.5.0.x branch. -2015-03-26 00:32:27 +0100 Mihai Moldovan (d86ce9c7a) +2015-03-26 00:32:27 +0100 Mihai Moldovan (d86ce9c) * nxcomp{,ext,shad}: only use the first three numbers in the full version for current_version on OS X. ld(1) on 10.6 fails otherwise. -2015-03-17 18:28:15 +0100 Mihai Moldovan (fcb2cb5e0) +2015-03-17 18:28:15 +0100 Mihai Moldovan (fcb2cb5) * nx-libs.spec: add overlooked Obsolete: statement to libNX_Xfixes3. -2015-03-17 18:26:26 +0100 Mihai Moldovan (8a260b94f) +2015-03-17 18:26:26 +0100 Mihai Moldovan (8a260b9) * nx-libs.spec: Versioned libXcomp* should obsolete unversioned libXcomp*, not libNX_Xcomp*. -2015-03-16 03:29:16 +0100 Mihai Moldovan (d8de5928e) +2015-03-16 03:29:16 +0100 Mihai Moldovan (d8de592) * nx{comp{,ext,shad},proxy}: try really hard to find makedepend. Do not fail if it is not available. -2015-03-15 17:29:50 +0100 Clemens Lang (638e31c2f) +2015-03-15 17:29:50 +0100 Clemens Lang (638e31c) * nxcomp{,ext,shad}: use the correct library naming scheme on OS X. It differs from other UNIX-based systems. -2015-03-15 17:26:24 +0100 Clemens Lang (ad7e12ed3) +2015-03-15 17:26:24 +0100 Clemens Lang (ad7e12e) * nxcomp{,shad}: fix dynamic library linking on OS X. Use -dynamiclib instead of -bundle. -2015-03-15 17:22:38 +0100 Clemens Lang (5464a6dba) +2015-03-15 17:22:38 +0100 Clemens Lang (5464a6d) * nx{comp{,ext,shad},proxy}: use path discovery for finding makedepend. Remove old cruft. -2015-03-15 01:13:56 +0100 Mihai Moldovan (c460e090b) +2015-03-15 01:13:56 +0100 Mihai Moldovan (c460e09) * debian/changelog: fix wrong signature. -2015-03-15 01:10:31 +0100 Mihai Moldovan (98e56c125) +2015-03-15 01:10:31 +0100 Mihai Moldovan (98e56c1) * debian/changelog: merge with 3.5.0.x release branch. -2015-03-13 15:14:07 +0100 Mike Gabriel (7d2254185) +2015-03-13 15:14:07 +0100 Mike Gabriel (7d22541) * README.md: Fix typo, update date. -2015-03-13 15:13:00 +0100 Mike Gabriel (286d8917c) +2015-03-13 15:13:00 +0100 Mike Gabriel (286d891) * README.md markdown fixup -2015-03-13 15:08:10 +0100 Mike Gabriel (2922ec512) +2015-03-13 15:08:10 +0100 Mike Gabriel (2922ec5) * README.md: Add 3.6.x release goals. -2015-03-05 12:24:42 +0100 Mike Gabriel (18e186b51) +2015-03-05 12:24:42 +0100 Mike Gabriel (18e186b) * Makefile: clean-up auto-generated nxversion.def in clean rule (not in build rule). -2015-03-03 12:34:48 +0100 Mike Gabriel (1a4d0c7c5) +2015-03-03 12:34:48 +0100 Mike Gabriel (1a4d0c7) * nx-X11/**: Drop non-imake Makefile* files. -2015-03-03 12:01:01 +0100 Mike Gabriel (f11393a05) +2015-03-03 12:01:01 +0100 Mike Gabriel (f11393a) * nx-X11/config/cf/X11.tmpl: Fix imake warning ("UseInstalledOnCrossCompile" is not defined). -2015-03-04 08:09:34 +0100 Mike Gabriel (897e2e2de) +2015-03-04 08:09:34 +0100 Mike Gabriel (897e2e2) * Merge pull request #4 from sunweaver/feature/libxpm-cleanup -2015-02-27 00:14:10 +0100 Mike Gabriel (1d71c9ebd) +2015-02-27 00:14:10 +0100 Mike Gabriel (1d71c9e) * library clean-up: Don't build libNX_Xpm anymore. Use system's libXpm shared library. -2015-02-18 08:14:09 -0500 Mike DePaulo (46318a51e) +2015-02-18 08:14:09 -0500 Mike DePaulo (46318a5) * Drop unused .cvsignore files -2015-02-18 07:51:55 -0500 Mike DePaulo (c29c331ce) +2015-02-18 07:51:55 -0500 Mike DePaulo (c29c331) * Update changelog for the CVE-2015-0255 commit and its 3 prereq commits -2015-02-18 08:01:54 +0100 Mike Gabriel (ec018a79c) +2015-02-18 08:01:54 +0100 Mike Gabriel (ec018a7) * Fix symlink to renamed README.md. -2015-02-18 06:18:03 +0100 Mike Gabriel (f7e109e5c) +2015-02-18 06:18:03 +0100 Mike Gabriel (f7e109e) * README.md: Mention the TheQVD project as collaborator on NX. -2015-02-18 05:06:41 +0100 Mike Gabriel (5c24a09a1) +2015-02-18 05:06:41 +0100 Mike Gabriel (5c24a09) * rename README.txt to README.md -2015-02-18 05:05:27 +0100 Mike Gabriel (04af6fefb) +2015-02-18 05:05:27 +0100 Mike Gabriel (04af6fe) * switch symlink and real file -2015-02-18 05:03:57 +0100 Mike Gabriel (f29801f37) +2015-02-18 05:03:57 +0100 Mike Gabriel (f29801f) * Add README.txt symlink to README.NX-development (to have it shown on the Github summary page). -2015-01-16 08:44:45 +0100 Olivier Fourdan (d7258444a) +2015-01-16 08:44:45 +0100 Olivier Fourdan (d725844) * xkb: Check strings length against request size -2015-01-16 20:08:59 +0100 Olivier Fourdan (9308c79ba) +2015-01-16 20:08:59 +0100 Olivier Fourdan (9308c79) * xkb: Don't swap XkbSetGeometry data in the input buffer -2009-06-29 13:09:57 +1000 Peter Hutterer (3937db18a) +2009-06-29 13:09:57 +1000 Peter Hutterer (3937db1) * include: introduce byte counting functions. -2006-04-07 16:07:50 +0000 Daniel Stone (d6ce946f9) +2006-04-07 16:07:50 +0000 Daniel Stone (d6ce946) * Coverity #844, #845, #846: Fix memory leaks. -2015-02-17 09:28:03 +0100 Mike Gabriel (c910bf7cd) +2015-02-17 09:28:03 +0100 Mike Gabriel (c910bf7) * Merge pull request #3 from sunweaver/feature/nxagent-version-v2 -2015-02-16 15:11:02 +0100 Mike Gabriel (203d97147) +2015-02-16 15:11:02 +0100 Mike Gabriel (203d971) * Make nxagent process aware of its current NX'ish version. -2015-02-16 15:10:43 +0100 Mike Gabriel (eb49d408c) +2015-02-16 15:10:43 +0100 Mike Gabriel (eb49d40) * nx-X11/programs/Xserver/hw/nxagent/: Drop unused VERSION file. -2011-08-21 18:51:53 +0200 Joerg Sonnenberger (65deb86f8) +2011-08-21 18:51:53 +0200 Joerg Sonnenberger (65deb86) * Do proper input validation to fix for CVE-2011-2895. -2015-02-16 10:29:14 +0100 Mike Gabriel (18e337ddf) +2015-02-16 10:29:14 +0100 Mike Gabriel (18e337d) * Revert "Do proper input validation to fix for CVE-2011-2895." -2015-02-16 06:24:38 +0100 Mike Gabriel (26cfe931f) +2015-02-16 06:24:38 +0100 Mike Gabriel (26cfe93) * fix 3.5.0.29 changelog entry -2015-02-16 06:19:54 +0100 Mike Gabriel (1f3222fa0) +2015-02-16 06:19:54 +0100 Mike Gabriel (1f3222f) * debian/changelog: fix too-long lines -2015-02-16 05:51:02 +0100 Mike Gabriel (db12538dd) +2015-02-16 05:51:02 +0100 Mike Gabriel (db12538) * Makefile.nx-libs: Fix uninstall-lite rule. The nxproxy and nxcomp uninstallation has to be in uninstall-lite, not in uninstall-full. -2015-02-16 05:45:17 +0100 Mike Gabriel (892c08ddc) +2015-02-16 05:45:17 +0100 Mike Gabriel (892c08d) * Make install-lite rule in Makefile.nx-libs more predictable and not rely on nxproxy/Makefile.in. -2015-02-14 21:55:30 +0100 Mike Gabriel (f29cc29fd) +2015-02-14 21:55:30 +0100 Mike Gabriel (f29cc29) * Install "%{_libdir}/nx/bin" into nxproxy package. -2015-02-14 21:53:00 +0100 Mike Gabriel (742430826) +2015-02-14 21:53:00 +0100 Mike Gabriel (7424308) * nx-libs.spec: Typo fix in comment. -2015-02-14 17:07:21 -0500 Mike DePaulo (e4d97018b) +2015-02-14 17:07:21 -0500 Mike DePaulo (e4d9701) * Fix FTBFS due to the nxproxy executable already existing under /usr/lib/nx/bin/nx -2011-08-21 18:51:53 +0200 Joerg Sonnenberger (6acafc933) +2011-08-21 18:51:53 +0200 Joerg Sonnenberger (6acafc9) * Do proper input validation to fix for CVE-2011-2895. -2015-02-16 06:03:48 +0100 Mihai Moldovan (b04f11915) +2015-02-16 06:03:48 +0100 Mihai Moldovan (b04f119) * nx-X11/lib/font/fc/fserve.c: initialize remaining bufleft variables. -2014-01-06 23:30:14 -0800 Alan Coopersmith (b6b5b14e4) +2014-01-06 23:30:14 -0800 Alan Coopersmith (b6b5b14) * dix: integer overflow in GetHosts() [CVE-2014-8092 2/4] -2015-02-16 05:55:23 +0100 Mihai Moldovan (03a2922d9) +2015-02-16 05:55:23 +0100 Mihai Moldovan (03a2922) * Revert "dix: integer overflow in GetHosts() [CVE-2014-8092 2/4]" -2015-02-08 21:03:33 -0500 Mike DePaulo (31322c2bd) +2015-02-08 21:03:33 -0500 Mike DePaulo (31322c2) * CVE-2014-0210: unvalidated length in _fs_recv_conn_setup() from xorg/lib/libXfont commit 891e084b26837162b12f841060086a105edde86d -2015-02-16 05:52:09 +0100 Mihai Moldovan (c0d0e373d) +2015-02-16 05:52:09 +0100 Mihai Moldovan (c0d0e37) * Revert "CVE-2014-0210: unvalidated length in _fs_recv_conn_setup() from xorg/lib/libXfont commit 891e084b26837162b12f841060086a105edde86d" -2015-02-08 22:08:09 -0500 Mike DePaulo (e29bbd5bf) +2015-02-08 22:08:09 -0500 Mike DePaulo (e29bbd5) * CVE-2014-0210: unvalidated length fields in fs_read_query_info() from xorg/lib/libXfont commit 491291cabf78efdeec8f18b09e14726a9030cc8f -2015-02-16 05:26:40 +0100 Mihai Moldovan (5fc2f57fb) +2015-02-16 05:26:40 +0100 Mihai Moldovan (5fc2f57) * Revert "CVE-2014-0210: unvalidated length fields in fs_read_query_info() from xorg/lib/libXfont commit 491291cabf78efdeec8f18b09e14726a9030cc8f" -2014-11-10 12:13:48 -0500 Adam Jackson (1ea1cd8c4) +2014-11-10 12:13:48 -0500 Adam Jackson (1ea1cd8) * glx: Pass remaining request length into ->varsize (v2) [CVE-2014-8098 8/8] (V3) -2014-11-10 12:13:43 -0500 Adam Jackson (9c558f9ca) +2014-11-10 12:13:43 -0500 Adam Jackson (9c558f9) * glx: Length checking for RenderLarge requests (v2) [CVE-2014-8098 3/8] (v3) -2014-11-10 12:13:47 -0500 Adam Jackson (893106607) +2014-11-10 12:13:47 -0500 Adam Jackson (8931066) * glx: Length checking for non-generated single requests (v2) [CVE-2014-8098 7/8] -2014-11-10 12:13:44 -0500 Adam Jackson (ad29acd76) +2014-11-10 12:13:44 -0500 Adam Jackson (ad29acd) * glx: Top-level length checking for swapped VendorPrivate requests [CVE-2014-8098 4/8] -2014-11-10 12:13:42 -0500 Adam Jackson (ddb1235bc) +2014-11-10 12:13:42 -0500 Adam Jackson (ddb1235) * glx: Integer overflow protection for non-generated render requests (v3) [CVE-2014-8093 5/6] -2014-11-10 12:13:41 -0500 Julien Cristau (78b38a8a3) +2014-11-10 12:13:41 -0500 Julien Cristau (78b38a8) * glx: Length checking for GLXRender requests (v2) [CVE-2014-8098 2/8] (v3) -2014-11-10 12:13:40 -0500 Adam Jackson (1a9f23118) +2014-11-10 12:13:40 -0500 Adam Jackson (1a9f231) * glx: Add safe_{add,mul,pad} (v3) [CVE-2014-8093 4/6] (v4) -2014-11-10 12:13:38 -0500 Adam Jackson (d0fcbc8a6) +2014-11-10 12:13:38 -0500 Adam Jackson (d0fcbc8) * glx: Additional paranoia in __glXGetAnswerBuffer / __GLX_GET_ANSWER_BUFFER (v2) [CVE-2014-8093 3/6] -2014-11-10 12:13:37 -0500 Adam Jackson (cdf0c3e65) +2014-11-10 12:13:37 -0500 Adam Jackson (cdf0c3e) * glx: Be more strict about rejecting invalid image sizes [CVE-2014-8093 2/6] -2014-11-10 12:13:36 -0500 Adam Jackson (5c43bb248) +2014-11-10 12:13:36 -0500 Adam Jackson (5c43bb2) * glx: Be more paranoid about variable-length requests [CVE-2014-8093 1/6] (v2) -2014-01-26 19:38:09 -0800 Alan Coopersmith (cea44678d) +2014-01-26 19:38:09 -0800 Alan Coopersmith (cea4467) * randr: unvalidated lengths in RandR extension swapped procs [CVE-2014-8101] -2014-01-26 20:02:20 -0800 Alan Coopersmith (c12a473f2) +2014-01-26 20:02:20 -0800 Alan Coopersmith (c12a473) * xfixes: unvalidated length in SProcXFixesSelectSelectionInput [CVE-2014-8102] -2014-01-26 19:51:29 -0800 Alan Coopersmith (9c3842a4f) +2014-01-26 19:51:29 -0800 Alan Coopersmith (9c3842a) * render: unvalidated lengths in Render extn. swapped procs [CVE-2014-8100 2/2] -2014-10-28 10:30:04 +0100 Julien Cristau (6c820648b) +2014-10-28 10:30:04 +0100 Julien Cristau (6c82064) * render: check request size before reading it [CVE-2014-8100 1/2] -2014-01-26 19:23:17 -0800 Alan Coopersmith (2abde565d) +2014-01-26 19:23:17 -0800 Alan Coopersmith (2abde56) * Xv: unvalidated lengths in XVideo extension swapped procs [CVE-2014-8099] -2014-01-26 17:18:54 -0800 Alan Coopersmith (0d53194f7) +2014-01-26 17:18:54 -0800 Alan Coopersmith (0d53194) * xcmisc: unvalidated length in SProcXCMiscGetXIDList() [CVE-2014-8096] -2014-01-26 10:54:41 -0800 Alan Coopersmith (fde1375e3) +2014-01-26 10:54:41 -0800 Alan Coopersmith (fde1375) * Xi: unvalidated lengths in Xinput extension [CVE-2014-8095] -2014-01-22 23:12:04 -0800 Alan Coopersmith (985ca320f) +2014-01-22 23:12:04 -0800 Alan Coopersmith (985ca32) * dbe: unvalidated lengths in DbeSwapBuffers calls [CVE-2014-8097] -2014-01-22 23:44:46 -0800 Alan Coopersmith (82d7279eb) +2014-01-22 23:44:46 -0800 Alan Coopersmith (82d7279) * dix: integer overflow in REQUEST_FIXED_SIZE() [CVE-2014-8092 4/4] -2014-01-22 22:37:15 -0800 Alan Coopersmith (ed1e13a1f) +2014-01-22 22:37:15 -0800 Alan Coopersmith (ed1e13a) * dix: integer overflow in RegionSizeof() [CVE-2014-8092 3/4] -2014-01-06 23:30:14 -0800 Alan Coopersmith (d4c76981f) +2014-01-06 23:30:14 -0800 Alan Coopersmith (d4c7698) * dix: integer overflow in GetHosts() [CVE-2014-8092 2/4] -2014-01-22 21:11:16 -0800 Alan Coopersmith (c1225fe64) +2014-01-22 21:11:16 -0800 Alan Coopersmith (c1225fe) * dix: integer overflow in ProcPutImage() [CVE-2014-8092 1/4] -2014-01-17 18:54:03 -0800 Alan Coopersmith (37e7fb1f6) +2014-01-17 18:54:03 -0800 Alan Coopersmith (37e7fb1) * unchecked malloc may allow unauthed client to crash Xserver [CVE-2014-8091] -2015-02-08 22:38:32 -0500 Mike DePaulo (b65259bf3) +2015-02-08 22:38:32 -0500 Mike DePaulo (b65259b) * CVE-2014-0210: unvalidated length fields in fs_read_list_info() from xorg/lib/libXfont commit d338f81df1e188eb16e1d6aeea7f4800f89c1218 -2015-02-08 22:35:21 -0500 Mike DePaulo (ef439da38) +2015-02-08 22:35:21 -0500 Mike DePaulo (ef439da) * CVE-2014-0210: unvalidated length fields in fs_read_list() from xorg/lib/libXfont commit 5fa73ac18474be3032ee7af9c6e29deab163ea39 -2015-02-08 22:27:47 -0500 Mike DePaulo (ece51493f) +2015-02-08 22:27:47 -0500 Mike DePaulo (ece5149) * CVE-2014-0210: unvalidated length fields in fs_read_glyphs() from xorg/lib/libXfont commit 520683652564c2a4e42328ae23eef9bb63271565 -2015-02-08 22:26:16 -0500 Mike DePaulo (d2b96c5d5) +2015-02-08 22:26:16 -0500 Mike DePaulo (d2b96c5) * CVE-2014-0210: unvalidated length fields in fs_read_extent_info() from xorg/lib/libXfont commit a3f21421537620fc4e1f844a594a4bcd9f7e2bd8 -2015-02-08 22:23:51 -0500 Mike DePaulo (a0bed4d9f) +2015-02-08 22:23:51 -0500 Mike DePaulo (a0bed4d) * CVE-2014-0211: integer overflow in fs_alloc_glyphs() from xorg/lib/libXfont commit a42f707f8a62973f5e8bbcd08afb10a79e9cee33 -2015-02-08 22:19:01 -0500 Mike DePaulo (bb7abd9da) +2015-02-08 22:19:01 -0500 Mike DePaulo (bb7abd9) * CVE-2014-0211: integer overflow in fs_read_extent_info() from xorg/lib/libXfont commit c578408c1fd4db09e4e3173f8a9e65c81cc187c1 -2015-02-08 22:08:09 -0500 Mike DePaulo (c6aebf928) +2015-02-08 22:08:09 -0500 Mike DePaulo (c6aebf9) * CVE-2014-0210: unvalidated length fields in fs_read_query_info() from xorg/lib/libXfont commit 491291cabf78efdeec8f18b09e14726a9030cc8f -2015-02-08 21:43:42 -0500 Mike DePaulo (2d724c1a0) +2015-02-08 21:43:42 -0500 Mike DePaulo (2d724c1) * CVE-2014-0211: Integer overflow in fs_get_reply/_fs_start_read from xorg/lib/libXfont commit 0f1a5d372c143f91a602bdf10c917d7eabaee09b -2015-02-08 21:39:55 -0500 Mike DePaulo (50e80a06c) +2015-02-08 21:39:55 -0500 Mike DePaulo (50e80a0) * CVE-2014-0210: unvalidated lengths when reading replies from font server from xorg/lib/libXfont commit cbb64aef35960b2882be721f4b8fbaa0fb649d12 -2015-02-08 21:33:30 -0500 Mike DePaulo (a2c7cd9fe) +2015-02-08 21:33:30 -0500 Mike DePaulo (a2c7cd9) * Don't crash when we receive an FS_Error from the font server (Guillem Jover). from xorg/lib/libXfont commit bfb8a71f4f7e5c5ed4278cb3ee271bf9990d276d -2015-02-08 21:03:33 -0500 Mike DePaulo (94c6de064) +2015-02-08 21:03:33 -0500 Mike DePaulo (94c6de0) * CVE-2014-0210: unvalidated length in _fs_recv_conn_setup() from xorg/lib/libXfont commit 891e084b26837162b12f841060086a105edde86d -2015-02-08 20:53:14 -0500 Mike DePaulo (36f1dae74) +2015-02-08 20:53:14 -0500 Mike DePaulo (36f1dae) * CVE-2014-0209: integer overflow of realloc() size in lexAlias() from xorg/lib/libXfont commit 05c8020a49416dd8b7510cbba45ce4f3fc81a7dc -2015-02-08 20:28:30 -0500 Mike DePaulo (f53f2474d) +2015-02-08 20:28:30 -0500 Mike DePaulo (f53f247) * CVE-2014-0209: integer overflow of realloc() size in FontFileAddEntry() from xorg/lib/libXfont commit 2f5e57317339c526e6eaee1010b0e2ab8089c42e -2015-02-08 20:12:25 -0500 Mike DePaulo (ac6694378) +2015-02-08 20:12:25 -0500 Mike DePaulo (ac66943) * CVE-2013-6462: unlimited sscanf overflows stack buffer in bdfReadCharacters() from xorg/lib/libXfont http://lists.x.org/archives/xorg-announce/2014-January/002389.html -2015-02-08 20:01:27 -0500 Mike DePaulo (72790a558) +2015-02-08 20:01:27 -0500 Mike DePaulo (72790a5) * Avoid use-after-free in dix/dixfonts.c: doImageText() [CVE-2013-4396] from xorg/Xserver http://lists.x.org/archives/xorg-announce/2013-October/002332.html -2015-02-08 19:16:38 -0500 Mike DePaulo (df4a3b727) +2015-02-08 19:16:38 -0500 Mike DePaulo (df4a3b7) * Fix CVE-2011-4028: File disclosure vulnerability. upstream xorg/xserver commit 6ba44b91e37622ef8c146d8f2ac92d708a18ed34 -2015-02-08 19:15:20 -0500 Mike DePaulo (af55da1e9) +2015-02-08 19:15:20 -0500 Mike DePaulo (af55da1) * LZW decompress: fix for CVE-2011-2895 From xorg/lib/Xfont commit d11ee5886e9d9ec610051a206b135a4cdc1e09a0 -2015-02-14 15:58:11 +0100 Mike Gabriel (902dc519d) +2015-02-14 15:58:11 +0100 Mike Gabriel (902dc51) * Move COPYING.full+lite as COPYING to / -2015-02-14 15:52:29 +0100 Mike Gabriel (9000c00dc) +2015-02-14 15:52:29 +0100 Mike Gabriel (9000c00) * Move all config files from $(srcbase)/debian/ into $(srcbase)/etc/ folder. -2015-02-14 15:29:25 +0100 Mike Gabriel (53329e609) +2015-02-14 15:29:25 +0100 Mike Gabriel (53329e6) * Provide wrapper scripts for launch NX components in $(src)/bin/. -2015-02-14 15:23:59 +0100 Mike Gabriel (1a824cfb5) +2015-02-14 15:23:59 +0100 Mike Gabriel (1a824cf) * Prepare for maintaing upstream changes in upstream ChangeLog. -2015-02-14 15:14:23 +0100 Mike Gabriel (ce531230f) +2015-02-14 15:14:23 +0100 Mike Gabriel (ce53123) * VERSION file: master VERSION file is in base folder, symlinked from nx*/VERSION and hw/nxagent/VERSION. -2015-02-14 15:08:07 +0100 Mike Gabriel (ea8ca04a7) +2015-02-14 15:08:07 +0100 Mike Gabriel (ea8ca04) * Move Makefile (and auxiliary file replace.sh) into base folder. Adapt packaging these scripts: -2015-02-14 14:50:20 +0100 Mike Gabriel (ebf71e0a4) +2015-02-14 14:50:20 +0100 Mike Gabriel (ebf71e0) * Add README.keystrokes file. Fix for commit e91277d02bf1288909daed3b0de8f876f6403acf. -2015-02-14 14:43:13 +0100 Mike Gabriel (823450515) +2015-02-14 14:43:13 +0100 Mike Gabriel (8234505) * nxcomp: Add Version.c file. Fix for commit d4d3fe0e6e77a58e68defc5895a589a681d7d092. -2015-02-14 14:28:35 +0100 Mike Gabriel (2d4a61d3c) +2015-02-14 14:28:35 +0100 Mike Gabriel (2d4a61d) * Version bump, continuing NX 3.x development.. Targetting NX 3.6.x some time. -2015-02-14 14:23:10 +0100 Mike Gabriel (e54e896a6) +2015-02-14 14:23:10 +0100 Mike Gabriel (e54e896) * Use proper quoting on build flag vars (they may contain spaces). -2015-02-14 14:21:52 +0100 Mike Gabriel (db3c6a6d2) +2015-02-14 14:21:52 +0100 Mike Gabriel (db3c6a6) * Revert "Fix build when LDFLAGS (etc) contains spaces." -2015-02-13 14:14:26 +0100 Mike Gabriel (1e5ee575d) +2015-02-13 14:14:26 +0100 Mike Gabriel (1e5ee57) * nx-X11 vs. X.Org 6.9 patches for further studying / documentation -2015-02-13 13:57:39 +0100 Oleksandr Shneyder (1fd8551f1) +2015-02-13 13:57:39 +0100 Oleksandr Shneyder (1fd8551) * Unbrand NX Agent Startup Screen / Brand X2Go Agent Startup Screen (999_nxagent_unbrand-nxagent-brand-x2goagent.full.patch). -2015-02-13 13:43:54 +0100 Mike Gabriel (23fb61755) +2015-02-13 13:43:54 +0100 Mike Gabriel (23fb617) * Fix several typos in nxcomp. -2015-02-13 13:41:31 +0100 Mihai Moldovan (6e6624731) +2015-02-13 13:41:31 +0100 Mihai Moldovan (6e66247) * Several fixes for building debug versions of NX (990_fix-DEBUG-and-TEST-builds.full.patch). -2015-02-13 13:38:39 +0100 Mike Gabriel (a8fb7d4f5) +2015-02-13 13:38:39 +0100 Mike Gabriel (a8fb7d4) * Detection for Mac OS X's launchd service on Mac OS X 10.10 and beyond (607_nxcomp_macosx-X11-launcher-in-private-tmp.full+lite.patch). -2015-02-13 13:37:33 +0100 Orion Poplawski (31cdd874c) +2015-02-13 13:37:33 +0100 Orion Poplawski (31cdd87) * Provide build support for aarch64 architecture (606_nx-X11_build-on-aarch64.full.patch). -2015-02-13 13:35:40 +0100 Clemens Lang (ab8d1276f) +2015-02-13 13:35:40 +0100 Clemens Lang (ab8d127) * In Types.h, don't use STL internals on libc++ (605_nxcomp_Types.h-dont-use-STL-internals-on-libc++.full+lite.patch). -2015-02-13 13:34:16 +0100 Mirraz Mirraz (96d5e74a3) +2015-02-13 13:34:16 +0100 Mirraz Mirraz (96d5e74) * Handle some serious compilation warnings (603_nx-X11_compilation_warnings.full.patch). -2015-02-13 13:32:17 +0100 Orion Poplawski (415b20b6f) +2015-02-13 13:32:17 +0100 Orion Poplawski (415b20b) * Be compliant with POS36-C: Observe correct revocation order while relinquishing privileges (602_nx-X11_initgroups.full.patch). -2015-02-13 13:30:31 +0100 Orion Poplawski (456f887d9) +2015-02-13 13:30:31 +0100 Orion Poplawski (456f887) * Do not build bundled libraries (601_nx-X11_build-option-changes-to-not-use-bundled-libraries.full.patch). -2015-02-13 13:27:42 +0100 Jan Engelhardt (c4a8556c4) +2015-02-13 13:27:42 +0100 Jan Engelhardt (c4a8556) * Unique Library Names Patch (600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch). -2015-02-13 13:26:27 +0100 Nito Martinez (d4d3fe0e6) +2015-02-13 13:26:27 +0100 Nito Martinez (d4d3fe0) * Allow version 4-digit version comparison/handshake (400_nxcomp-version.full+lite.patch). -2015-02-13 13:06:53 +0100 Horst Schirmeier (fea8fb5ae) +2015-02-13 13:06:53 +0100 Horst Schirmeier (fea8fb5) * Adapt paths of keystrokes.cfg if nxagent runs as x2goagent (321_nxagent_x2go-specific-keystroke-config.full.patch). -2015-02-13 09:52:21 +0100 Alexander Wuerstlein (e91277d02) +2015-02-13 09:52:21 +0100 Alexander Wuerstlein (e91277d) * Make nxagent-specific keyboard bindings configurable (320_nxagent_configurable-keystrokes.full.patch). -2015-02-13 09:49:52 +0100 Mike Gabriel (4dc1bd004) +2015-02-13 09:49:52 +0100 Mike Gabriel (4dc1bd0) * Test for xkb/rules/base instead of xkb/keymap.dir for setting XkbBaseDir (302_nx-X11_xkbbasedir-detection.full.patch). -2015-02-03 05:11:09 +0100 Mike Gabriel (a43c49594) +2015-02-03 05:11:09 +0100 Mike Gabriel (a43c495) * update changelog -2015-02-01 22:27:06 +0100 Ulrich Sibiller (08114b1e4) +2015-02-01 22:27:06 +0100 Ulrich Sibiller (08114b1) * Fix patch rollout in tarball -2015-02-12 10:07:40 +0100 Mike Gabriel (fa8fb7288) +2015-02-12 10:07:40 +0100 Mike Gabriel (fa8fb72) * changelog: add 3.5.0.x entry for commit 4436e97 -2015-02-12 09:59:57 +0100 Mike Gabriel (d569145e6) +2015-02-12 09:59:57 +0100 Mike Gabriel (d569145) * Makefile.nx-libs: Run make install for nxproxy first, then create the wrapper script. -2015-02-12 09:59:12 +0100 Mike Gabriel (a7cc4edef) +2015-02-12 09:59:12 +0100 Mike Gabriel (a7cc4ed) * Remove upstream nx-libs ChangeLog during override_dh_clean. -2015-02-11 19:02:57 -0500 Mike DePaulo (4436e9790) +2015-02-11 19:02:57 -0500 Mike DePaulo (4436e97) * Fix build when LDFLAGS (etc) contains spaces. -2015-02-10 21:47:31 +0100 Jan Engelhardt (6fc37fa76) +2015-02-10 21:47:31 +0100 Jan Engelhardt (6fc37fa) * Use shared libraries (301_nx-X11_use-shared-libs.full.patch). -2015-02-10 21:45:19 +0100 Oleksandr Shneyder (1e99734ec) +2015-02-10 21:45:19 +0100 Oleksandr Shneyder (1e99734) * Set WM_CLASS to X2GoAgent/NXAgent (300_nxagent_set-wm-class.full.patch). -2015-02-10 21:11:27 +0100 Mike Gabriel (1be1c4a21) +2015-02-10 21:11:27 +0100 Mike Gabriel (1be1c4a) * Force NX proxy to bind to loopback devices only (loopback option) (220_nxproxy_bind-loopback-only.full+lite.patch). -2015-02-10 19:47:58 +0100 Nito Martinez (79f218b56) +2015-02-10 19:47:58 +0100 Nito Martinez (79f218b) * Fix FTBFS of nxproxy/nxcomp on Android (212_nxcomp_build-on-Android.full+lite.patch). -2015-02-10 19:46:04 +0100 Oleksandr Shneyder (46c2aebca) +2015-02-10 19:46:04 +0100 Oleksandr Shneyder (46c2aeb) * Set default pack and link options to avoid damage of session (211_nxcomp_set_default_options.full+lite.patch). -2015-02-10 19:43:41 +0100 Oleksandr Shneyder (8c1b852ab) +2015-02-10 19:43:41 +0100 Oleksandr Shneyder (8c1b852) * Save session state in file. -2015-02-10 19:38:45 +0100 Mike Gabriel (4a6ccd503) +2015-02-10 19:38:45 +0100 Mike Gabriel (4a6ccd5) * Add x2goagent man page (209_x2goagent_add-man-page.full.patch). -2015-02-10 19:36:57 +0100 Ulrich Sibiller (57a58c73c) +2015-02-10 19:36:57 +0100 Ulrich Sibiller (57a58c7) * Fix XFIXES selection handling (copy and paste via middle mouse button) (207_nxagent_fix-xfixes-selection.full.patch). -2015-02-10 19:33:51 +0100 Mike Gabriel (4ef611eea) +2015-02-10 19:33:51 +0100 Mike Gabriel (4ef611e) * Add -clipboard cmdline option to nxagent (206_nxagent_clipboard-as-nxoption.full.patch). -2015-02-10 19:32:12 +0100 Oleksandr Shneyder (35aab85c7) +2015-02-10 19:32:12 +0100 Oleksandr Shneyder (35aab85) * Fix refresh errors on Win2012 RDP connections with speed=ADS (205_nxagent_refresh-adsl.full.patch). -2015-02-10 19:29:53 +0100 Oleksandr Shneyder (db8705564) +2015-02-10 19:29:53 +0100 Oleksandr Shneyder (db87055) * Fix repainting of SolidFill pictures with libcairo > 1.12.x (204_nxagent_repaint-solidpict.full.patch). -2015-02-10 19:26:42 +0100 Oleksandr Shneyder (4f5dc807a) +2015-02-10 19:26:42 +0100 Oleksandr Shneyder (4f5dc80) * Add -norootlessexit cmdline option to nxagent (203_nxagent_disable-rootless-exit.full.patch). -2015-02-10 19:23:16 +0100 Oleksandr Shneyder (d26930d59) +2015-02-10 19:23:16 +0100 Oleksandr Shneyder (d26930d) * Enable Xinerama support for NX (202_nx-X11_enable-xinerama.full.patch). -2015-02-10 19:21:35 +0100 Oleksandr Shneyder (6aa18cc28) +2015-02-10 19:21:35 +0100 Oleksandr Shneyder (6aa18cc) * X2Go icon when run with x2goagent flavour (201_nxagent_set-x2go-icon-if-x2goagent-flavour.full.patch). -2015-02-10 19:19:25 +0100 Oleksandr Shneyder (1681f1110) +2015-02-10 19:19:25 +0100 Oleksandr Shneyder (1681f11) * Detect nxagent/x2goagent flavour (200_nxagent_check-binary-x2go-flavour.full.patch). -2015-02-10 19:17:58 +0100 Mike Gabriel (471223907) +2015-02-10 19:17:58 +0100 Mike Gabriel (4712239) * Avoid large pixmaps (110_nxagent_createpixmap-bounds-check.full.patch). -2015-02-10 19:14:04 +0100 Mike Gabriel (223f5548b) +2015-02-10 19:14:04 +0100 Mike Gabriel (223f554) * Wine Close Delay (108_nxagent_wine-close-delay.full.patch). -2015-02-10 19:04:00 +0100 Mike Gabriel (658d07e93) +2015-02-10 19:04:00 +0100 Mike Gabriel (658d07e) * Prevent sending COMPOUND_TEXT (107_nxagent_clipboard-compound-text+small-bed-sheets.full.patch). -2015-02-10 19:00:06 +0100 Mike Gabriel (9674c4346) +2015-02-10 19:00:06 +0100 Mike Gabriel (9674c43) * UTF-8 Clipboard copying (106_nxagent_utf8-copy-clipboard.full.patch). -2015-02-10 18:56:59 +0100 Marcelo Boveto Shima (c91fe980b) +2015-02-10 18:56:59 +0100 Marcelo Boveto Shima (c91fe98) * Export remote keyboard configuration to session directory (105_nxagent_export-remote-keyboard-config.full.patch) -2015-02-10 18:54:29 +0100 Mike Gabriel (c106ad8e8) +2015-02-10 18:54:29 +0100 Mike Gabriel (c106ad8) * FHS path fix for keyboard config file (103_nxagent_set-X0-config-path.full.patch). -2015-02-10 18:52:39 +0100 Marcelo Boveto Shima (057999efa) +2015-02-10 18:52:39 +0100 Marcelo Boveto Shima (057999e) * FHS path fix for SecurityPolicy file (102_xserver-xext_set-securitypolicy-path.full.patch). -2015-02-10 18:48:39 +0100 Marcelo Boveto Shima (ceb70505c) +2015-02-10 18:48:39 +0100 Marcelo Boveto Shima (ceb7050) * FHS path fix for rgb file This patch is needed on Debian only, not reporting this path addition to upstream. -2015-02-10 18:41:08 +0100 Mihai Moldovan (2d68caca7) +2015-02-10 18:41:08 +0100 Mihai Moldovan (2d68cac) * Create Windows and fix drawing issues on Big Endian 64bit systems (057_nx-X11_sanitize-eventmasks.full.patch). -2015-02-09 15:58:22 +0100 Orion Poplawski (4dac57f3d) +2015-02-09 15:58:22 +0100 Orion Poplawski (4dac57f) * Fix -Werror=format-security errors (056_nx-X11_Werror-format-security.full.patch). -2015-02-09 15:51:26 +0100 Orion Poplawski (95dbaa614) +2015-02-09 15:51:26 +0100 Orion Poplawski (95dbaa6) * Fix FTBFS when compiled with -Werror=format-security (055_nx-X11_imake-Werror-format-security.full.patch). -2015-02-09 15:49:51 +0100 Orion Poplawski (0b711de48) +2015-02-09 15:49:51 +0100 Orion Poplawski (0b711de) * Fix FTBFS on ppc64 architecture (054_nx-X11_ppc64-ftbfs.full.patch). -2015-02-09 15:47:44 +0100 Orion Poplawski (9ea734b21) +2015-02-09 15:47:44 +0100 Orion Poplawski (9ea734b) * Avoid building libXcomp.so.1 (which is identical to libXcomp.so.3), (053_nx-X11_no-xcomp1-install-target.full.patch). -2015-02-09 15:45:33 +0100 Mihai Moldovan (e736fff09) +2015-02-09 15:45:33 +0100 Mihai Moldovan (e736fff) * Fix nxauth location on Mac OS X 10 (052_nxcomp_macos10-nxauth-location.full+lite.patch) -2015-02-09 15:41:35 +0100 Mihai Moldovan (905478694) +2015-02-09 15:41:35 +0100 Mihai Moldovan (9054786) * workaround for Mac OS X 10.5 (051_nxcomp_macos105-fdisset.full+lite.patch( -2015-02-09 15:38:59 +0100 Jan Engelhardt (6101bd956) +2015-02-09 15:38:59 +0100 Jan Engelhardt (6101bd9) * Description: Enable parallel make (031_nx-X11_parallel-make.full.patch). -2015-02-09 15:34:02 +0100 Jan Engelhardt (9f4b494fa) +2015-02-09 15:34:02 +0100 Jan Engelhardt (9f4b494) * Allow to pass in configure args (030_nx-X11_configure-args.full.patch). -2015-02-09 15:31:46 +0100 Mihai Moldovan (bd10fe591) +2015-02-09 15:31:46 +0100 Mihai Moldovan (bd10fe5) * Fix BIGENDIAN issue in nxcomp (relevant on PPC64 arch) (029_nxcomp_ppc64.full+lite.patch) -2015-02-09 15:29:53 +0100 Mike Gabriel (f6619070b) +2015-02-09 15:29:53 +0100 Mike Gabriel (f661907) * Support abstract local sockets for Linux systems (028_nx-X11_abstract-kernel-sockets.full.patch). -2015-02-09 15:27:46 +0100 Mike Gabriel (aaf4a59e4) +2015-02-09 15:27:46 +0100 Mike Gabriel (aaf4a59) * Add X11 abstract socket support to nxcomp/nxproxy (027_nxcomp_abstract-X11-socket.full+lite.patch). -2015-02-09 15:22:07 +0100 Orion Poplawski (3384aba38) +2015-02-09 15:22:07 +0100 Orion Poplawski (3384aba) * Honour compiler/linker option flags. -2015-02-09 15:19:12 +0100 Gabriel Marcano (78efa8bf9) +2015-02-09 15:19:12 +0100 Gabriel Marcano (78efa8b) * Fix FTBFS against libjpeg9a (025_nxcomp-fix-ftbfs-against-jpeg9a.full+lite.patch). -2015-02-09 15:16:30 +0100 Mike Gabriel (236ee4ffa) +2015-02-09 15:16:30 +0100 Mike Gabriel (236ee4f) * nxcomp*, nxproxy: Fix clean-up of source tree via Makefile.in templates. -2015-02-09 15:12:11 +0100 Mike Gabriel (9b72eeaa2) +2015-02-09 15:12:11 +0100 Mike Gabriel (9b72eea) * FHS adaptation for Debian packaging (016_nx-X11_install-location.full.patch). From tarball, @@ -5965,42 +7178,42 @@ debian/rules. This should be merged into the NX build logic finally. -2015-02-09 08:37:40 -0500 Mike DePaulo (519bcac93) +2015-02-09 08:37:40 -0500 Mike DePaulo (519bcac) * Fix RPM spec syntax error -2015-02-09 14:26:02 +0100 Mike Gabriel (4bc550e86) +2015-02-09 14:26:02 +0100 Mike Gabriel (4bc550e) * nxcomp*,nxproxy: Add clean rules to Makefile.in templates. -2015-02-09 14:23:12 +0100 Mike Gabriel (27ddd1695) +2015-02-09 14:23:12 +0100 Mike Gabriel (27ddd16) * Work on man pages. -2015-02-09 14:20:22 +0100 Mike Gabriel (a0b2fd836) +2015-02-09 14:20:22 +0100 Mike Gabriel (a0b2fd8) * sa_restorer vs. memset (008_nxcomp_sa-restorer.full+lite.patch). Use memset instead of setting sa_restorer to NULL. -2015-02-09 14:18:50 +0100 Mike Gabriel (a720908a6) +2015-02-09 14:18:50 +0100 Mike Gabriel (a720908) * Remove .gch files during cleanup (007_nxcompshad_clean-gch-files.full.patch). When building nxcompshad .gch files get created. On cleanup these should be removed. -2015-02-09 14:16:10 +0100 Mike Gabriel (f27e7424f) +2015-02-09 14:16:10 +0100 Mike Gabriel (f27e742) * Fix building against libpng 1.5 (006_nxcomp_libpng15.full+lite.patch). From the libpng homepage... -2015-02-09 11:57:55 +0100 Marcelo Boveto Shima (48c828107) +2015-02-09 11:57:55 +0100 Marcelo Boveto Shima (48c8281) * Description: gcc43 fix (005_nxcomp_gcc43.full+lite.patch) Use builtin includes to build with gcc43. -2015-02-09 11:56:14 +0100 Mike Gabriel (dd20ab5e6) +2015-02-09 11:56:14 +0100 Mike Gabriel (dd20ab5) * Description: Fix build on Debian (004_nx-X11_fix-nxcompshad-build.full.patch) By an @@ -6008,12 +7221,12 @@ nx-X11, nxcomp, nxcompshad and nxcompext with dpkg-buildpackage and debuild. -2015-02-09 11:53:47 +0100 Marcelo Boveto Shima (b3496d0a7) +2015-02-09 11:53:47 +0100 Marcelo Boveto Shima (b3496d0) * gcc43 fix (003_nxcompshad_gcc43.full.patch) Use builtin includes to build with gcc43. -2015-02-09 11:46:07 +0100 Mike Gabriel (3b4a91598) +2015-02-09 11:46:07 +0100 Mike Gabriel (3b4a915) * Build nxcompshad against nx-X11 (002_nxcompshad_build-against-nx-x11-only.full.patch). @@ -6021,477 +7234,477 @@ Furthermore /usr/X11R6/lib is an outdated path on current Debian systems. -2015-02-09 11:44:17 +0100 Mike Gabriel (7a1bd6b29) +2015-02-09 11:44:17 +0100 Mike Gabriel (7a1bd6b) * Provide README.NX-development file. Drop README.NX-redistribution file. -2015-02-09 10:46:10 +0100 Mike Gabriel (abbe93861) +2015-02-09 10:46:10 +0100 Mike Gabriel (abbe938) * fix long-line in changelog -2015-02-09 10:37:17 +0100 Mike Gabriel (eb55dc8fd) +2015-02-09 10:37:17 +0100 Mike Gabriel (eb55dc8) * Drop not-used-anymore NX source tree clean-up code. Source tree has been cleaned up natively. -2015-02-09 10:32:49 +0100 Mike Gabriel (939492d83) +2015-02-09 10:32:49 +0100 Mike Gabriel (939492d) * Revert "Add patch 700_nx-X11_mesa-initialize-server-support-correctly.full.patch. Initialize server_support array with correct size. Fix Mesa upstream bugzilla bug #7353. (Fixes: #776)." -2015-02-03 04:59:13 +0100 Mike Gabriel (4db6f0fdb) +2015-02-03 04:59:13 +0100 Mike Gabriel (4db6f0f) * Add patch 700_nx-X11_mesa-initialize-server-support-correctly.full.patch. Initialize server_support array with correct size. Fix Mesa upstream bugzilla bug #7353. (Fixes: #776). -2015-02-02 15:31:35 +0100 Mike Gabriel (231ffa85e) +2015-02-02 15:31:35 +0100 Mike Gabriel (231ffa8) * Update 991_fix-hr-typos.full.patch. Don't patch files that get removed by the NX code reduction effort. -2015-02-02 15:29:45 +0100 Mike Gabriel (91dc4b509) +2015-02-02 15:29:45 +0100 Mike Gabriel (91dc4b5) * Drop 604_nx-X11_recent-freetype-API.full.patch. Not used in current build process. -2015-02-02 15:26:51 +0100 Mike Gabriel (237d7487f) +2015-02-02 15:26:51 +0100 Mike Gabriel (237d748) * Update 600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch. Don't patch files matter to the NX code reduction efforts. -2015-02-02 15:25:43 +0100 Mike Gabriel (0c42e33b4) +2015-02-02 15:25:43 +0100 Mike Gabriel (0c42e33) * Update 031_nx-X11_parallel-make.full.patch. Don't patch .original files in NX code tree. -2015-02-02 15:24:31 +0100 Mike Gabriel (42f3b1442) +2015-02-02 15:24:31 +0100 Mike Gabriel (42f3b14) * Drop patches: 017_nx-X11_update-autotools-helper-files.full.patch, 018_nx-X11_update-libtool-ltmain-script.full.patch, 019_nx-X11_expat-build-against-system-libxmltok.full.patch. They patch files that are not used at build time. -2015-02-02 15:20:12 +0100 Mike Gabriel (86f96b065) +2015-02-02 15:20:12 +0100 Mike Gabriel (86f96b0) * empty CODE-REDUCTION_* files (maybe usable later for futher code reduction efforts -2015-02-02 15:04:01 +0100 Mike Gabriel (e399356ed) +2015-02-02 15:04:01 +0100 Mike Gabriel (e399356) * drop .original files from the current code base -2015-02-02 15:02:49 +0100 Mike Gabriel (b16b9e465) +2015-02-02 15:02:49 +0100 Mike Gabriel (b16b9e4) * massive reduction of unneeded files -2015-02-02 14:47:22 +0100 Mike Gabriel (0d5a83e98) +2015-02-02 14:47:22 +0100 Mike Gabriel (0d5a83e) * On SLE 11.x: libX* packages are prefixed with "xorg-x11-". -2015-01-29 13:04:46 +0100 Mike Gabriel (dc7495063) +2015-01-29 13:04:46 +0100 Mike Gabriel (dc74950) - * Assure that BuildRoot: is set. + * Assure that BuildRoot: is set. (gh-uli42/master) -2015-01-29 12:48:05 +0100 Mike Gabriel (d9a48367e) +2015-01-29 12:48:05 +0100 Mike Gabriel (d9a4836) * nx-libs.spec: Set PREFIX=%{_prefix} USRLIBDIR=%{_libdir} SHLIBDIR=%{_libdir} at build time. -2015-01-29 12:40:22 +0100 Mike Gabriel (804584cb1) +2015-01-29 12:40:22 +0100 Mike Gabriel (804584c) * Don't fail if removing *.a files fails due to the files being non-present. -2015-01-29 12:12:15 +0100 Mike Gabriel (0b9fce27b) +2015-01-29 12:12:15 +0100 Mike Gabriel (0b9fce2) * Makefile.nx-libs: fix faulty path to nxproxy.1 man page -2015-01-29 12:05:23 +0100 Mike Gabriel (5e8563876) +2015-01-29 12:05:23 +0100 Mike Gabriel (5e85638) * nx-libs.spec: several dependency fixes... -2015-01-29 11:53:16 +0100 Mike Gabriel (a161173d1) +2015-01-29 11:53:16 +0100 Mike Gabriel (a161173) * Make libNX_X11-6 and libXinerama1 compliant to Shared Library Policy. -2015-01-29 11:49:37 +0100 Mike Gabriel (76c529124) +2015-01-29 11:49:37 +0100 Mike Gabriel (76c5291) * nx-libs.spec: Install man pages into bin:packages. -2015-01-29 11:49:28 +0100 Mike Gabriel (9a901a9f6) +2015-01-29 11:49:28 +0100 Mike Gabriel (9a901a9) * Makefile.nx-libs: Install man pages via main Makefile. -2015-01-29 11:46:31 +0100 Mike Gabriel (7e0de4df1) +2015-01-29 11:46:31 +0100 Mike Gabriel (7e0de4d) * nx-libs.spec: Mention NX technology in every package description. -2015-01-29 09:46:34 +0100 Mike Gabriel (10d670c0c) +2015-01-29 09:46:34 +0100 Mike Gabriel (10d670c) * Support .symbols for 64bit and 32bit alike. -2015-01-28 23:18:58 +0100 Mike Gabriel (cde624f45) +2015-01-28 23:18:58 +0100 Mike Gabriel (cde624f) * Use SONAME based library package naming scheme. -2015-01-28 23:17:45 +0100 Mike Gabriel (5a74175cd) +2015-01-28 23:17:45 +0100 Mike Gabriel (5a74175) * Revert "Use SONAME based library package naming scheme." -2015-01-28 23:14:49 +0100 Mike Gabriel (1e5c83e8b) +2015-01-28 23:14:49 +0100 Mike Gabriel (1e5c83e) * Use SONAME based library package naming scheme. -2015-01-28 23:06:25 +0100 Mike Gabriel (6d54eba6c) +2015-01-28 23:06:25 +0100 Mike Gabriel (6d54eba) * debian/control: don't use 1 person plural in LONG_DESCRIPTION -2015-01-28 23:01:59 +0100 Mike Gabriel (d306c9004) +2015-01-28 23:01:59 +0100 Mike Gabriel (d306c90) * nx-libs.spec: Make %{_libdir}/nx{,/X11} owned by libNX_X11 bin:package -2015-01-28 22:54:40 +0100 Mike Gabriel (752dac2b5) +2015-01-28 22:54:40 +0100 Mike Gabriel (752dac2) * CODE-REDUCTION_PRESERVE-NEEDED: keep cross.def and cross.rules -2015-01-28 22:52:34 +0100 Mike Gabriel (f99299998) +2015-01-28 22:52:34 +0100 Mike Gabriel (f992999) * debian/control: fix several packaging issues since the re-packaging started -2015-01-28 22:52:01 +0100 Mike Gabriel (1d7eb36d3) +2015-01-28 22:52:01 +0100 Mike Gabriel (1d7eb36) * Add Description: and Author: fields to various patch headers. -2015-01-28 22:32:09 +0100 Mike Gabriel (89b285f2a) +2015-01-28 22:32:09 +0100 Mike Gabriel (89b285f) * nx-libs.spec: Non-packaged files detected: nxagent.xpm, /usr/share/nx/rgb in bin:package nxagent -2015-01-28 22:31:16 +0100 Mike Gabriel (06212f51f) +2015-01-28 22:31:16 +0100 Mike Gabriel (06212f5) * latest tarball size: 41MiB -2015-01-28 22:24:24 +0100 Mike Gabriel (ce1078e87) +2015-01-28 22:24:24 +0100 Mike Gabriel (ce1078e) * Makefile.nx-libs: Don't allow symlinks to point into buildroot. -2015-01-28 22:21:22 +0100 Mike Gabriel (279b74158) +2015-01-28 22:21:22 +0100 Mike Gabriel (279b741) * Add 991_fix-hr-typos.full+lite.patch and 991_fix-hr-typos.full.patch. Fix several typos in upstream code detected by lintian. -2015-01-28 22:08:16 +0100 Mike Gabriel (3de46599f) +2015-01-28 22:08:16 +0100 Mike Gabriel (3de4659) * debian/libnx-xinerama1.dirs: no non-multi-arch dir in multi-arch packages -2015-01-28 21:56:13 +0100 Mike Gabriel (2a548a079) +2015-01-28 21:56:13 +0100 Mike Gabriel (2a548a0) * Provide CDBS-generated debian/copyright.in file. -2015-01-28 21:52:17 +0100 Mike Gabriel (79c0bac99) +2015-01-28 21:52:17 +0100 Mike Gabriel (79c0bac) * enable official changelog -2015-01-28 21:50:33 +0100 Mike Gabriel (94d5bb3c1) +2015-01-28 21:50:33 +0100 Mike Gabriel (94d5bb3) * debian/control: dummy packages don't have the substvar -2015-01-28 21:47:56 +0100 Mike Gabriel (e2cc535c7) +2015-01-28 21:47:56 +0100 Mike Gabriel (e2cc535) * nx-libs.spec: NX libs are installed in %{_libdir} -2015-01-28 21:43:27 +0100 Mike Gabriel (1d39845b3) +2015-01-28 21:43:27 +0100 Mike Gabriel (1d39845) * Add debian/*.symbols files for shared nx-X11 libraries. -2015-01-28 21:42:15 +0100 Mike Gabriel (dd79903cd) +2015-01-28 21:42:15 +0100 Mike Gabriel (dd79903) * nx-libs.spec: fix permission setting on outdated path -2015-01-28 21:31:37 +0100 Mike Gabriel (801dc1fe8) +2015-01-28 21:31:37 +0100 Mike Gabriel (801dc1f) * fix typos in CODE-REDUCTION scripts -2015-01-28 21:28:04 +0100 Mike Gabriel (912d62ba5) +2015-01-28 21:28:04 +0100 Mike Gabriel (912d62b) * Install upstream ChangeLogs into bin:packages. -2015-01-28 21:26:40 +0100 Mike Gabriel (f72fb34eb) +2015-01-28 21:26:40 +0100 Mike Gabriel (f72fb34) * silence lintian warning about licence file being a symlink -2015-01-28 20:42:34 +0100 Mike Gabriel (72ecc24e6) +2015-01-28 20:42:34 +0100 Mike Gabriel (72ecc24) * CODE-REDUCTION_PRESERVE-SYMLINKED: fix Mesa builds on 32bit intel arch -2015-01-28 20:41:56 +0100 Mike Gabriel (1b458e32e) +2015-01-28 20:41:56 +0100 Mike Gabriel (1b458e3) * CODE-REDUCTION_CLEANUP-UNUSED: remove DPS include files, remove XTrap shared lib -2015-01-28 19:51:32 +0100 Mike Gabriel (62d4f6a06) +2015-01-28 19:51:32 +0100 Mike Gabriel (62d4f6a) * CODE-REDUCTION_CLEANUP-BACKUPFILES: fine-tune dropped file -2015-01-28 19:49:11 +0100 Mike Gabriel (4fae286b8) +2015-01-28 19:49:11 +0100 Mike Gabriel (4fae286) * CODE-REDUCTION_CLEANUP-UNUSED: remove faulty path -2015-01-28 19:39:16 +0100 Mike Gabriel (8b05e1918) +2015-01-28 19:39:16 +0100 Mike Gabriel (8b05e19) * Update .spec file to meet changes in tarball size reduction and restructuring. -2015-01-28 18:21:44 +0100 Mike Gabriel (3c7c3b7f4) +2015-01-28 18:21:44 +0100 Mike Gabriel (3c7c3b7) * Support hardened builds for nxagent and libNX_*.so files. -2015-01-28 18:21:17 +0100 Mike Gabriel (f0f1df262) +2015-01-28 18:21:17 +0100 Mike Gabriel (f0f1df2) * more code reduction and adaptation of patch 600_....patch -2015-01-28 15:11:12 +0100 Mike Gabriel (350fb90d6) +2015-01-28 15:11:12 +0100 Mike Gabriel (350fb90) * remove more unused code from nx-X11/lib/ -2015-01-28 15:04:50 +0100 Mike Gabriel (151bca3a1) +2015-01-28 15:04:50 +0100 Mike Gabriel (151bca3) * Update 600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch. Don't patch files that get removed during code reduction. -2015-01-28 14:58:17 +0100 Mike Gabriel (2a4015865) +2015-01-28 14:58:17 +0100 Mike Gabriel (2a40158) * Support hardened builds for nxcomp* libraries. -2015-01-28 14:57:42 +0100 Mike Gabriel (8b432c7a5) +2015-01-28 14:57:42 +0100 Mike Gabriel (8b432c7) * debian/changelog: whitespace fix -2015-01-28 15:10:54 +0100 Mike Gabriel (f18608de2) +2015-01-28 15:10:54 +0100 Mike Gabriel (f18608d) * rebase with unify -2015-01-28 12:58:30 +0100 Mike Gabriel (5565184a6) +2015-01-28 12:58:30 +0100 Mike Gabriel (5565184) * Unify source tree reduction (debian/rules vs. roll-tarball.sh) via file/folder lists in text files named debian/CODE-REDUCTION_*. -2015-01-28 11:44:04 +0100 Mike Gabriel (22f0208cb) +2015-01-28 11:44:04 +0100 Mike Gabriel (22f0208) * re-arrange changelog, work-in missing entries for previous commits -2015-01-28 11:31:41 +0100 Mike Gabriel (100276175) +2015-01-28 11:31:41 +0100 Mike Gabriel (1002761) * debian/roll-tarball.sh: Install etc/ files into etc/ subfolder (rgb, nxagent.keyboard, x2goagent.keyboard). -2015-01-28 11:34:05 +0100 Mike Gabriel (a7a4246f4) +2015-01-28 11:34:05 +0100 Mike Gabriel (a7a4246) * debian/rules: Correctly link config files (etc/rgb, etc/nxagent.keyboard, etc/x2goagent.keyboard) before dh_auto_build. -2015-01-28 11:25:02 +0100 Mike Gabriel (0956f0c7d) +2015-01-28 11:25:02 +0100 Mike Gabriel (0956f0c) * Provide support for separate .keyboard files for nxagent/x2goagent. -2015-01-28 11:24:34 +0100 Mike Gabriel (04307b247) +2015-01-28 11:24:34 +0100 Mike Gabriel (04307b2) * Allow sysadmins to manipulate nxagent's / x2goagent's rgb file by placing it into /etc/nxagent or /etc/x2go. -2015-01-28 11:29:52 +0100 Mike Gabriel (78c016e77) +2015-01-28 11:29:52 +0100 Mike Gabriel (78c016e) * Extend 999_nxagent_unbrand-nxagent-brand-x2goagent.full.patch. Allow separate .keyboard files for x2goagent and nxagent. -2015-01-28 11:28:38 +0100 Mike Gabriel (fc2dcc9c3) +2015-01-28 11:28:38 +0100 Mike Gabriel (fc2dcc9) * Extend 999_nxagent_unbrand-nxagent-brand-x2goagent.full.patch. Let rgb file shipped with x2goagent supersede rgb file shipped with nxagent. FIXME: a better approach would be to decide at runtime if to use /etc/x2go/rgb or /etc/nxagent/rgb. -2015-01-28 11:21:02 +0100 Mike Gabriel (bb70adf75) +2015-01-28 11:21:02 +0100 Mike Gabriel (bb70adf) * Modify 101_nxagent_set-rgb-path.full.patch. Allow configurable rgb files. -2015-01-28 11:13:45 +0100 Mike Gabriel (7357f8c0e) +2015-01-28 11:13:45 +0100 Mike Gabriel (7357f8c) * Base Debian packaging 100% on Makefile install. -2015-01-27 13:56:36 +0100 Mike Gabriel (b3d32ec56) +2015-01-27 13:56:36 +0100 Mike Gabriel (b3d32ec) * Fully rework the way nx-libs gets packaged for Debian/Ubuntu. -2015-01-22 15:50:30 +0100 Mike Gabriel (a3087eec9) +2015-01-22 15:50:30 +0100 Mike Gabriel (a3087ee) * fix for last commit -2015-01-22 15:43:36 +0100 Mike Gabriel (caa9e8c9a) +2015-01-22 15:43:36 +0100 Mike Gabriel (caa9e8c) * Header files need not be removed anymore. They don't get installed via Makefile.nx-libs anymore. -2015-01-22 15:17:47 +0100 Mike Gabriel (c5ceb16a5) +2015-01-22 15:17:47 +0100 Mike Gabriel (c5ceb16) * Makefile.nx-libs: Don't install Mesa header files into DESTDIR anymore. -2015-01-22 13:48:18 +0100 Mike Gabriel (30ade9cb7) +2015-01-22 13:48:18 +0100 Mike Gabriel (30ade9c) * More source tree size reduction by analyzing what exactly of the Mesa source code in nx-X11/extras/ is used and what not. -2015-01-22 11:47:31 +0100 Mike Gabriel (4c73b97cf) +2015-01-22 11:47:31 +0100 Mike Gabriel (4c73b97) * debian/control: Turn libnx-*-dev packages into dummy packages. Shipping development files for nx-X11 makes no sense. No other programme build against nx-X11's header files except nxagent itself. -2015-01-22 11:00:15 +0100 Mike Gabriel (8de5a897a) +2015-01-22 11:00:15 +0100 Mike Gabriel (8de5a89) * Drop more unused folders from tarball release / before .deb package build. -2015-01-22 10:16:50 +0100 Mike Gabriel (3cfe4bfa3) +2015-01-22 10:16:50 +0100 Mike Gabriel (3cfe4bf) * Drop nx-X11/programs/Xserver/hw/xfree86 except of four files symlinked to other locations in the source tree at build time. -2015-01-22 06:19:42 +0100 Mike Gabriel (b590ce38c) +2015-01-22 06:19:42 +0100 Mike Gabriel (b590ce3) * Stop shipping unused / very old xterm code. -2015-01-22 06:12:10 +0100 Mike Gabriel (be832e8e1) +2015-01-22 06:12:10 +0100 Mike Gabriel (be832e8) * Drop more unused code in nx-X11/programs/Xserver/hw/. Do this in roll-tarball.sh and in debian/rules alike. -2015-01-22 06:10:11 +0100 Mike Gabriel (040962da7) +2015-01-22 06:10:11 +0100 Mike Gabriel (040962d) * Fix removal of unused code (that part of the code that we know of so far). (The debian/rules file is a Makefile and Makefiles don't understand shell globbing with curly braces). -2015-01-22 06:06:37 +0100 Mike Gabriel (694523eee) +2015-01-22 06:06:37 +0100 Mike Gabriel (694523e) * debian/rules: Backup nxcomp/VERSION file from NoMachine before replacing it with a symlink to debian/VERSION. Recreate the original file when cleaning up. -2015-01-19 10:32:03 +0100 Mike Gabriel (24986dd2e) +2015-01-19 10:32:03 +0100 Mike Gabriel (24986dd) * Update 320_nxagent_configurable-keystrokes.full.patch. Fix patch header referring to keystrokes.cfg (plural), not keystroke.cfg. -2015-01-19 10:28:59 +0100 Horst Schirmeier (4e5a11596) +2015-01-19 10:28:59 +0100 Horst Schirmeier (4e5a115) * Add 321_nxagent_x2go-specific-keystroke-config.full.patch. If nxagent is launched as x2goagent, use X2Go-specific paths for the keystrokes.cfg file. (Fixes: #744). -2015-01-13 12:17:58 +0100 Mike Gabriel (6ca1073ea) +2015-01-13 12:17:58 +0100 Mike Gabriel (6ca1073) * give credits to Horst Schirmeier for solving #741 -2015-01-13 06:05:32 +0100 Mike Gabriel (0648d56a9) +2015-01-13 06:05:32 +0100 Mike Gabriel (0648d56) * grammar fix in changelog -2015-01-13 05:36:24 +0100 Mike Gabriel (c09580a52) +2015-01-13 05:36:24 +0100 Mike Gabriel (c09580a) * Update 320_nxagent_configurable-keystrokes.full.patch. Fix a typo that prevented the /etc/nxagent/keystrokes.cfg file to be parsed. (Fixes: #741). -2015-01-09 04:51:03 +0100 Mihai Moldovan (3fb038d6c) +2015-01-09 04:51:03 +0100 Mihai Moldovan (3fb038d) * debian/changelog: add entry for last change. -2015-01-09 03:46:38 +0100 Mihai Moldovan (7750a7eaf) +2015-01-09 03:46:38 +0100 Mihai Moldovan (7750a7e) * common: change X2go -> X2Go. -2014-12-03 15:28:59 +0100 Mike Gabriel (3fa67b673) +2014-12-03 15:28:59 +0100 Mike Gabriel (3fa67b6) * fix for last commit(2) -2014-12-03 15:23:14 +0100 Mike Gabriel (8b36b798e) +2014-12-03 15:23:14 +0100 Mike Gabriel (8b36b79) * fix for last commit -2014-12-03 15:19:03 +0100 Mike Gabriel (992ec61a1) +2014-12-03 15:19:03 +0100 Mike Gabriel (992ec61) * nx-libs.spec: The gpg-offline bin:package is not available in our SLE repo. We can do without. -2014-12-03 15:09:54 +0100 Mike Gabriel (e44f1aec8) +2014-12-03 15:09:54 +0100 Mike Gabriel (e44f1ae) * DISABLED:401_nxcomp_bigrequests-and-genericevent-extensions.full+lite.patch. -2014-11-13 23:29:07 +0100 Paul Szabo (b2ac5aaf1) +2014-11-13 23:29:07 +0100 Paul Szabo (b2ac5aa) * Add 401_nxcomp_bigrequests-and-genericevent-extensions.full+lite.patch. Enable support for the X11 big requests extension and the generic events extension. -2014-11-13 21:59:11 +0100 Mike Gabriel (ec61d2e72) +2014-11-13 21:59:11 +0100 Mike Gabriel (ec61d2e) * Continue development... -2014-11-13 21:39:59 +0100 Mike Gabriel (c69789464) +2014-11-13 21:39:59 +0100 Mike Gabriel (c697894) * release 3.5.0.28 (tag: redist-server/3.5.0.28, tag: redist-client/3.5.0.28) -2014-11-13 21:38:32 +0100 Mike Gabriel (0f5dbb95c) +2014-11-13 21:38:32 +0100 Mike Gabriel (0f5dbb9) * Revert "Add 401_nxcomp_big-requests.full+lite.patch. Support usage of the BIG-REQUESTS X11 extension on the server-side. (See Debian bug #766299)." -2014-11-13 21:38:24 +0100 Mike Gabriel (6f59493da) +2014-11-13 21:38:24 +0100 Mike Gabriel (6f59493) * Revert "401_nxcomp_bigrequests.full+lite.patch: PATCH DISABLED FOR NOW, IT CAUSES NXPROXY CRASHES EVERY 1-2 minutes." -2014-11-05 10:07:39 +0100 Ulrich Sibiller (d1f040121) +2014-11-05 10:07:39 +0100 Ulrich Sibiller (d1f0401) * Add 207_nxagent_fix-xfixes-selection.full.patch. Fix selection handling when XFIXES is enabled. (Fixes: #585) -2014-10-25 23:02:16 +0200 Mike Gabriel (d505944e0) +2014-10-25 23:02:16 +0200 Mike Gabriel (d505944) * 401_nxcomp_bigrequests.full+lite.patch: PATCH DISABLED FOR NOW, IT CAUSES NXPROXY CRASHES EVERY 1-2 minutes. -2014-10-25 22:11:45 +0200 Mike Gabriel (c69c2e2ea) +2014-10-25 22:11:45 +0200 Mike Gabriel (c69c2e2) * Add 401_nxcomp_big-requests.full+lite.patch. Support usage of the BIG-REQUESTS X11 extension on the server-side. (See Debian bug #766299). -2014-10-19 00:19:38 +0200 Mike Gabriel (429dbe708) +2014-10-19 00:19:38 +0200 Mike Gabriel (429dbe7) * Rename 605_nxcomp_Types.h-dont-use-STL-internals-on-libc++.full.patch @@ -6500,182 +7713,182 @@ It is an nxcomp patch that needs to be applied in the nx-libs-lite _and_ the nx-libs-full tarball release. -2014-10-18 23:04:25 +0200 Mike Gabriel (b0727a02f) +2014-10-18 23:04:25 +0200 Mike Gabriel (b0727a0) * Add 607_nxcomp_macosx-X11-launcher-in-private-tmp.full+lite.patch. Fix check for launchd socket path in $DISPLAY on recent Mac OS X systems. -2014-10-14 19:17:11 +0200 Mike Gabriel (efe4d1f73) +2014-10-14 19:17:11 +0200 Mike Gabriel (efe4d1f) * nx-libs.spec: Fix more rpmlint warnings. -2014-10-13 15:47:05 +0200 Mike Gabriel (aa7a0c834) +2014-10-13 15:47:05 +0200 Mike Gabriel (aa7a0c8) * nx-libs.spec: Fix SUSE-specific R for libXext(6). -2014-10-13 14:54:11 +0200 Mike Gabriel (33f69da55) +2014-10-13 14:54:11 +0200 Mike Gabriel (33f69da) * nx-libs.spec: typo fix -2014-10-13 14:28:04 +0200 Mike Gabriel (370e56ec4) +2014-10-13 14:28:04 +0200 Mike Gabriel (370e56e) * nx-libs.spec: minor dep fix -2014-10-13 14:26:57 +0200 Mike Gabriel (44b7138b3) +2014-10-13 14:26:57 +0200 Mike Gabriel (44b7138) * nx-libs.spec: Fix Xinerama deps for SUSE builds. -2014-10-13 13:49:42 +0200 Mike Gabriel (ef4a6c845) +2014-10-13 13:49:42 +0200 Mike Gabriel (ef4a6c8) * nx-libs.spec: Do not conflict with nx... This will break our own neck. -2014-10-13 13:29:18 +0200 Mike Gabriel (aeb9b430c) +2014-10-13 13:29:18 +0200 Mike Gabriel (aeb9b43) * nx-libs.spec: fix nx-libs builds in mock -2014-10-13 11:48:15 +0200 Mike Gabriel (61c21fce0) +2014-10-13 11:48:15 +0200 Mike Gabriel (61c21fc) * nx-libs.spec: fix for last commit -2014-10-13 11:42:00 +0200 Mike Gabriel (d86c1be2c) +2014-10-13 11:42:00 +0200 Mike Gabriel (d86c1be) * Fix Xinerama symlink installation into RPM bin:package libNX_Xinerama. (Fixes: #269). -2014-10-13 11:27:50 +0200 Mike Gabriel (827cbcc04) +2014-10-13 11:27:50 +0200 Mike Gabriel (827cbcc) * Make sure all package directories are owned by one of the built bin:packages. -2014-10-13 11:27:23 +0200 Mike Gabriel (26e55cf81) +2014-10-13 11:27:23 +0200 Mike Gabriel (26e55cf) * fix last changelog entry -2014-10-13 11:19:14 +0200 Mike Gabriel (52ac26bec) +2014-10-13 11:19:14 +0200 Mike Gabriel (52ac26b) * nx-libs.spec: Fix for last commit. -2014-10-13 11:01:57 +0200 Mike Gabriel (0387e383d) +2014-10-13 11:01:57 +0200 Mike Gabriel (0387e38) * nx-libs.spec: SUSE hack for linking to files in libX11-6 and libXext6. -2014-10-13 10:36:53 +0200 Mike Gabriel (1bc6c85e5) +2014-10-13 10:36:53 +0200 Mike Gabriel (1bc6c85) * nx-libs.spec: follow up for last commits -2014-10-13 10:33:12 +0200 Mike Gabriel (894199e60) +2014-10-13 10:33:12 +0200 Mike Gabriel (894199e) * nx-libs.spec: follow up for last commits -2014-10-13 10:29:51 +0200 Mike Gabriel (b96e120f1) +2014-10-13 10:29:51 +0200 Mike Gabriel (b96e120) * nx-libs.spec: follow-up commit for last commit -2014-10-13 10:20:34 +0200 Mike Gabriel (5e4ae04ef) +2014-10-13 10:20:34 +0200 Mike Gabriel (5e4ae04) * Additionally adapt to building on openSUSE/SLES. -2014-10-11 10:13:33 +0200 Mike Gabriel (45c592cf4) +2014-10-11 10:13:33 +0200 Mike Gabriel (45c592c) * Update 027_nxcomp_abstract-X11-socket.full+lite: Add patch header (Description: and Author: field). -2014-10-02 13:52:00 +0200 Mike Gabriel (bddc7e0ba) +2014-10-02 13:52:00 +0200 Mike Gabriel (bddc7e0) * debian/rules: fix nxcomp/VERSION symlink creation at build-time -2014-10-02 13:32:13 +0200 Mike Gabriel (0cac9efd4) +2014-10-02 13:32:13 +0200 Mike Gabriel (0cac9ef) * debian/rules: No such option for dh_auto_build: --with quilt." -2014-10-02 12:34:22 +0200 Mike Gabriel (0277e0857) +2014-10-02 12:34:22 +0200 Mike Gabriel (0277e08) * nx-libs.spec: Adapt installation of debian/VERSION as VERSION.x2goagent and nxcomp/VERSION to latest changes introduced by 400_nxcomp-version.full+lite.patch. -2014-10-02 12:30:20 +0200 Mike Gabriel (8d0798ec7) +2014-10-02 12:30:20 +0200 Mike Gabriel (8d0798e) * fix symlink creation -2014-10-02 11:53:47 +0200 Mike Gabriel (5a82f5994) +2014-10-02 11:53:47 +0200 Mike Gabriel (5a82f59) * debian/libnx-x11.postinst: Don't use dpkg-architecture (bin:package dpkg-dev) in postinst script. Instead prep a libnx-x11.postinst script at build time. (Fixes: #621). -2014-10-02 10:40:55 +0200 Nito Martinez (61d047d63) +2014-10-02 10:40:55 +0200 Nito Martinez (61d047d) * Add 400_nxcomp-version.full+lite.patch. Allow 4-digit version comparison during NX session handshake. (Fixes: #610). -2014-08-20 13:02:53 +0200 Mike Gabriel (c9bc8accc) +2014-08-20 13:02:53 +0200 Mike Gabriel (c9bc8ac) * Add 025_nxcomp-fix-ftbfs-against-jpeg9a.full+lite.patch. Fix FTBFS when built against libjpeg9a. Thanks to Gabriel Marcano for sending this in. -2014-07-09 19:04:25 +0200 Mike Gabriel (0e3b414ea) +2014-07-09 19:04:25 +0200 Mike Gabriel (0e3b414) * Provide COPYING file in tarball. Update debian/copyright. -2014-06-30 15:06:06 +0200 Mike Gabriel (340ec14a4) +2014-06-30 15:06:06 +0200 Mike Gabriel (340ec14) * Continue development... -2014-06-30 14:53:48 +0200 Mike Gabriel (aeb5e8ad5) +2014-06-30 14:53:48 +0200 Mike Gabriel (aeb5e8a) * release 3.5.0.27 (tag: redist-server/3.5.0.27, tag: redist-client/3.5.0.27) -2014-06-30 14:53:09 +0200 Mike Gabriel (77c3e1550) +2014-06-30 14:53:09 +0200 Mike Gabriel (77c3e15) * Split up patch 210 (for correct creation nx-libs, nx-libs-lite tarballs): -2014-06-30 14:43:02 +0200 Mike Gabriel (035de8281) +2014-06-30 14:43:02 +0200 Mike Gabriel (035de82) * release 3.5.0.26 (tag: redist-server/3.5.0.26, tag: redist-client/3.5.0.26) -2014-06-30 14:42:40 +0200 Mike Gabriel (9c7bf9da2) +2014-06-30 14:42:40 +0200 Mike Gabriel (9c7bf9d) * Fix patch names... -2014-06-30 14:25:25 +0200 Mike Gabriel (c92704558) +2014-06-30 14:25:25 +0200 Mike Gabriel (c927045) * Continue development... -2014-06-30 14:14:35 +0200 Mike Gabriel (752a80cee) +2014-06-30 14:14:35 +0200 Mike Gabriel (752a80c) * release 3.5.0.25 (tag: redist-server/3.5.0.25, tag: redist-client/3.5.0.25) -2014-06-29 15:34:25 +0200 Mike Gabriel (2a31f67c7) +2014-06-29 15:34:25 +0200 Mike Gabriel (2a31f67) * changelog fix -2014-06-29 15:11:31 +0200 Mike Gabriel (cf029b619) +2014-06-29 15:11:31 +0200 Mike Gabriel (cf029b6) * Add 212_nxcomp_build-on-Android.patch. Fix FTBFS of nxproxy/nxcomp when build against the Android system. (Fixes: #339). -2014-06-27 17:40:00 +0200 Mike Gabriel (fa886dff8) +2014-06-27 17:40:00 +0200 Mike Gabriel (fa886df) * update patch name in changelog -2014-06-27 17:39:00 +0200 Mike Gabriel (e474a3f35) +2014-06-27 17:39:00 +0200 Mike Gabriel (e474a3f) * update changelog, update patches -2014-06-27 10:52:52 +0200 Oleksandr Shneyder (92a0f58e8) +2014-06-27 10:52:52 +0200 Oleksandr Shneyder (92a0f58) * Rename Patches 210 and 211. Update series file. -2014-06-27 02:01:15 +0200 Mike Gabriel (0cf283dca) +2014-06-27 02:01:15 +0200 Mike Gabriel (0cf283d) * Add 206_nxagent_clipboard-as-nxoption.full.patch. Make the clipboard option configurable in nxagent via NX options as @@ -6684,13 +7897,13 @@ option. Possible values are both or 1, client, server, none or 0. -2014-06-25 11:43:44 +0200 Oleksandr Shneyder (c62b81304) +2014-06-25 11:43:44 +0200 Oleksandr Shneyder (c62b813) * Add 211_nxcomp_set_default_options.patch. Set default arguments for options 'link' and 'pack' to avoid session damage by resuming with incorrect options file. -2014-06-25 10:02:02 +0200 Oleksandr Shneyder (9f6eb6f79) +2014-06-25 10:02:02 +0200 Oleksandr Shneyder (9f6eb6f) * Add 210_nxagent_nxcomp_save_session_state.patch. Save session state in path specified by "state" option in agent options file. @@ -6698,7 +7911,7 @@ Session states are: STARTING, RUNNING, SUSPENDING, SUSPENDED, RESUMING, TERMINATING, TERMINATED. -2014-06-25 09:59:35 +0200 Oleksandr Shneyder (480a05519) +2014-06-25 09:59:35 +0200 Oleksandr Shneyder (480a055) * Revert "Add 210_nxagent_nxcomp_save_session_state.patch. Save session state in path specified by "state" option in agent @@ -6706,7 +7919,7 @@ be saved. Session states are: STARTING, RUNNING, SUSPENDING, SUSPENDED, RESUMING, TERMINATING, TERMINATED." -2014-06-25 09:57:42 +0200 Oleksandr Shneyder (fcd9b71bc) +2014-06-25 09:57:42 +0200 Oleksandr Shneyder (fcd9b71) * Add 210_nxagent_nxcomp_save_session_state.patch. Save session state in path specified by "state" option in agent options file. @@ -6714,49 +7927,49 @@ Session states are: STARTING, RUNNING, SUSPENDING, SUSPENDED, RESUMING, TERMINATING, TERMINATED. -2014-06-22 09:16:45 +0200 Mike Gabriel (7154096b7) +2014-06-22 09:16:45 +0200 Mike Gabriel (7154096) * fix changelog entry for patch 057 -2014-06-22 09:16:02 +0200 Mike Gabriel (c00d26974) +2014-06-22 09:16:02 +0200 Mike Gabriel (c00d269) * fix Description: in patch 057 -2014-06-22 09:14:35 +0200 Mike Gabriel (ead0f653f) +2014-06-22 09:14:35 +0200 Mike Gabriel (ead0f65) * Rename patches to match our naming scheme: -2014-06-22 09:07:56 +0200 Mike Gabriel (53a0a47b8) +2014-06-22 09:07:56 +0200 Mike Gabriel (53a0a47) * renmae patch 057 -2014-06-21 23:40:09 +0200 Mike Gabriel (d8c9f89b1) +2014-06-21 23:40:09 +0200 Mike Gabriel (d8c9f89) * update description for patch 057_nx-X11-bigendian-ppc64-no-session-window.full.patch as proposed by the patch author -2014-06-21 23:20:33 +0200 Mike Gabriel (eca0ee98c) +2014-06-21 23:20:33 +0200 Mike Gabriel (eca0ee9) * Update patches, to make them apply cleanly after above changes: -2014-06-21 23:17:41 +0200 Mike Gabriel (8be0a0472) +2014-06-21 23:17:41 +0200 Mike Gabriel (8be0a04) * fix 057, rebase -2014-06-21 23:04:16 +0200 Mihai Moldovan (abbe7e840) +2014-06-21 23:04:16 +0200 Mihai Moldovan (abbe7e8) * Add 990_fix-DEBUG-and-TEST-builds.full.patch. Fix debug builds (e.g. when globally setting -DDEBUG and -DTEST at build time). -2014-06-21 22:39:10 +0200 Mihai Moldovan (3446d14ea) +2014-06-21 22:39:10 +0200 Mihai Moldovan (3446d14) * Improve 028_nx-X11_abstract-kernel-sockets.full.patch. Make it more Big Endian robust by assigning correct types for socklen_t objects. -2014-06-21 22:35:47 +0200 Mihai Moldovan (afcc7a93d) +2014-06-21 22:35:47 +0200 Mihai Moldovan (afcc7a9) * Improve 105_nxagent_export-remote-keyboard-config.full.patch. Don't print out nonsensical information, if there really was no @@ -6765,235 +7978,235 @@ keyboard file. Only print an error message if SessionPath *really* is not defined. -2014-06-21 22:29:44 +0200 Mihai Moldovan (cfb1990d4) +2014-06-21 22:29:44 +0200 Mihai Moldovan (cfb1990) * Add 057_nx-X11-bigendian-ppc64-no-session-window.patch. Fix failures in session windows coming up on Big Endian systems like PPC64. (Fixes: #516). -2014-06-15 01:03:15 +0200 Mike Gabriel (359c458f1) +2014-06-15 01:03:15 +0200 Mike Gabriel (359c458) * update last committed patch, fix EOL style -2014-06-15 00:49:26 +0200 Mike Gabriel (ecd6d4e85) +2014-06-15 00:49:26 +0200 Mike Gabriel (ecd6d4e) * giving credits to Mihai for digging out patch 029_nxcomp_ppc64.full+lite.patch -2014-06-15 00:33:28 +0200 Mike Gabriel (36f4e34b2) +2014-06-15 00:33:28 +0200 Mike Gabriel (36f4e34) * Add 029_nxcomp_ppc64.full+lite.patch. Fix sockaddr handling on Big Endian systems (like PPC64). (Fixes: #515). -2014-06-13 01:55:49 +0200 Mike Gabriel (75987a76f) +2014-06-13 01:55:49 +0200 Mike Gabriel (75987a7) * Add 302_nx-X11_xkbbasedir-detection.patch. For detecting XkbBaseDir test for xkb/rules/base instead of testing for deprecated file xkb/keymap.dir. (Fixes: #40). -2014-06-11 16:37:37 +0200 Mike Gabriel (e30d46d85) +2014-06-11 16:37:37 +0200 Mike Gabriel (e30d46d) * Make 016_nx-X11_install-location.debian.patch cleanly apply again. -2014-06-11 16:35:13 +0200 Mike Gabriel (656f29cc6) +2014-06-11 16:35:13 +0200 Mike Gabriel (656f29c) * Add 028_nx-X11_abstract-kernel-sockets.full.patch. Provide abstract local socket support for Linux based systems. This patch pulls in abstract socket relevant code from xtrans 1.2.7. -2014-06-11 14:48:08 +0200 Mike Gabriel (9268d270e) +2014-06-11 14:48:08 +0200 Mike Gabriel (9268d27) * Wrap too-long-line in changelog. -2014-06-11 12:25:52 +0200 Mike Gabriel (065dcc903) +2014-06-11 12:25:52 +0200 Mike Gabriel (065dcc9) * fix patch name -2014-06-11 10:43:14 +0200 Mike Gabriel (5a07d00e0) +2014-06-11 10:43:14 +0200 Mike Gabriel (5a07d00) * Make 220_nxproxy-bind-loopback-only.full+lite.patch cleanly apply after having added 027_nxcomp_abstract-X11-socket.patch. -2014-06-11 10:42:04 +0200 Mike Gabriel (57fb5bb57) +2014-06-11 10:42:04 +0200 Mike Gabriel (57fb5bb) * Add 027_nxcomp_abstract-X11-socket.patch. In proxy mode server let NX proxy attempt connecting to the abstract X11 socket first, and only fallback to the file system socket, if the abstract socket is not available. (Fixes: #505). -2014-05-09 12:57:23 +0200 Mike Gabriel (eb3642101) +2014-05-09 12:57:23 +0200 Mike Gabriel (eb36421) * Add 606_nx-X11_build-on-aarch64.full.patch. Build on aarch64 architectures. (Fixes: #490). -2014-05-07 09:59:08 +0200 Mike Gabriel (21ba6e22c) +2014-05-07 09:59:08 +0200 Mike Gabriel (21ba6e2) * Continue development... -2014-05-07 09:56:12 +0200 Mike Gabriel (460a3cb39) +2014-05-07 09:56:12 +0200 Mike Gabriel (460a3cb) * release 3.5.0.24 (tag: redist-server/3.5.0.24, tag: redist-client/3.5.0.24) -2014-05-07 09:55:40 +0200 Mike Gabriel (c6f84a448) +2014-05-07 09:55:40 +0200 Mike Gabriel (c6f84a4) * Configurable keystrokes: Don't ignore first XML element in keystrokes.cfg anymore. (Fixes: #488). -2014-05-07 09:38:04 +0200 Mike Gabriel (7e55c36f4) +2014-05-07 09:38:04 +0200 Mike Gabriel (7e55c36) * Update 320_nxagent_configurable-keystrokes.full.patch: The keystrokes config file's default name now is keystrokes.cfg (plural). -2014-05-07 09:24:45 +0200 Mike Gabriel (a481c137a) +2014-05-07 09:24:45 +0200 Mike Gabriel (a481c13) * Debian lintian: Fix: nx-libs source: not-binnmuable-all-depends-any x2goagent -> nxagent. -2014-05-07 09:08:13 +0200 Mike Gabriel (440fd40c5) +2014-05-07 09:08:13 +0200 Mike Gabriel (440fd40) * Make sure, patch 056_nx-X11-Werror-format-security.full.patch gets included into rolled tarball (by renaming *.patch to *.full.patch). -2014-05-07 09:04:55 +0200 Mike Gabriel (a8be15e1d) +2014-05-07 09:04:55 +0200 Mike Gabriel (a8be15e) * Clean debian/patches/series: Remove commented out patches. -2014-05-06 18:34:53 +0200 Mike Gabriel (43ee5101c) +2014-05-06 18:34:53 +0200 Mike Gabriel (43ee510) * Continue development... -2014-05-06 18:06:05 +0200 Mike Gabriel (085bfbd25) +2014-05-06 18:06:05 +0200 Mike Gabriel (085bfbd) * release 3.5.0.23 (tag: redist-server/3.5.0.23, tag: redist-client/3.5.0.23) -2014-05-06 17:59:42 +0200 Mike Gabriel (f0aa66536) +2014-05-06 17:59:42 +0200 Mike Gabriel (f0aa665) * fix changelog -2014-05-06 13:27:49 +0200 Oleksandr Shneyder (a544b9d4c) +2014-05-06 13:27:49 +0200 Oleksandr Shneyder (a544b9d) * nxagent: add patch to fix refresh error on RDP connections to Windows 2012 if speed=ADSL. -2014-03-29 21:22:59 +0100 Mike Gabriel (4bbcbe505) +2014-03-29 21:22:59 +0100 Mike Gabriel (4bbcbe5) * Add patch: 056_nx-X11-Werror-format-security.patch. Fix more -Werror=format-security errors that only show up on ARM builds. (Fixes: #423). -2014-01-28 23:47:15 +0100 Mike Gabriel (d999822bf) +2014-01-28 23:47:15 +0100 Mike Gabriel (d999822) * nx-libs.spec: Build our imake against xorg-x11-proto-devel. -2014-01-28 23:45:10 +0100 Mike Gabriel (d95e47f3b) +2014-01-28 23:45:10 +0100 Mike Gabriel (d95e47f) * debian/control: Build our imake against x11proto-core-dev headers. -2014-01-28 19:48:21 +0100 Mike Gabriel (faa289a82) +2014-01-28 19:48:21 +0100 Mike Gabriel (faa289a) * nx-libs.spec: Sync nx-libs.spec in Fedora with upstream's nx-libs.spec file. (Fixes: #393). -2014-01-28 19:41:15 +0100 Mike Gabriel (fc91d4d04) +2014-01-28 19:41:15 +0100 Mike Gabriel (fc91d4d) * Add patch: 055_nx-X11_imake-Werror-format-security.full.patch. Fix FTBFS of imake on current Fedora rawhide (21) which uses the compiler option -Werror=format-security for all builds. (Fixes: #412). -2014-01-28 19:40:45 +0100 Mike Gabriel (d5f2bbb3d) +2014-01-28 19:40:45 +0100 Mike Gabriel (d5f2bbb) * fix patch 054_nx-X11_ppc64-ftbfs.full.patch -2014-01-28 19:32:53 +0100 Mike Gabriel (54f39758c) +2014-01-28 19:32:53 +0100 Mike Gabriel (54f3975) * Add patch: 054_nx-X11_ppc64-ftbfs.full.patch. Fix FTBFS on ppc64 architecture. (Fixes: #411). -2014-01-04 22:03:44 +0100 Mike Gabriel (e8a69d261) +2014-01-04 22:03:44 +0100 Mike Gabriel (e8a69d2) * Continue development... -2014-01-04 22:02:09 +0100 Mike Gabriel (80d10df87) +2014-01-04 22:02:09 +0100 Mike Gabriel (80d10df) * release hotfix build -2014-01-04 22:01:16 +0100 Mike Gabriel (0d07f3e8b) +2014-01-04 22:01:16 +0100 Mike Gabriel (0d07f3e) * Update version in VERSION.x2goagent. -2014-01-04 21:39:35 +0100 Mike Gabriel (626b5dbae) +2014-01-04 21:39:35 +0100 Mike Gabriel (626b5db) * release 3.5.0.22 (tag: redist-server/3.5.0.22, tag: redist-client/3.5.0.22) -2013-12-17 21:03:26 +0100 Mike Gabriel (1d074b1ae) +2013-12-17 21:03:26 +0100 Mike Gabriel (1d074b1) * nx-libs.spec: fix symlink creation for Xinerama (missing subfolder) -2013-12-17 17:16:47 +0100 Mike Gabriel (edbd95b90) +2013-12-17 17:16:47 +0100 Mike Gabriel (edbd95b) * attempt to correct symlink creation for Xinerama support -2013-12-17 12:32:34 +0100 Mike Gabriel (36cdfdcb5) +2013-12-17 12:32:34 +0100 Mike Gabriel (36cdfdc) * Make sure all nx-libs components depend on the very same version. -2013-12-17 12:09:54 +0100 Mike Gabriel (a96a43f14) +2013-12-17 12:09:54 +0100 Mike Gabriel (a96a43f) * Enable Xinerama support for RPM packages. (Fixes: #370). -2013-12-17 11:50:25 +0100 Mike Gabriel (ded201707) +2013-12-17 11:50:25 +0100 Mike Gabriel (ded2017) * Drop symlinking libNX_xrandr for setting a custom LD_LIBRARY_PATH. Not in use anymore and not recommended at all to have that. -2013-12-08 12:05:46 +0100 Mike Gabriel (a6ab07de8) +2013-12-08 12:05:46 +0100 Mike Gabriel (a6ab07d) * Clear (Fedora package) changelog. -2013-12-13 18:48:59 +0100 Mike Gabriel (501112b2a) +2013-12-13 18:48:59 +0100 Mike Gabriel (501112b) * nx-libs.spec: x2goagent does not depend on x2goserver (rather vice versa) -2013-12-13 18:24:09 +0100 Mike Gabriel (3fbb9ca30) +2013-12-13 18:24:09 +0100 Mike Gabriel (3fbb9ca) * nx-libs.spec: fix spellings in package descriptions -2013-12-08 01:19:44 +0100 Mike Gabriel (19033a157) +2013-12-08 01:19:44 +0100 Mike Gabriel (19033a1) * make sure our RPM package version is lower than a package version from EPEL -2013-12-08 00:27:53 +0100 Mike Gabriel (ce11917ad) +2013-12-08 00:27:53 +0100 Mike Gabriel (ce11917) * typo fix -2013-12-08 00:07:14 +0100 Mike Gabriel (703a67ac7) +2013-12-08 00:07:14 +0100 Mike Gabriel (703a67a) * compensate missing %buildroot macro in EPEL5 -2013-12-07 23:04:18 +0100 Mike Gabriel (51afd69b2) +2013-12-07 23:04:18 +0100 Mike Gabriel (51afd69) * The RPM macro for the linker flags does not exist on EPEL. Thus, hardcode __global_ldflags macro for EPEL builds. -2013-12-07 22:11:17 +0100 Mike Gabriel (1ac043b94) +2013-12-07 22:11:17 +0100 Mike Gabriel (1ac043b) * debian/rules: Remove bundled libraries from source tree before building the package. -2013-12-06 15:42:26 +0100 Mike Gabriel (1061630f1) +2013-12-06 15:42:26 +0100 Mike Gabriel (1061630) * adapt spec file to last commit -2013-12-06 15:39:59 +0100 Mike Gabriel (523d50529) +2013-12-06 15:39:59 +0100 Mike Gabriel (523d505) * Improve patch: 601_nx-X11_build-option-changes-to-not-use-bundled-libraries.full.patch. @@ -7001,81 +8214,81 @@ to Orion Paplowski!!! Also adapt roll-tarball.sh do dropping more bundled libraries. -2013-12-06 15:20:15 +0100 Mike Gabriel (40aa275cd) +2013-12-06 15:20:15 +0100 Mike Gabriel (40aa275) * Add patch: 302_nx-X11_do-not-build-bundled-libs.full.patch. Rename patch: 302_nxagent_configurable-keystrokes.full.patch. -2013-12-06 15:06:42 +0100 Mike Gabriel (e3da34510) +2013-12-06 15:06:42 +0100 Mike Gabriel (e3da345) * prep source tree after unpacking tarball, bring files from debian/ folder in place before building the RPM package -2013-12-06 14:54:38 +0100 Mike Gabriel (21cde6e42) +2013-12-06 14:54:38 +0100 Mike Gabriel (21cde6e) * nx-libs.spec: Use local tarball, don't expect ,,-full'' in tarball name. -2013-12-06 14:50:59 +0100 Mike Gabriel (2fceb10d2) +2013-12-06 14:50:59 +0100 Mike Gabriel (2fceb10) * nx-libs.specs: remove duplication of file contents -2013-12-06 13:55:53 +0100 Mike Gabriel (8c78f3204) +2013-12-06 13:55:53 +0100 Mike Gabriel (8c78f32) * Ship nx-libs.spec (RPM package definitions) in upstream project. (Thanks to the Fedora package maintainers). File differs from the Fedora file already. -2013-12-06 13:54:42 +0100 Mike Gabriel (b413799fb) +2013-12-06 13:54:42 +0100 Mike Gabriel (b413799) * Refresh patch: 600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch. -2013-12-03 21:33:08 +0100 Mike Gabriel (08312e2e1) +2013-12-03 21:33:08 +0100 Mike Gabriel (08312e2) * Add patch 605_nxcomp_Types.h-dont-use-STL-internals-on-libc++.full.patch. Fix FTBFS of nx-libs-lite on Mac OS X Mavericks. (Fixes: #337). -2013-12-03 15:08:30 +0100 Mike Gabriel (2382d8835) +2013-12-03 15:08:30 +0100 Mike Gabriel (2382d88) * Add patch 604_nx-X11_recent-freetype-API.full.patch. Fix FTBFS against recent (>= 2.5.0) libfreetype6 API. -2013-11-30 21:55:36 +0100 Mike Gabriel (8cd7d82d7) +2013-11-30 21:55:36 +0100 Mike Gabriel (8cd7d82) * debian/control: Add libfreetype6-dev to Build-Depends: field. -2013-11-29 12:37:48 +0100 Mike Gabriel (c50b2a90e) +2013-11-29 12:37:48 +0100 Mike Gabriel (c50b2a9) * change versioning scheme -2013-11-27 14:54:44 +0100 Mike Gabriel (ca414e175) +2013-11-27 14:54:44 +0100 Mike Gabriel (ca414e1) * debian/source/format: Switch to format 1.0. -2013-09-30 21:00:41 +0200 Mike Gabriel (2ef4ab414) +2013-09-30 21:00:41 +0200 Mike Gabriel (2ef4ab4) * Add patch: 603_nx-X11_compilation_warnings.full.patch. Fix 3 evident bugs: one implicit function declaration issue and two array index out of bounds issues. (Fixes: #314). -2013-08-30 16:20:29 +0200 Mike Gabriel (b29654d54) +2013-08-30 16:20:29 +0200 Mike Gabriel (b29654d) * Continue development... -2013-08-30 16:18:40 +0200 Mike Gabriel (b2a3143f8) +2013-08-30 16:18:40 +0200 Mike Gabriel (b2a3143) * release 3.5.0.21 (tag: redist-server/3.5.0.21, tag: redist-client/3.5.0.21) -2013-08-29 22:58:19 +0200 Mike Gabriel (13f2b57d4) +2013-08-29 22:58:19 +0200 Mike Gabriel (13f2b57) * Fix keystrokes.cfg, use Ctrl+Alt+ instead of just Ctrl+. (Adds to fixing #223). -2013-08-29 22:24:26 +0200 Mike Gabriel (0946b4375) +2013-08-29 22:24:26 +0200 Mike Gabriel (0946b43) * Add patch: 602_nx-X11_initgroups.full.patch. Fix calling setuid and setgid without setgroups or initgroups. There is a high @@ -7084,641 +8297,641 @@ Seek POS36-C on the web for details about the problem. (Fixes: #293). -2013-08-29 20:48:09 +0200 Mike Gabriel (e46b43443) +2013-08-29 20:48:09 +0200 Mike Gabriel (e46b434) * fix underscore in name of patch 601_... -2013-07-19 19:27:09 +0200 Mike Gabriel (2a41a2ca5) +2013-07-19 19:27:09 +0200 Mike Gabriel (2a41a2c) * /debian/nx-libs-dev.install: Remove unrelated files from -dev package. -2013-07-19 19:26:37 +0200 Mike Gabriel (19ef7a2ca) +2013-07-19 19:26:37 +0200 Mike Gabriel (19ef7a2) * /debian/control: Add B-Ds: libfontconfig1-dev, libfontenc-dev. -2013-07-19 19:25:05 +0200 Orion Poplawski (9113131a7) +2013-07-19 19:25:05 +0200 Orion Poplawski (9113131) * Change build options so that bundled libraries are not used anymore at build time. Remove bundled libraries from rolled tarballs, as well. (Fixes: #116, #238). -2013-05-29 19:02:02 +0200 Mike Gabriel (d90c457c4) +2013-05-29 19:02:02 +0200 Mike Gabriel (d90c457) * Use a keystrokes.cfg that reflects the normally hard-coded defaults of a vanilla nxagent. (Fixes: #223). -2013-05-11 20:40:57 +0200 Mike Gabriel (ead1e823a) +2013-05-11 20:40:57 +0200 Mike Gabriel (ead1e82) * * Tarball roller script: + Only install keystrokes.cfg when in full mode. + Only install nxproxy wrapper when in lite mode. -2013-05-08 14:21:49 +0200 Mike Gabriel (4c462f28d) +2013-05-08 14:21:49 +0200 Mike Gabriel (4c462f2) * addition to last commit -2013-05-07 20:20:43 +0200 Mike Gabriel (dafbbf21a) +2013-05-07 20:20:43 +0200 Mike Gabriel (dafbbf2) * For vanilla nxagent move keystrokes.cfg from /etc/nx to /etc/nxagent. -2013-05-07 20:03:27 +0200 Mike Gabriel (995b70cdc) +2013-05-07 20:03:27 +0200 Mike Gabriel (995b70c) * /debian/rules: clean etc/keystrokes.cfg symlink -2013-05-07 20:00:51 +0200 Mike Gabriel (ee35c3ff9) +2013-05-07 20:00:51 +0200 Mike Gabriel (ee35c3f) * fix broker symlink -2013-05-06 23:09:35 +0200 Mike Gabriel (e0fb697e9) +2013-05-06 23:09:35 +0200 Mike Gabriel (e0fb697) * Set NXAGENT_KEYSTROKEFILE to /etc/x2go/keystrokes.cfg for wrapper x2goagent. -2013-05-06 22:44:32 +0200 Mike Gabriel (fc118b4bb) +2013-05-06 22:44:32 +0200 Mike Gabriel (fc118b4) * add forgotten file: debian/keystrokes.cfg -2013-05-06 22:38:51 +0200 Mike Gabriel (d8a55d2c6) +2013-05-06 22:38:51 +0200 Mike Gabriel (d8a55d2) * Provide a default keystrokes.cfg in /etc/nx (for nxagent) and /etc/x2go (for x2goagent). (Fixes: #199). -2013-03-28 21:09:09 +0100 Mike Gabriel (dc5faf7af) +2013-03-28 21:09:09 +0100 Mike Gabriel (dc5faf7) * increment version in VERSION.x2goagent -2013-03-28 21:07:59 +0100 Mike Gabriel (121f7ca9d) +2013-03-28 21:07:59 +0100 Mike Gabriel (121f7ca) * Continue development... -2013-03-28 20:43:53 +0100 Mike Gabriel (225445db3) +2013-03-28 20:43:53 +0100 Mike Gabriel (225445d) * release 3.5.0.20 (tag: redist-server/3.5.0.20, tag: redist-client/3.5.0.20) -2013-03-28 20:43:14 +0100 Mike Gabriel (ef0c6b4b8) +2013-03-28 20:43:14 +0100 Mike Gabriel (ef0c6b4) * add bug closure for #156 -2013-03-28 15:27:57 +0100 Mike Gabriel (bd2eb481a) +2013-03-28 15:27:57 +0100 Mike Gabriel (bd2eb48) * Fix faulty symlink path. Make sure that x2goagent symlink does not point to absolute path somewhere within the build environment. -2013-03-28 09:12:07 +0100 Mike Gabriel (5ff8e62d1) +2013-03-28 09:12:07 +0100 Mike Gabriel (5ff8e62) * Continue development... -2013-03-28 08:59:14 +0100 Mike Gabriel (436d06739) +2013-03-28 08:59:14 +0100 Mike Gabriel (436d067) * release 3.5.0.19 (tag: redist-server/3.5.0.19, tag: redist-client/3.5.0.19) -2013-03-28 08:58:35 +0100 Mike Gabriel (db7feaf98) +2013-03-28 08:58:35 +0100 Mike Gabriel (db7feaf) * Revert "release 3.5.0.19" -2013-03-28 08:55:23 +0100 Mike Gabriel (e77bf36d9) +2013-03-28 08:55:23 +0100 Mike Gabriel (e77bf36) * release 3.5.0.19 -2013-03-28 08:55:00 +0100 Mike Gabriel (d16188f08) +2013-03-28 08:55:00 +0100 Mike Gabriel (d16188f) * fix my mail address in changelog -2013-03-28 08:43:52 +0100 Mike Gabriel (478015eb1) +2013-03-28 08:43:52 +0100 Mike Gabriel (478015e) * increment version in VERSION.x2goagent -2013-03-28 08:42:56 +0100 Mike Gabriel (a40d4b7b1) +2013-03-28 08:42:56 +0100 Mike Gabriel (a40d4b7) * Fix FTBFS for .deb packages after including fix for #145. -2013-03-23 00:43:17 +0100 Mike Gabriel (1af59b317) +2013-03-23 00:43:17 +0100 Mike Gabriel (1af59b3) * Add Jan's reasoning for using string_rep() instead of bash based string substitutions as comment to /debian/Makefile.replaces.sh. -2013-03-22 23:40:44 +0100 Mike Gabriel (1b4092e0f) +2013-03-22 23:40:44 +0100 Mike Gabriel (1b4092e) * release 3.5.0.18 (tag: redist-server/3.5.0.18, tag: redist-client/3.5.0.18) -2013-03-22 23:35:40 +0100 Mike Gabriel (f81df1a69) +2013-03-22 23:35:40 +0100 Mike Gabriel (f81df1a) * Main Makefile: Use absolute symlink when linking from $(X2GOLIBDIR) into $(NXLIBDIR) (i.e. linking x2goagent -> nxagent). (Fixes: #143). -2013-03-22 22:33:40 +0100 Mike Gabriel (8f151d797) +2013-03-22 22:33:40 +0100 Mike Gabriel (8f151d7) * Work-in patch from Jan Engehardt for working around different improper bash implementations of string-in-string replacing. (Fixes: #145). -2013-02-12 08:32:30 +0100 Orion Poplawski (258902bec) +2013-02-12 08:32:30 +0100 Orion Poplawski (258902b) * Avoid building of libxcomp1 (which actually is identical to libxcomp3, just with a wrong name). (Fixes: #104). -2013-02-12 08:13:37 +0100 Orion Poplawski (d439556ff) +2013-02-12 08:13:37 +0100 Orion Poplawski (d439556) * Fix wrong symlink direction of libNX_* files. (Fixes: #107). -2013-01-21 10:35:47 +0100 Mike Gabriel (cf521a4b6) +2013-01-21 10:35:47 +0100 Mike Gabriel (cf521a4) * increment VERSION.x2goagent -2013-01-08 00:39:32 +0100 Mike Gabriel (c8a5fddf1) +2013-01-08 00:39:32 +0100 Mike Gabriel (c8a5fdd) * replaces Closes: by Fixes: statements in changelog -2013-01-07 10:45:58 +0100 Mike Gabriel (b121300fd) +2013-01-07 10:45:58 +0100 Mike Gabriel (b121300) * Remove duplicate install of nxproxy from main Makefile. Spotted by Jan Engelhard. -2013-01-04 13:27:41 +0100 Mike Gabriel (39e84229d) +2013-01-04 13:27:41 +0100 Mike Gabriel (39e8422) * Continue development... -2013-01-04 13:24:18 +0100 Mike Gabriel (69c809af9) +2013-01-04 13:24:18 +0100 Mike Gabriel (69c809a) * release 3.5.0.17 (tag: redist-server/3.5.0.17, tag: redist-client/3.5.0.17) -2013-01-03 08:03:46 +0100 Mike Gabriel (1d7669458) +2013-01-03 08:03:46 +0100 Mike Gabriel (1d76694) * let nx-x11-dbg depend on libnx-x11 and nxagent -2013-01-03 08:02:57 +0100 Mike Gabriel (abc2ce3f8) +2013-01-03 08:02:57 +0100 Mike Gabriel (abc2ce3) * fix multiple binaries-have-file-conflicts lintian issue -2013-01-02 17:41:04 +0100 Mike Gabriel (17371711f) +2013-01-02 17:41:04 +0100 Mike Gabriel (1737171) * add misc:Depends to nx-x11-dbg -2013-01-02 17:40:49 +0100 Mike Gabriel (62f66b02a) +2013-01-02 17:40:49 +0100 Mike Gabriel (62f66b0) * fix multiple binaries-have-file-conflicts lintian issue -2013-01-02 15:55:33 +0100 Mike Gabriel (bfe6f4349) +2013-01-02 15:55:33 +0100 Mike Gabriel (bfe6f43) * Continue Reinhard's work on top-level install/uninstall. Esp. integrate debian/post-nx-build.sh into main Makefile. Make value of CONFIGURE variable traversable through the Makefile tree. -2013-01-02 14:58:22 +0100 Mike Gabriel (36a2247e0) +2013-01-02 14:58:22 +0100 Mike Gabriel (36a2247) * fix lintian: missing-separator-between-items in x2goagent depends field between nxagent (>= ${source:Version}) and ${misc:Depends} -2012-12-15 14:45:26 +0100 Reinhard Tartler (300bafb1a) +2012-12-15 14:45:26 +0100 Reinhard Tartler (300bafb) * integrate install and uninstall rules into the top-level Makefile -2012-12-15 14:58:58 +0100 Reinhard Tartler (978aaa0a4) +2012-12-15 14:58:58 +0100 Reinhard Tartler (978aaa0) * integrate nx*/x2go* shell wrappers into debian/wrappers -2012-12-16 11:40:09 +0100 Reinhard Tartler (918e2b10d) +2012-12-16 11:40:09 +0100 Reinhard Tartler (918e2b1) * Use Fixes instead of Closes syntax -2012-12-15 15:05:33 +0100 Reinhard Tartler (352751ef9) +2012-12-15 15:05:33 +0100 Reinhard Tartler (352751e) * simplify clean rule in debian/rules -2012-12-16 00:00:09 +0100 Mike Gabriel (f2011a718) +2012-12-16 00:00:09 +0100 Mike Gabriel (f2011a7) * add closure for #87 -2012-12-15 14:29:41 +0100 Reinhard Tartler (08d568a2c) +2012-12-15 14:29:41 +0100 Reinhard Tartler (08d568a) * reenable parallel builds -2012-12-15 14:29:25 +0100 Reinhard Tartler (d123923a5) +2012-12-15 14:29:25 +0100 Reinhard Tartler (d123923) * update 031_nx-X11_parallel-make.full.patch. -2012-12-13 13:11:40 +0100 Mike Gabriel (0ef5ea2eb) +2012-12-13 13:11:40 +0100 Mike Gabriel (0ef5ea2) * add changelog entries for Reinhard's previous commits -2012-12-13 12:19:20 +0100 Reinhard Tartler (682c80705) +2012-12-13 12:19:20 +0100 Reinhard Tartler (682c807) * fix installation of libxcompext -2012-12-12 12:48:34 +0100 Reinhard Tartler (e559c7522) +2012-12-12 12:48:34 +0100 Reinhard Tartler (e559c75) * delete nxproxy/configure -2012-12-12 12:47:54 +0100 Reinhard Tartler (9a3737b14) +2012-12-12 12:47:54 +0100 Reinhard Tartler (9a3737b) * drop debian/patches/025_nxproxy_no-configure-file.full+lite.patch -2012-12-12 15:20:44 +0100 Reinhard Tartler (b09b686cf) +2012-12-12 15:20:44 +0100 Reinhard Tartler (b09b686) * add rewritten roll-tarballs.sh script -2012-12-12 12:45:41 +0100 Reinhard Tartler (d139e5d3d) +2012-12-12 12:45:41 +0100 Reinhard Tartler (d139e5d) * drop debian/patches/001_add-main-makefile.full+lite.patch -2012-12-12 12:42:03 +0100 Reinhard Tartler (a12ad5050) +2012-12-12 12:42:03 +0100 Reinhard Tartler (a12ad50) * integrate debian/pre-build-nx.sh into debian/rules -2012-12-12 12:27:00 +0100 Reinhard Tartler (3970fabc5) +2012-12-12 12:27:00 +0100 Reinhard Tartler (3970fab) * Rely on shlibs files instead of hard coding library dependencies -2012-12-12 12:31:51 +0100 Reinhard Tartler (263523d7b) +2012-12-12 12:31:51 +0100 Reinhard Tartler (263523d) * disable parallel builds -2012-12-12 10:07:52 +0100 Reinhard Tartler (6b505a48a) +2012-12-12 10:07:52 +0100 Reinhard Tartler (6b505a4) * remove unnecessary build-conflict on xbitmaps -2012-12-12 10:30:57 +0100 Reinhard Tartler (d634c16aa) +2012-12-12 10:30:57 +0100 Reinhard Tartler (d634c16) * make xfonts-base a recommends -2012-12-12 13:23:37 +0100 Mike Gabriel (3727d736b) +2012-12-12 13:23:37 +0100 Mike Gabriel (3727d73) * add (forgotten) files belong to last commit -2012-12-12 13:20:39 +0100 Orion Poplawski (923b7c7eb) +2012-12-12 13:20:39 +0100 Orion Poplawski (923b7c7) * Add patches: 026_nxcomp*_honour-optflags.full*.patch. (Closes upstream issue #84). -2012-12-12 13:06:25 +0100 Mike Gabriel (016959d11) +2012-12-12 13:06:25 +0100 Mike Gabriel (016959d) * changelog cleanup -2012-12-12 13:05:56 +0100 Mike Gabriel (241010302) +2012-12-12 13:05:56 +0100 Mike Gabriel (2410103) * exchange X2Go by NX -2012-12-08 18:25:28 +0100 Reinhard Tartler (19685c566) +2012-12-08 18:25:28 +0100 Reinhard Tartler (19685c5) * install debug symbols for all packages in a new binary package 'nx-x11-dbg' -2012-12-06 09:07:09 +0100 Alexander Wuerstlein (26901cc52) +2012-12-06 09:07:09 +0100 Alexander Wuerstlein (26901cc) * Follow-up commit for 302_nxagent_configurable-keystrokes.full.patch, fixes FTBFS problem with the first version of that patch. -2012-12-04 15:28:00 +0100 Mike Gabriel (fe598a1e5) +2012-12-04 15:28:00 +0100 Mike Gabriel (fe598a1) * changelog entry for having added libxml2-dev to build dependencies -2012-12-04 15:27:00 +0100 Mike Gabriel (0def0092f) +2012-12-04 15:27:00 +0100 Mike Gabriel (0def009) * control file: add some kommata at EOLs, fix dependency of x2goagent on nxagent -2012-12-04 15:24:25 +0100 Mike Gabriel (6c9bd8865) +2012-12-04 15:24:25 +0100 Mike Gabriel (6c9bd88) * Add pkg-config to build dependencies. -2012-12-04 14:55:01 +0100 Mike Gabriel (2093e705a) +2012-12-04 14:55:01 +0100 Mike Gabriel (2093e70) * Add README.keystrokes to doc section of bin:package nxagent. -2012-12-04 14:54:30 +0100 Mike Gabriel (cf5ac17d6) +2012-12-04 14:54:30 +0100 Mike Gabriel (cf5ac17) * whitespace fix -2012-12-04 13:50:47 +0100 Mike Gabriel (2a112c1c3) +2012-12-04 13:50:47 +0100 Mike Gabriel (2a112c1) * add bug closure for X2Go BTS issue #74 -2012-12-04 13:49:18 +0100 Mike Gabriel (5938c38ae) +2012-12-04 13:49:18 +0100 Mike Gabriel (5938c38) * re-add renamed patch file -2012-12-04 13:48:12 +0100 Mike Gabriel (0a91caa98) +2012-12-04 13:48:12 +0100 Mike Gabriel (0a91caa) * Add patch: 302_nxagent_configurable-keystrokes.full.patch, replaces the... (fixing patch application, fixing up follow-up patches, cleaning up patch-system). -2012-12-04 13:31:01 +0100 Alexander Wuerstlein (34f232c14) +2012-12-04 13:31:01 +0100 Alexander Wuerstlein (34f232c) * Add patch: 210_nxagent_configurable-keystrokes.full.patch, replaces the hardcoded nxagent keybindings by a configurable table of keybindings. -2012-11-12 08:45:46 +0100 Mike Gabriel (5a640efd1) +2012-11-12 08:45:46 +0100 Mike Gabriel (5a640ef) * Fix /bin/Makefile. Add $(DESTDIR) to every install path. -2012-11-07 21:14:41 +0100 Mike Gabriel (9e8a2792f) +2012-11-07 21:14:41 +0100 Mike Gabriel (9e8a279) * Continue development... -2012-11-07 21:08:06 +0100 Mike Gabriel (3fd30962b) +2012-11-07 21:08:06 +0100 Mike Gabriel (3fd3096) * release 3.5.0.16 (tag: redist-server/3.5.0.16, tag: redist-client/3.5.0.16) -2012-11-07 21:07:43 +0100 Mike Gabriel (9568a1655) +2012-11-07 21:07:43 +0100 Mike Gabriel (9568a16) * Bump Debian Standards to 3.9.3 (no changes needed). Update Home page and Vcs information. -2012-11-07 21:05:47 +0100 Mike Gabriel (232f1a46e) +2012-11-07 21:05:47 +0100 Mike Gabriel (232f1a4) * Bump Debian Standards to 3.9.3 (no changes needed). -2012-11-07 20:36:04 +0100 Mike Gabriel (b246e9f75) +2012-11-07 20:36:04 +0100 Mike Gabriel (b246e9f) * Dropping empty override rules for quilt patch from /debian/rules. -2012-10-20 22:56:14 +0200 Mike Gabriel (45b9bb839) +2012-10-20 22:56:14 +0200 Mike Gabriel (45b9bb8) * Modify patch: 001_add-main-makefile.full+lite.patch. Add uninstall routine. -2012-10-20 22:27:26 +0200 Mike Gabriel (f801d405d) +2012-10-20 22:27:26 +0200 Mike Gabriel (f801d40) * Fix wrapper scripts: make sure all NX executables can be launched if NX gets installed via the tarball installation method. -2012-10-20 17:58:04 +0200 Mike Gabriel (d39771037) +2012-10-20 17:58:04 +0200 Mike Gabriel (d397710) * Modify patch: 001_add-main-makefile.full+lite.patch. Install nx* and x2goagent wrapper scripts during make install. -2012-10-20 09:33:11 +0200 Mike Gabriel (30d311a68) +2012-10-20 09:33:11 +0200 Mike Gabriel (30d311a) * Add patch: 025_nxproxy_no-configure-file.full+lite.patch. Remove unneeded build file from NoMachine's nxproxy sources. -2012-10-20 08:15:35 +0200 Mike Gabriel (380d23968) +2012-10-20 08:15:35 +0200 Mike Gabriel (380d239) * Add patches: 024_fix-make-clean.full.patch, 024_fix-make-clean.full+lite.patch. Fix clean-up of build tree after make build has run. -2012-10-20 08:05:53 +0200 Mike Gabriel (1e3d69216) +2012-10-20 08:05:53 +0200 Mike Gabriel (1e3d692) * drop build file from nx-libs tree -2012-10-19 09:56:26 +0200 Mike Gabriel (11980c79b) +2012-10-19 09:56:26 +0200 Mike Gabriel (11980c7) * Drop patch 032, fix other patches so that installation via make install installs NX components to /usr/local/lib/nx and /usr/local/include/nx. -2012-10-05 14:37:20 +0200 Mike Gabriel (fbb3ba912) +2012-10-05 14:37:20 +0200 Mike Gabriel (fbb3ba9) * Modify patch: 032_no-x11r6.full.patch. Install nx-X11 to /usr/local/lib/nx. Add patch: 032_no-x11r6.debian.patch. Use /usr/lib/nx for nx-X11 on Debian. -2012-10-05 14:26:48 +0200 Mike Gabriel (cd631e0bc) +2012-10-05 14:26:48 +0200 Mike Gabriel (cd631e0) * Fix patch file names concerning component nx-X11. -2012-09-28 15:18:07 +0200 Mike Gabriel (e3ba4bdc6) +2012-09-28 15:18:07 +0200 Mike Gabriel (e3ba4bd) * Fix installation of header files in Debian package. -2012-09-21 10:07:07 +0200 Mike Gabriel (21b09b85b) +2012-09-21 10:07:07 +0200 Mike Gabriel (21b09b8) * Continue development... -2012-09-21 10:03:00 +0200 Mike Gabriel (51412cd02) +2012-09-21 10:03:00 +0200 Mike Gabriel (51412cd) * release 3.5.0.15 (tag: redist-server/3.5.0.15, tag: redist-client/3.5.0.15) -2012-09-20 22:13:12 +0200 Mike Gabriel (9f1868def) +2012-09-20 22:13:12 +0200 Mike Gabriel (9f1868d) * mark issue #16 as closed by last added patch -2012-09-20 22:12:00 +0200 Mike Gabriel (dc30db8a1) +2012-09-20 22:12:00 +0200 Mike Gabriel (dc30db8) * fix patch name -2012-09-20 21:27:59 +0200 Oleksandr Shneyder (f6adfd1fa) +2012-09-20 21:27:59 +0200 Oleksandr Shneyder (f6adfd1) * Add patch: 204-nxagent_repaint-solidpict.full.patch. Fixes repainting of SolidFill pictures by nxagent/x2goagent on reconnects. -2012-09-17 18:50:50 +0200 Mike Gabriel (b8db5192d) +2012-09-17 18:50:50 +0200 Mike Gabriel (b8db519) * Add patch: 220_nxproxy-bind-loopback-only.full+lite.patch, adds loopback option to nxproxy options and forces nxproxy to bind to loopback devices only. -2012-09-17 16:50:15 +0200 Mike Gabriel (b9a7a1b4f) +2012-09-17 16:50:15 +0200 Mike Gabriel (b9a7a1b) * Add patch: 220_nxproxy-bind-loopback-only.patch, adds loopback option to nxproxy options and forces nxproxy to bind to loopback devices only. -2012-09-15 21:01:51 +0200 Mike Gabriel (f83009075) +2012-09-15 21:01:51 +0200 Mike Gabriel (f830090) * remove Priorty: extra from -dev package -2012-09-15 20:39:50 +0200 Mike Gabriel (78dc96a39) +2012-09-15 20:39:50 +0200 Mike Gabriel (78dc96a) * /debian/control: Maintainer change in package: X2Go Developers . Priority: optional. -2012-09-14 16:48:43 +0200 Mike Gabriel (2d6352839) +2012-09-14 16:48:43 +0200 Mike Gabriel (2d63528) * remove weird remainders of configure files... -2012-09-14 16:47:20 +0200 Mike Gabriel (b8605d4d6) +2012-09-14 16:47:20 +0200 Mike Gabriel (b8605d4) * Link libNX_Xrandr to a separate location where we can provide it as libXrandr. -2012-09-04 12:50:38 +0200 Mike Gabriel (189bfbe14) +2012-09-04 12:50:38 +0200 Mike Gabriel (189bfbe) * Make sure the NX_TEMP envvar gets set in all wrapper script for all nx* executables -2012-09-04 12:47:27 +0200 Mike Gabriel (8d2827b2a) +2012-09-04 12:47:27 +0200 Mike Gabriel (8d2827b) * Refresh patch 200_nxagent_check-binary-x2go-flavour.full.patch -2012-07-13 16:36:27 +0200 Mike Gabriel (3fdfd5142) +2012-07-13 16:36:27 +0200 Mike Gabriel (3fdfd51) * Add VERSION.x2goagent to package x2goagent package so x2goversion command lists up x2goagent in the list of X2Go server-side packages. -2012-06-28 22:22:00 +0200 Mike Gabriel (b42268b13) +2012-06-28 22:22:00 +0200 Mike Gabriel (b42268b) * Improve 020_add-nxagent-wrapper.full.patch: Properly set NX_TEMP, make sure nxagent launches even with pam_tmpdir.so being in use. -2012-06-28 22:20:57 +0200 Mike Gabriel (7b3d592e6) +2012-06-28 22:20:57 +0200 Mike Gabriel (7b3d592) * debian/changelog -2012-06-28 14:55:16 +0200 Mike Gabriel (6af3d3b80) +2012-06-28 14:55:16 +0200 Mike Gabriel (6af3d3b) * Continue development... -2012-06-28 14:52:41 +0200 Mike Gabriel (136375188) +2012-06-28 14:52:41 +0200 Mike Gabriel (1363751) * release 3.5.0.14 (tag: redist-server/3.5.0.14) -2012-06-28 12:31:01 +0200 Mike Gabriel (b65b83ba4) +2012-06-28 12:31:01 +0200 Mike Gabriel (b65b83b) * Drop patch: 109_nxagent_locale-utf8-compound-text.patch, the patch causes Qt applications to be rendered without window decorations when running in rootless window mode. -2012-06-04 08:19:19 +0200 Mike Gabriel (dd7b5eb3c) +2012-06-04 08:19:19 +0200 Mike Gabriel (dd7b5eb) * Add patch: 052_nxcomp_macos10-nxauth-location.full+lite.patch, change nxauth search location on Mac OS X to $NX_SYSTEM/nxauth to facilitate application bundle building. -2012-05-22 00:57:21 +0200 Mike Gabriel (e2e7008b3) +2012-05-22 00:57:21 +0200 Mike Gabriel (e2e7008) * New upstream release of nxagent (3.5.0-9). -2012-05-22 00:50:51 +0200 Mike Gabriel (fdaa24043) +2012-05-22 00:50:51 +0200 Mike Gabriel (fdaa240) * Merge branch 'nxagent' -2012-05-22 00:49:10 +0200 Mike Gabriel (222a4a222) +2012-05-22 00:49:10 +0200 Mike Gabriel (222a4a2) * Imported nxagent-3.5.0-9.tar.gz (origin/nxagent, - gh-sunweaver/nxagent) + gh-sunweaver/nxagent, gh-Ionic/nxagent) -2012-05-11 23:57:35 +0200 Mike Gabriel (fe72988fb) +2012-05-11 23:57:35 +0200 Mike Gabriel (fe72988) * Continue development... -2012-05-11 23:52:39 +0200 Mike Gabriel (789c75851) +2012-05-11 23:52:39 +0200 Mike Gabriel (789c758) * release 3.5.0.13 (tag: redist-server/3.5.0.13) -2012-05-11 23:51:09 +0200 Mike Gabriel (3511e8791) +2012-05-11 23:51:09 +0200 Mike Gabriel (3511e87) * add patch header for 120_nxagent_libcairo-null-source-drawables.full.patch -2012-05-11 12:48:36 +0200 Mike Gabriel (45311f783) +2012-05-11 12:48:36 +0200 Mike Gabriel (45311f7) * Add patch: 120_nxagent_libcairo-null-source-drawables.full.patch, solves crashes of GTK applications based on libcairo 1.12.1+. -2012-03-17 17:22:51 +0100 Mike Gabriel (4372dfa53) +2012-03-17 17:22:51 +0100 Mike Gabriel (4372dfa) * Let nxagent Debian package depend on xfonts-base. -2012-03-17 17:21:50 +0100 Mike Gabriel (fc87c4fbb) +2012-03-17 17:21:50 +0100 Mike Gabriel (fc87c4f) * Revert "Let nxagent Debian package depend on xfonts-base." -2012-03-17 17:20:49 +0100 Mike Gabriel (ab04ba217) +2012-03-17 17:20:49 +0100 Mike Gabriel (ab04ba2) * Let nxagent Debian package depend on xfonts-base. -2012-03-07 21:01:44 +0100 Mike Gabriel (30110dd4a) +2012-03-07 21:01:44 +0100 Mike Gabriel (30110dd) * Continue development... -2012-03-07 20:51:27 +0100 Mike Gabriel (1b1a26ae6) +2012-03-07 20:51:27 +0100 Mike Gabriel (1b1a26a) * release 3.5.0.12 (tag: redist-server/3.5.0.12, tag: redist-client/3.5.0.12) -2012-03-01 22:31:35 +0100 Mike Gabriel (4f7c8d079) +2012-03-01 22:31:35 +0100 Mike Gabriel (4f7c8d0) * Re-introduce proper Xinerama support on non-multiarch systems. -2012-03-01 22:27:26 +0100 Mike Gabriel (95929b8a5) +2012-03-01 22:27:26 +0100 Mike Gabriel (95929b8) * no bashisms in package scripts -2012-03-01 22:26:38 +0100 Mike Gabriel (9b17e8a96) +2012-03-01 22:26:38 +0100 Mike Gabriel (9b17e8a) * changelog cleanup: fixing too-long-line -2012-03-01 22:13:32 +0100 Mike Gabriel (fb274937d) +2012-03-01 22:13:32 +0100 Mike Gabriel (fb27493) * Provide temporary workaround for installation on Debian 64bit with multiarch support (via libnx-x11.postinst and .prerm). -2012-03-01 22:06:08 +0100 Mike Gabriel (055436f48) +2012-03-01 22:06:08 +0100 Mike Gabriel (055436f) * fix wrong lib-name in libnx-x11.postinst -2012-03-01 21:53:28 +0100 Mike Gabriel (3776a6f41) +2012-03-01 21:53:28 +0100 Mike Gabriel (3776a6f) * typofix in libnx-x11.postinst -2012-03-01 21:12:54 +0100 Mike Gabriel (a71cebf04) +2012-03-01 21:12:54 +0100 Mike Gabriel (a71cebf) * Provide temporary workaround for installation on Debian 64bit with multiarch support. -2012-03-01 20:43:53 +0100 Mihai Moldovan (22d41ae20) +2012-03-01 20:43:53 +0100 Mihai Moldovan (22d41ae) * Update patch: 005_nxcomp_gcc43.full+lite.patch, fix faulty path to nxcomp/Split.cpp. -2012-03-01 20:39:37 +0100 Mike Gabriel (7e5c04b5d) +2012-03-01 20:39:37 +0100 Mike Gabriel (7e5c04b) * Pass address of fd_set structs on the stack to the FD_ISSET macro/function, instead of the struct itself. -2012-02-29 15:56:49 +0100 Mihai Moldovan (655173ff2) +2012-02-29 15:56:49 +0100 Mihai Moldovan (655173f) * Add patch: 051_nxcomp_macos105-fdisset.full+lite.patch, work around issue in Mac OS X 10.5 SDK. -2012-02-28 13:44:25 +0100 Oleksandr Shneyder (be86627ad) +2012-02-28 13:44:25 +0100 Oleksandr Shneyder (be86627) * Create patch: 203_nxagent_disable-rootless-exit.full.patch -2012-02-22 22:49:06 +0100 Mike Gabriel (0586f0d6e) +2012-02-22 22:49:06 +0100 Mike Gabriel (0586f0d) * Update patch: 001_add-main-makefile.full+lite.patch, adapt patch from packaging. Test for Makefiles in subfolders before calling them. Fixes build failure during ,,make distclean'' calls. -2012-02-22 15:05:55 +0100 Mike Gabriel (a8bf2dd81) +2012-02-22 15:05:55 +0100 Mike Gabriel (a8bf2dd) * Continue development... -2012-02-22 14:41:26 +0100 Mike Gabriel (50690ea17) +2012-02-22 14:41:26 +0100 Mike Gabriel (50690ea) * release 3.5.0.11 (tag: redist-server/3.5.0.11, tag: redist-client/3.5.0.11) -2012-02-20 10:00:00 +0100 Mike Gabriel (fde6a88a8) +2012-02-20 10:00:00 +0100 Mike Gabriel (fde6a88) * Fine-tune symlinking of libXinerama. -2012-02-18 02:28:53 +0100 Mike Gabriel (ec47c22c2) +2012-02-18 02:28:53 +0100 Mike Gabriel (ec47c22) * Fix Xinerama support in Debian package libnx-x11 when NX gets built with patch @@ -7726,20 +8939,20 @@ Still on the todo list: fix the nx-X11 installation via Makefile. -2012-02-16 19:38:48 +0100 Mike Gabriel (7a6cf42d4) +2012-02-16 19:38:48 +0100 Mike Gabriel (7a6cf42) * another last patch with .diff suffix -2012-02-16 19:35:28 +0100 Mike Gabriel (e63819e64) +2012-02-16 19:35:28 +0100 Mike Gabriel (e63819e) * Fix faulty patch name suffix (has to be .patch, not .diff). -2012-02-16 19:31:08 +0100 Mike Gabriel (78fba0271) +2012-02-16 19:31:08 +0100 Mike Gabriel (78fba02) * Apply patches for the Debian package as the last patches in the series. -2012-02-15 09:42:35 +0100 Mike Gabriel (c26e4bd82) +2012-02-15 09:42:35 +0100 Mike Gabriel (c26e4bd) * Update patches: 012_nxcomp..., 013_nxcompext_..., 014_nxcompshad_.... Also make use of $(LIBFULL) in @@ -7748,320 +8961,320 @@ version name change requested in that patch has been rejected for NX (redistributed). -2012-02-15 08:50:48 +0100 Mike Gabriel (b99168fc3) +2012-02-15 08:50:48 +0100 Mike Gabriel (b99168f) * changelog cleanup, fix long-line-wraps -2012-02-15 08:49:49 +0100 Jan Engelhardt (07f9dfa05) +2012-02-15 08:49:49 +0100 Jan Engelhardt (07f9dfa) * Add patch 600_nx-X11+nxcompext+nxcompshad_unique-libnames.full.patch, use unique library names for nx-X11 based X11 libraries. -2012-02-15 08:10:21 +0100 Mike Gabriel (548d50ba5) +2012-02-15 08:10:21 +0100 Mike Gabriel (548d50b) * changelog cleanup, typo fix -2012-02-15 08:09:41 +0100 Jan Engelhardt (3deee8f94) +2012-02-15 08:09:41 +0100 Jan Engelhardt (3deee8f) * Add patch 032_nx-X11_no-x11r6-project-root. We must not overlap with any existing files, therefore, both /usr/X11R6 and /usr are excluded possibilities for ProjectRoot. Use %_libexecdir/somename, since that is still allowed by FHS. -2012-02-14 23:34:51 +0100 Mike Gabriel (9282c00e2) +2012-02-14 23:34:51 +0100 Mike Gabriel (9282c00) * Update patch: 001_add-main-makefile.full+lite.patch, fix missing $(CONFIGURE) variable. -2012-02-14 23:03:45 +0100 Mike Gabriel (6a96ae450) +2012-02-14 23:03:45 +0100 Mike Gabriel (6a96ae4) * Make patch headers DEP5 compliant (030_nx-X11_... and 031_nx-X11_...). -2012-02-14 22:59:50 +0100 Jan Engelhardt (8d6d0a921) +2012-02-14 22:59:50 +0100 Jan Engelhardt (8d6d0a9) * Add patch: 301_nx-X11_use-shared-libs.full.diff, use shared libraries from distribution rather then libs included in source tree. -2012-02-14 22:42:48 +0100 Mike Gabriel (01e97f0f8) +2012-02-14 22:42:48 +0100 Mike Gabriel (01e97f0) * Rename patches 030_nx-X11_... and 031_nx-X11_..., the tarball roll script currently requires ,,full'' or ,,full+lite'' in the file name. -2012-02-14 22:40:15 +0100 Mike Gabriel (c621c22f8) +2012-02-14 22:40:15 +0100 Mike Gabriel (c621c22) * Merge honor-ac-dirs.patch from Jan Engelhardt (OpenSUSE) with already existing Makefile patches (012_nxcomp..., 013_nxcompext_..., 014_nxcompshad_...). -2012-02-14 22:30:26 +0100 Mike Gabriel (4d6e1c4fb) +2012-02-14 22:30:26 +0100 Mike Gabriel (4d6e1c4) * Enable parallel build for Debian package. -2012-02-14 08:47:19 +0100 Jan Engelhardt (ba589d1fd) +2012-02-14 08:47:19 +0100 Jan Engelhardt (ba589d1) * Add patch: 031_nx-X11_parallel-make.diff, enable parallel make. -2012-02-14 08:39:32 +0100 Mike Gabriel (b4b4e209b) +2012-02-14 08:39:32 +0100 Mike Gabriel (b4b4e20) * Update patch: 001_add-main-makefile.full+lite.patch, use curly braces for macros. -2012-02-14 08:33:42 +0100 Jan Engelhardt (280d8751c) +2012-02-14 08:33:42 +0100 Jan Engelhardt (280d875) * Add patch: 030_nx-X11_configure-args.diff. Allow passing of configure args. -2012-02-14 08:27:52 +0100 Mike Gabriel (165206eb2) +2012-02-14 08:27:52 +0100 Mike Gabriel (165206e) * changelog fix, long-line-wrap -2012-02-14 08:26:50 +0100 Jan Engelhardt (448a1db30) +2012-02-14 08:26:50 +0100 Jan Engelhardt (448a1db) * Update patch: 001_add-main-makefile.full+lite.patch, allow passing of configure args. -2012-02-12 12:40:01 +0100 Mike Gabriel (b087877b2) +2012-02-12 12:40:01 +0100 Mike Gabriel (b087877) * Xinerama path has to be put into debian/rules, that dpkg-shlibs can find the libXinerama files. -2012-02-12 01:03:38 +0100 Mike Gabriel (4feedb214) +2012-02-12 01:03:38 +0100 Mike Gabriel (4feedb2) * fix for intra-dependency lintian fix -2012-02-12 00:37:51 +0100 Mike Gabriel (278f94136) +2012-02-12 00:37:51 +0100 Mike Gabriel (278f941) * fix libXinerama removal -2012-02-11 23:39:16 +0100 Mike Gabriel (4473c3ab9) +2012-02-11 23:39:16 +0100 Mike Gabriel (4473c3a) * Do not install libXinerama directly into /usr/lib/nx. Recommended method is installing to /usr/lib/nx/Xinerama, so that you can enable/disable usage of the Xinerama extension. -2012-02-11 23:06:58 +0100 Mike Gabriel (ec7237798) +2012-02-11 23:06:58 +0100 Mike Gabriel (ec72377) * Revert "Add patch: 111_nxcomp_byerace.full+lite.patch. Work around race condition in qtnx and libnxcl." -2012-02-08 08:52:18 +0100 Mike Gabriel (4eae840bd) +2012-02-08 08:52:18 +0100 Mike Gabriel (4eae840) * Add patch: 111_nxcomp_byerace.full+lite.patch. Work around race condition in qtnx and libnxcl. -2012-02-07 21:00:44 +0100 Mike Gabriel (54792fe29) +2012-02-07 21:00:44 +0100 Mike Gabriel (54792fe) * another fix for the main Makefile -2012-02-07 16:39:58 +0100 Mike Gabriel (7f7cb5d87) +2012-02-07 16:39:58 +0100 Mike Gabriel (7f7cb5d) * more simplification of the main Makefile -2012-02-07 16:19:36 +0100 Mike Gabriel (eb5ef91b6) +2012-02-07 16:19:36 +0100 Mike Gabriel (eb5ef91) * simplify main Makefile a little... -2012-02-07 16:10:34 +0100 Mike Gabriel (00b266b82) +2012-02-07 16:10:34 +0100 Mike Gabriel (00b266b) * Use ,,$(MAKE) -C'' in main Makefile for calling Makefiles in subdirectories, make build stanza work for nx-libs-full and nx-libs-lite. -2012-02-07 15:23:45 +0100 Mike Gabriel (f4ef2967b) +2012-02-07 15:23:45 +0100 Mike Gabriel (f4ef296) * Use ,,make -C'' in main Makefile for calling Makefiles in subdirectories. -2012-02-07 13:48:36 +0100 Mike Gabriel (a751baaab) +2012-02-07 13:48:36 +0100 Mike Gabriel (a751baa) * Continue development... -2012-02-07 13:44:21 +0100 Mike Gabriel (419d505c9) +2012-02-07 13:44:21 +0100 Mike Gabriel (419d505) * release 3.5.0.10 (tag: redist-server/3.5.0.10, tag: redist-client/3.5.0.10) -2012-02-07 13:37:16 +0100 Mike Gabriel (28acb2ea1) +2012-02-07 13:37:16 +0100 Mike Gabriel (28acb2e) * changelog fix (revision was missing) -2012-02-07 13:09:02 +0100 Mike Gabriel (2f8b190c8) +2012-02-07 13:09:02 +0100 Mike Gabriel (2f8b190) * Reintroduce patch: 008_nxcomp_sa_restorer.full+lite.patch, now in a version found on etersoft.ru, fixes build on ia64 architecture. -2012-02-06 12:15:13 +0100 Mike Gabriel (6ae5c16b8) +2012-02-06 12:15:13 +0100 Mike Gabriel (6ae5c16) * cleanup patch -2012-02-06 12:12:20 +0100 Mike Gabriel (e326dd760) +2012-02-06 12:12:20 +0100 Mike Gabriel (e326dd7) * Add patch: 006_nxcomp_libpng15.full+lite.patch, fix build against libpng 1.5.x. -2012-02-01 14:48:55 +0100 Mike Gabriel (dbbbbc5ff) +2012-02-01 14:48:55 +0100 Mike Gabriel (dbbbbc5) * Continue development... -2012-02-01 14:40:41 +0100 Mike Gabriel (220c985d3) +2012-02-01 14:40:41 +0100 Mike Gabriel (220c985) * release NX re-distributed 3.5.0.9 (tag: redist-server/3.5.0.9) -2012-02-01 14:38:14 +0100 Mike Gabriel (8ba08fa2e) +2012-02-01 14:38:14 +0100 Mike Gabriel (8ba08fa) * Providing pending patches in source tree. -2012-01-30 13:45:07 +0100 Oleksandr Shneyder (2d226a609) +2012-01-30 13:45:07 +0100 Oleksandr Shneyder (2d226a6) * Update patch: 202_nx-x11_enable-xinerama.full.patch, disable Xinerama extension if NX_XINERAMA_CONF not exists. -2012-01-30 13:18:30 +0100 Oleksandr Shneyder (3467d6b76) +2012-01-30 13:18:30 +0100 Oleksandr Shneyder (3467d6b) * Revert "Update patch: 202_nx-x11_enable-xinerama.full.patch disable Xinerama extension if NX_XINERAMA_CONF not exists" -2012-01-30 13:18:12 +0100 Oleksandr Shneyder (3c0e43a41) +2012-01-30 13:18:12 +0100 Oleksandr Shneyder (3c0e43a) * Revert "changelog cleanup: add interpunctation." -2012-01-30 13:12:26 +0100 Mike Gabriel (d4d85ca86) +2012-01-30 13:12:26 +0100 Mike Gabriel (d4d85ca) * changelog cleanup: add interpunctation. -2012-01-30 13:05:01 +0100 Oleksandr Shneyder (f17b59824) +2012-01-30 13:05:01 +0100 Oleksandr Shneyder (f17b598) * Update patch: 202_nx-x11_enable-xinerama.full.patch disable Xinerama extension if NX_XINERAMA_CONF not exists -2012-01-28 08:58:43 +0100 Reinhard Tartler (36ca6646b) +2012-01-28 08:58:43 +0100 Reinhard Tartler (36ca664) * fix typos in nxproxy manpage -2012-01-23 00:05:29 +0100 Mike Gabriel (104623396) +2012-01-23 00:05:29 +0100 Mike Gabriel (1046233) * version increment, continue development... -2012-01-22 23:42:43 +0100 Mike Gabriel (f4379f608) +2012-01-22 23:42:43 +0100 Mike Gabriel (f4379f6) * release NX re-distributed 3.5.0.8 (tag: redist-server/3.5.0.8) -2012-01-22 23:02:50 +0100 Mike Gabriel (cf5a5980c) +2012-01-22 23:02:50 +0100 Mike Gabriel (cf5a598) * Fix patch: 109_nxagent_locale-utf8-compound-text.patch, fix crashes reported from Stefan Baur. Thanks for reporting and testing!!! -2012-01-22 22:47:30 +0100 Mike Gabriel (5027f1e8b) +2012-01-22 22:47:30 +0100 Mike Gabriel (5027f1e) * Add folder /debian/patches-pending-evaluation with two newly discovered patches from git.etersoft.ru (AltLinux packaging repository for NX). -2012-01-18 20:09:39 +0100 Mike Gabriel (a05b56038) +2012-01-18 20:09:39 +0100 Mike Gabriel (a05b560) * Package x2goagent is an ,,all'' package, not ,,any''. -2012-01-16 22:57:29 +0100 Mike Gabriel (8b013ce80) +2012-01-16 22:57:29 +0100 Mike Gabriel (8b013ce) * Update patch: 001_add-main-makefile.full+lite.patch, only build, install, clean etc. NX subprojects if the folder exists. -2012-01-16 22:29:05 +0100 Mike Gabriel (e9241fe8c) +2012-01-16 22:29:05 +0100 Mike Gabriel (e9241fe) * Reorganize patch names, to reflect patch inclusion into lite+full or full-only ,,NX (redistributed)'' tarball. -2012-01-16 11:28:26 +0100 Mike Gabriel (d7ecf7214) +2012-01-16 11:28:26 +0100 Mike Gabriel (d7ecf72) * release NX re-distributed 3.5.0.7 (tag: redist-server/3.5.0.7) -2012-01-16 10:54:19 +0100 Mike Gabriel (1bd66f19c) +2012-01-16 10:54:19 +0100 Mike Gabriel (1bd66f1) * Drop patch: 011_nxcomp_sa-restorer.patch. -2012-01-13 13:22:13 +0100 Mike Gabriel (28b2a3a93) +2012-01-13 13:22:13 +0100 Mike Gabriel (28b2a3a) * release NX re-distributed 3.5.0.6 (tag: redist-server/3.5.0.6) -2012-01-13 13:09:43 +0100 Mike Gabriel (8d655bc1a) +2012-01-13 13:09:43 +0100 Mike Gabriel (8d655bc) * Install libXinerama into libnx-x11 package. Header files into libnx-x11-dev. -2012-01-13 12:45:15 +0100 Mike Gabriel (d086c3699) +2012-01-13 12:45:15 +0100 Mike Gabriel (d086c36) * fix for lintian-overrids (debian-revision-should-not-be-zero), package: libxcomp-dev -2012-01-13 11:34:21 +0100 Mike Gabriel (55ee602bb) +2012-01-13 11:34:21 +0100 Mike Gabriel (55ee602) * Silence lintian on debian-revision-should-not-be-zero. As this is no Debian packaging repository, but ,,NX (redistributed)'', we will always release with rev no. set to ,,0''. -2012-01-13 11:29:10 +0100 Mike Gabriel (e32a5590f) +2012-01-13 11:29:10 +0100 Mike Gabriel (e32a559) * Add patch header/copyright to: 202_nx-x11_enable-xinerama.patch. -2012-01-13 11:28:17 +0100 Mike Gabriel (2be056d38) +2012-01-13 11:28:17 +0100 Mike Gabriel (2be056d) * Fix lintian issue: missing-separator-between-items for x2goagent package. Drop dependency on libnx-x11 as we already depend on nxagent and fix description synopsis of x2goagent package. -2012-01-13 10:29:47 +0100 Mike Gabriel (fa996b5bc) +2012-01-13 10:29:47 +0100 Mike Gabriel (fa996b5) * Add patch: 202_nx-x11_enable-xinerama.patch. -2012-01-13 00:38:30 +0100 Mike Gabriel (fdf0d1ccf) +2012-01-13 00:38:30 +0100 Mike Gabriel (fdf0d1c) * release NX re-distributed 3.5.0.5 (tag: redist-server/3.5.0.5) -2012-01-13 00:36:28 +0100 Mike Gabriel (a295d73f6) +2012-01-13 00:36:28 +0100 Mike Gabriel (a295d73) * Fix wrapper script patches for nxagent, x2goagent, nxauth, nxproxy. -2012-01-12 23:05:32 +0100 Mike Gabriel (8199a5d2a) +2012-01-12 23:05:32 +0100 Mike Gabriel (8199a5d) * release NX re-distributed 3.5.0.4 (tag: redist-server/3.5.0.4) -2012-01-12 23:04:03 +0100 Mike Gabriel (96cd4325b) +2012-01-12 23:04:03 +0100 Mike Gabriel (96cd432) * Update/fix patch: 999_nxagent_unbrand-nxagent-brand-x2goagent.patch. -2012-01-12 13:09:00 +0100 Mike Gabriel (e40208d7c) +2012-01-12 13:09:00 +0100 Mike Gabriel (e40208d) * release NX re-distributed 3.5.0.3 (tag: redist-server/3.5.0.3) -2012-01-12 13:03:59 +0100 Mike Gabriel (86dc68806) +2012-01-12 13:03:59 +0100 Mike Gabriel (86dc688) * set version to 3.5.0.3-0 -2012-01-12 13:02:36 +0100 Mike Gabriel (1bbc9cc9e) +2012-01-12 13:02:36 +0100 Mike Gabriel (1bbc9cc) * changelog cleanup -2012-01-12 13:01:47 +0100 Mike Gabriel (496f31a51) +2012-01-12 13:01:47 +0100 Mike Gabriel (496f31a) * Fix RGB color pallette (gray X2GO logo to be more accurate) for agent splash screen. -2012-01-12 13:01:04 +0100 Mike Gabriel (df8dc83d1) +2012-01-12 13:01:04 +0100 Mike Gabriel (df8dc83) * two more patches belonging to last commit: 016a_debian_nx-X11_install-location.patch, 102a_debian_xserver-xext_set-securitypolicy-path.patch -2012-01-12 13:00:23 +0100 Mike Gabriel (760c5c07c) +2012-01-12 13:00:23 +0100 Mike Gabriel (760c5c0) * Provide patches that are tarball / distro aware. Either NX (redistributed) has been installed to /usr/local/lib/nx @@ -8069,45 +9282,45 @@ is installed to /usr/lib/nx. Other installation paths are currently not supported. -2012-01-12 12:15:14 +0100 Mike Gabriel (d6fee9a41) +2012-01-12 12:15:14 +0100 Mike Gabriel (d6fee9a) * Modify patch: 101_nxagent_set-rgb-path.patch, add path to RGB file if NX (redistributed) is installed via tarball under /usr/local. -2012-01-11 17:37:45 +0100 Mike Gabriel (8f76198c5) +2012-01-11 17:37:45 +0100 Mike Gabriel (8f76198) * Add binary package: x2goagent, includes man page patch: 209_x2goagent-add-man-page.patch -2012-01-11 17:34:18 +0100 Mike Gabriel (0d3a820b3) +2012-01-11 17:34:18 +0100 Mike Gabriel (0d3a820) * Revert "Drop patch: 101_nxagent_set-rgb-path.path, add patch: 202_nxagent_set-rgb-path-x2go-flavour-aware.patch." -2012-01-11 17:25:08 +0100 Mike Gabriel (d9d49b5d8) +2012-01-11 17:25:08 +0100 Mike Gabriel (d9d49b5) * Drop patch: 101_nxagent_set-rgb-path.path, add patch: 202_nxagent_set-rgb-path-x2go-flavour-aware.patch. -2012-01-11 17:03:23 +0100 Mike Gabriel (43de8b972) +2012-01-11 17:03:23 +0100 Mike Gabriel (43de8b9) * Add patch: 209_x2goagent-add-man-page.patch. -2012-01-11 16:41:26 +0100 Mike Gabriel (fdfed536c) +2012-01-11 16:41:26 +0100 Mike Gabriel (fdfed53) * Add patch: 023_add-x2goagent-wrapper.patch. -2012-01-11 16:38:36 +0100 Mike Gabriel (9d99eeb53) +2012-01-11 16:38:36 +0100 Mike Gabriel (9d99eeb) * remove copy+paste cruft from debian/patches/999_nxagent_unbrand-nxagent-brand-x2goagent.patch -2012-01-11 16:38:10 +0100 Mike Gabriel (6ae3d7efc) +2012-01-11 16:38:10 +0100 Mike Gabriel (6ae3d7e) * add EOL at EOF -2012-01-11 16:17:51 +0100 Mike Gabriel (405bc8f25) +2012-01-11 16:17:51 +0100 Mike Gabriel (405bc8f) * Add X2Go agent / NX agent flavouring via patch system: - 200_nxagent_check-binary-x2go-flavour.patch - @@ -8115,42 +9328,42 @@ 300_nxagent_set-wm-class.patch - 999_nxagent_unbrand-nxagent-brand-x2goagent.patch -2012-01-11 16:15:38 +0100 Mike Gabriel (19f248733) +2012-01-11 16:15:38 +0100 Mike Gabriel (19f2487) * Drop NX agent unbrand patch from FreeNX. -2012-01-11 15:31:11 +0100 Mike Gabriel (3744795d3) +2012-01-11 15:31:11 +0100 Mike Gabriel (3744795) * Rename nxagent-unbrand patch, so that is the last patch to be applied (999_). -2012-01-10 14:39:07 +0100 Mike Gabriel (eaea40dec) +2012-01-10 14:39:07 +0100 Mike Gabriel (eaea40d) * release NX re-distributed 3.5.0.2 (tag: redist-server/3.5.0.2) -2012-01-10 14:37:25 +0100 Mike Gabriel (e669607f9) +2012-01-10 14:37:25 +0100 Mike Gabriel (e669607) * Update folder name where applied patches end up in the tarball release. -2012-01-10 14:34:27 +0100 Mike Gabriel (eac87da64) +2012-01-10 14:34:27 +0100 Mike Gabriel (eac87da) * Re-add binary wrapper scripts to the patch system as we want to provide them in the tarball. -2012-01-10 12:06:00 +0100 Mike Gabriel (c84ad97a7) +2012-01-10 12:06:00 +0100 Mike Gabriel (c84ad97) * release NX re-distributed 3.5.0.1 (tag: redist-server/3.5.0.1) -2012-01-10 12:05:44 +0100 Mike Gabriel (ca0994c84) +2012-01-10 12:05:44 +0100 Mike Gabriel (ca0994c) * Increment version to stay in sync with client-only branch. -2012-01-10 11:39:35 +0100 Mike Gabriel (d97802ad7) +2012-01-10 11:39:35 +0100 Mike Gabriel (d97802a) * release NX re-distributed 3.5.0.0 (tag: redist-server/3.5.0.0) -2012-01-10 11:14:36 +0100 Mike Gabriel (281b04f70) +2012-01-10 11:14:36 +0100 Mike Gabriel (281b04f) * Add patches: 009_add-nxagent-man-page.patch, 009_add-nxproxy-man-page.patch. Reintroduce man page @@ -8158,169 +9371,169 @@ their way into the NX-redistribution tarball created from this source project. -2012-01-10 10:50:01 +0100 Mike Gabriel (71cc495aa) +2012-01-10 10:50:01 +0100 Mike Gabriel (71cc495) * Fix dh_installman for nxproxy. -2012-01-10 10:12:50 +0100 Mike Gabriel (e685cc890) +2012-01-10 10:12:50 +0100 Mike Gabriel (e685cc8) * switch NX-redistribution version to 3.5.0.0 -2012-01-10 10:07:56 +0100 Mike Gabriel (736356ea7) +2012-01-10 10:07:56 +0100 Mike Gabriel (736356e) * Add patch: 000_add-NX-redistribution-README.patch. -2011-12-31 19:28:56 +0100 Mike Gabriel (c9c1f8b91) +2011-12-31 19:28:56 +0100 Mike Gabriel (c9c1f8b) * Remove branding from descriptions in control file. -2011-12-31 18:55:05 +0100 Mike Gabriel (c9bf030aa) +2011-12-31 18:55:05 +0100 Mike Gabriel (c9bf030) * Call dh_clean again. This got lost somewhere on the way. -2011-12-31 18:32:01 +0100 Mike Gabriel (e292f23ac) +2011-12-31 18:32:01 +0100 Mike Gabriel (e292f23) * forgot to add patch file: 005_nxcomp_gcc43.patch -2011-12-31 18:31:40 +0100 Mike Gabriel (91ae4d4e4) +2011-12-31 18:31:40 +0100 Mike Gabriel (91ae4d4) * Fix line hunks: 011_nxcomp_sa-restorer.patch. -2011-12-31 18:29:56 +0100 Mike Gabriel (b494b5287) +2011-12-31 18:29:56 +0100 Mike Gabriel (b494b52) * Revert "Fix linking of doc folders for nxcomp*-dev." -2011-12-31 17:12:52 +0100 Mike Gabriel (2fe05f6ad) +2011-12-31 17:12:52 +0100 Mike Gabriel (2fe05f6) * patches/series cleanup -2011-12-31 17:12:20 +0100 Mike Gabriel (6f30998ad) +2011-12-31 17:12:20 +0100 Mike Gabriel (6f30998) * Add/insert patch: 005_nxcomp_gcc43.patch. -2011-12-31 17:04:48 +0100 Mike Gabriel (448872e70) +2011-12-31 17:04:48 +0100 Mike Gabriel (448872e) * Add patch: 011_nxcomp_sa-restorer.patch. -2011-12-31 16:27:58 +0100 Mike Gabriel (82e5023ed) +2011-12-31 16:27:58 +0100 Mike Gabriel (82e5023) * Transfer patch: 009_nxproxy_add-man-page.patch into man page file in /debian/man. -2011-12-31 16:24:02 +0100 Mike Gabriel (608bbb6d9) +2011-12-31 16:24:02 +0100 Mike Gabriel (608bbb6) * Fix linking of doc folders for nxcomp*-dev. -2011-12-31 16:22:46 +0100 Mike Gabriel (eb069a4e6) +2011-12-31 16:22:46 +0100 Mike Gabriel (eb069a4) * grammar fix in pre-build-nx.sh -2011-12-31 03:18:07 +0100 Mike Gabriel (85e87ab6c) +2011-12-31 03:18:07 +0100 Mike Gabriel (85e87ab) * Add patch headers to all patch files, report most patches upstream. Waiting for feedback and quotable URLs from NoMachine. -2011-12-31 03:16:59 +0100 Mike Gabriel (24261f05e) +2011-12-31 03:16:59 +0100 Mike Gabriel (24261f0) * Remove patch: 104_nxagent_enable_debug.patch, as it breaks package build. -2011-12-31 02:57:25 +0100 Mike Gabriel (a24c4b2e7) +2011-12-31 02:57:25 +0100 Mike Gabriel (a24c4b2) * also forgotten: scripts for last two commits -2011-12-31 01:41:34 +0100 Mike Gabriel (0db119427) +2011-12-31 01:41:34 +0100 Mike Gabriel (0db1194) * changelog: forgot to ship with last commit -2011-12-31 01:39:39 +0100 Mike Gabriel (92374647e) +2011-12-31 01:39:39 +0100 Mike Gabriel (9237464) * * Remove patches and put as executable scripts into /debian/bin/ - 005_add-nxagent-wrapper.patch. - 008_add-nxproxy-wrapper.patch. - 011_add-nxauth-wrapper.patch. -2011-12-31 01:27:13 +0100 Mike Gabriel (383f8eece) +2011-12-31 01:27:13 +0100 Mike Gabriel (383f8ee) * Remove patch 006_remove-configure-files.patch. Implemented via /debian/rules. -2011-12-31 01:03:16 +0100 Mike Gabriel (faa3dee7e) +2011-12-31 01:03:16 +0100 Mike Gabriel (faa3dee) * Make package descriptions in /debian/control more explanatory. -2011-12-31 00:29:09 +0100 Mike Gabriel (a193a0a0a) +2011-12-31 00:29:09 +0100 Mike Gabriel (a193a0a) * Remove *-dbg packages from /debian/control file. -2011-12-31 00:26:16 +0100 Mike Gabriel (caa6dd5f1) +2011-12-31 00:26:16 +0100 Mike Gabriel (caa6dd5) * Add more upstream source information to README.source. -2011-12-30 23:46:45 +0100 Mike Gabriel (c2cdc1da3) +2011-12-30 23:46:45 +0100 Mike Gabriel (c2cdc1d) * Set homepage of NoMachine upstream site (using http://www.nomachine.com/sources.php). -2011-12-30 19:21:24 +0100 Mike Gabriel (7fabca589) +2011-12-30 19:21:24 +0100 Mike Gabriel (7fabca5) * Set homepage of X2Go upstream project (using http://wiki.x2go.org). Packaging Vcs has been relocated to Alioth. -2011-12-30 15:34:02 +0100 Mike Gabriel (f1c239c07) +2011-12-30 15:34:02 +0100 Mike Gabriel (f1c239c) * changelog fix for latest changelog line -2011-12-30 15:32:37 +0100 Mike Gabriel (e20dc398f) +2011-12-30 15:32:37 +0100 Mike Gabriel (e20dc39) * control file: fixing Breaks/Replaces statements -2011-12-30 15:29:39 +0100 Mike Gabriel (28a112c7a) +2011-12-30 15:29:39 +0100 Mike Gabriel (28a112c) * changelog fix: typo -2011-12-30 15:29:01 +0100 Mike Gabriel (74e810a31) +2011-12-30 15:29:01 +0100 Mike Gabriel (74e810a) * changelog fix: wrap long line -2011-12-30 15:28:23 +0100 Mike Gabriel (d6fa23c86) +2011-12-30 15:28:23 +0100 Mike Gabriel (d6fa23c) * Break/conflict with nxlibs and nxlibs-dev (packages provided by freenx-team on Launchpad). -2011-12-30 15:25:30 +0100 Mike Gabriel (290fdeddf) +2011-12-30 15:25:30 +0100 Mike Gabriel (290fded) * Make `breaks-without-version' lintian overrides needless. -2011-12-30 15:20:02 +0100 Mike Gabriel (f9177685a) +2011-12-30 15:20:02 +0100 Mike Gabriel (f917768) * changelog modification: use Debianic revision numbers -2011-12-30 15:16:59 +0100 Mike Gabriel (5287efc44) +2011-12-30 15:16:59 +0100 Mike Gabriel (5287efc) * X2Go Packaging Team becomes maintainer, Mike Gabriel + Reinhard Tartler become uploaders. -2011-12-29 21:38:51 +0100 Mike Gabriel (7d9e1544f) +2011-12-29 21:38:51 +0100 Mike Gabriel (7d9e154) * Fix LD_LIBRARY_PATH export in wrapper scripts/patches. -2011-12-29 16:33:57 +0100 Mike Gabriel (0e3b58b7f) +2011-12-29 16:33:57 +0100 Mike Gabriel (0e3b58b) * Add patch: 019_nx-x11_expat-build-against-system-libxmltok.patch, fixes lintian error: embedded-library: expat. Build-depend on libxmltok1-dev. -2011-12-29 16:28:19 +0100 Mike Gabriel (93b716f78) +2011-12-29 16:28:19 +0100 Mike Gabriel (93b716f) * Disable patch: 006_remove-configure-files.patch, remove configure files from within /debian/rules. -2011-12-29 14:45:18 +0100 Mike Gabriel (21a85ffbe) +2011-12-29 14:45:18 +0100 Mike Gabriel (21a85ff) * Make sure upstream changelog file names are in lower case. -2011-12-29 14:34:35 +0100 Mike Gabriel (5dea6a378) +2011-12-29 14:34:35 +0100 Mike Gabriel (5dea6a3) * * Override lintian warnings - libnx-x11: postinst-has-useless-call-to-ldconfig - libnx-x11: @@ -8329,92 +9542,92 @@ touch any directory controlled by /etc/ld.so.conf, amongst others see BTS issue #205142). -2011-12-29 13:51:47 +0100 Mike Gabriel (3b7914dd7) +2011-12-29 13:51:47 +0100 Mike Gabriel (3b7914d) * Add upstream CHANGELOG files to all .deb packages of this source package. -2011-12-29 13:50:34 +0100 Mike Gabriel (e1f46f911) +2011-12-29 13:50:34 +0100 Mike Gabriel (e1f46f9) * explicitly name all source version from upstream used for initial package release. -2011-12-29 13:27:14 +0100 Mike Gabriel (d57ff7754) +2011-12-29 13:27:14 +0100 Mike Gabriel (d57ff77) * Update patch: 017_nx-x11_update-autotools-helper-files.patch. Add lintian override to source.lintian-overrides: ancient-autotools-helper-file as we handle autotools helper file updates via patch system. -2011-12-29 13:22:26 +0100 Mike Gabriel (776fa97cb) +2011-12-29 13:22:26 +0100 Mike Gabriel (776fa97) * changelog fix: wrap long lines -2011-12-29 13:08:43 +0100 Mike Gabriel (fafea0918) +2011-12-29 13:08:43 +0100 Mike Gabriel (fafea09) * Add patch: 018_nx-x11_update-libtool-ltmain-script.patch. Silence lintian warning ancient-libtool via lintian override as we patch in a new version of ltmain.sh by this patch. -2011-12-29 13:06:55 +0100 Mike Gabriel (a8d1eab2c) +2011-12-29 13:06:55 +0100 Mike Gabriel (a8d1eab) * Add lintian-override: outdated-autotools-helper-file to source.lintian-overrides as we patch-update the outdated helper files before building binaries. -2011-12-29 12:29:24 +0100 Mike Gabriel (184c63e7b) +2011-12-29 12:29:24 +0100 Mike Gabriel (184c63e) * Add README.source file, fixes lintian warning: patch-system-but-no-source-readme. -2011-12-29 12:24:49 +0100 Mike Gabriel (b3eac91c9) +2011-12-29 12:24:49 +0100 Mike Gabriel (b3eac91) * Add patch: 017_nx-x11_update-autotools-helper-files.patch. -2011-12-29 12:17:22 +0100 Mike Gabriel (e68f15a9d) +2011-12-29 12:17:22 +0100 Mike Gabriel (e68f15a) * changelog fix: wrap long line -2011-12-29 11:59:40 +0100 Mike Gabriel (da0bfe6ea) +2011-12-29 11:59:40 +0100 Mike Gabriel (da0bfe6) * Disable patch: 104_nxagent_enable_debug.patch for now as it let's the build fail. -2011-12-29 11:54:02 +0100 Mike Gabriel (3d575c45c) +2011-12-29 11:54:02 +0100 Mike Gabriel (3d575c4) * add possible-new-upstream-release-without-new-version lintian override for *-dev packages, as well -2011-12-29 11:37:35 +0100 Mike Gabriel (b97f5a78b) +2011-12-29 11:37:35 +0100 Mike Gabriel (b97f5a7) * wrap long lines in /debian/changelog -2011-12-29 11:01:23 +0100 Mike Gabriel (dda2c7cd6) +2011-12-29 11:01:23 +0100 Mike Gabriel (dda2c7c) * Rename patch: 008_nxproxy_add-nx-proxy-wrapper.patch to 008_nxproxy_add-nxproxy-wrapper.patch. Add patch from FreeNX patchset: 110_nxagent_createpixmap-bounds-check.patch. -2011-12-29 10:44:39 +0100 Mike Gabriel (c93ae9697) +2011-12-29 10:44:39 +0100 Mike Gabriel (c93ae96) * Install nxagent.xpm icon to /usr/share/pixmaps. -2011-12-29 10:42:42 +0100 Mike Gabriel (43c04dbfd) +2011-12-29 10:42:42 +0100 Mike Gabriel (43c04db) * Rework FreeNX patches to be applicable to latest NX sources. -2011-12-29 10:25:45 +0100 Mike Gabriel (9f226601f) +2011-12-29 10:25:45 +0100 Mike Gabriel (9f22660) * Adapt path names in FreeNX patches to meet requirements for source tree of this package. -2011-12-29 10:03:08 +0100 Mike Gabriel (4cffd99f2) +2011-12-29 10:03:08 +0100 Mike Gabriel (4cffd99) * fix debian/patches/series file to reflect new patch naming scheme... -2011-12-29 09:57:30 +0100 Mike Gabriel (89fea9279) +2011-12-29 09:57:30 +0100 Mike Gabriel (89fea92) * Add FreeNX patches for nxagent (some with other names compared to FreeNX): - 101_nxagent_set-rgb-path.patch - @@ -8428,563 +9641,565 @@ 109_nxagent_locale-utf8-compound-text.patch - 200_nxagent_unbrand-agent.patch -2011-12-29 09:47:29 +0100 Mike Gabriel (dd287a5c8) +2011-12-29 09:47:29 +0100 Mike Gabriel (dd287a5) * Add man page for nxagent. Fix lintian warning: binary-without-manpage. -2011-12-29 09:42:45 +0100 Mike Gabriel (1f87c87a1) +2011-12-29 09:42:45 +0100 Mike Gabriel (1f87c87) * forgot to commit changelog for last two commits (adding of watch files, change of patch file naming scheme) -2011-12-28 23:18:58 +0100 Mike Gabriel (3c2fe1ace) +2011-12-28 23:18:58 +0100 Mike Gabriel (3c2fe1a) * Change naming scheme of patch files. -2011-12-28 23:15:54 +0100 Mike Gabriel (082c8ae3a) +2011-12-28 23:15:54 +0100 Mike Gabriel (082c8ae) * Add individual watch files for NX components in this source package. -2011-12-28 19:25:43 +0100 Mike Gabriel (13b60f760) +2011-12-28 19:25:43 +0100 Mike Gabriel (13b60f7) * Add lintian-overrides for every package. Override lintian warning: possible-new-upstream-release-without-new-version as there will be new upstream releases of NX subprojects that will not require a version increment of the Debian package. -2011-12-28 19:07:03 +0100 Mike Gabriel (c853e1eb8) +2011-12-28 19:07:03 +0100 Mike Gabriel (c853e1e) * changelog update: new upstream release of nxagent 3.5.0-7 -2011-12-28 18:48:50 +0100 Mike Gabriel (82ab807fd) +2011-12-28 18:48:50 +0100 Mike Gabriel (82ab807) * Merge branch 'nxagent' -2011-12-28 18:46:39 +0100 Mike Gabriel (c29053f82) +2011-12-28 18:46:39 +0100 Mike Gabriel (c29053f) * Imported nxagent-3.5.0-7.tar.gz (tag: nxagent/3.5.0-7) -2011-12-06 14:48:04 +0100 Mike Gabriel (aa1665506) +2011-12-06 14:48:04 +0100 Mike Gabriel (aa16655) * fix for patch 016_nx-x11-install.patch (2) -2011-12-06 14:44:40 +0100 Mike Gabriel (37c5f0ee8) +2011-12-06 14:44:40 +0100 Mike Gabriel (37c5f0e) * fix for patch 016_nx-x11-install.patch -2011-12-05 09:51:35 +0100 Mike Gabriel (3132e1d02) +2011-12-05 09:51:35 +0100 Mike Gabriel (3132e1d) * Add patch 016_nx-x11-install.patch, to allow installation of nx-X11 from Makefile (via make install). -2011-12-05 09:50:16 +0100 Mike Gabriel (4c66f3d5c) +2011-12-05 09:50:16 +0100 Mike Gabriel (4c66f3d) * forgot to add file (015_nxproxy-makefile-uninstall.patch) -2011-12-05 09:42:05 +0100 Mike Gabriel (a2d77744d) +2011-12-05 09:42:05 +0100 Mike Gabriel (a2d7774) * Add install/uninstall stanza to main Makefile (via patch 001_add-main-makefile.patch). -2011-12-05 09:39:08 +0100 Mike Gabriel (f4fac4535) +2011-12-05 09:39:08 +0100 Mike Gabriel (f4fac45) * Add patch: 015_nxproxy-makefile-uninstall.patch. -2011-12-05 09:35:03 +0100 Mike Gabriel (8eb3ea78b) +2011-12-05 09:35:03 +0100 Mike Gabriel (8eb3ea7) * Add patches: 012, 013, 014 - Makefile uninstall stanza patches for nxcomp, nxcompext, nxcompshad. -2011-12-02 11:54:03 +0100 Mike Gabriel (9852dfad0) +2011-12-02 11:54:03 +0100 Mike Gabriel (9852dfa) * fix EOF of pre-build-nx.sh script -2011-11-20 18:12:44 +0100 Mike Gabriel (23dcaefb6) +2011-11-20 18:12:44 +0100 Mike Gabriel (23dcaef) * missing control file changes to build nxauth -2011-11-20 18:07:06 +0100 Mike Gabriel (a6903100a) +2011-11-20 18:07:06 +0100 Mike Gabriel (a690310) * Add lintian overrides for libxcomp*: breaks-without-version. -2011-11-20 18:01:52 +0100 Mike Gabriel (7402df3ba) +2011-11-20 18:01:52 +0100 Mike Gabriel (7402df3) * fix ext. description of nxagent in control file -2011-11-20 17:06:41 +0100 Mike Gabriel (b55577524) +2011-11-20 17:06:41 +0100 Mike Gabriel (b555775) * fix patch 001 -2011-11-20 16:51:27 +0100 Mike Gabriel (5814d15bb) +2011-11-20 16:51:27 +0100 Mike Gabriel (5814d15) * Build nxauth package. -2011-11-20 16:46:36 +0100 Mike Gabriel (4fef9e4a4) +2011-11-20 16:46:36 +0100 Mike Gabriel (4fef9e4) * add forgotten patch files for patch 010 and 011 -2011-11-20 16:45:16 +0100 Mike Gabriel (7b5552f70) +2011-11-20 16:45:16 +0100 Mike Gabriel (7b5552f) * Add patch: 011_add-nxauth-wrapper.patch. -2011-11-20 16:42:28 +0100 Mike Gabriel (369972db3) +2011-11-20 16:42:28 +0100 Mike Gabriel (369972d) * Add patch: 010_nxauth-fix-binary-name-in-man-page.patch. -2011-11-20 16:18:39 +0100 Mike Gabriel (e6fa2ca31) +2011-11-20 16:18:39 +0100 Mike Gabriel (e6fa2ca) * Fix of nxproxy build in main Makefile (modifies 001_add-main-makefile.patch). -2011-11-20 16:15:36 +0100 Mike Gabriel (b3d3ea7d8) +2011-11-20 16:15:36 +0100 Mike Gabriel (b3d3ea7) * main Makefile does not need x-bits set -2011-11-20 15:51:32 +0100 Mike Gabriel (379f32a5e) +2011-11-20 15:51:32 +0100 Mike Gabriel (379f32a) * Add nxproxy man page to nxproxy package. -2011-11-20 15:50:20 +0100 Mike Gabriel (5336186cf) +2011-11-20 15:50:20 +0100 Mike Gabriel (5336186) * Add patch: 009_nxproxy-add-man-page.patch. -2011-11-20 15:41:55 +0100 Mike Gabriel (ed08056fd) +2011-11-20 15:41:55 +0100 Mike Gabriel (ed08056) * fix permission of nxproxy wrapper -2011-11-20 15:40:39 +0100 Mike Gabriel (a84dd07bb) +2011-11-20 15:40:39 +0100 Mike Gabriel (a84dd07) * rename 005_add-nxagent-wrapper.patch -2011-11-20 15:39:31 +0100 Mike Gabriel (5ea24ed1e) +2011-11-20 15:39:31 +0100 Mike Gabriel (5ea24ed) * Add patch: 008_add-nxproxy-wrapper.patch. Build nxproxy package. -2011-11-20 15:36:37 +0100 Mike Gabriel (867c3b978) +2011-11-20 15:36:37 +0100 Mike Gabriel (867c3b9) * Add autoconf as build dependency. -2011-11-20 15:27:49 +0100 Mike Gabriel (63bdc1f87) +2011-11-20 15:27:49 +0100 Mike Gabriel (63bdc1f) * Remove unknown option --with from dh_auto_clean. -2011-11-20 15:26:17 +0100 Mike Gabriel (c0fb3c34b) +2011-11-20 15:26:17 +0100 Mike Gabriel (c0fb3c3) * remove build cruft from nxproxy, adapt patch set 006 -2011-11-20 15:03:19 +0100 Mike Gabriel (41c5c2537) +2011-11-20 15:03:19 +0100 Mike Gabriel (41c5c25) * fix distclean for patch 001_add-main-makefile.patch -2011-11-20 14:56:16 +0100 Mike Gabriel (b026a8005) +2011-11-20 14:56:16 +0100 Mike Gabriel (b026a80) * Add patch: 007_nxcompshad-clean-gch-files.patch. -2011-11-20 14:49:53 +0100 Mike Gabriel (d93577c58) +2011-11-20 14:49:53 +0100 Mike Gabriel (d93577c) * Add patch: 006_remove-configure-files.patch. -2011-11-20 14:43:34 +0100 Mike Gabriel (5489d4648) +2011-11-20 14:43:34 +0100 Mike Gabriel (5489d46) * Disable build of *-dbg packages. -2011-11-19 18:15:36 +0100 Mike Gabriel (70ccae44a) +2011-11-19 18:15:36 +0100 Mike Gabriel (70ccae4) * Fix for lintian issue: extended-description-line-too-long (nxagent). -2011-11-19 18:09:05 +0100 Mike Gabriel (3add2cba4) +2011-11-19 18:09:05 +0100 Mike Gabriel (3add2cb) * Fix for lintian issue: missing-build-dependency quilt (>= 0.46-7~). -2011-11-19 17:54:22 +0100 Mike Gabriel (687e07b0c) +2011-11-19 17:54:22 +0100 Mike Gabriel (687e07b) * chown has to be chmod... stupid error... -2011-11-19 17:50:14 +0100 Mike Gabriel (7fb19af29) +2011-11-19 17:50:14 +0100 Mike Gabriel (7fb19af) * add chown a+x for nxagent wrapper script -2011-11-19 17:49:48 +0100 Mike Gabriel (9da568986) +2011-11-19 17:49:48 +0100 Mike Gabriel (9da5689) * add newline at EOF -2011-11-19 17:44:07 +0100 Mike Gabriel (5a7e3cc13) +2011-11-19 17:44:07 +0100 Mike Gabriel (5a7e3cc) * Add patch: 005_add_nxagent_wrapper.patch. -2011-11-19 17:40:48 +0100 Mike Gabriel (e60334546) +2011-11-19 17:40:48 +0100 Mike Gabriel (e603345) * changelog maintenance -2011-11-19 17:40:33 +0100 Mike Gabriel (1234d1b89) +2011-11-19 17:40:33 +0100 Mike Gabriel (1234d1b) * Add patch: 004_nx-x11-fix-nxcompshad-build.patch. -2011-11-19 17:36:45 +0100 Mike Gabriel (85be77cb3) +2011-11-19 17:36:45 +0100 Mike Gabriel (85be77c) * Add patch: 003_nxcompshad-gcc43.patch -2011-11-19 17:30:04 +0100 Mike Gabriel (f7e6c45a5) +2011-11-19 17:30:04 +0100 Mike Gabriel (f7e6c45) * Add patch: 002_nxcompshad-build-against-nx-x11-only.patch -2011-11-19 17:08:40 +0100 Mike Gabriel (954557e90) +2011-11-19 17:08:40 +0100 Mike Gabriel (954557e) * Add main Makefile via patch: 001_add-main-makefile.patch. -2011-11-19 16:43:25 +0100 Mike Gabriel (4076b4132) +2011-11-19 16:43:25 +0100 Mike Gabriel (4076b41) * Add quilt as build dependency. -2011-11-19 16:10:28 +0100 Mike Gabriel (d03110473) +2011-11-19 16:10:28 +0100 Mike Gabriel (d031104) * add /debian folder -2011-11-19 15:59:43 +0100 Mike Gabriel (65f882e05) +2011-11-19 15:59:43 +0100 Mike Gabriel (65f882e) * Merge branch 'nxproxy' -2011-11-19 15:59:38 +0100 Mike Gabriel (9bfca1c2d) +2011-11-19 15:59:38 +0100 Mike Gabriel (9bfca1c) * Merge branch 'nxcompshad' -2011-11-19 15:59:26 +0100 Mike Gabriel (5e502cbb1) +2011-11-19 15:59:26 +0100 Mike Gabriel (5e502cb) * Merge branch 'nxcompext' -2011-11-19 15:59:16 +0100 Mike Gabriel (a48361b11) +2011-11-19 15:59:16 +0100 Mike Gabriel (a48361b) * Merge branch 'nxcomp' -2011-11-13 09:53:38 +0100 Reinhard Tartler (6dc46faed) +2011-11-13 09:53:38 +0100 Reinhard Tartler (6dc46fa) * Imported nxproxy-3.5.0-1.tar.gz (tag: nxproxy/3.5.0-1, - origin/nxproxy, gh-sunweaver/nxproxy) + origin/nxproxy, gh-sunweaver/nxproxy, gh-Ionic/nxproxy) -2011-11-13 09:53:38 +0100 Reinhard Tartler (d83d9f6be) +2011-11-13 09:53:38 +0100 Reinhard Tartler (d83d9f6) * Imported nxproxy-3.4.0-2.tar.gz (tag: nxproxy/3.4.0-2) -2011-11-13 09:53:38 +0100 Reinhard Tartler (7b07a64ea) +2011-11-13 09:53:38 +0100 Reinhard Tartler (7b07a64) * Imported nxproxy-3.3.0-2.tar.gz (tag: nxproxy/3.3.0-2) -2011-11-13 09:53:38 +0100 Reinhard Tartler (131e675bd) +2011-11-13 09:53:38 +0100 Reinhard Tartler (131e675) * Imported nxproxy-3.2.0-1.tar.gz (tag: nxproxy/3.2.0-1) -2011-11-13 09:53:38 +0100 Reinhard Tartler (d588e1f09) +2011-11-13 09:53:38 +0100 Reinhard Tartler (d588e1f) * Imported nxproxy-3.1.0-2.tar.gz (tag: nxproxy/3.1.0-2) -2011-11-13 09:53:38 +0100 Reinhard Tartler (35472e348) +2011-11-13 09:53:38 +0100 Reinhard Tartler (35472e3) * Imported nxproxy-3.0.0-4.tar.gz (tag: nxproxy/3.0.0-4) -2011-11-13 09:53:12 +0100 Reinhard Tartler (bf85c6e69) +2011-11-13 09:53:12 +0100 Reinhard Tartler (bf85c6e) * Imported nxcompshad-3.5.0-2.tar.gz (tag: nxcompshad/3.5.0-2, - origin/nxcompshad, gh-sunweaver/nxcompshad) + origin/nxcompshad, gh-sunweaver/nxcompshad, + gh-Ionic/nxcompshad) -2011-11-13 09:53:12 +0100 Reinhard Tartler (c70adf725) +2011-11-13 09:53:12 +0100 Reinhard Tartler (c70adf7) * Imported nxcompshad-3.4.0-3.tar.gz (tag: nxcompshad/3.4.0-3) -2011-11-13 09:53:12 +0100 Reinhard Tartler (2208f4f9e) +2011-11-13 09:53:12 +0100 Reinhard Tartler (2208f4f) * Imported nxcompshad-3.4.0-1.tar.gz (tag: nxcompshad/3.4.0-1) -2011-11-13 09:53:12 +0100 Reinhard Tartler (3d8e85c47) +2011-11-13 09:53:12 +0100 Reinhard Tartler (3d8e85c) * Imported nxcompshad-3.3.0-3.tar.gz (tag: nxcompshad/3.3.0-3) -2011-11-13 09:53:12 +0100 Reinhard Tartler (3b4404668) +2011-11-13 09:53:12 +0100 Reinhard Tartler (3b44046) * Imported nxcompshad-3.3.0-2.tar.gz (tag: nxcompshad/3.3.0-2) -2011-11-13 09:53:12 +0100 Reinhard Tartler (9f7021392) +2011-11-13 09:53:12 +0100 Reinhard Tartler (9f70213) * Imported nxcompshad-3.2.0-3.tar.gz (tag: nxcompshad/3.2.0-3) -2011-11-13 09:53:12 +0100 Reinhard Tartler (c7dc0c3cd) +2011-11-13 09:53:12 +0100 Reinhard Tartler (c7dc0c3) * Imported nxcompshad-3.2.0-1.tar.gz (tag: nxcompshad/3.2.0-1) -2011-11-13 09:53:12 +0100 Reinhard Tartler (8fa612d1a) +2011-11-13 09:53:12 +0100 Reinhard Tartler (8fa612d) * Imported nxcompshad-3.1.0-2.tar.gz (tag: nxcompshad/3.1.0-2) -2011-11-13 09:52:38 +0100 Reinhard Tartler (88dace9a9) +2011-11-13 09:52:38 +0100 Reinhard Tartler (88dace9) * Imported nxcompext-3.5.0-1.tar.gz (tag: nxcompext/3.5.0-1, - origin/nxcompext, gh-sunweaver/nxcompext) + origin/nxcompext, gh-sunweaver/nxcompext, + gh-Ionic/nxcompext) -2011-11-13 09:52:38 +0100 Reinhard Tartler (9573b5669) +2011-11-13 09:52:38 +0100 Reinhard Tartler (9573b56) * Imported nxcompext-3.4.0-1.tar.gz (tag: nxcompext/3.4.0-1) -2011-11-13 09:52:38 +0100 Reinhard Tartler (9ea069139) +2011-11-13 09:52:38 +0100 Reinhard Tartler (9ea0691) * Imported nxcompext-3.3.0-4.tar.gz (tag: nxcompext/3.3.0-4) -2011-11-13 09:52:38 +0100 Reinhard Tartler (f2f6dab87) +2011-11-13 09:52:38 +0100 Reinhard Tartler (f2f6dab) * Imported nxcompext-3.3.0-3.tar.gz (tag: nxcompext/3.3.0-3) -2011-11-13 09:52:37 +0100 Reinhard Tartler (abf03fd2c) +2011-11-13 09:52:37 +0100 Reinhard Tartler (abf03fd) * Imported nxcompext-3.3.0-2.tar.gz (tag: nxcompext/3.3.0-2) -2011-11-13 09:52:37 +0100 Reinhard Tartler (4ad13f4ef) +2011-11-13 09:52:37 +0100 Reinhard Tartler (4ad13f4) * Imported nxcompext-3.2.0-1.tar.gz (tag: nxcompext/3.2.0-1) -2011-11-13 09:52:37 +0100 Reinhard Tartler (42e72ef5f) +2011-11-13 09:52:37 +0100 Reinhard Tartler (42e72ef) * Imported nxcompext-3.1.0-2.tar.gz (tag: nxcompext/3.1.0-2) -2011-11-13 09:27:53 +0100 Reinhard Tartler (232dfc41d) +2011-11-13 09:27:53 +0100 Reinhard Tartler (232dfc4) * Imported nxcomp-3.5.0-2.tar.gz (tag: nxcomp/3.5.0-2, origin/nxcomp, - gh-sunweaver/nxcomp) + gh-sunweaver/nxcomp, gh-Ionic/nxcomp) -2011-11-13 09:27:53 +0100 Reinhard Tartler (233de71fc) +2011-11-13 09:27:53 +0100 Reinhard Tartler (233de71) * Imported nxcomp-3.5.0-1.tar.gz (tag: nxcomp/3.5.0-1) -2011-11-13 09:27:53 +0100 Reinhard Tartler (7c9e193ae) +2011-11-13 09:27:53 +0100 Reinhard Tartler (7c9e193) * Imported nxcomp-3.4.0-7.tar.gz (tag: nxcomp/3.4.0-7) -2011-11-13 09:27:53 +0100 Reinhard Tartler (477961678) +2011-11-13 09:27:53 +0100 Reinhard Tartler (4779616) * Imported nxcomp-3.4.0-6.tar.gz (tag: nxcomp/3.4.0-6) -2011-11-13 09:27:52 +0100 Reinhard Tartler (799bf672a) +2011-11-13 09:27:52 +0100 Reinhard Tartler (799bf67) * Imported nxcomp-3.4.0-1.tar.gz (tag: nxcomp/3.4.0-1) -2011-11-13 09:27:52 +0100 Reinhard Tartler (ca416e797) +2011-11-13 09:27:52 +0100 Reinhard Tartler (ca416e7) * Imported nxcomp-3.3.0-4.tar.gz (tag: nxcomp/3.3.0-4) -2011-11-13 09:27:52 +0100 Reinhard Tartler (95ce6b74b) +2011-11-13 09:27:52 +0100 Reinhard Tartler (95ce6b7) * Imported nxcomp-3.3.0-3.tar.gz (tag: nxcomp/3.3.0-3) -2011-11-13 09:27:52 +0100 Reinhard Tartler (920705cf7) +2011-11-13 09:27:52 +0100 Reinhard Tartler (920705c) * Imported nxcomp-3.2.0-7.tar.gz (tag: nxcomp/3.2.0-7) -2011-11-13 09:27:52 +0100 Reinhard Tartler (92239dafb) +2011-11-13 09:27:52 +0100 Reinhard Tartler (92239da) * Imported nxcomp-3.2.0-6.tar.gz (tag: nxcomp/3.2.0-6) -2011-11-13 09:27:52 +0100 Reinhard Tartler (d7a8d67d7) +2011-11-13 09:27:52 +0100 Reinhard Tartler (d7a8d67) * Imported nxcomp-3.1.0-6.tar.gz (tag: nxcomp/3.1.0-6) -2011-11-13 09:27:51 +0100 Reinhard Tartler (3e924126b) +2011-11-13 09:27:51 +0100 Reinhard Tartler (3e92412) * Imported nxcomp-3.1.0-4.tar.gz (tag: nxcomp/3.1.0-4) -2011-10-10 18:03:17 +0200 Reinhard Tartler (9997e13bb) +2011-10-10 18:03:17 +0200 Reinhard Tartler (9997e13) * Merge branch 'nx-X11' -2011-10-10 18:02:52 +0200 Reinhard Tartler (5b4ca0f93) +2011-10-10 18:02:52 +0200 Reinhard Tartler (5b4ca0f) * Merge branch 'nxagent' -2011-10-10 18:02:41 +0200 Reinhard Tartler (e29a11209) +2011-10-10 18:02:41 +0200 Reinhard Tartler (e29a112) * Merge branch 'nxauth' -2011-10-10 17:59:01 +0200 Reinhard Tartler (e01b9177b) +2011-10-10 17:59:01 +0200 Reinhard Tartler (e01b917) * Imported nxagent-3.5.0-5.tar.gz (tag: nxagent/3.5.0-5) -2011-10-10 17:59:00 +0200 Reinhard Tartler (39b738a67) +2011-10-10 17:59:00 +0200 Reinhard Tartler (39b738a) * Imported nxagent-3.5.0-2.tar.gz (tag: nxagent/3.5.0-2) -2011-10-10 17:59:00 +0200 Reinhard Tartler (e6db7e936) +2011-10-10 17:59:00 +0200 Reinhard Tartler (e6db7e9) * Imported nxagent-3.4.0-9.tar.gz (tag: nxagent/3.4.0-9) -2011-10-10 17:58:59 +0200 Reinhard Tartler (b7494f082) +2011-10-10 17:58:59 +0200 Reinhard Tartler (b7494f0) * Imported nxagent-3.4.0-8.tar.gz (tag: nxagent/3.4.0-8) -2011-10-10 17:58:59 +0200 Reinhard Tartler (c07802401) +2011-10-10 17:58:59 +0200 Reinhard Tartler (c078024) * Imported nxagent-3.4.0-5.tar.gz (tag: nxagent/3.4.0-5) -2011-10-10 17:58:58 +0200 Reinhard Tartler (d30ef0340) +2011-10-10 17:58:58 +0200 Reinhard Tartler (d30ef03) * Imported nxagent-3.4.0-3.tar.gz (tag: nxagent/3.4.0-3) -2011-10-10 17:58:57 +0200 Reinhard Tartler (25af86cd3) +2011-10-10 17:58:57 +0200 Reinhard Tartler (25af86c) * Imported nxagent-3.4.0-16.tar.gz (tag: nxagent/3.4.0-16) -2011-10-10 17:58:57 +0200 Reinhard Tartler (e9132da09) +2011-10-10 17:58:57 +0200 Reinhard Tartler (e9132da) * Imported nxagent-3.4.0-11.tar.gz (tag: nxagent/3.4.0-11) -2011-10-10 17:58:56 +0200 Reinhard Tartler (6f5e20bc4) +2011-10-10 17:58:56 +0200 Reinhard Tartler (6f5e20b) * Imported nxagent-3.3.0-9.tar.gz (tag: nxagent/3.3.0-9) -2011-10-10 17:58:56 +0200 Reinhard Tartler (45b970f25) +2011-10-10 17:58:56 +0200 Reinhard Tartler (45b970f) * Imported nxagent-3.3.0-6.tar.gz (tag: nxagent/3.3.0-6) -2011-10-10 17:58:56 +0200 Reinhard Tartler (229144470) +2011-10-10 17:58:56 +0200 Reinhard Tartler (2291444) * Imported nxagent-3.3.0-18.tar.gz (tag: nxagent/3.3.0-18) -2011-10-10 17:58:56 +0200 Reinhard Tartler (fc05e5e04) +2011-10-10 17:58:56 +0200 Reinhard Tartler (fc05e5e) * Imported nxagent-3.3.0-13.tar.gz (tag: nxagent/3.3.0-13) -2011-10-10 17:58:55 +0200 Reinhard Tartler (1a74e0323) +2011-10-10 17:58:55 +0200 Reinhard Tartler (1a74e03) * Imported nxagent-3.3.0-10.tar.gz (tag: nxagent/3.3.0-10) -2011-10-10 17:58:55 +0200 Reinhard Tartler (97fe7650e) +2011-10-10 17:58:55 +0200 Reinhard Tartler (97fe765) * Imported nxagent-3.2.0-8.tar.gz (tag: nxagent/3.2.0-8) -2011-10-10 17:58:55 +0200 Reinhard Tartler (c4e7705d2) +2011-10-10 17:58:55 +0200 Reinhard Tartler (c4e7705) * Imported nxagent-3.2.0-7.tar.gz (tag: nxagent/3.2.0-7) -2011-10-10 17:58:55 +0200 Reinhard Tartler (c9983230f) +2011-10-10 17:58:55 +0200 Reinhard Tartler (c998323) * Imported nxagent-3.2.0-6.tar.gz (tag: nxagent/3.2.0-6) -2011-10-10 17:58:55 +0200 Reinhard Tartler (b79164001) +2011-10-10 17:58:55 +0200 Reinhard Tartler (b791640) * Imported nxagent-3.2.0-5.tar.gz (tag: nxagent/3.2.0-5) -2011-10-10 17:58:31 +0200 Reinhard Tartler (1c25e92b9) +2011-10-10 17:58:31 +0200 Reinhard Tartler (1c25e92) * Imported nxagent-3.2.0-10.tar.gz (tag: nxagent/3.2.0-10) -2011-10-10 17:58:31 +0200 Reinhard Tartler (266b55549) +2011-10-10 17:58:31 +0200 Reinhard Tartler (266b555) * Imported nxagent-3.1.0-7.tar.gz (tag: nxagent/3.1.0-7) -2011-10-10 17:58:31 +0200 Reinhard Tartler (3e7c6697a) +2011-10-10 17:58:31 +0200 Reinhard Tartler (3e7c669) * Imported nxagent-3.1.0-6.tar.gz (tag: nxagent/3.1.0-6) -2011-10-10 17:58:30 +0200 Reinhard Tartler (9e3371021) +2011-10-10 17:58:30 +0200 Reinhard Tartler (9e33710) * Imported nxagent-3.1.0-2.tar.gz (tag: nxagent/3.1.0-2) -2011-10-10 17:57:25 +0200 Reinhard Tartler (edddbe876) +2011-10-10 17:57:25 +0200 Reinhard Tartler (edddbe8) * creating nxagent -2011-10-10 17:51:57 +0200 Reinhard Tartler (caf1bc41f) +2011-10-10 17:51:57 +0200 Reinhard Tartler (caf1bc4) * Imported nxauth-3.5.0-1.tar.gz (tag: nxauth/3.5.0-1) -2011-10-10 17:51:57 +0200 Reinhard Tartler (fea16d7bb) +2011-10-10 17:51:57 +0200 Reinhard Tartler (fea16d7) * Imported nxauth-3.4.0-3.tar.gz (tag: nxauth/3.4.0-3) -2011-10-10 17:51:57 +0200 Reinhard Tartler (d90fd5d13) +2011-10-10 17:51:57 +0200 Reinhard Tartler (d90fd5d) * Imported nxauth-3.4.0-2.tar.gz (tag: nxauth/3.4.0-2) -2011-10-10 17:51:57 +0200 Reinhard Tartler (7881dac52) +2011-10-10 17:51:57 +0200 Reinhard Tartler (7881dac) * Imported nxauth-3.4.0-1.tar.gz (tag: nxauth/3.4.0-1) -2011-10-10 17:51:57 +0200 Reinhard Tartler (c76c07835) +2011-10-10 17:51:57 +0200 Reinhard Tartler (c76c078) * Imported nxauth-3.3.0-1.tar.gz (tag: nxauth/3.3.0-1) -2011-10-10 17:51:57 +0200 Reinhard Tartler (76b9f2d91) +2011-10-10 17:51:57 +0200 Reinhard Tartler (76b9f2d) * Imported nxauth-3.2.0-1.tar.gz (tag: nxauth/3.2.0-1) -2011-10-10 17:51:57 +0200 Reinhard Tartler (9610c1e72) +2011-10-10 17:51:57 +0200 Reinhard Tartler (9610c1e) * Imported nxauth-3.1.0-1.tar.gz (tag: nxauth/3.1.0-1) -2011-10-10 17:47:59 +0200 Reinhard Tartler (15cee47a4) +2011-10-10 17:47:59 +0200 Reinhard Tartler (15cee47) * Imported nx-X11-3.5.0-2.tar.gz (tag: nx-X11/3.5.0-2, origin/nx-X11, - gh-sunweaver/nx-X11) + gh-sunweaver/nx-X11, gh-Ionic/nx-X11) -2011-10-10 17:47:52 +0200 Reinhard Tartler (964f53964) +2011-10-10 17:47:52 +0200 Reinhard Tartler (964f539) * Imported nx-X11-3.5.0-1.tar.gz (tag: nx-X11/3.5.0-1) -2011-10-10 17:47:50 +0200 Reinhard Tartler (17bae6bff) +2011-10-10 17:47:50 +0200 Reinhard Tartler (17bae6b) * Imported nx-X11-3.4.0-4.tar.gz (tag: nx-X11/3.4.0-4) -2011-10-10 17:47:47 +0200 Reinhard Tartler (4fceb197e) +2011-10-10 17:47:47 +0200 Reinhard Tartler (4fceb19) * Imported nx-X11-3.4.0-3.tar.gz (tag: nx-X11/3.4.0-3) -2011-10-10 17:47:45 +0200 Reinhard Tartler (3daf6d446) +2011-10-10 17:47:45 +0200 Reinhard Tartler (3daf6d4) * Imported nx-X11-3.4.0-1.tar.gz (tag: nx-X11/3.4.0-1) -2011-10-10 17:47:42 +0200 Reinhard Tartler (5036ffbe6) +2011-10-10 17:47:42 +0200 Reinhard Tartler (5036ffb) * Imported nx-X11-3.3.0-7.tar.gz (tag: nx-X11/3.3.0-7) -2011-10-10 17:47:40 +0200 Reinhard Tartler (bd433c648) +2011-10-10 17:47:40 +0200 Reinhard Tartler (bd433c6) * Imported nx-X11-3.3.0-6.tar.gz (tag: nx-X11/3.3.0-6) -2011-10-10 17:47:37 +0200 Reinhard Tartler (55a9311fb) +2011-10-10 17:47:37 +0200 Reinhard Tartler (55a9311) * Imported nx-X11-3.3.0-5.tar.gz (tag: nx-X11/3.3.0-5) -2011-10-10 17:47:35 +0200 Reinhard Tartler (aefdef62f) +2011-10-10 17:47:35 +0200 Reinhard Tartler (aefdef6) * Imported nx-X11-3.3.0-4.tar.gz (tag: nx-X11/3.3.0-4) -2011-10-10 17:47:32 +0200 Reinhard Tartler (01ed75712) +2011-10-10 17:47:32 +0200 Reinhard Tartler (01ed757) * Imported nx-X11-3.3.0-3.tar.gz (tag: nx-X11/3.3.0-3) -2011-10-10 17:47:30 +0200 Reinhard Tartler (30463b084) +2011-10-10 17:47:30 +0200 Reinhard Tartler (30463b0) * Imported nx-X11-3.2.0-2.tar.gz (tag: nx-X11/3.2.0-2) -2011-10-10 17:47:28 +0200 Reinhard Tartler (713da2260) +2011-10-10 17:47:28 +0200 Reinhard Tartler (713da22) * Imported nx-X11-3.2.0-1.tar.gz (tag: nx-X11/3.2.0-1) -2011-10-10 17:46:43 +0200 Reinhard Tartler (3d1c57d5e) +2011-10-10 17:46:43 +0200 Reinhard Tartler (3d1c57d) * Imported nx-X11-3.1.0-4.tar.gz (tag: nx-X11/3.1.0-4) -2011-10-10 17:46:25 +0200 Reinhard Tartler (844a4094f) +2011-10-10 17:46:25 +0200 Reinhard Tartler (844a409) * Imported nx-X11-3.1.0-3.tar.gz (tag: nx-X11/3.1.0-3) -2011-10-10 17:43:39 +0200 Reinhard Tartler (f4092abdf) +2011-10-10 17:43:39 +0200 Reinhard Tartler (f4092ab) * Imported nx-X11-3.1.0-1.tar.gz (tag: nx-X11/3.1.0-1) -2011-10-10 17:22:20 +0200 Reinhard Tartler (e5c70dac0) +2011-10-10 17:22:20 +0200 Reinhard Tartler (e5c70da) * creating nxauth -2011-10-10 15:28:54 +0200 Reinhard Tartler (a840692ed) +2011-10-10 15:28:54 +0200 Reinhard Tartler (a840692) * creating nx-X11 diff --git a/VERSION b/VERSION index f1a1688ce..81712ca79 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.99.4 +3.5.99.5 diff --git a/debian/changelog b/debian/changelog index 9e2dd7ae8..81092a664 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +nx-libs (2:3.5.99.5-0.1) unstable; urgency=medium + + * Upstream-provided Debian package for nx-libs. + See upstream ChangeLog for recent changes. + + -- Mike Gabriel Tue, 11 Apr 2017 17:00:28 +0200 + nx-libs (2:3.5.99.4-0.1) unstable; urgency=medium * Upstream-provided Debian package for nx-libs. diff --git a/debian/copyright b/debian/copyright index 975432d43..b3573e421 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1016,19 +1016,10 @@ Files: make-changelog.sh Copyright: 2012, Mike Gabriel 2016, Mike Gabriel License: GPL-2+ -Comment: - See https://github.com/ArcticaProject/nx-libs/commit/9c0d528 for - make-changelog.sh and regenerate-symbol-docs.sh. - . - FIXME: Drop this comment for 3.5.99.4. Files: replace.sh Copyright: 2013, Jan Engelhardt License: GPL-2+ -Comment: - See https://github.com/ArcticaProject/nx-libs/commit/9c0d528. - . - FIXME: Drop this comment for 3.5.99.4. Files: nx-X11/extras/Mesa/src/mesa/main/get.c nx-X11/extras/Mesa/src/mesa/main/texrender.c @@ -2516,22 +2507,6 @@ Comment: over the NX protocol, have to be considered as strictly GPL-2 licensed. -Files: nx-X11/programs/Xserver/hw/nxagent/os2Stub.c -Copyright: 1996, Sebastien Marineau - 2001, 2011, NoMachine (http://www.nomachine.com) - 2008-2014, Oleksandr Shneyder - 2011-2016, Mike Gabriel */ - 2014-2016, Mihai Moldovan - 2014-2016, Ulrich Sibiller - 2015-2016, Qindel Group (http://www.qindel.com) -License: Expat~NoAdvert -Comment: - No NX specific changes can be found in this file. GPL-2 - license in file header does not apply. - . - Note from upstream side: This file will be removed in - nx-libs 3.5.99.4. - Files: nx-X11/programs/Xserver/hw/nxagent/Agent.h Copyright: 1995, X Consortium 2001, 2011, NoMachine (http://www.nomachine.com) @@ -2549,18 +2524,10 @@ Files: nx-X11/programs/Xserver/composite/compositeext.h Copyright: 2009, NVIDIA Corporation License: Expat -Files: nx-X11/lib/X11/os2Stubs.c -Copyright: 1996, Sebastien Marineau and Holger Veit -License: Expat~NoAdvert -Comment: - Note from upstream side: This file will be removed in - nx-libs 3.5.99.4. - Files: nx-X11/extras/Mesa/src/mesa/main/texenvprogram.c Copyright: 2003, Tungsten Graphics, Inc., Cedar Park, Texas License: Expat - Files: nx-X11/extras/Mesa/src/mesa/main/mm.c Copyright: 1999, Wittawat Yamwong License: Expat @@ -2967,11 +2934,6 @@ Files: nxcomp/install-sh nxproxy/install-sh Copyright: 1994, X Consortium License: Expat~NoAdvert -Comment: - Missing license headers. License and copyright information obtained from - later versions of this file as found in automake-1.14. - . - FIXME: This comment will be obsolete for 3.5.99.4. Files: debian/* Copyright: 2011-2016, Mike Gabriel diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index d204acdc5..302603ab0 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -24,7 +24,7 @@ .\" other dealings in this Software without prior written authorization .\" from The Open Group. .ds q \N'34' -.TH nxagent 1 "Feb 2017" "Version 3.6.x" "NX Agent (Xserver)" +.TH nxagent 1 "April 2017" "Version 3.6.x" "NX Agent (Xserver)" .SH NAME nxagent \- nx-X11 Agent (nested Xserver optimized for remote computing) .SH SYNOPSIS diff --git a/nx-libs.spec b/nx-libs.spec index 935219f0f..ed5e7cb49 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -1,7 +1,7 @@ %global _hardened_build 1 Name: nx-libs -Version: 3.5.99.4 +Version: 3.5.99.5 Release: 0.0build1%{?dist} Summary: NX X11 protocol compression libraries diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index dd14afa12..afb5f69d4 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH nxproxy 1 "Feb 2017" "Version 3.6.x" "NX Proxy" +.TH nxproxy 1 "April 2017" "Version 3.6.x" "NX Proxy" .SH NAME nxproxy \- NX Proxy Tool .SH SYNOPSIS -- cgit v1.2.3 From 3b15804cef3c4412897bf243c063af6506a21976 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 30 Jun 2017 21:21:49 +0200 Subject: release 3.5.99.8 --- ChangeLog | 238 ++++++++++++++++++++++- VERSION | 2 +- debian/changelog | 7 + debian/copyright | 3 +- nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 2 +- nx-libs.spec | 2 +- nxproxy/man/nxproxy.1 | 2 +- 7 files changed, 241 insertions(+), 15 deletions(-) (limited to 'nxproxy') diff --git a/ChangeLog b/ChangeLog index f10f0d8ef..2953b7a33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,226 @@ -2017-05-05 00:16:41 +0200 Mike Gabriel (36b61e417) +2017-06-30 21:21:49 +0200 Mike Gabriel (891c059f5) - * release 3.5.99.7 (HEAD -> 3.6.x, release-builds/3.6.x) + * release 3.5.99.8 (HEAD -> 3.6.x) + +2017-06-30 20:59:27 +0200 Mihai Moldovan (4c7641a1f) + + * Merge branch 'sunweaver-pr/mese-quilt-without-quilt' into 3.6.x + (origin/HEAD, origin/3.6.x) + +2017-06-30 20:24:28 +0200 Mike Gabriel (79fcce3ee) + + * README.Mesa.patches: Define some rules for patch naming and + numbering scheme. + (gh-sunweaver/pr/mese-quilt-without-quilt, + pr/mese-quilt-without-quilt) + +2017-06-27 19:21:23 +0200 Mike Gabriel (638b334c8) + + * mesa-quilt: Provide a fallback patching method on systems where + pulling quilt into the build env is not trivial. + +2017-06-27 19:47:35 +0200 Mike Gabriel (bac473917) + + * nx-libs.spec: Use mesa-quilt with Fedora builds, but rely on + fallback mode in mesa-quilt for RHEL and SUSE. + +2017-06-30 17:41:21 +0200 Mihai Moldovan (05450d0e8) + + * Merge branch 'sunweaver-pr/browser-scrolling-improvements' into + 3.6.x + +2017-06-29 10:08:56 +0200 Oleksandr Shneyder (7d51cb676) + + * nxcomp: Set TokenSize to 1536 for link type ADSL and WAN. Improving + non-xrender based browser scrolling behaviour when link + type is set to ADSL or WAN. + (gh-sunweaver/pr/browser-scrolling-improvements, + pr/browser-scrolling-improvements) + +2017-06-30 16:22:25 +0200 Mike Gabriel (4365fe38e) + + * Merge branch 'sunweaver-pr/nx-real-wid' into 3.6.x + +2017-05-30 21:28:03 +0200 Mike Gabriel (588be6386) + + * hw/nxagent/Window.c: Introduce NX_REAL_WINDOW window property. + (gh-sunweaver/pr/nx-real-wid, sunweaver-pr/nx-real-wid, + pr/nx-real-wid) + +2017-05-30 21:33:33 +0200 Mike Gabriel (c88e87bc8) + + * hw/nxagnet/Atoms.c: In DEBUG mode, we need validateString() which + is not statically defined in Utils.h. Thus including it + for DEBUG builds. + +2017-06-28 22:23:42 +0200 Mihai Moldovan (3d255540f) + + * Merge branch 'sunweaver-pr/fix-ftbfs-on-hppa' into 3.6.x + +2017-05-06 01:31:14 +0200 Mike Gabriel (65c420515) + + * debian/patches: Update 016_nx-X11_install-location.debian.patch + (line numbers only). (gh-sunweaver/pr/fix-ftbfs-on-hppa, + pr/fix-ftbfs-on-hppa) + +2017-05-06 00:38:01 +0200 Mike Gabriel (347363f3f) + + * Fix FTBFS on Linux based HP-PARisc 32-bit systems. Thanks to John + Paul Adrian Glaubitz from FU Berlin for providing access + to a corresponding porters' machine. + +2017-05-06 00:29:46 +0200 Adam Jackson (f77a4b405) + + * dix: Remove arch awareness from servermd.h (X.org v2, nx-libs v4) + +2017-06-28 19:20:36 +0200 Mihai Moldovan (78d41614e) + + * Merge branch 'sunweaver-pr/fix-ftbfs-on-mips64el' into 3.6.x + +2017-06-27 19:59:36 +0200 Mike Gabriel (c22c3f729) + + * nx-X11/config/cf/linux.cf: Drop AsOutputArchSize macro from + Sparc(64)Architecture ifdef-block. It does not seem to be + used anywhere else. + (gh-sunweaver/pr/fix-ftbfs-on-mips64el, + pr/fix-ftbfs-on-mips64el) + +2017-05-07 19:47:27 +0200 Mike Gabriel (1839dd642) + + * Fix FTBFS on mips64el architecture due to missing definition of the + _XSERVER64 macro. + +2017-06-27 19:16:33 +0200 Mike Gabriel (cde05c090) + + * Mesa.patches_6.4.1: Add missing EOL at EOF to series file. + +2017-06-27 19:15:53 +0200 Mike Gabriel (e2d72b599) + + * Mesa.patches: Have Mesa.patches_6.4.2 rather as a copy than as a + symlink to Mesa.patches_6.4.1. Rebase + 4004_define-USE_IEEE-macro-for-more-platforms.patch + against Mesa 6.4.2 while being at it. + +2017-06-27 18:34:20 +0200 Mike Gabriel (3dcdea4dd) + + * Merge branch 'frantracer-mesa-update-6.4.2' into 3.6.x + +2017-06-27 15:53:30 +0200 ftrapero (fa70485dc) + + * roll-tarball.sh: Fix resolution of symbolic links and removal of + useless Mesa versions (frantracer-mesa-update-6.4.2) + +2017-06-27 12:12:09 +0200 ftrapero (2dd6ca0c8) + + * nx-X11/extras: Add symlinks to Mesa_6.4.2 and patches + +2017-06-27 12:08:38 +0200 ftrapero (b30506dfa) + + * Include mesa-6.4.2 project + +2017-06-27 12:08:38 +0200 ftrapero (663631725) + + * Squashed 'nx-X11/extras/Mesa_6.4.2/' content from commit 475b1f7 + +2017-06-19 11:01:22 +0200 Mike Gabriel (c032f0e34) + + * roll-tarball.sh: Fix tarball creation, now that we pull in Mesa as + a git-subtree. This basically moves versioned folders + around and drops the Mesa/ and Mesa.patches/ symlinks. + +2017-06-19 10:16:14 +0200 Mike Gabriel (014365877) + + * Merge branch 'frantracer-mesa-squash-subtree' into 3.6.x + +2017-02-20 15:36:36 +0100 Mike Gabriel (123fb7fe7) + + * roll-tarball.sh: Drop various unused files from the bundled Mesa + version when creating release tarballs. + (frantracer-mesa-squash-subtree) + +2017-02-20 12:54:14 +0100 Mike Gabriel (c20b946b4) + + * Mesa subtree: Adapt build process for building against Mesa that + gets pulled in via git subtree. + +2017-02-17 16:11:01 +0100 Mike Gabriel (209657f69) + + * nx-X11/extras/Mesa: Drop bundled Mesa, place a symlink to imported + Git subtree of Mesa_6.4.1 instead. + +2017-06-15 14:15:08 +0200 ftrapero (459021c16) + + * Include mesa-6.4.1 project + +2017-06-15 14:15:08 +0200 ftrapero (8667d4d97) + + * Squashed 'nx-X11/extras/Mesa_6.4.1/' content from commit 53d1bc0 + +2017-06-11 14:26:35 +0200 Mike Gabriel (4f216e7cf) + + * Merge branch 'uli42-pr/fix_sync_segfault' into 3.6.x + +2017-06-09 22:27:20 +0200 Ulrich Sibiller (19116a61c) + + * Args.c: fix sync option parsing (gh-uli42/pr/fix_sync_segfault, + uli42-pr/fix_sync_segfault) + +2017-06-06 20:33:55 +0200 Mike Gabriel (7fd59fbd1) + + * Merge branch 'uli42-pr/remove_unused_defines' into 3.6.x + +2016-11-04 00:30:02 +0100 Ulrich Sibiller (52d65a4f6) + + * remove BuildRman define (gh-uli42/pr/remove_unused_defines, + uli42-pr/remove_unused_defines) + +2017-06-06 14:29:20 +0200 Mike Gabriel (7b00b7bb8) + + * Merge branch 'salva-install-as-non-root' into 3.6.x + +2017-05-31 11:44:59 +0200 Salvador Fandiño (320352d64) + + * Don't force root ownership of dirs when installing + (salva-install-as-non-root) + +2017-05-31 14:30:32 +0200 Salvador Fandiño (f61956c16) + + * Propagate DESTDIR and PREFIX from Makefile + +2017-05-31 13:01:58 +0200 Mike Gabriel (04fbb2726) + + * Merge branch 'mikedep333-f24-ftbfs' into 3.6.x + +2017-05-25 08:14:49 -0400 Mike DePaulo (c7ce96546) + + * nx-libs.xpec: Fix FTBFS on F24 due to missing Xfont2 + (mikedep333-f24-ftbfs) + +2017-05-06 02:01:47 +0200 Mike Gabriel (150cbc23d) + + * debian/copyright: Update copyright attributions. + +2017-05-06 00:03:48 +0200 Mike Gabriel (6479ed576) + + * nx-X11/config/cf/gnuLib.rules: Drop ancient Vcs comment. + Erroneously sneaked in with reintroduction of + GNU/ support. + +2017-05-05 14:07:29 +0200 Mihai Moldovan (53cabac9e) + + * Merge branch 'uli42-pr/fix_rhel6' into 3.6.x + +2017-04-25 14:47:48 +0200 Ulrich Sibiller (444e62156) + + * nx-libs.spec: fix FTBFS on RHEL6 (gh-uli42/pr/fix_rhel6) + +2017-05-05 00:16:41 +0200 Mike Gabriel (5d5336541) + + * release 3.5.99.7 (tag: 3.5.99.7) 2017-05-04 23:54:31 +0200 Ulrich Sibiller (13753ddfd) * Merge pull request #427 from sunweaver/pr/gnu-hurd-i386-support - (origin/HEAD, origin/3.6.x) 2017-04-13 12:01:07 +0200 Mike Gabriel (681069d7a) @@ -30,7 +245,8 @@ * Revert "Switch from using libNX_X11's deprecated XKeycodeToKeysym() function to using XGetKeyboardMapping()." - (uli42-pr/fix_keyboard_delay) + (gh-uli42/pr/fix_keyboard_delay, + uli42-pr/fix_keyboard_delay) 2017-04-25 14:20:55 +0200 Mihai Moldovan (60d7c02e0) @@ -43,7 +259,7 @@ 2017-04-21 16:26:31 +0200 Mike Gabriel (06a6a5fca) - * release 3.5.99.6 (tag: 3.5.99.6, origin/release-builds/3.6.x) + * release 3.5.99.6 (tag: 3.5.99.6) 2017-04-21 16:20:50 +0200 Mihai Moldovan (1c6217054) @@ -119,7 +335,8 @@ 2017-04-18 00:10:46 +0200 Ulrich Sibiller (394246855) - * nxagent.1: some more rephrasing (uli42-pr/extend_manpage) + * nxagent.1: some more rephrasing (gh-uli42/pr/extend_manpage, + uli42-pr/extend_manpage) 2017-04-18 00:08:55 +0200 Ulrich Sibiller (4998c41de) @@ -428,7 +645,8 @@ 2017-03-27 22:58:38 +0200 Ulrich Sibiller (ee18cd43d) * Keystrokes: rename left/up/right/down keystrokes to descriptive - names (uli42-pr/cleanup_keystroke) + names (gh-uli42/pr/cleanup_keystroke, + uli42-pr/cleanup_keystroke) 2017-03-27 22:46:47 +0200 Ulrich Sibiller (d28cf5574) @@ -532,7 +750,7 @@ 2017-02-01 15:02:41 +0100 Arthur Huillet (00405b278) * _XDefaultError: set XlibDisplayIOError flag before calling exit - (uli42-pr/libX11-HEAD) + (gh-uli42/pr/libX11-HEAD, uli42-pr/libX11-HEAD) 2017-01-07 16:20:31 +0100 Julien Cristau (8ad49a03e) @@ -704,7 +922,7 @@ 2017-03-19 21:59:17 +0100 Ulrich Sibiller (7065e0bf2) * Keystroke.c: ignore CapsLock and NumLock most of the time - (uli42-pr/ignore_caps) + (gh-uli42/pr/ignore_caps, uli42-pr/ignore_caps) 2017-03-17 20:39:28 +0100 Mihai Moldovan (7fd5d934c) @@ -748,7 +966,7 @@ 2017-03-13 22:19:17 +0100 Ulrich Sibiller (6f4eb1540) - * Update keystroke readme (gh-uli42/pr/cleanup_keystroke) + * Update keystroke readme 2017-03-13 22:07:58 +0100 Ulrich Sibiller (cb40cc448) diff --git a/VERSION b/VERSION index 3f9f9de96..5e5089265 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.99.7 +3.5.99.8 diff --git a/debian/changelog b/debian/changelog index 93d779b59..77c9eedc3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +nx-libs (2:3.5.99.8-0.1) unstable; urgency=medium + + * Upstream-provided Debian package for nx-libs. + See upstream ChangeLog for recent changes. + + -- Mike Gabriel Fri, 30 Jun 2017 21:21:09 +0200 + nx-libs (2:3.5.99.7-0.1) unstable; urgency=medium * Upstream-provided Debian package for nx-libs. diff --git a/debian/copyright b/debian/copyright index dfa30adc4..607cb2a1d 100644 --- a/debian/copyright +++ b/debian/copyright @@ -2952,7 +2952,8 @@ Comment: Missing license headers. License and copyright information obtained from later versions of this file as found in automake-1.14. . - FIXME: This comment will be obsolete for 3.5.99.7. + FIXME: This block will be obsolete for 3.5.99.8. We are about to + remove the above files entirely from the code tree. Files: nx-X11/extras/Mesa.patches/* Copyright: 2017, Mike Gabriel */ diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index 89985a2f7..364afd51d 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -24,7 +24,7 @@ .\" other dealings in this Software without prior written authorization .\" from The Open Group. .ds q \N'34' -.TH nxagent 1 "April 2017" "Version 3.6.x" "NX Agent (Xserver)" +.TH nxagent 1 "June 2017" "Version 3.5.99.8" "NX Agent (Xserver)" .SH NAME nxagent \- nested Xserver optimized for remote computing .SH SYNOPSIS diff --git a/nx-libs.spec b/nx-libs.spec index 3b4212675..ce175059d 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -1,7 +1,7 @@ %global _hardened_build 1 Name: nx-libs -Version: 3.5.99.7 +Version: 3.5.99.8 Release: 0.0build1%{?dist} Summary: NX X11 protocol compression libraries diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index afb5f69d4..30c6e983b 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH nxproxy 1 "April 2017" "Version 3.6.x" "NX Proxy" +.TH nxproxy 1 "June 2017" "Version 3.5.99.8" "NX Proxy" .SH NAME nxproxy \- NX Proxy Tool .SH SYNOPSIS -- cgit v1.2.3 From 41ea54b0217175a4b78980671f4c6818eb66b166 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 26 Apr 2017 13:26:47 +0200 Subject: nxproxy: Switch to autoreconf. This also solves the last remnant of overlinking as described in GH issue #133. Fixes ArcticaProject/nx-libs#133. --- Makefile | 16 +--- debian/copyright | 11 ++- debian/rules | 3 +- nxproxy/.gitignore | 22 ++++- nxproxy/Main.c | 120 ------------------------ nxproxy/Makefile.am | 17 ++++ nxproxy/Makefile.in | 112 ----------------------- nxproxy/configure.ac | 32 +++++++ nxproxy/configure.in | 186 ------------------------------------- nxproxy/install-sh | 238 ------------------------------------------------ nxproxy/m4/nx-macros.m4 | 1 + nxproxy/man/Makefile.am | 5 + nxproxy/mkinstalldirs | 34 ------- nxproxy/src/Main.c | 120 ++++++++++++++++++++++++ nxproxy/src/Makefile.am | 17 ++++ 15 files changed, 226 insertions(+), 708 deletions(-) delete mode 100644 nxproxy/Main.c create mode 100644 nxproxy/Makefile.am delete mode 100644 nxproxy/Makefile.in create mode 100644 nxproxy/configure.ac delete mode 100644 nxproxy/configure.in delete mode 100755 nxproxy/install-sh create mode 120000 nxproxy/m4/nx-macros.m4 create mode 100644 nxproxy/man/Makefile.am delete mode 100755 nxproxy/mkinstalldirs create mode 100644 nxproxy/src/Main.c create mode 100644 nxproxy/src/Makefile.am (limited to 'nxproxy') diff --git a/Makefile b/Makefile index 7103efb34..6fb11333c 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ SHLIBDIR ?= $(LIBDIR) NXLIBDIR ?= $(SHLIBDIR)/nx USRLIBDIR ?= $(NXLIBDIR)/X11 INCLUDEDIR ?= $(PREFIX)/include -CONFIGURE ?= ./configure --prefix=$(DESTDIR)$(PREFIX) +CONFIGURE ?= ./configure --prefix=$(DESTDIR)$(PREFIX) --libexecdir=$(NXLIBDIR)/bin # use Xfont2 if available in the build env FONT_DEFINES ?= $(shell pkg-config --modversion xfont2 1>/dev/null 2>/dev/null && echo "-DHAS_XFONT2") @@ -56,7 +56,7 @@ test: build-lite: cd nxcomp && autoconf && (${CONFIGURE}) && ${MAKE} - cd nxproxy && autoconf && (${CONFIGURE}) && ${MAKE} + cd nxproxy && autoreconf -vfsi && (${CONFIGURE}) && ${MAKE} build-full: # in the full case, we rely on "magic" in the nx-X11 imake-based makefiles... @@ -84,7 +84,7 @@ build-full: cd nx-X11 && ${MAKE} World USRLIBDIR=$(USRLIBDIR) SHLIBDIR=$(SHLIBDIR) FONT_DEFINES=$(FONT_DEFINES) XFONTLIB=$(XFONTLIB) - cd nxproxy && autoconf && (${CONFIGURE}) && ${MAKE} + cd nxproxy && autoreconf -vfsi && (${CONFIGURE}) && ${MAKE} build: if ! test -d nx-X11; then \ @@ -106,14 +106,8 @@ install-lite: sed -e 's|@@NXLIBDIR@@|$(NXLIBDIR)|g' bin/nxproxy.in > bin/nxproxy $(INSTALL_PROGRAM) bin/nxproxy $(DESTDIR)$(BINDIR) - # FIXME: the below install logic should work via nxproxy/Makefile.in - # overriding for now... - $(INSTALL_DIR) $(DESTDIR)$(NXLIBDIR)/bin - $(INSTALL_PROGRAM) nxproxy/nxproxy $(DESTDIR)$(NXLIBDIR)/bin - - $(INSTALL_DIR) $(DESTDIR)$(PREFIX)/share/man/man1/ - $(INSTALL_FILE) nxproxy/man/nxproxy.1 $(DESTDIR)$(PREFIX)/share/man/man1/ - gzip $(DESTDIR)$(PREFIX)/share/man/man1/*.1 + # install the nxproxy executable and its man page + $(MAKE) -C nxproxy install install-full: # install nxagent wrapper script diff --git a/debian/copyright b/debian/copyright index cce8e17dd..b08ec0335 100644 --- a/debian/copyright +++ b/debian/copyright @@ -2756,7 +2756,7 @@ Files: nx-X11/programs/Xserver/os/xdmcp.c Copyright: 1989, Network Computing Devices, Inc., Mountain View, California License: MIT~VeryOldStyle~NCD -Files: nxproxy/Main.c +Files: nxproxy/src/Main.c Copyright: 2001, 2011, NoMachine, http://www.nomachine.com/. License: GPL-2 @@ -2912,10 +2912,13 @@ Files: ChangeLog nxcompshad/VERSION nxcompshad/configure.in nxcompshad/nxcompshad.pc.in - nxproxy/Makefile.in nxproxy/VERSION - nxproxy/configure.in nxproxy/man/nxproxy.1 + nxproxy/Makefile.am + nxproxy/configure.ac + nxproxy/m4/.placeholder + nxproxy/man/Makefile.am + nxproxy/src/Makefile.am Copyright: 2001, 2011, NoMachine (http://www.nomachine.com) 2008-2014, Oleksandr Shneyder 2011-2016, Mike Gabriel */ @@ -2944,13 +2947,11 @@ Comment: Contributions by Daniel Stone have been licensed under MIT~X11. Files: nxcomp/mkinstalldirs - nxproxy/mkinstalldirs Copyright: *No copyright* License: public-domain Files: nxcomp/install-sh nxcompshad/install-sh - nxproxy/install-sh Copyright: 1994, X Consortium License: Expat~NoAdvert Comment: diff --git a/debian/rules b/debian/rules index 707bdec54..1400c79bd 100755 --- a/debian/rules +++ b/debian/rules @@ -7,10 +7,11 @@ DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/buildflags.mk export LIBDIR = "/usr/lib/$(shell dpkg-architecture -qDEB_BUILD_MULTIARCH)" +export LIBEXECDIR = "$(LIBDIR)/nx/bin" export INCLUDEDIR = "/usr/include/$(shell dpkg-architecture -qDEB_BUILD_MULTIARCH)" %: - CONFIGURE="./configure --with-symbols --prefix=/usr --libdir=$(LIBDIR) --includedir=$(INCLUDEDIR)" dh $@ --with quilt + CONFIGURE="./configure --with-symbols --prefix=/usr --libdir=$(LIBDIR) --includedir=$(INCLUDEDIR) --libexecdir=$(LIBEXECDIR)" dh $@ --with quilt override_dh_auto_clean: rm -Rf nx-X11/.build-exports diff --git a/nxproxy/.gitignore b/nxproxy/.gitignore index 3d98254b2..6b771262b 100644 --- a/nxproxy/.gitignore +++ b/nxproxy/.gitignore @@ -1,2 +1,22 @@ Makefile -nxproxy +Makefile.in +aclocal.m4 +compile +config.guess +config.sub +depcomp +install-sh +ltmain.sh +missing +config.h +config.h.in +libtool +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 +src/.deps/ +src/Makefile +src/Makefile.in +stamp-h1 diff --git a/nxproxy/Main.c b/nxproxy/Main.c deleted file mode 100644 index d9fb1ef4f..000000000 --- a/nxproxy/Main.c +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ -/* */ -/* NXPROXY, NX protocol compression and NX extensions to this software */ -/* are copyright of NoMachine. Redistribution and use of the present */ -/* software is allowed according to terms specified in the file LICENSE */ -/* which comes in the source distribution. */ -/* */ -/* Check http://www.nomachine.com/licensing.html for applicability. */ -/* */ -/* NX and NoMachine are trademarks of Medialogic S.p.A. */ -/* */ -/* All rigths reserved. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "NX.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -extern const char *__progname; - -/* - * Entry point when running nxproxy stand-alone. - */ - -int main(int argc, const char **argv) -{ - int result = -1; - - char *options = NULL; - - char *nx_commfd_str = NULL; - - options = getenv("NX_DISPLAY"); - - if ((nx_commfd_str = getenv("NX_COMMFD")) != NULL) - { - errno = 0; - unsigned long int nx_commfd = strtoul(nx_commfd_str, NULL, 10); - - if ((errno) && (0 == nx_commfd)) - { - fprintf(stderr, "%s: NX_COMMFD environment variable's value [%s] is not a file descriptor number. " - "Aborting...\n", - __progname, nx_commfd_str - ); - NXTransCleanup(); - } - else if ((unsigned long int) INT_MAX < nx_commfd) - { - fprintf(stderr, "%s: NX_COMMFD environment variable's value [%lu] is out of range for a file descriptor number. " - "Aborting...\n", - __progname, nx_commfd); - NXTransCleanup(); - } - else { - result = NXTransCreate(nx_commfd, NX_MODE_SERVER, options); - - if (result != 1) - { - fprintf(stderr, "%s: NXTransCreate failed for FD#%lu\n" - "Aborting...", - __progname, nx_commfd); - NXTransCleanup(); - } - - } - - // go into endless loop - - if (result == 1) - { - while (NXTransRunning(NX_FD_ANY)) - result = NXTransContinue(NULL); - } - } - else - { - - if (NXTransParseCommandLine(argc, argv) < 0) - { - NXTransCleanup(); - } - - if (NXTransParseEnvironment(options, 0) < 0) - { - NXTransCleanup(); - } - - /* - * This should not return... - */ - - #ifdef TEST - fprintf(stderr, "%s: Yielding control to NX entry point.\n", __progname); - #endif - - result = NXTransProxy(NX_FD_ANY, NX_MODE_ANY, NX_DISPLAY_ANY); - } - - /* - * ...So these should not be called. - */ - - NXTransExit(result); - - return 0; -} diff --git a/nxproxy/Makefile.am b/nxproxy/Makefile.am new file mode 100644 index 000000000..87ca0cfad --- /dev/null +++ b/nxproxy/Makefile.am @@ -0,0 +1,17 @@ +SUBDIRS = src man + +MAINTAINERCLEANFILES = \ + $(srcdir)/autom4te.cache/* \ + $(srcdir)/build-aux/* \ + $(srcdir)/Makefile.in \ + $(srcdir)/man/Makefile.in \ + $(srcdir)/src/Makefile.in \ + $(srcdir)/aclocal.m4 \ + $(srcdir)/config.h.in \ + $(srcdir)/config.h.in~ \ + $(srcdir)/config.guess \ + $(srcdir)/config.sub \ + $(srcdir)/configure \ + $(NULL) + +DISTCLEANFILES=$(MAINTAINERCLEANFILES) \ No newline at end of file diff --git a/nxproxy/Makefile.in b/nxproxy/Makefile.in deleted file mode 100644 index 3a27cbd29..000000000 --- a/nxproxy/Makefile.in +++ /dev/null @@ -1,112 +0,0 @@ -# -# Get values from configure script. -# -VERSION=@VERSION@ -LIBVERSION=@LIBVERSION@ - -# -# Enable really all warnings. This, though, gives -# a warning due to pthread.h and unistd.h. -# -# -Wredundant-decls -# -CXX = @CXX@ -CXXFLAGS = @CXXFLAGS@ @X_CFLAGS@ @DEFS@ \ - -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \ - -Wmissing-declarations -Wnested-externs - -CXXINCLUDES = -I. -I../nxcomp - -CC = @CC@ -CCFLAGS = $(CXXFLAGS) -CCINCLUDES = -I. -I../nxcomp -CCDEFINES = - -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ - -# -# Only if THREADS is defined. -# -# LIBS = $(LIBS) -lpthread -# - -srcdir = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -man1dir = @mandir@/man1 -VPATH = @srcdir@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -DESTDIR = -RM_FILE = rm -f - -# -# This should be autodetected. -# - -MAKEDEPEND = @MAKEDEPEND@ -DEPENDINCLUDES = -I/usr/include/g++ -I/usr/include/g++-3 - -.SUFFIXES: .cpp.c - -.cpp.o: - $(CXX) -c $(CXXFLAGS) $(CXXINCLUDES) $(CXXDEFINES) $< -.c.o: - $(CC) -c $(CCFLAGS) $(CCINCLUDES) $(CCDEFINES) $< - -PROGRAM = nxproxy - -all: depend $(PROGRAM) - -MSRC = Main.c - -CSRC = - -CXXSRC = - -MOBJ = $(MSRC:.c=.o) -COBJ = $(CSRC:.c=.o) -CXXOBJ = $(CXXSRC:.cpp=.o) - -$(PROGRAM): $(MOBJ) $(COBJ) $(CXXOBJ) - $(CXX) $(CXXFLAGS) -o $@ $(MOBJ) $(LDFLAGS) $(LIBS) - -depends: depend.status - -depend: depend.status - -depend.status: - if [ -n "$(MAKEDEPEND)" ] && [ -x "$(MAKEDEPEND)" ] ; then \ - $(MAKEDEPEND) $(CXXINCLUDES) $(CCINCLUDES) \ - $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) $(CXXSRC) 2>/dev/null; \ - fi - touch depend.status - -install: install.bin install.man - -install.bin: $(PROGRAM) - $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) $(PROGRAM) $(DESTDIR)$(bindir)/$(PROGRAM) - -install.man: - $(srcdir)/mkinstalldirs $(DESTDIR)$(man1dir) - $(INSTALL_DATA) man/$(PROGRAM).1 $(DESTDIR)$(man1dir)/$(PROGRAM).1 - -uninstall: uninstall.bin uninstall.man - -uninstall.bin: - $(RM_FILE) $(DESTDIR)$(bindir)/$(PROGRAM) - -uninstall.man: - $(RM_FILE) $(DESTDIR)$(man1dir)/nxproxy.1 - -clean: - -rm -f *~ *.o *.bak st?????? core core.* *.out.* \ - $(PROGRAM) $(PROGRAM).exe $(LIBFULL) $(LIBLOAD) $(LIBSHARED) $(LIBARCHIVE) - -distclean: clean - -rm -rf autom4te.cache config.status config.log config.cache depend.status Makefile tags configure diff --git a/nxproxy/configure.ac b/nxproxy/configure.ac new file mode 100644 index 000000000..b233ff8e3 --- /dev/null +++ b/nxproxy/configure.ac @@ -0,0 +1,32 @@ +dnl *************************************************************************** +dnl *** configure.ac for nxproxy *** +dnl *************************************************************************** + +m4_define([nxproxy_version], m4_esyscmd([tr -d '\n' < VERSION])) + +# Initialize Autoconf +AC_PREREQ(2.60) + +AC_INIT([NX Proxy], [nxproxy_version], [https://github.com/ArcticaProject/nx-libs/issues]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_PROG_CC +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz]) + +PROXY_VERSION=nxproxy_version +AC_SUBST([PROXY_VERSION]) + +NX_COMPILER_BRAND +AC_LANG([C]) +NX_COMPILER_FLAGS + +AC_CONFIG_FILES([ +Makefile +man/Makefile +src/Makefile +]) + +AC_OUTPUT diff --git a/nxproxy/configure.in b/nxproxy/configure.in deleted file mode 100644 index 12e2a08d2..000000000 --- a/nxproxy/configure.in +++ /dev/null @@ -1,186 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -dnl Prolog - -AC_INIT(Main.c) -AC_PREREQ(2.13) - -dnl Reset default compilation flags. - -if test "x$CXXFLAGS" == "x"; then - CXXFLAGS="-O3" -fi -if test "x$CPPFLAGS" == "x"; then - CPPFLAGS="-O3" -fi - -dnl Prefer headers and libraries from nx-X11 if present. - -if test -d "../nx-X11/exports/include" ; then - CXXFLAGS="$CXXFLAGS -I../nx-X11/exports/include" - LIBS="$LIBS -L../nx-X11/exports/lib" -fi - -dnl Check whether --with-ipaq was given. - -if test "${with_ipaq}" = yes; then - echo -e "enabling ipaq configuration" - CXX="arm-linux-c++" - CC="arm-linux-gcc" - unset ac_cv_prog_armcxx - unset ac_cv_prog_armcc - unset ac_cv_prog_CXXCPP - AC_CHECK_PROG([armcxx],["$CXX"],[yes],[no],[$PATH]) - AC_CHECK_PROG([armcc],["$CC"],[yes],[no],[$PATH]) - if test $armcxx = "yes" && test $armcc = "yes" ; then - ac_cv_prog_CXX="$CXX" - ac_cv_prog_CC="$CC" - else - AC_MSG_ERROR(installation or configuration problem: I cannot find compiler for arm-linux) - fi -else - unset ac_cv_prog_CXX - unset ac_cv_prog_CC - unset ac_cv_prog_CXXCPP -fi - -dnl Check for programs. - -AC_PROG_CXX -AC_PROG_CC -AC_LANG_CPLUSPLUS - -dnl Check for BSD compatible install. - -AC_PROG_INSTALL - -dnl Check for extra header files. - -AC_PATH_XTRA - -dnl Custom addition. - -ac_help="$ac_help - --with-symbols give -g flag to compiler to produce debug symbols - --with-info define INFO at compile time to get basic log output - --with-valgrind clean up allocated buffers to avoid valgrind warnings - --with-version use this version for produced libraries" - -dnl Check to see if we're running under Cygwin32. - - -dnl Check to see if we're running under FreeBSD. -AC_DEFUN(nxconf_FreeBSD, -[AC_CACHE_CHECK(for FreeBSD environment, nxconf_cv_freebsd, -[AC_TRY_COMPILE(,[return __FreeBSD__;], -nxconf_cv_freebsd=yes, nxconf_cv_freebsd=no) -rm -f conftest*]) -FreeBSD= -test "$nxconf_cv_freebsd" = yes && FreeBSD=yes]) -nxconf_FreeBSD - - -AC_DEFUN(nxconf_CYGWIN32, -[AC_CACHE_CHECK(for Cygwin32 environment, nxconf_cv_cygwin32, -[AC_TRY_COMPILE(,[return __CYGWIN32__;], -nxconf_cv_cygwin32=yes, nxconf_cv_cygwin32=no) -rm -f conftest*]) -CYGWIN32= -test "$nxconf_cv_cygwin32" = yes && CYGWIN32=yes]) -nxconf_CYGWIN32 - -dnl Check for Darwin environment. - -AC_DEFUN(nxconf_DARWIN, -[AC_CACHE_CHECK(for Darwin environment, nxconf_cv_darwin, -[AC_TRY_COMPILE(,[return __APPLE__;], -nxconf_cv_darwin=yes, nxconf_cv_darwin=no) -rm -f conftest*]) -DARWIN= -test "$nxconf_cv_darwin" = yes && DARWIN=yes]) -nxconf_DARWIN - -dnl Check to see if we're running under Solaris. - -AC_DEFUN(nxconf_SUN, -[AC_CACHE_CHECK(for SunOS environment, nxconf_cv_sun, -[AC_TRY_COMPILE(,[return __sun;], -nxconf_cv_sun=yes, nxconf_cv_sun=no) -rm -f conftest*]) -SUN= -test "$nxconf_cv_sun" = yes && SUN=yes]) -nxconf_SUN - -dnl Check whether --with-version was given. - -AC_SUBST(LIBVERSION) -AC_SUBST(VERSION) -if test "${with_version}" = yes; then - VERSION=${ac_option} -else - VERSION=`cat VERSION` -fi -echo -e "compiling version ${VERSION}" - -LIBVERSION=`echo ${VERSION} | cut -d '.' -f 1` - -CXXFLAGS="$CXXFLAGS -DVERSION=\\\"${VERSION}\\\"" -CPPFLAGS="$CPPFLAGS -DVERSION=\\\"${VERSION}\\\"" - -dnl Check whether --with-symbols or --without-symbols was -dnl given and set the required optimization level. - -if test "${with_symbols}" = yes; then - echo -e "enabling production of debug symbols" - CXXFLAGS="-g $CXXFLAGS" - CPPFLAGS="-g $CPPFLAGS" -else - echo -e "disabling production of debug symbols" -fi - -dnl Check whether --with-info or --without-info was given. - -if test "${with_info}" = yes; then - echo -e "enabling info output in the log file" - CXXFLAGS="$CXXFLAGS -DINFO" - CPPFLAGS="$CPPFLAGS -DINFO" -else - echo -e "disabling info output in the log file" -fi - -dnl Check whether --with-valgrind or --without-valgrind was given. - -if test "${with_valgrind}" = yes; then - echo -e "enabling valgrind memory checker workarounds" - CXXFLAGS="$CXXFLAGS -DVALGRIND" - CPPFLAGS="$CPPFLAGS -DVALGRIND" -else - echo -e "disabling valgrind memory checker workarounds" -fi - -dnl Cygwin requires that the stdc++ library is linked explicitly. -dnl GCC 3.3.x requires also the z, png and jpeg libraries. This is -dnl not true anymore since GCC 3.4.x. - -if test "$CYGWIN32" = yes; then - LIBS="$LIBS -L../nxcomp -lXcomp -lstdc++ -Wl,-e,_mainCRTStartup -ljpeg -lpng -lz" -else - LIBS="$LIBS -L../nxcomp -lXcomp" -fi - -dnl Find makedepend somewhere. - -AC_SUBST(MAKEDEPEND) -MAKEDEPEND="$(which makedepend)" - -# Try to desperately find makedepend. -# Set MAKEDEPEND to the shipped makedepend binary. This will not -# exist in nx-libs-lite, though, in which case MAKEDEPEND -# will stay empty. -if test -z "${MAKEDEPEND}"; then - if test -x "../nx-X11/config/makedepend/makedepend"; then - MAKEDEPEND="../nx-X11/config/makedepend/makedepend" - fi -fi - -AC_OUTPUT(Makefile) diff --git a/nxproxy/install-sh b/nxproxy/install-sh deleted file mode 100755 index 58719246f..000000000 --- a/nxproxy/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/nxproxy/m4/nx-macros.m4 b/nxproxy/m4/nx-macros.m4 new file mode 120000 index 000000000..813e9b041 --- /dev/null +++ b/nxproxy/m4/nx-macros.m4 @@ -0,0 +1 @@ +../../m4/nx-macros.m4 \ No newline at end of file diff --git a/nxproxy/man/Makefile.am b/nxproxy/man/Makefile.am new file mode 100644 index 000000000..8f9211c07 --- /dev/null +++ b/nxproxy/man/Makefile.am @@ -0,0 +1,5 @@ +NULL = + +dist_man_MANS = \ + nxproxy.1 \ + $(NULL) diff --git a/nxproxy/mkinstalldirs b/nxproxy/mkinstalldirs deleted file mode 100755 index 936cf3407..000000000 --- a/nxproxy/mkinstalldirs +++ /dev/null @@ -1,34 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Last modified: 1995-03-05 -# Public domain - -errstatus=0 - -for file in ${1+"$@"} ; do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d in ${1+"$@"} ; do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" 1>&2 - mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$? - fi - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus diff --git a/nxproxy/src/Main.c b/nxproxy/src/Main.c new file mode 100644 index 000000000..d9fb1ef4f --- /dev/null +++ b/nxproxy/src/Main.c @@ -0,0 +1,120 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NXPROXY, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rigths reserved. */ +/* */ +/**************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "NX.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +extern const char *__progname; + +/* + * Entry point when running nxproxy stand-alone. + */ + +int main(int argc, const char **argv) +{ + int result = -1; + + char *options = NULL; + + char *nx_commfd_str = NULL; + + options = getenv("NX_DISPLAY"); + + if ((nx_commfd_str = getenv("NX_COMMFD")) != NULL) + { + errno = 0; + unsigned long int nx_commfd = strtoul(nx_commfd_str, NULL, 10); + + if ((errno) && (0 == nx_commfd)) + { + fprintf(stderr, "%s: NX_COMMFD environment variable's value [%s] is not a file descriptor number. " + "Aborting...\n", + __progname, nx_commfd_str + ); + NXTransCleanup(); + } + else if ((unsigned long int) INT_MAX < nx_commfd) + { + fprintf(stderr, "%s: NX_COMMFD environment variable's value [%lu] is out of range for a file descriptor number. " + "Aborting...\n", + __progname, nx_commfd); + NXTransCleanup(); + } + else { + result = NXTransCreate(nx_commfd, NX_MODE_SERVER, options); + + if (result != 1) + { + fprintf(stderr, "%s: NXTransCreate failed for FD#%lu\n" + "Aborting...", + __progname, nx_commfd); + NXTransCleanup(); + } + + } + + // go into endless loop + + if (result == 1) + { + while (NXTransRunning(NX_FD_ANY)) + result = NXTransContinue(NULL); + } + } + else + { + + if (NXTransParseCommandLine(argc, argv) < 0) + { + NXTransCleanup(); + } + + if (NXTransParseEnvironment(options, 0) < 0) + { + NXTransCleanup(); + } + + /* + * This should not return... + */ + + #ifdef TEST + fprintf(stderr, "%s: Yielding control to NX entry point.\n", __progname); + #endif + + result = NXTransProxy(NX_FD_ANY, NX_MODE_ANY, NX_DISPLAY_ANY); + } + + /* + * ...So these should not be called. + */ + + NXTransExit(result); + + return 0; +} diff --git a/nxproxy/src/Makefile.am b/nxproxy/src/Makefile.am new file mode 100644 index 000000000..5ec1f9401 --- /dev/null +++ b/nxproxy/src/Makefile.am @@ -0,0 +1,17 @@ +NULL = + +nxexecdir = $(libexecdir) + +nxexec_PROGRAMS = nxproxy + +nxproxy_SOURCES = \ + Main.c \ + $(NULL) + +nxproxy_LDADD = \ + -L$(top_srcdir)/../nxcomp/ -lXcomp \ + $(NULL) + +AM_CPPFLAGS = \ + -I$(top_srcdir)/../nxcomp/ \ + $(NULL) -- cgit v1.2.3 From 107fba32e3147b660eeeb474dd866480c53e8ca0 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Thu, 13 Jul 2017 08:52:08 +0200 Subject: nxproxy/configure.ac: Have AC_LANG before NX_COMPILER_BRAND. Thanks to Ionic for spotting this same flaw in nxcompshad. --- nxproxy/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nxproxy') diff --git a/nxproxy/configure.ac b/nxproxy/configure.ac index b233ff8e3..0a23f13d7 100644 --- a/nxproxy/configure.ac +++ b/nxproxy/configure.ac @@ -19,8 +19,8 @@ AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz]) PROXY_VERSION=nxproxy_version AC_SUBST([PROXY_VERSION]) -NX_COMPILER_BRAND AC_LANG([C]) +NX_COMPILER_BRAND NX_COMPILER_FLAGS AC_CONFIG_FILES([ -- cgit v1.2.3 From f76c82403888bb498973ec974dbfd20e4edb02fe Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 30 Jun 2017 20:13:51 +0200 Subject: nxcomp: Switch to autoreconf. --- Makefile | 16 +- debian/libxcomp-dev.install | 1 + debian/rules | 2 +- nx-X11/lib/X11/Imakefile | 6 +- nx-X11/programs/Xserver/Imakefile | 20 +- nxcomp/.gitignore | 23 +- nxcomp/ActionCache.cpp | 47 - nxcomp/ActionCache.h | 49 - nxcomp/Agent.cpp | 80 - nxcomp/Agent.h | 263 - nxcomp/Alpha.cpp | 134 - nxcomp/Alpha.h | 35 - nxcomp/Auth.cpp | 667 -- nxcomp/Auth.h | 127 - nxcomp/Bitmap.cpp | 114 - nxcomp/Bitmap.h | 36 - nxcomp/BlockCache.cpp | 77 - nxcomp/BlockCache.h | 67 - nxcomp/BlockCacheSet.cpp | 143 - nxcomp/BlockCacheSet.h | 49 - nxcomp/ChangeGC.cpp | 180 - nxcomp/ChangeGC.h | 185 - nxcomp/ChangeProperty.cpp | 187 - nxcomp/ChangeProperty.h | 189 - nxcomp/Channel.cpp | 2035 ---- nxcomp/Channel.h | 664 -- nxcomp/ChannelCache.cpp | 64 - nxcomp/ChannelCache.h | 61 - nxcomp/ChannelEndPoint.cpp | 345 - nxcomp/ChannelEndPoint.h | 71 - nxcomp/ChannelStore.h | 54 - nxcomp/CharCache.cpp | 69 - nxcomp/CharCache.h | 91 - nxcomp/Children.cpp | 1055 -- nxcomp/ClearArea.cpp | 121 - nxcomp/ClearArea.h | 182 - nxcomp/ClientCache.cpp | 388 - nxcomp/ClientCache.h | 417 - nxcomp/ClientChannel.cpp | 7877 -------------- nxcomp/ClientChannel.h | 434 - nxcomp/ClientProxy.cpp | 549 - nxcomp/ClientProxy.h | 113 - nxcomp/ClientReadBuffer.cpp | 174 - nxcomp/ClientReadBuffer.h | 65 - nxcomp/ClientStore.cpp | 222 - nxcomp/ClientStore.h | 143 - nxcomp/Colormap.cpp | 102 - nxcomp/Colormap.h | 32 - nxcomp/ConfigureWindow.cpp | 138 - nxcomp/ConfigureWindow.h | 178 - nxcomp/Control.cpp | 818 -- nxcomp/Control.h | 764 -- nxcomp/CopyArea.cpp | 195 - nxcomp/CopyArea.h | 192 - nxcomp/CreateGC.cpp | 190 - nxcomp/CreateGC.h | 186 - nxcomp/CreatePixmap.cpp | 276 - nxcomp/CreatePixmap.h | 162 - nxcomp/DecodeBuffer.cpp | 635 -- nxcomp/DecodeBuffer.h | 138 - nxcomp/EncodeBuffer.cpp | 619 -- nxcomp/EncodeBuffer.h | 183 - nxcomp/FillPoly.cpp | 235 - nxcomp/FillPoly.h | 200 - nxcomp/Fork.cpp | 106 - nxcomp/Fork.h | 31 - nxcomp/FreeCache.h | 42 - nxcomp/GenericChannel.cpp | 491 - nxcomp/GenericChannel.h | 440 - nxcomp/GenericReadBuffer.cpp | 78 - nxcomp/GenericReadBuffer.h | 61 - nxcomp/GenericReply.cpp | 298 - nxcomp/GenericReply.h | 161 - nxcomp/GenericRequest.cpp | 330 - nxcomp/GenericRequest.h | 160 - nxcomp/GetImage.cpp | 173 - nxcomp/GetImage.h | 190 - nxcomp/GetImageReply.cpp | 190 - nxcomp/GetImageReply.h | 150 - nxcomp/GetProperty.cpp | 115 - nxcomp/GetProperty.h | 183 - nxcomp/GetPropertyReply.cpp | 300 - nxcomp/GetPropertyReply.h | 160 - nxcomp/ImageText16.cpp | 227 - nxcomp/ImageText16.h | 190 - nxcomp/ImageText8.cpp | 227 - nxcomp/ImageText8.h | 190 - nxcomp/IntCache.cpp | 226 - nxcomp/IntCache.h | 119 - nxcomp/InternAtom.cpp | 127 - nxcomp/InternAtom.h | 178 - nxcomp/Jpeg.cpp | 886 -- nxcomp/Jpeg.h | 36 - nxcomp/Keeper.cpp | 608 -- nxcomp/Keeper.h | 199 - nxcomp/List.cpp | 108 - nxcomp/List.h | 95 - nxcomp/ListFontsReply.cpp | 209 - nxcomp/ListFontsReply.h | 146 - nxcomp/Loop.cpp | 16689 ---------------------------- nxcomp/MD5.c | 399 - nxcomp/MD5.h | 91 - nxcomp/Makefile.am | 21 + nxcomp/Makefile.in | 333 - nxcomp/Message.cpp | 2339 ---- nxcomp/Message.h | 1089 -- nxcomp/Misc.cpp | 1930 ---- nxcomp/Misc.h | 279 - nxcomp/NX.h | 471 - nxcomp/NXalert.h | 276 - nxcomp/NXmitshm.h | 56 - nxcomp/NXpack.h | 141 - nxcomp/NXproto.h | 447 - nxcomp/NXrender.h | 78 - nxcomp/NXvars.h | 201 - nxcomp/OpcodeCache.h | 53 - nxcomp/OpcodeStore.cpp | 84 - nxcomp/OpcodeStore.h | 91 - nxcomp/Pack.c | 180 - nxcomp/Pgn.cpp | 805 -- nxcomp/Pgn.h | 42 - nxcomp/Pipe.cpp | 429 - nxcomp/Pipe.h | 35 - nxcomp/PolyArc.cpp | 158 - nxcomp/PolyArc.h | 185 - nxcomp/PolyFillArc.cpp | 158 - nxcomp/PolyFillArc.h | 185 - nxcomp/PolyFillRectangle.cpp | 156 - nxcomp/PolyFillRectangle.h | 185 - nxcomp/PolyLine.cpp | 164 - nxcomp/PolyLine.h | 186 - nxcomp/PolyPoint.cpp | 164 - nxcomp/PolyPoint.h | 186 - nxcomp/PolySegment.cpp | 158 - nxcomp/PolySegment.h | 185 - nxcomp/PolyText16.cpp | 308 - nxcomp/PolyText16.h | 188 - nxcomp/PolyText8.cpp | 306 - nxcomp/PolyText8.h | 188 - nxcomp/Proxy.cpp | 6525 ----------- nxcomp/Proxy.h | 1276 --- nxcomp/ProxyReadBuffer.cpp | 207 - nxcomp/ProxyReadBuffer.h | 57 - nxcomp/PutImage.cpp | 407 - nxcomp/PutImage.h | 172 - nxcomp/PutPackedImage.cpp | 600 -- nxcomp/PutPackedImage.h | 218 - nxcomp/QueryFontReply.cpp | 150 - nxcomp/QueryFontReply.h | 136 - nxcomp/ReadBuffer.cpp | 635 -- nxcomp/ReadBuffer.h | 128 - nxcomp/RenderAddGlyphs.cpp | 229 - nxcomp/RenderAddGlyphs.h | 88 - nxcomp/RenderChangePicture.cpp | 234 - nxcomp/RenderChangePicture.h | 88 - nxcomp/RenderComposite.cpp | 396 - nxcomp/RenderComposite.h | 88 - nxcomp/RenderCompositeGlyphs.cpp | 625 -- nxcomp/RenderCompositeGlyphs.h | 100 - nxcomp/RenderCreateGlyphSet.cpp | 181 - nxcomp/RenderCreateGlyphSet.h | 88 - nxcomp/RenderCreatePicture.cpp | 274 - nxcomp/RenderCreatePicture.h | 88 - nxcomp/RenderExtension.cpp | 423 - nxcomp/RenderExtension.h | 504 - nxcomp/RenderFillRectangles.cpp | 233 - nxcomp/RenderFillRectangles.h | 88 - nxcomp/RenderFreeGlyphSet.cpp | 162 - nxcomp/RenderFreeGlyphSet.h | 88 - nxcomp/RenderFreePicture.cpp | 162 - nxcomp/RenderFreePicture.h | 88 - nxcomp/RenderGenericRequest.cpp | 266 - nxcomp/RenderGenericRequest.h | 89 - nxcomp/RenderMinorExtensionHeaders.h | 42 - nxcomp/RenderMinorExtensionMethods.h | 81 - nxcomp/RenderMinorExtensionTags.h | 194 - nxcomp/RenderPictureClip.cpp | 299 - nxcomp/RenderPictureClip.h | 88 - nxcomp/RenderPictureFilter.cpp | 274 - nxcomp/RenderPictureFilter.h | 88 - nxcomp/RenderPictureTransform.cpp | 210 - nxcomp/RenderPictureTransform.h | 88 - nxcomp/RenderTrapezoids.cpp | 368 - nxcomp/RenderTrapezoids.h | 88 - nxcomp/RenderTriangles.cpp | 358 - nxcomp/RenderTriangles.h | 88 - nxcomp/Rgb.cpp | 102 - nxcomp/Rgb.h | 36 - nxcomp/Rle.cpp | 102 - nxcomp/Rle.h | 36 - nxcomp/SendEvent.cpp | 300 - nxcomp/SendEvent.h | 195 - nxcomp/SequenceQueue.cpp | 170 - nxcomp/SequenceQueue.h | 91 - nxcomp/ServerCache.cpp | 191 - nxcomp/ServerCache.h | 303 - nxcomp/ServerChannel.cpp | 7942 -------------- nxcomp/ServerChannel.h | 529 - nxcomp/ServerProxy.cpp | 617 -- nxcomp/ServerProxy.h | 154 - nxcomp/ServerReadBuffer.cpp | 243 - nxcomp/ServerReadBuffer.h | 73 - nxcomp/ServerStore.cpp | 179 - nxcomp/ServerStore.h | 83 - nxcomp/SetClipRectangles.cpp | 150 - nxcomp/SetClipRectangles.h | 187 - nxcomp/SetUnpackAlpha.cpp | 262 - nxcomp/SetUnpackAlpha.h | 162 - nxcomp/SetUnpackColormap.cpp | 262 - nxcomp/SetUnpackColormap.h | 162 - nxcomp/SetUnpackGeometry.cpp | 301 - nxcomp/SetUnpackGeometry.h | 167 - nxcomp/ShapeExtension.cpp | 301 - nxcomp/ShapeExtension.h | 164 - nxcomp/Socket.cpp | 753 -- nxcomp/Socket.h | 96 - nxcomp/Split.cpp | 1835 ---- nxcomp/Split.h | 543 - nxcomp/StaticCompressor.cpp | 428 - nxcomp/StaticCompressor.h | 80 - nxcomp/Statistics.cpp | 2003 ---- nxcomp/Statistics.h | 745 -- nxcomp/Timestamp.cpp | 73 - nxcomp/Timestamp.h | 307 - nxcomp/TranslateCoords.cpp | 111 - nxcomp/TranslateCoords.h | 185 - nxcomp/Transport.cpp | 3064 ------ nxcomp/Transport.h | 577 - nxcomp/Types.h | 271 - nxcomp/Unpack.cpp | 1510 --- nxcomp/Unpack.h | 149 - nxcomp/Vars.c | 54 - nxcomp/Version.c | 97 - nxcomp/WriteBuffer.cpp | 496 - nxcomp/WriteBuffer.h | 134 - nxcomp/XidCache.cpp | 47 - nxcomp/XidCache.h | 49 - nxcomp/Z.cpp | 142 - nxcomp/Z.h | 37 - nxcomp/configure.ac | 83 + nxcomp/configure.in | 413 - nxcomp/include/MD5.h | 91 + nxcomp/include/NX.h | 471 + nxcomp/include/NXalert.h | 276 + nxcomp/include/NXpack.h | 141 + nxcomp/include/NXproto.h | 447 + nxcomp/include/NXvars.h | 201 + nxcomp/install-sh | 238 - nxcomp/m4/nx-macros.m4 | 1 + nxcomp/mkinstalldirs | 34 - nxcomp/nxcomp.pc.in | 2 +- nxcomp/src/ActionCache.cpp | 51 + nxcomp/src/ActionCache.h | 49 + nxcomp/src/Agent.cpp | 84 + nxcomp/src/Agent.h | 263 + nxcomp/src/Alpha.cpp | 138 + nxcomp/src/Alpha.h | 35 + nxcomp/src/Auth.cpp | 671 ++ nxcomp/src/Auth.h | 127 + nxcomp/src/Bitmap.cpp | 118 + nxcomp/src/Bitmap.h | 36 + nxcomp/src/BlockCache.cpp | 81 + nxcomp/src/BlockCache.h | 67 + nxcomp/src/BlockCacheSet.cpp | 147 + nxcomp/src/BlockCacheSet.h | 49 + nxcomp/src/ChangeGC.cpp | 184 + nxcomp/src/ChangeGC.h | 185 + nxcomp/src/ChangeProperty.cpp | 191 + nxcomp/src/ChangeProperty.h | 189 + nxcomp/src/Channel.cpp | 2039 ++++ nxcomp/src/Channel.h | 664 ++ nxcomp/src/ChannelCache.cpp | 68 + nxcomp/src/ChannelCache.h | 61 + nxcomp/src/ChannelEndPoint.cpp | 349 + nxcomp/src/ChannelEndPoint.h | 71 + nxcomp/src/ChannelStore.h | 54 + nxcomp/src/CharCache.cpp | 73 + nxcomp/src/CharCache.h | 91 + nxcomp/src/Children.cpp | 1059 ++ nxcomp/src/ClearArea.cpp | 125 + nxcomp/src/ClearArea.h | 182 + nxcomp/src/ClientCache.cpp | 392 + nxcomp/src/ClientCache.h | 417 + nxcomp/src/ClientChannel.cpp | 7881 ++++++++++++++ nxcomp/src/ClientChannel.h | 434 + nxcomp/src/ClientProxy.cpp | 553 + nxcomp/src/ClientProxy.h | 113 + nxcomp/src/ClientReadBuffer.cpp | 178 + nxcomp/src/ClientReadBuffer.h | 65 + nxcomp/src/ClientStore.cpp | 226 + nxcomp/src/ClientStore.h | 143 + nxcomp/src/Colormap.cpp | 106 + nxcomp/src/Colormap.h | 32 + nxcomp/src/ConfigureWindow.cpp | 142 + nxcomp/src/ConfigureWindow.h | 178 + nxcomp/src/Control.cpp | 822 ++ nxcomp/src/Control.h | 764 ++ nxcomp/src/CopyArea.cpp | 199 + nxcomp/src/CopyArea.h | 192 + nxcomp/src/CreateGC.cpp | 194 + nxcomp/src/CreateGC.h | 186 + nxcomp/src/CreatePixmap.cpp | 280 + nxcomp/src/CreatePixmap.h | 162 + nxcomp/src/DecodeBuffer.cpp | 639 ++ nxcomp/src/DecodeBuffer.h | 138 + nxcomp/src/EncodeBuffer.cpp | 623 ++ nxcomp/src/EncodeBuffer.h | 183 + nxcomp/src/FillPoly.cpp | 239 + nxcomp/src/FillPoly.h | 200 + nxcomp/src/Fork.cpp | 110 + nxcomp/src/Fork.h | 31 + nxcomp/src/FreeCache.h | 42 + nxcomp/src/GenericChannel.cpp | 495 + nxcomp/src/GenericChannel.h | 440 + nxcomp/src/GenericReadBuffer.cpp | 82 + nxcomp/src/GenericReadBuffer.h | 61 + nxcomp/src/GenericReply.cpp | 302 + nxcomp/src/GenericReply.h | 161 + nxcomp/src/GenericRequest.cpp | 334 + nxcomp/src/GenericRequest.h | 160 + nxcomp/src/GetImage.cpp | 177 + nxcomp/src/GetImage.h | 190 + nxcomp/src/GetImageReply.cpp | 194 + nxcomp/src/GetImageReply.h | 150 + nxcomp/src/GetProperty.cpp | 119 + nxcomp/src/GetProperty.h | 183 + nxcomp/src/GetPropertyReply.cpp | 304 + nxcomp/src/GetPropertyReply.h | 160 + nxcomp/src/ImageText16.cpp | 231 + nxcomp/src/ImageText16.h | 190 + nxcomp/src/ImageText8.cpp | 231 + nxcomp/src/ImageText8.h | 190 + nxcomp/src/IntCache.cpp | 230 + nxcomp/src/IntCache.h | 119 + nxcomp/src/InternAtom.cpp | 131 + nxcomp/src/InternAtom.h | 178 + nxcomp/src/Jpeg.cpp | 890 ++ nxcomp/src/Jpeg.h | 36 + nxcomp/src/Keeper.cpp | 612 ++ nxcomp/src/Keeper.h | 199 + nxcomp/src/List.cpp | 112 + nxcomp/src/List.h | 95 + nxcomp/src/ListFontsReply.cpp | 213 + nxcomp/src/ListFontsReply.h | 146 + nxcomp/src/Loop.cpp | 16693 +++++++++++++++++++++++++++++ nxcomp/src/MD5.c | 403 + nxcomp/src/Makefile.am | 146 + nxcomp/src/Message.cpp | 2343 ++++ nxcomp/src/Message.h | 1089 ++ nxcomp/src/Misc.cpp | 1934 ++++ nxcomp/src/Misc.h | 279 + nxcomp/src/NXmitshm.h | 56 + nxcomp/src/NXrender.h | 78 + nxcomp/src/OpcodeCache.h | 53 + nxcomp/src/OpcodeStore.cpp | 88 + nxcomp/src/OpcodeStore.h | 91 + nxcomp/src/Pack.c | 180 + nxcomp/src/Pgn.cpp | 809 ++ nxcomp/src/Pgn.h | 42 + nxcomp/src/Pipe.cpp | 433 + nxcomp/src/Pipe.h | 35 + nxcomp/src/PolyArc.cpp | 162 + nxcomp/src/PolyArc.h | 185 + nxcomp/src/PolyFillArc.cpp | 162 + nxcomp/src/PolyFillArc.h | 185 + nxcomp/src/PolyFillRectangle.cpp | 160 + nxcomp/src/PolyFillRectangle.h | 185 + nxcomp/src/PolyLine.cpp | 168 + nxcomp/src/PolyLine.h | 186 + nxcomp/src/PolyPoint.cpp | 168 + nxcomp/src/PolyPoint.h | 186 + nxcomp/src/PolySegment.cpp | 162 + nxcomp/src/PolySegment.h | 185 + nxcomp/src/PolyText16.cpp | 312 + nxcomp/src/PolyText16.h | 188 + nxcomp/src/PolyText8.cpp | 310 + nxcomp/src/PolyText8.h | 188 + nxcomp/src/Proxy.cpp | 6529 +++++++++++ nxcomp/src/Proxy.h | 1276 +++ nxcomp/src/ProxyReadBuffer.cpp | 211 + nxcomp/src/ProxyReadBuffer.h | 57 + nxcomp/src/PutImage.cpp | 411 + nxcomp/src/PutImage.h | 172 + nxcomp/src/PutPackedImage.cpp | 604 ++ nxcomp/src/PutPackedImage.h | 218 + nxcomp/src/QueryFontReply.cpp | 154 + nxcomp/src/QueryFontReply.h | 136 + nxcomp/src/ReadBuffer.cpp | 639 ++ nxcomp/src/ReadBuffer.h | 128 + nxcomp/src/RenderAddGlyphs.cpp | 233 + nxcomp/src/RenderAddGlyphs.h | 88 + nxcomp/src/RenderChangePicture.cpp | 238 + nxcomp/src/RenderChangePicture.h | 88 + nxcomp/src/RenderComposite.cpp | 400 + nxcomp/src/RenderComposite.h | 88 + nxcomp/src/RenderCompositeGlyphs.cpp | 629 ++ nxcomp/src/RenderCompositeGlyphs.h | 100 + nxcomp/src/RenderCreateGlyphSet.cpp | 185 + nxcomp/src/RenderCreateGlyphSet.h | 88 + nxcomp/src/RenderCreatePicture.cpp | 278 + nxcomp/src/RenderCreatePicture.h | 88 + nxcomp/src/RenderExtension.cpp | 427 + nxcomp/src/RenderExtension.h | 504 + nxcomp/src/RenderFillRectangles.cpp | 237 + nxcomp/src/RenderFillRectangles.h | 88 + nxcomp/src/RenderFreeGlyphSet.cpp | 166 + nxcomp/src/RenderFreeGlyphSet.h | 88 + nxcomp/src/RenderFreePicture.cpp | 166 + nxcomp/src/RenderFreePicture.h | 88 + nxcomp/src/RenderGenericRequest.cpp | 270 + nxcomp/src/RenderGenericRequest.h | 89 + nxcomp/src/RenderMinorExtensionHeaders.h | 42 + nxcomp/src/RenderMinorExtensionMethods.h | 81 + nxcomp/src/RenderMinorExtensionTags.h | 194 + nxcomp/src/RenderPictureClip.cpp | 303 + nxcomp/src/RenderPictureClip.h | 88 + nxcomp/src/RenderPictureFilter.cpp | 278 + nxcomp/src/RenderPictureFilter.h | 88 + nxcomp/src/RenderPictureTransform.cpp | 214 + nxcomp/src/RenderPictureTransform.h | 88 + nxcomp/src/RenderTrapezoids.cpp | 372 + nxcomp/src/RenderTrapezoids.h | 88 + nxcomp/src/RenderTriangles.cpp | 362 + nxcomp/src/RenderTriangles.h | 88 + nxcomp/src/Rgb.cpp | 106 + nxcomp/src/Rgb.h | 36 + nxcomp/src/Rle.cpp | 106 + nxcomp/src/Rle.h | 36 + nxcomp/src/SendEvent.cpp | 304 + nxcomp/src/SendEvent.h | 195 + nxcomp/src/SequenceQueue.cpp | 174 + nxcomp/src/SequenceQueue.h | 91 + nxcomp/src/ServerCache.cpp | 195 + nxcomp/src/ServerCache.h | 303 + nxcomp/src/ServerChannel.cpp | 7946 ++++++++++++++ nxcomp/src/ServerChannel.h | 529 + nxcomp/src/ServerProxy.cpp | 621 ++ nxcomp/src/ServerProxy.h | 154 + nxcomp/src/ServerReadBuffer.cpp | 247 + nxcomp/src/ServerReadBuffer.h | 73 + nxcomp/src/ServerStore.cpp | 183 + nxcomp/src/ServerStore.h | 83 + nxcomp/src/SetClipRectangles.cpp | 154 + nxcomp/src/SetClipRectangles.h | 187 + nxcomp/src/SetUnpackAlpha.cpp | 266 + nxcomp/src/SetUnpackAlpha.h | 162 + nxcomp/src/SetUnpackColormap.cpp | 266 + nxcomp/src/SetUnpackColormap.h | 162 + nxcomp/src/SetUnpackGeometry.cpp | 305 + nxcomp/src/SetUnpackGeometry.h | 167 + nxcomp/src/ShapeExtension.cpp | 305 + nxcomp/src/ShapeExtension.h | 164 + nxcomp/src/Socket.cpp | 757 ++ nxcomp/src/Socket.h | 96 + nxcomp/src/Split.cpp | 1839 ++++ nxcomp/src/Split.h | 543 + nxcomp/src/StaticCompressor.cpp | 432 + nxcomp/src/StaticCompressor.h | 80 + nxcomp/src/Statistics.cpp | 2007 ++++ nxcomp/src/Statistics.h | 745 ++ nxcomp/src/Timestamp.cpp | 77 + nxcomp/src/Timestamp.h | 307 + nxcomp/src/TranslateCoords.cpp | 115 + nxcomp/src/TranslateCoords.h | 185 + nxcomp/src/Transport.cpp | 3068 ++++++ nxcomp/src/Transport.h | 577 + nxcomp/src/Types.h | 271 + nxcomp/src/Unpack.cpp | 1514 +++ nxcomp/src/Unpack.h | 149 + nxcomp/src/Vars.c | 54 + nxcomp/src/Version.c | 101 + nxcomp/src/WriteBuffer.cpp | 500 + nxcomp/src/WriteBuffer.h | 134 + nxcomp/src/XidCache.cpp | 51 + nxcomp/src/XidCache.h | 49 + nxcomp/src/Z.cpp | 146 + nxcomp/src/Z.h | 37 + nxproxy/src/Makefile.am | 4 +- 478 files changed, 105105 insertions(+), 105414 deletions(-) delete mode 100644 nxcomp/ActionCache.cpp delete mode 100644 nxcomp/ActionCache.h delete mode 100644 nxcomp/Agent.cpp delete mode 100644 nxcomp/Agent.h delete mode 100644 nxcomp/Alpha.cpp delete mode 100644 nxcomp/Alpha.h delete mode 100644 nxcomp/Auth.cpp delete mode 100644 nxcomp/Auth.h delete mode 100644 nxcomp/Bitmap.cpp delete mode 100644 nxcomp/Bitmap.h delete mode 100644 nxcomp/BlockCache.cpp delete mode 100644 nxcomp/BlockCache.h delete mode 100644 nxcomp/BlockCacheSet.cpp delete mode 100644 nxcomp/BlockCacheSet.h delete mode 100644 nxcomp/ChangeGC.cpp delete mode 100644 nxcomp/ChangeGC.h delete mode 100644 nxcomp/ChangeProperty.cpp delete mode 100644 nxcomp/ChangeProperty.h delete mode 100644 nxcomp/Channel.cpp delete mode 100644 nxcomp/Channel.h delete mode 100644 nxcomp/ChannelCache.cpp delete mode 100644 nxcomp/ChannelCache.h delete mode 100644 nxcomp/ChannelEndPoint.cpp delete mode 100644 nxcomp/ChannelEndPoint.h delete mode 100644 nxcomp/ChannelStore.h delete mode 100644 nxcomp/CharCache.cpp delete mode 100644 nxcomp/CharCache.h delete mode 100644 nxcomp/Children.cpp delete mode 100644 nxcomp/ClearArea.cpp delete mode 100644 nxcomp/ClearArea.h delete mode 100644 nxcomp/ClientCache.cpp delete mode 100644 nxcomp/ClientCache.h delete mode 100644 nxcomp/ClientChannel.cpp delete mode 100644 nxcomp/ClientChannel.h delete mode 100644 nxcomp/ClientProxy.cpp delete mode 100644 nxcomp/ClientProxy.h delete mode 100644 nxcomp/ClientReadBuffer.cpp delete mode 100644 nxcomp/ClientReadBuffer.h delete mode 100644 nxcomp/ClientStore.cpp delete mode 100644 nxcomp/ClientStore.h delete mode 100644 nxcomp/Colormap.cpp delete mode 100644 nxcomp/Colormap.h delete mode 100644 nxcomp/ConfigureWindow.cpp delete mode 100644 nxcomp/ConfigureWindow.h delete mode 100644 nxcomp/Control.cpp delete mode 100644 nxcomp/Control.h delete mode 100644 nxcomp/CopyArea.cpp delete mode 100644 nxcomp/CopyArea.h delete mode 100644 nxcomp/CreateGC.cpp delete mode 100644 nxcomp/CreateGC.h delete mode 100644 nxcomp/CreatePixmap.cpp delete mode 100644 nxcomp/CreatePixmap.h delete mode 100644 nxcomp/DecodeBuffer.cpp delete mode 100644 nxcomp/DecodeBuffer.h delete mode 100644 nxcomp/EncodeBuffer.cpp delete mode 100644 nxcomp/EncodeBuffer.h delete mode 100644 nxcomp/FillPoly.cpp delete mode 100644 nxcomp/FillPoly.h delete mode 100644 nxcomp/Fork.cpp delete mode 100644 nxcomp/Fork.h delete mode 100644 nxcomp/FreeCache.h delete mode 100644 nxcomp/GenericChannel.cpp delete mode 100644 nxcomp/GenericChannel.h delete mode 100644 nxcomp/GenericReadBuffer.cpp delete mode 100644 nxcomp/GenericReadBuffer.h delete mode 100644 nxcomp/GenericReply.cpp delete mode 100644 nxcomp/GenericReply.h delete mode 100644 nxcomp/GenericRequest.cpp delete mode 100644 nxcomp/GenericRequest.h delete mode 100644 nxcomp/GetImage.cpp delete mode 100644 nxcomp/GetImage.h delete mode 100644 nxcomp/GetImageReply.cpp delete mode 100644 nxcomp/GetImageReply.h delete mode 100644 nxcomp/GetProperty.cpp delete mode 100644 nxcomp/GetProperty.h delete mode 100644 nxcomp/GetPropertyReply.cpp delete mode 100644 nxcomp/GetPropertyReply.h delete mode 100644 nxcomp/ImageText16.cpp delete mode 100644 nxcomp/ImageText16.h delete mode 100644 nxcomp/ImageText8.cpp delete mode 100644 nxcomp/ImageText8.h delete mode 100644 nxcomp/IntCache.cpp delete mode 100644 nxcomp/IntCache.h delete mode 100644 nxcomp/InternAtom.cpp delete mode 100644 nxcomp/InternAtom.h delete mode 100644 nxcomp/Jpeg.cpp delete mode 100644 nxcomp/Jpeg.h delete mode 100644 nxcomp/Keeper.cpp delete mode 100644 nxcomp/Keeper.h delete mode 100644 nxcomp/List.cpp delete mode 100644 nxcomp/List.h delete mode 100644 nxcomp/ListFontsReply.cpp delete mode 100644 nxcomp/ListFontsReply.h delete mode 100644 nxcomp/Loop.cpp delete mode 100644 nxcomp/MD5.c delete mode 100644 nxcomp/MD5.h create mode 100644 nxcomp/Makefile.am delete mode 100644 nxcomp/Makefile.in delete mode 100644 nxcomp/Message.cpp delete mode 100644 nxcomp/Message.h delete mode 100644 nxcomp/Misc.cpp delete mode 100644 nxcomp/Misc.h delete mode 100644 nxcomp/NX.h delete mode 100644 nxcomp/NXalert.h delete mode 100644 nxcomp/NXmitshm.h delete mode 100644 nxcomp/NXpack.h delete mode 100644 nxcomp/NXproto.h delete mode 100644 nxcomp/NXrender.h delete mode 100644 nxcomp/NXvars.h delete mode 100644 nxcomp/OpcodeCache.h delete mode 100644 nxcomp/OpcodeStore.cpp delete mode 100644 nxcomp/OpcodeStore.h delete mode 100644 nxcomp/Pack.c delete mode 100644 nxcomp/Pgn.cpp delete mode 100644 nxcomp/Pgn.h delete mode 100644 nxcomp/Pipe.cpp delete mode 100644 nxcomp/Pipe.h delete mode 100644 nxcomp/PolyArc.cpp delete mode 100644 nxcomp/PolyArc.h delete mode 100644 nxcomp/PolyFillArc.cpp delete mode 100644 nxcomp/PolyFillArc.h delete mode 100644 nxcomp/PolyFillRectangle.cpp delete mode 100644 nxcomp/PolyFillRectangle.h delete mode 100644 nxcomp/PolyLine.cpp delete mode 100644 nxcomp/PolyLine.h delete mode 100644 nxcomp/PolyPoint.cpp delete mode 100644 nxcomp/PolyPoint.h delete mode 100644 nxcomp/PolySegment.cpp delete mode 100644 nxcomp/PolySegment.h delete mode 100644 nxcomp/PolyText16.cpp delete mode 100644 nxcomp/PolyText16.h delete mode 100644 nxcomp/PolyText8.cpp delete mode 100644 nxcomp/PolyText8.h delete mode 100644 nxcomp/Proxy.cpp delete mode 100644 nxcomp/Proxy.h delete mode 100644 nxcomp/ProxyReadBuffer.cpp delete mode 100644 nxcomp/ProxyReadBuffer.h delete mode 100644 nxcomp/PutImage.cpp delete mode 100644 nxcomp/PutImage.h delete mode 100644 nxcomp/PutPackedImage.cpp delete mode 100644 nxcomp/PutPackedImage.h delete mode 100644 nxcomp/QueryFontReply.cpp delete mode 100644 nxcomp/QueryFontReply.h delete mode 100644 nxcomp/ReadBuffer.cpp delete mode 100644 nxcomp/ReadBuffer.h delete mode 100644 nxcomp/RenderAddGlyphs.cpp delete mode 100644 nxcomp/RenderAddGlyphs.h delete mode 100644 nxcomp/RenderChangePicture.cpp delete mode 100644 nxcomp/RenderChangePicture.h delete mode 100644 nxcomp/RenderComposite.cpp delete mode 100644 nxcomp/RenderComposite.h delete mode 100644 nxcomp/RenderCompositeGlyphs.cpp delete mode 100644 nxcomp/RenderCompositeGlyphs.h delete mode 100644 nxcomp/RenderCreateGlyphSet.cpp delete mode 100644 nxcomp/RenderCreateGlyphSet.h delete mode 100644 nxcomp/RenderCreatePicture.cpp delete mode 100644 nxcomp/RenderCreatePicture.h delete mode 100644 nxcomp/RenderExtension.cpp delete mode 100644 nxcomp/RenderExtension.h delete mode 100644 nxcomp/RenderFillRectangles.cpp delete mode 100644 nxcomp/RenderFillRectangles.h delete mode 100644 nxcomp/RenderFreeGlyphSet.cpp delete mode 100644 nxcomp/RenderFreeGlyphSet.h delete mode 100644 nxcomp/RenderFreePicture.cpp delete mode 100644 nxcomp/RenderFreePicture.h delete mode 100644 nxcomp/RenderGenericRequest.cpp delete mode 100644 nxcomp/RenderGenericRequest.h delete mode 100644 nxcomp/RenderMinorExtensionHeaders.h delete mode 100644 nxcomp/RenderMinorExtensionMethods.h delete mode 100644 nxcomp/RenderMinorExtensionTags.h delete mode 100644 nxcomp/RenderPictureClip.cpp delete mode 100644 nxcomp/RenderPictureClip.h delete mode 100644 nxcomp/RenderPictureFilter.cpp delete mode 100644 nxcomp/RenderPictureFilter.h delete mode 100644 nxcomp/RenderPictureTransform.cpp delete mode 100644 nxcomp/RenderPictureTransform.h delete mode 100644 nxcomp/RenderTrapezoids.cpp delete mode 100644 nxcomp/RenderTrapezoids.h delete mode 100644 nxcomp/RenderTriangles.cpp delete mode 100644 nxcomp/RenderTriangles.h delete mode 100644 nxcomp/Rgb.cpp delete mode 100644 nxcomp/Rgb.h delete mode 100644 nxcomp/Rle.cpp delete mode 100644 nxcomp/Rle.h delete mode 100644 nxcomp/SendEvent.cpp delete mode 100644 nxcomp/SendEvent.h delete mode 100644 nxcomp/SequenceQueue.cpp delete mode 100644 nxcomp/SequenceQueue.h delete mode 100644 nxcomp/ServerCache.cpp delete mode 100644 nxcomp/ServerCache.h delete mode 100644 nxcomp/ServerChannel.cpp delete mode 100644 nxcomp/ServerChannel.h delete mode 100644 nxcomp/ServerProxy.cpp delete mode 100644 nxcomp/ServerProxy.h delete mode 100644 nxcomp/ServerReadBuffer.cpp delete mode 100644 nxcomp/ServerReadBuffer.h delete mode 100644 nxcomp/ServerStore.cpp delete mode 100644 nxcomp/ServerStore.h delete mode 100644 nxcomp/SetClipRectangles.cpp delete mode 100644 nxcomp/SetClipRectangles.h delete mode 100644 nxcomp/SetUnpackAlpha.cpp delete mode 100644 nxcomp/SetUnpackAlpha.h delete mode 100644 nxcomp/SetUnpackColormap.cpp delete mode 100644 nxcomp/SetUnpackColormap.h delete mode 100644 nxcomp/SetUnpackGeometry.cpp delete mode 100644 nxcomp/SetUnpackGeometry.h delete mode 100644 nxcomp/ShapeExtension.cpp delete mode 100644 nxcomp/ShapeExtension.h delete mode 100644 nxcomp/Socket.cpp delete mode 100644 nxcomp/Socket.h delete mode 100644 nxcomp/Split.cpp delete mode 100644 nxcomp/Split.h delete mode 100644 nxcomp/StaticCompressor.cpp delete mode 100644 nxcomp/StaticCompressor.h delete mode 100644 nxcomp/Statistics.cpp delete mode 100644 nxcomp/Statistics.h delete mode 100644 nxcomp/Timestamp.cpp delete mode 100644 nxcomp/Timestamp.h delete mode 100644 nxcomp/TranslateCoords.cpp delete mode 100644 nxcomp/TranslateCoords.h delete mode 100644 nxcomp/Transport.cpp delete mode 100644 nxcomp/Transport.h delete mode 100644 nxcomp/Types.h delete mode 100644 nxcomp/Unpack.cpp delete mode 100644 nxcomp/Unpack.h delete mode 100644 nxcomp/Vars.c delete mode 100644 nxcomp/Version.c delete mode 100644 nxcomp/WriteBuffer.cpp delete mode 100644 nxcomp/WriteBuffer.h delete mode 100644 nxcomp/XidCache.cpp delete mode 100644 nxcomp/XidCache.h delete mode 100644 nxcomp/Z.cpp delete mode 100644 nxcomp/Z.h create mode 100644 nxcomp/configure.ac delete mode 100644 nxcomp/configure.in create mode 100644 nxcomp/include/MD5.h create mode 100644 nxcomp/include/NX.h create mode 100644 nxcomp/include/NXalert.h create mode 100644 nxcomp/include/NXpack.h create mode 100644 nxcomp/include/NXproto.h create mode 100644 nxcomp/include/NXvars.h delete mode 100755 nxcomp/install-sh create mode 120000 nxcomp/m4/nx-macros.m4 delete mode 100755 nxcomp/mkinstalldirs create mode 100644 nxcomp/src/ActionCache.cpp create mode 100644 nxcomp/src/ActionCache.h create mode 100644 nxcomp/src/Agent.cpp create mode 100644 nxcomp/src/Agent.h create mode 100644 nxcomp/src/Alpha.cpp create mode 100644 nxcomp/src/Alpha.h create mode 100644 nxcomp/src/Auth.cpp create mode 100644 nxcomp/src/Auth.h create mode 100644 nxcomp/src/Bitmap.cpp create mode 100644 nxcomp/src/Bitmap.h create mode 100644 nxcomp/src/BlockCache.cpp create mode 100644 nxcomp/src/BlockCache.h create mode 100644 nxcomp/src/BlockCacheSet.cpp create mode 100644 nxcomp/src/BlockCacheSet.h create mode 100644 nxcomp/src/ChangeGC.cpp create mode 100644 nxcomp/src/ChangeGC.h create mode 100644 nxcomp/src/ChangeProperty.cpp create mode 100644 nxcomp/src/ChangeProperty.h create mode 100644 nxcomp/src/Channel.cpp create mode 100644 nxcomp/src/Channel.h create mode 100644 nxcomp/src/ChannelCache.cpp create mode 100644 nxcomp/src/ChannelCache.h create mode 100644 nxcomp/src/ChannelEndPoint.cpp create mode 100644 nxcomp/src/ChannelEndPoint.h create mode 100644 nxcomp/src/ChannelStore.h create mode 100644 nxcomp/src/CharCache.cpp create mode 100644 nxcomp/src/CharCache.h create mode 100644 nxcomp/src/Children.cpp create mode 100644 nxcomp/src/ClearArea.cpp create mode 100644 nxcomp/src/ClearArea.h create mode 100644 nxcomp/src/ClientCache.cpp create mode 100644 nxcomp/src/ClientCache.h create mode 100644 nxcomp/src/ClientChannel.cpp create mode 100644 nxcomp/src/ClientChannel.h create mode 100644 nxcomp/src/ClientProxy.cpp create mode 100644 nxcomp/src/ClientProxy.h create mode 100644 nxcomp/src/ClientReadBuffer.cpp create mode 100644 nxcomp/src/ClientReadBuffer.h create mode 100644 nxcomp/src/ClientStore.cpp create mode 100644 nxcomp/src/ClientStore.h create mode 100644 nxcomp/src/Colormap.cpp create mode 100644 nxcomp/src/Colormap.h create mode 100644 nxcomp/src/ConfigureWindow.cpp create mode 100644 nxcomp/src/ConfigureWindow.h create mode 100644 nxcomp/src/Control.cpp create mode 100644 nxcomp/src/Control.h create mode 100644 nxcomp/src/CopyArea.cpp create mode 100644 nxcomp/src/CopyArea.h create mode 100644 nxcomp/src/CreateGC.cpp create mode 100644 nxcomp/src/CreateGC.h create mode 100644 nxcomp/src/CreatePixmap.cpp create mode 100644 nxcomp/src/CreatePixmap.h create mode 100644 nxcomp/src/DecodeBuffer.cpp create mode 100644 nxcomp/src/DecodeBuffer.h create mode 100644 nxcomp/src/EncodeBuffer.cpp create mode 100644 nxcomp/src/EncodeBuffer.h create mode 100644 nxcomp/src/FillPoly.cpp create mode 100644 nxcomp/src/FillPoly.h create mode 100644 nxcomp/src/Fork.cpp create mode 100644 nxcomp/src/Fork.h create mode 100644 nxcomp/src/FreeCache.h create mode 100644 nxcomp/src/GenericChannel.cpp create mode 100644 nxcomp/src/GenericChannel.h create mode 100644 nxcomp/src/GenericReadBuffer.cpp create mode 100644 nxcomp/src/GenericReadBuffer.h create mode 100644 nxcomp/src/GenericReply.cpp create mode 100644 nxcomp/src/GenericReply.h create mode 100644 nxcomp/src/GenericRequest.cpp create mode 100644 nxcomp/src/GenericRequest.h create mode 100644 nxcomp/src/GetImage.cpp create mode 100644 nxcomp/src/GetImage.h create mode 100644 nxcomp/src/GetImageReply.cpp create mode 100644 nxcomp/src/GetImageReply.h create mode 100644 nxcomp/src/GetProperty.cpp create mode 100644 nxcomp/src/GetProperty.h create mode 100644 nxcomp/src/GetPropertyReply.cpp create mode 100644 nxcomp/src/GetPropertyReply.h create mode 100644 nxcomp/src/ImageText16.cpp create mode 100644 nxcomp/src/ImageText16.h create mode 100644 nxcomp/src/ImageText8.cpp create mode 100644 nxcomp/src/ImageText8.h create mode 100644 nxcomp/src/IntCache.cpp create mode 100644 nxcomp/src/IntCache.h create mode 100644 nxcomp/src/InternAtom.cpp create mode 100644 nxcomp/src/InternAtom.h create mode 100644 nxcomp/src/Jpeg.cpp create mode 100644 nxcomp/src/Jpeg.h create mode 100644 nxcomp/src/Keeper.cpp create mode 100644 nxcomp/src/Keeper.h create mode 100644 nxcomp/src/List.cpp create mode 100644 nxcomp/src/List.h create mode 100644 nxcomp/src/ListFontsReply.cpp create mode 100644 nxcomp/src/ListFontsReply.h create mode 100644 nxcomp/src/Loop.cpp create mode 100644 nxcomp/src/MD5.c create mode 100644 nxcomp/src/Makefile.am create mode 100644 nxcomp/src/Message.cpp create mode 100644 nxcomp/src/Message.h create mode 100644 nxcomp/src/Misc.cpp create mode 100644 nxcomp/src/Misc.h create mode 100644 nxcomp/src/NXmitshm.h create mode 100644 nxcomp/src/NXrender.h create mode 100644 nxcomp/src/OpcodeCache.h create mode 100644 nxcomp/src/OpcodeStore.cpp create mode 100644 nxcomp/src/OpcodeStore.h create mode 100644 nxcomp/src/Pack.c create mode 100644 nxcomp/src/Pgn.cpp create mode 100644 nxcomp/src/Pgn.h create mode 100644 nxcomp/src/Pipe.cpp create mode 100644 nxcomp/src/Pipe.h create mode 100644 nxcomp/src/PolyArc.cpp create mode 100644 nxcomp/src/PolyArc.h create mode 100644 nxcomp/src/PolyFillArc.cpp create mode 100644 nxcomp/src/PolyFillArc.h create mode 100644 nxcomp/src/PolyFillRectangle.cpp create mode 100644 nxcomp/src/PolyFillRectangle.h create mode 100644 nxcomp/src/PolyLine.cpp create mode 100644 nxcomp/src/PolyLine.h create mode 100644 nxcomp/src/PolyPoint.cpp create mode 100644 nxcomp/src/PolyPoint.h create mode 100644 nxcomp/src/PolySegment.cpp create mode 100644 nxcomp/src/PolySegment.h create mode 100644 nxcomp/src/PolyText16.cpp create mode 100644 nxcomp/src/PolyText16.h create mode 100644 nxcomp/src/PolyText8.cpp create mode 100644 nxcomp/src/PolyText8.h create mode 100644 nxcomp/src/Proxy.cpp create mode 100644 nxcomp/src/Proxy.h create mode 100644 nxcomp/src/ProxyReadBuffer.cpp create mode 100644 nxcomp/src/ProxyReadBuffer.h create mode 100644 nxcomp/src/PutImage.cpp create mode 100644 nxcomp/src/PutImage.h create mode 100644 nxcomp/src/PutPackedImage.cpp create mode 100644 nxcomp/src/PutPackedImage.h create mode 100644 nxcomp/src/QueryFontReply.cpp create mode 100644 nxcomp/src/QueryFontReply.h create mode 100644 nxcomp/src/ReadBuffer.cpp create mode 100644 nxcomp/src/ReadBuffer.h create mode 100644 nxcomp/src/RenderAddGlyphs.cpp create mode 100644 nxcomp/src/RenderAddGlyphs.h create mode 100644 nxcomp/src/RenderChangePicture.cpp create mode 100644 nxcomp/src/RenderChangePicture.h create mode 100644 nxcomp/src/RenderComposite.cpp create mode 100644 nxcomp/src/RenderComposite.h create mode 100644 nxcomp/src/RenderCompositeGlyphs.cpp create mode 100644 nxcomp/src/RenderCompositeGlyphs.h create mode 100644 nxcomp/src/RenderCreateGlyphSet.cpp create mode 100644 nxcomp/src/RenderCreateGlyphSet.h create mode 100644 nxcomp/src/RenderCreatePicture.cpp create mode 100644 nxcomp/src/RenderCreatePicture.h create mode 100644 nxcomp/src/RenderExtension.cpp create mode 100644 nxcomp/src/RenderExtension.h create mode 100644 nxcomp/src/RenderFillRectangles.cpp create mode 100644 nxcomp/src/RenderFillRectangles.h create mode 100644 nxcomp/src/RenderFreeGlyphSet.cpp create mode 100644 nxcomp/src/RenderFreeGlyphSet.h create mode 100644 nxcomp/src/RenderFreePicture.cpp create mode 100644 nxcomp/src/RenderFreePicture.h create mode 100644 nxcomp/src/RenderGenericRequest.cpp create mode 100644 nxcomp/src/RenderGenericRequest.h create mode 100644 nxcomp/src/RenderMinorExtensionHeaders.h create mode 100644 nxcomp/src/RenderMinorExtensionMethods.h create mode 100644 nxcomp/src/RenderMinorExtensionTags.h create mode 100644 nxcomp/src/RenderPictureClip.cpp create mode 100644 nxcomp/src/RenderPictureClip.h create mode 100644 nxcomp/src/RenderPictureFilter.cpp create mode 100644 nxcomp/src/RenderPictureFilter.h create mode 100644 nxcomp/src/RenderPictureTransform.cpp create mode 100644 nxcomp/src/RenderPictureTransform.h create mode 100644 nxcomp/src/RenderTrapezoids.cpp create mode 100644 nxcomp/src/RenderTrapezoids.h create mode 100644 nxcomp/src/RenderTriangles.cpp create mode 100644 nxcomp/src/RenderTriangles.h create mode 100644 nxcomp/src/Rgb.cpp create mode 100644 nxcomp/src/Rgb.h create mode 100644 nxcomp/src/Rle.cpp create mode 100644 nxcomp/src/Rle.h create mode 100644 nxcomp/src/SendEvent.cpp create mode 100644 nxcomp/src/SendEvent.h create mode 100644 nxcomp/src/SequenceQueue.cpp create mode 100644 nxcomp/src/SequenceQueue.h create mode 100644 nxcomp/src/ServerCache.cpp create mode 100644 nxcomp/src/ServerCache.h create mode 100644 nxcomp/src/ServerChannel.cpp create mode 100644 nxcomp/src/ServerChannel.h create mode 100644 nxcomp/src/ServerProxy.cpp create mode 100644 nxcomp/src/ServerProxy.h create mode 100644 nxcomp/src/ServerReadBuffer.cpp create mode 100644 nxcomp/src/ServerReadBuffer.h create mode 100644 nxcomp/src/ServerStore.cpp create mode 100644 nxcomp/src/ServerStore.h create mode 100644 nxcomp/src/SetClipRectangles.cpp create mode 100644 nxcomp/src/SetClipRectangles.h create mode 100644 nxcomp/src/SetUnpackAlpha.cpp create mode 100644 nxcomp/src/SetUnpackAlpha.h create mode 100644 nxcomp/src/SetUnpackColormap.cpp create mode 100644 nxcomp/src/SetUnpackColormap.h create mode 100644 nxcomp/src/SetUnpackGeometry.cpp create mode 100644 nxcomp/src/SetUnpackGeometry.h create mode 100644 nxcomp/src/ShapeExtension.cpp create mode 100644 nxcomp/src/ShapeExtension.h create mode 100644 nxcomp/src/Socket.cpp create mode 100644 nxcomp/src/Socket.h create mode 100644 nxcomp/src/Split.cpp create mode 100644 nxcomp/src/Split.h create mode 100644 nxcomp/src/StaticCompressor.cpp create mode 100644 nxcomp/src/StaticCompressor.h create mode 100644 nxcomp/src/Statistics.cpp create mode 100644 nxcomp/src/Statistics.h create mode 100644 nxcomp/src/Timestamp.cpp create mode 100644 nxcomp/src/Timestamp.h create mode 100644 nxcomp/src/TranslateCoords.cpp create mode 100644 nxcomp/src/TranslateCoords.h create mode 100644 nxcomp/src/Transport.cpp create mode 100644 nxcomp/src/Transport.h create mode 100644 nxcomp/src/Types.h create mode 100644 nxcomp/src/Unpack.cpp create mode 100644 nxcomp/src/Unpack.h create mode 100644 nxcomp/src/Vars.c create mode 100644 nxcomp/src/Version.c create mode 100644 nxcomp/src/WriteBuffer.cpp create mode 100644 nxcomp/src/WriteBuffer.h create mode 100644 nxcomp/src/XidCache.cpp create mode 100644 nxcomp/src/XidCache.h create mode 100644 nxcomp/src/Z.cpp create mode 100644 nxcomp/src/Z.h (limited to 'nxproxy') diff --git a/Makefile b/Makefile index d38015a00..2b4e5dfbd 100644 --- a/Makefile +++ b/Makefile @@ -54,14 +54,7 @@ all: test: echo "No testing for NX (redistributed)" -build-lite: - cd nxcomp && autoconf && (${CONFIGURE}) && ${MAKE} - cd nxproxy && autoreconf -vfsi && (${CONFIGURE}) && ${MAKE} - -build-full: -# in the full case, we rely on "magic" in the nx-X11 imake-based makefiles... - cd nxcomp && autoconf && (${CONFIGURE}) && ${MAKE} - +build-env: # prepare nx-X11/config/cf/nxversion.def sed \ -e 's/###NX_VERSION_MAJOR###/$(NX_VERSION_MAJOR)/' \ @@ -74,6 +67,13 @@ build-full: # prepare Makefiles and the nx-X11 symlinking magic cd nx-X11 && make BuildEnv FONT_DEFINES=$(FONT_DEFINES) +build-lite: + cd nxcomp && autoreconf -vfsi && (${CONFIGURE}) && ${MAKE} + cd nxproxy && autoreconf -vfsi && (${CONFIGURE}) && ${MAKE} + +build-full: build-env +# in the full case, we rely on "magic" in the nx-X11 imake-based makefiles... + cd nxcomp && autoreconf -vfsi && (${CONFIGURE}) && ${MAKE} # build libNX_X11 and libNX_Xext prior to building # nxcomp{ext,shad}. cd nx-X11/lib && make diff --git a/debian/libxcomp-dev.install b/debian/libxcomp-dev.install index e27e6ecf0..f73422f40 100644 --- a/debian/libxcomp-dev.install +++ b/debian/libxcomp-dev.install @@ -1,4 +1,5 @@ usr/lib/*/libXcomp.so +usr/lib/*/libXcomp.a usr/include/*/nx/NX.h usr/include/*/nx/NXalert.h usr/include/*/nx/NXpack.h diff --git a/debian/rules b/debian/rules index b59ba83a5..13490a86c 100755 --- a/debian/rules +++ b/debian/rules @@ -24,7 +24,7 @@ override_dh_clean: override_dh_install: # remove static libs - rm debian/tmp/usr/lib/$(DEB_BUILD_MULTIARCH)/libXcomp.a + rm debian/tmp/usr/lib/$(DEB_BUILD_MULTIARCH)/libXcomp.la rm debian/tmp/usr/lib/$(DEB_BUILD_MULTIARCH)/libXcompshad.la # remove extras, GL, and other unneeded headers diff --git a/nx-X11/lib/X11/Imakefile b/nx-X11/lib/X11/Imakefile index 5b289fae8..a6471bff1 100644 --- a/nx-X11/lib/X11/Imakefile +++ b/nx-X11/lib/X11/Imakefile @@ -36,9 +36,9 @@ BuildIncludes($(HEADERS),IncSubdir,..) #if NXLibraries #ifdef SunArchitecture -NX_INCLUDES = -I../../../nxcomp -I/usr/sfw/include +NX_INCLUDES = -I../../../nxcomp/include -I/usr/sfw/include #else -NX_INCLUDES = -I../../../nxcomp +NX_INCLUDES = -I../../../nxcomp/include #endif NX_DEFINES = -DNX_TRANS_SOCKET \ @@ -81,7 +81,7 @@ NX_XCOMPLIBNAME = libXcomp.so NX_XCOMPEXTLIBNAME = libXcompext.so #endif -NX_XCOMPLIBDIR = $(XTOP)/../nxcomp +NX_XCOMPLIBDIR = $(XTOP)/../nxcomp/src/.libs NX_XCOMPLIBLINK = Xcomp NX_XCOMPLIBTARGET = $(NX_XCOMPLIBDIR)/$(NX_XCOMPLIBNAME) NX_REQUIREDLIBS = -L$(NX_XCOMPLIBDIR) -l$(NX_XCOMPLIBLINK) diff --git a/nx-X11/programs/Xserver/Imakefile b/nx-X11/programs/Xserver/Imakefile index ed49313ee..3c7e68597 100644 --- a/nx-X11/programs/Xserver/Imakefile +++ b/nx-X11/programs/Xserver/Imakefile @@ -213,12 +213,12 @@ NXAGENTDDXDIR = hw NXAGENTDIRS = $(STDDIRS) $(FBDIR) $(MIDAMAGEDIR) $(NXAGENTDDXDIR) $(DEPDIRS) NX_XCOMP_HEADERS = \ - ../../../nxcomp/MD5.h \ - ../../../nxcomp/NXalert.h \ - ../../../nxcomp/NX.h \ - ../../../nxcomp/NXpack.h \ - ../../../nxcomp/NXproto.h \ - ../../../nxcomp/NXvars.h \ + ../../../nxcomp/include/MD5.h \ + ../../../nxcomp/include/NXalert.h \ + ../../../nxcomp/include/NX.h \ + ../../../nxcomp/include/NXpack.h \ + ../../../nxcomp/include/NXproto.h \ + ../../../nxcomp/include/NXvars.h \ $(NULL) NX_XCOMPSHAD_HEADERS = \ @@ -315,7 +315,7 @@ $(NXAGENTOBJS) $(NXAGENTLIBS) $(NXAGENTSYSLIBS):: $(NXAGENTDIRS) #if defined(SunArchitecture) NXAGENTNXLIBS = -L/usr/sfw/lib \ - -L../../../nxcomp \ + -L../../../nxcomp/src/.libs \ -L../../../nxcompshad/src/.libs \ -lrt \ -lXcomp \ @@ -330,7 +330,7 @@ NXAGENTNXLIBS = -L/usr/sfw/lib \ -lXext \ $(NULL) #elif defined(cygwinArchitecture) -NXAGENTNXLIBS = -L../../../nxcomp \ +NXAGENTNXLIBS = -L../../../nxcomp/src/.libs \ -L../../../nxcompshad/src/.libs \ -lXcomp \ -lXcompshad \ @@ -343,7 +343,7 @@ NXAGENTNXLIBS = -L../../../nxcomp \ -lXext \ $(NULL) #elif defined(OpenBSDArchitecture) -NXAGENTNXLIBS = -L../../../nxcomp \ +NXAGENTNXLIBS = -L../../../nxcomp/src/.libs \ -L../../../nx-X11/exports/lib \ -L../../../nxcompshad/src/.libs \ -lkvm \ @@ -359,7 +359,7 @@ NXAGENTNXLIBS = -L../../../nxcomp \ -lXext \ $(NULL) #else -NXAGENTNXLIBS = -L../../../nxcomp \ +NXAGENTNXLIBS = -L../../../nxcomp/src/.libs \ -L../../../nxcompshad/src/.libs \ -lXcomp \ -lXcompshad \ diff --git a/nxcomp/.gitignore b/nxcomp/.gitignore index 27a99e5b2..a148dfa93 100644 --- a/nxcomp/.gitignore +++ b/nxcomp/.gitignore @@ -1,2 +1,23 @@ -nxcomp.pc Makefile +Makefile.in +aclocal.m4 +compile +config.guess +config.sub +depcomp +install-sh +ltmain.sh +missing +config.h +config.h.in +libtool +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 +nxcomp.pc +src/.deps/ +src/Makefile +src/Makefile.in +stamp-h1 diff --git a/nxcomp/ActionCache.cpp b/nxcomp/ActionCache.cpp deleted file mode 100644 index 8ad7f7ba2..000000000 --- a/nxcomp/ActionCache.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Control.h" - -#include "ActionCache.h" - -ActionCache::ActionCache() -{ - for (int i = 0; i < 256; i++) - { - base_[i] = new IntCache(8); - } - - slot_ = 0; - last_ = 0; -} - -ActionCache::~ActionCache() -{ - for (int i = 0; i < 256; i++) - { - delete base_[i]; - } -} diff --git a/nxcomp/ActionCache.h b/nxcomp/ActionCache.h deleted file mode 100644 index 2aedd4a07..000000000 --- a/nxcomp/ActionCache.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ActionCache_H -#define ActionCache_H - -#include "IntCache.h" - -class ActionCache -{ - friend class EncodeBuffer; - friend class DecodeBuffer; - - public: - - ActionCache(); - ~ActionCache(); - - private: - - IntCache *base_[256]; - - unsigned int slot_; - unsigned short last_; -}; - -#endif /* ActionCache_H */ diff --git a/nxcomp/Agent.cpp b/nxcomp/Agent.cpp deleted file mode 100644 index cd65101b3..000000000 --- a/nxcomp/Agent.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Agent.h" -#include "Proxy.h" - -extern Proxy *proxy; - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -Agent::Agent(int fd[2]) -{ - remoteFd_ = fd[0]; - localFd_ = fd[1]; - - transport_ = new AgentTransport(localFd_); - - if (transport_ == NULL) - { - #ifdef PANIC - *logofs << "Agent: PANIC! Can't create the memory-to-memory transport " - << "for FD#" << localFd_ << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't create the memory-to-memory transport " - << "for FD#" << localFd_ << ".\n"; - - HandleCleanup(); - } - - FD_ZERO(&saveRead_); - FD_ZERO(&saveWrite_); - - canRead_ = 0; - - #ifdef DEBUG - *logofs << "Agent: Created agent object at " << this - << ".\n" << logofs_flush; - #endif -} - -Agent::~Agent() -{ - delete transport_; - - #ifdef DEBUG - *logofs << "Agent: Deleted agent object at " << this - << ".\n" << logofs_flush; - #endif -} diff --git a/nxcomp/Agent.h b/nxcomp/Agent.h deleted file mode 100644 index 3e1a50ae5..000000000 --- a/nxcomp/Agent.h +++ /dev/null @@ -1,263 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Agent_H -#define Agent_H - -#include - -#include -#include -#include - -#include "Misc.h" -#include "Transport.h" -#include "Proxy.h" - -extern Proxy *proxy; - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -class Agent -{ - public: - - // - // Must be created by passing the fake descriptor that - // will be used for simulating socket communication - // betwen the agent and the proxy. I/O will take place - // by copying data to the agent's read and write buf- - // fers. - // - - Agent(int fd[2]); - - ~Agent(); - - AgentTransport *getTransport() const - { - return transport_; - } - - void saveReadMask(fd_set *readSet) - { - saveRead_ = *readSet; - } - - void saveWriteMask(fd_set *writeSet) - { - saveWrite_ = *writeSet; - } - - void clearReadMask(fd_set *readSet) - { - FD_CLR(remoteFd_, readSet); - FD_CLR(localFd_, readSet); - } - - void clearWriteMask(fd_set *writeSet) - { - FD_CLR(remoteFd_, writeSet); - FD_CLR(localFd_, writeSet); - } - - void setLocalRead(fd_set *readSet, int *result) - { - (*result)++; - - FD_SET(localFd_, readSet); - } - - void setRemoteRead(fd_set *readSet, int *result) - { - (*result)++; - - FD_SET(remoteFd_, readSet); - } - - void setRemoteWrite(fd_set *writeSet, int *result) - { - (*result)++; - - FD_SET(remoteFd_, writeSet); - } - - fd_set *getSavedReadMask() - { - return &saveRead_; - } - - fd_set *getSavedWriteMask() - { - return &saveWrite_; - } - - int getRemoteFd() const - { - return remoteFd_; - } - - int getLocalFd() const - { - return localFd_; - } - - int getProxyFd() const - { - return proxy -> getFd(); - } - - int isValid() const - { - return (transport_ != NULL); - } - - int localReadable() - { - return (transport_ -> readable() != 0); - } - - // - // Check if we can process more data from - // the agent descriptor and cache the result - // to avoid multiple calls. This must be - // always called before querying the other - // functions. - // - - void saveChannelState() - { - canRead_ = (proxy != NULL ? proxy -> canRead(localFd_) : 0); - } - - int remoteCanRead(const fd_set * const readSet) - { - // OS X 10.5 requires the second argument to be non-const, so copy readSet. - // It's safe though, as FD_ISSET does not operate on it. - fd_set readWorkSet = *readSet; - - #if defined(TEST) || defined(INFO) - *logofs << "Agent: remoteCanRead() is " << - (FD_ISSET(remoteFd_, &readWorkSet) && transport_ -> dequeuable() != 0) - << " with FD_ISSET() " << (int) FD_ISSET(remoteFd_, &readWorkSet) - << " and dequeuable " << transport_ -> dequeuable() - << ".\n" << logofs_flush; - #endif - - return (FD_ISSET(remoteFd_, &readWorkSet) && - transport_ -> dequeuable() != 0); - } - - int remoteCanWrite(const fd_set * const writeSet) - { - // OS X 10.5 requires the second argument to be non-const, so copy writeSet. - // It's safe though, as FD_ISSET does not operate on it. - fd_set writeWorkSet = *writeSet; - - #if defined(TEST) || defined(INFO) - *logofs << "Agent: remoteCanWrite() is " << - (FD_ISSET(remoteFd_, &writeWorkSet) && transport_ -> - queuable() != 0 && canRead_ == 1) << " with FD_ISSET() " - << (int) FD_ISSET(remoteFd_, &writeWorkSet) << " queueable " - << transport_ -> queuable() << " channel can read " - << canRead_ << ".\n" << logofs_flush; - #endif - - return (FD_ISSET(remoteFd_, &writeWorkSet) && - transport_ -> queuable() != 0 && - canRead_ == 1); - } - - int localCanRead() - { - #if defined(TEST) || defined(INFO) - *logofs << "Agent: localCanRead() is " << - (transport_ -> readable() != 0 && canRead_ == 1) - << " with readable " << transport_ -> readable() - << " channel can read " << canRead_ << ".\n" - << logofs_flush; - #endif - - return (transport_ -> readable() != 0 && - canRead_ == 1); - } - - int proxyCanRead() - { - #if defined(TEST) || defined(INFO) - *logofs << "Agent: proxyCanRead() is " << proxy -> canRead() - << ".\n" << logofs_flush; - #endif - - return (proxy -> canRead()); - } - - int proxyCanRead(const fd_set * const readSet) - { - // OS X 10.5 requires the second argument to be non-const, so copy readSet. - // It's safe though, as FD_ISSET does not operate on it. - fd_set readWorkSet = *readSet; - - #if defined(TEST) || defined(INFO) - *logofs << "Agent: proxyCanRead() is " - << ((int) FD_ISSET(proxy -> getFd(), &readWorkSet)) - << ".\n" << logofs_flush; - #endif - - return (FD_ISSET(proxy -> getFd(), &readWorkSet)); - } - - int enqueueData(const char *data, const int size) const - { - return transport_ -> enqueue(data, size); - } - - int dequeueData(char *data, int size) const - { - return transport_ -> dequeue(data, size); - } - - int dequeuableData() const - { - return transport_ -> dequeuable(); - } - - private: - - int remoteFd_; - int localFd_; - - fd_set saveRead_; - fd_set saveWrite_; - - int canRead_; - - AgentTransport *transport_; -}; - -#endif /* Agent_H */ diff --git a/nxcomp/Alpha.cpp b/nxcomp/Alpha.cpp deleted file mode 100644 index 31a31f7cb..000000000 --- a/nxcomp/Alpha.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Unpack.h" -#include "Alpha.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -int UnpackAlpha(unsigned char method, unsigned char *src_data, int src_size, - unsigned char *dst_data, int dst_size) -{ - if (*src_data == 0) - { - if (dst_size != src_size - 1) - { - #ifdef TEST - *logofs << "UnpackAlpha: PANIC! Invalid destination size " - << dst_size << " with source " << src_size - << ".\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef TEST - *logofs << "UnpackAlpha: Expanding " << src_size - 1 - << " bytes of plain alpha data.\n" << logofs_flush; - #endif - - memcpy(dst_data, src_data + 1, src_size - 1); - - return 1; - } - - unsigned int check_size = dst_size; - - int result = ZDecompress(&unpackStream, dst_data, &check_size, - src_data + 1, src_size - 1); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "UnpackAlpha: PANIC! Failure decompressing alpha data. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decompressing alpha data. " - << "Error is '" << zError(result) << "'.\n"; - - return -1; - } - else if (check_size != (unsigned int) dst_size) - { - #ifdef PANIC - *logofs << "UnpackAlpha: PANIC! Size mismatch in alpha data. " - << "Resulting size is " << check_size << " with " - << "expected size " << dst_size << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Size mismatch in alpha data. " - << "Resulting size is " << check_size << " with " - << "expected size " << dst_size << ".\n"; - - return -1; - } - - #ifdef TEST - *logofs << "UnpackAlpha: Decompressed " << src_size - 1 - << " bytes to " << dst_size << " bytes of alpha data.\n" - << logofs_flush; - #endif - - return 1; -} - -int UnpackAlpha(T_alpha *alpha, unsigned char *dst_data, - int dst_size, int big_endian) -{ - unsigned int count = dst_size >> 2; - - unsigned int i; - - int shift; - - if (count != alpha -> entries) - { - #ifdef WARNING - *logofs << "UnpackAlpha: WARNING! Not applying the alpha with " - << count << " elements needed and " << alpha -> entries - << " available.\n" << logofs_flush; - #endif - - return 0; - } - - shift = (big_endian == 1 ? 0 : 3); - - for (i = 0; i < count; i++) - { - *(dst_data + shift) = *(alpha -> data + i); - - dst_data += 4; - } - - return 1; -} diff --git a/nxcomp/Alpha.h b/nxcomp/Alpha.h deleted file mode 100644 index ea5068812..000000000 --- a/nxcomp/Alpha.h +++ /dev/null @@ -1,35 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Alpha_H -#define Alpha_H - -int UnpackAlpha(unsigned char method, unsigned char *src_data, int src_size, - unsigned char *dst_data, int dst_size); - -int UnpackAlpha(T_alpha *alpha, unsigned char *dst_data, - int dst_size, int big_endian); - -#endif /* Aplha_H */ diff --git a/nxcomp/Auth.cpp b/nxcomp/Auth.cpp deleted file mode 100644 index bc047aa30..000000000 --- a/nxcomp/Auth.cpp +++ /dev/null @@ -1,667 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Auth.h" - -#include "Misc.h" -#include "Control.h" -#include "Timestamp.h" -#include "Pipe.h" - -#define DEFAULT_STRING_LIMIT 512 - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Store the provided cookie as our 'fake' cookie, then -// read the 'real' cookie from the current X authority -// file. -// - -Auth::Auth(char *display, char *cookie) -{ - display_ = NULL; - - file_ = NULL; - - last_ = nullTimestamp(); - - fakeCookie_ = NULL; - realCookie_ = NULL; - - fakeData_ = NULL; - realData_ = NULL; - - dataSize_ = 0; - - generatedCookie_ = 0; - - if (display == NULL || *display == '\0' || cookie == NULL || - *cookie == '\0' || strlen(cookie) != 32) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Can't create the X authorization data " - << "with cookie '" << cookie << "' and display '" - << display << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't create the X authorization data " - << "with cookie '" << cookie << "' and display '" - << display << "'.\n"; - - return; - } - - #ifdef TEST - *logofs << "Auth: Creating X authorization data with cookie '" - << cookie << "' and display '" << display << "'.\n" - << logofs_flush; - #endif - - // - // Get a local copy of all parameters. - // - - display_ = new char[strlen(display) + 1]; - file_ = new char[DEFAULT_STRING_LIMIT]; - - fakeCookie_ = new char[strlen(cookie) + 1]; - realCookie_ = new char[DEFAULT_STRING_LIMIT]; - - if (display_ == NULL || file_ == NULL || - fakeCookie_ == NULL || realCookie_ == NULL) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Cannot allocate memory for the X " - << "authorization data.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot allocate memory for the X " - << "authorization data.\n"; - - return; - } - - strcpy(display_, display); - - *file_ = '\0'; - - strcpy(fakeCookie_, cookie); - - *realCookie_ = '\0'; - - // - // Get the real cookie from the authorization file. - // - - updateCookie(); -} - -Auth::~Auth() -{ - delete [] display_; - delete [] file_; - - delete [] fakeCookie_; - delete [] realCookie_; - - delete [] fakeData_; - delete [] realData_; -} - -// -// At the present moment the cookie is read only once, -// at the time the instance is initialized. If the auth -// file changes along the life of the session, the old -// cookie will be used. This works with X servers beca- -// use of an undocumented "feature". See nx-X11. -// - -int Auth::updateCookie() -{ - if (isTimestamp(last_) == 0) - { - #ifdef TEST - *logofs << "Auth: Reading the X authorization file " - << "with last update at " << strMsTimestamp(last_) - << ".\n" << logofs_flush; - #endif - - if (getCookie() == 1 && validateCookie() == 1) - { - // - // It should rather be the modification time - // the auth file, so we can read it again if - // the file is changed. - // - - #ifdef TEST - *logofs << "Auth: Setting last X authorization file " - << "update at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - last_ = getTimestamp(); - - return 1; - } - - #ifdef PANIC - *logofs << "Auth: PANIC! Cannot read the cookie from the X " - << "authorization file.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot read the cookie from the X " - << "authorization file.\n"; - - return -1; - } - - #ifdef TEST - *logofs << "Auth: WARNING! Skipping check on the X " - << "authorization file.\n" << logofs_flush; - #endif - - return 0; -} - -int Auth::getCookie() -{ - // - // Check the name of the auth file that we are going to use. - // It can be either the value of the XAUTHORITY environment - // or the default .Xauthority file in the user's home. - // - - char *environment; - - environment = getenv("XAUTHORITY"); - - if (environment != NULL && *environment != '\0') - { - strncpy(file_, environment, DEFAULT_STRING_LIMIT - 1); - } - else - { - snprintf(file_, DEFAULT_STRING_LIMIT - 1, "%s/.Xauthority", - control -> HomePath); - } - - *(file_ + DEFAULT_STRING_LIMIT - 1) = '\0'; - - #ifdef TEST - *logofs << "Auth: Using X authorization file '" << file_ - << "'.\n" << logofs_flush; - #endif - - // - // Use the nxauth command on Windows and the Mac, xauth - // on all the other platforms. On Windows we assume that - // the nxauth command is located under bin in the client - // installation directory. On Mac OS X we assume that the - // command is located directly in the client installation - // directory, to make bundle shipping easier. On all the - // other platforms we use the default xauth command that - // is in our path. - // - - char command[DEFAULT_STRING_LIMIT]; - - #if defined(__CYGWIN32__) - - snprintf(command, DEFAULT_STRING_LIMIT - 1, - "%s/bin/nxauth", control -> SystemPath); - - *(command + DEFAULT_STRING_LIMIT - 1) = '\0'; - - #elif defined(__APPLE__) - - snprintf(command, DEFAULT_STRING_LIMIT - 1, - "%s/nxauth", control -> SystemPath); - - *(command + DEFAULT_STRING_LIMIT - 1) = '\0'; - - #else - - strcpy(command, "xauth"); - - #endif - - #ifdef TEST - *logofs << "Auth: Using X auth command '" << command - << "'.\n" << logofs_flush; - #endif - - // - // The SSH code forces using the unix:n port when passing localhost:n. - // This is probably because localhost:n can fail to return a valid - // entry on machines where the hostname for localhost doesn't match - // exactly the 'localhost' string. For example, on a freshly installed - // Fedora Core 3 I get a 'localhost.localdomain/unix:0' entry. Query- - // ing 'xauth list localhost:0' results in an empty result, while the - // query 'xauth list unix:0' works as expected. Note anyway that if - // the cookie for the TCP connection on 'localhost' is set to a dif- - // ferent cookie than the one for the Unix connections, both SSH and - // NX will match the wrong cookie and session will fail. - // - - char line[DEFAULT_STRING_LIMIT]; - - if (strncmp(display_, "localhost:", 10) == 0) - { - snprintf(line, DEFAULT_STRING_LIMIT, "unix:%s", display_ + 10); - } - else - { - snprintf(line, DEFAULT_STRING_LIMIT, "%.200s", display_); - } - - const char *parameters[256]; - - parameters[0] = command; - parameters[1] = command; - parameters[2] = "-f"; - parameters[3] = file_; - parameters[4] = "list"; - parameters[5] = line; - parameters[6] = NULL; - - #ifdef TEST - *logofs << "Auth: Executing command "; - - for (int i = 0; i < 256 && parameters[i] != NULL; i++) - { - *logofs << "[" << parameters[i] << "]"; - } - - *logofs << ".\n" << logofs_flush; - #endif - - // - // Use the popen() function to read the result - // of the command. We would better use our own - // implementation. - // - - FILE *data = Popen((char *const *) parameters, "r"); - - int result = -1; - - if (data == NULL) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Failed to execute the X auth command.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to execute the X auth command.\n"; - - goto AuthGetCookieResult; - } - - if (fgets(line, DEFAULT_STRING_LIMIT, data) == NULL) - { - #ifdef WARNING - *logofs << "Auth: WARNING! Failed to read data from the X " - << "auth command.\n" << logofs_flush; - #endif - - #ifdef TEST - cerr << "Warning" << ": Failed to read data from the X " - << "auth command.\n"; - #endif - - #ifdef PANIC - *logofs << "Auth: WARNING! Generating a fake cookie for " - << "X authentication.\n" << logofs_flush; - #endif - - #ifdef TEST - cerr << "Warning" << ": Generating a fake cookie for " - << "X authentication.\n"; - #endif - - generateCookie(realCookie_); - } - else - { - #ifdef TEST - *logofs << "Auth: Checking cookie in string '" << line - << "'.\n" << logofs_flush; - #endif - - // - // Skip the hostname in the authority entry - // just in case it includes some white spaces. - // - - char *cookie = NULL; - - cookie = index(line, ':'); - - if (cookie == NULL) - { - cookie = line; - } - - if (sscanf(cookie, "%*s %*s %511s", realCookie_) != 1) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Failed to identify the cookie " - << "in string '" << line << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to identify the cookie " - << "in string '" << line << "'.\n"; - - goto AuthGetCookieResult; - } - - #ifdef TEST - *logofs << "Auth: Got cookie '" << realCookie_ - << "' from file '" << file_ << "'.\n" - << logofs_flush; - #endif - } - - result = 1; - -AuthGetCookieResult: - - if (data != NULL) - { - Pclose(data); - } - - return result; -} - -int Auth::validateCookie() -{ - unsigned int length = strlen(realCookie_); - - if (length > DEFAULT_STRING_LIMIT / 2 - 1 || - strlen(fakeCookie_) != length) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Size mismatch between cookies '" - << realCookie_ << "' and '" << fakeCookie_ << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Size mismatch between cookies '" - << realCookie_ << "' and '" << fakeCookie_ << "'.\n"; - - goto AuthValidateCookieError; - } - - // - // The length of the resulting data will be - // half the size of the Hex cookie. - // - - length = length / 2; - - fakeData_ = new char[length]; - realData_ = new char[length]; - - if (fakeData_ == NULL || realData_ == NULL) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Cannot allocate memory for the binary X " - << "authorization data.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot allocate memory for the binary X " - << "authorization data.\n"; - - goto AuthValidateCookieError; - } - - // - // Translate the real cookie from Hex data - // to its binary representation. - // - - unsigned int value; - - for (unsigned int i = 0; i < length; i++) - { - if (sscanf(realCookie_ + 2 * i, "%2x", &value) != 1) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Bad X authorization data in real " - << "cookie '" << realCookie_ << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Bad X authorization data in real cookie '" - << realCookie_ << "'.\n"; - - goto AuthValidateCookieError; - } - - realData_[i] = value; - - if (sscanf(fakeCookie_ + 2 * i, "%2x", &value) != 1) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Bad X authorization data in fake " - << "cookie '" << fakeCookie_ << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Bad X authorization data in fake cookie '" - << fakeCookie_ << "'.\n"; - - goto AuthValidateCookieError; - } - - fakeData_[i] = value; - } - - dataSize_ = length; - - #ifdef TEST - *logofs << "Auth: Validated real cookie '" - << realCookie_ << "' and fake cookie '" << fakeCookie_ - << "' with data with size " << dataSize_ << ".\n" - << logofs_flush; - - *logofs << "Auth: Ready to accept incoming connections.\n" - << logofs_flush; - #endif - - return 1; - -AuthValidateCookieError: - - delete [] fakeData_; - delete [] realData_; - - fakeData_ = NULL; - realData_ = NULL; - - dataSize_ = 0; - - return -1; -} - -int Auth::checkCookie(unsigned char *buffer) -{ - if (isValid() != 1) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Attempt to check the X cookie with " - << "invalid authorization data.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Attempt to check the X cookie with " - << "invalid authorization data.\n"; - - return -1; - } - - const char *protoName = "MIT-MAGIC-COOKIE-1"; - int protoSize = strlen(protoName); - - int matchedProtoSize; - int matchedDataSize; - - if (buffer[0] == 0x42) - { - // - // Byte order is MSB first. - // - - matchedProtoSize = 256 * buffer[6] + buffer[7]; - matchedDataSize = 256 * buffer[8] + buffer[9]; - } - else if (buffer[0] == 0x6c) - { - // - // Byte order is LSB first. - // - - matchedProtoSize = buffer[6] + 256 * buffer[7]; - matchedDataSize = buffer[8] + 256 * buffer[9]; - } - else - { - #ifdef WARNING - *logofs << "Auth: WARNING! Bad X connection data in the buffer.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Bad X connection data in the buffer.\n"; - - return -1; - } - - // - // Check if both the authentication protocol - // and the fake cookie match our data. - // - - int protoOffset = 12; - - #ifdef TEST - *logofs << "Auth: Received a protocol size of " - << matchedProtoSize << " bytes.\n" - << logofs_flush; - #endif - - if (matchedProtoSize != protoSize || - memcmp(buffer + protoOffset, protoName, protoSize) != 0) - { - #ifdef WARNING - *logofs << "Auth: WARNING! Protocol mismatch or no X " - << "authentication data.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Protocol mismatch or no X " - << "authentication data.\n"; - - return -1; - } - - int dataOffset = protoOffset + ((matchedProtoSize + 3) & ~3); - - #ifdef TEST - *logofs << "Auth: Received a data size of " - << matchedDataSize << " bytes.\n" - << logofs_flush; - #endif - - if (matchedDataSize != dataSize_ || - memcmp(buffer + dataOffset, fakeData_, dataSize_) != 0) - { - #ifdef WARNING - *logofs << "Auth: WARNING! Cookie mismatch in the X " - << "authentication data.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Cookie mismatch in the X " - << "authentication data.\n"; - - return -1; - } - - // - // Everything is OK. Replace the fake data. - // - - #ifdef TEST - *logofs << "Auth: Replacing fake X authentication data " - << "with the real data.\n" << logofs_flush; - #endif - - memcpy(buffer + dataOffset, realData_, dataSize_); - - return 1; -} - -void Auth::generateCookie(char *cookie) -{ - // - // Code is from the SSH implementation, except that - // we use a much weaker random number generator. - // This is not critical, anyway, as this is just a - // fake cookie. The X server doesn't have a cookie - // for the display, so it will ignore the value we - // feed to it. - // - - T_timestamp timer = getTimestamp(); - - srand((unsigned int) timer.tv_usec); - - unsigned int data = rand(); - - for (int i = 0; i < 16; i++) - { - if (i % 4 == 0) - { - data = rand(); - } - - snprintf(cookie + 2 * i, 3, "%02x", data & 0xff); - - data >>= 8; - } - - generatedCookie_ = 1; - - #ifdef TEST - *logofs << "Auth: Generated X cookie string '" - << cookie << "'.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/Auth.h b/nxcomp/Auth.h deleted file mode 100644 index d51d9a26f..000000000 --- a/nxcomp/Auth.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Auth_H -#define Auth_H - -#include "Timestamp.h" - -// -// Handle the forwarding of authorization credentials -// to the X server by replacing the fake cookie with -// the real cookie as it is read from the auth file. -// At the moment only the MIT-MAGIC-COOKIE-1 cookies -// are recognized. The implementation is based on the -// corresponding code found in the SSH client. -// - -class Auth -{ - public: - - // - // Must be created by passing the fake cookie that - // will be forwarded by the remote end and with the - // real X display that is going to be used for the - // session. - // - - Auth(char *display, char *cookie); - - ~Auth(); - - int isValid() - { - return (isTimestamp(last_) == 1 && fakeCookie_ != NULL && - *fakeCookie_ != '\0' && realCookie_ != NULL && - *realCookie_ != '\0' && fakeData_ != NULL && - realData_ != NULL && dataSize_ != 0); - } - - int isFake() const - { - return generatedCookie_; - } - - // - // Method called in the channel class to find if the - // provided cookie matches the fake one. If the data - // matches, the fake cookie is replaced with the real - // one. - // - - int checkCookie(unsigned char *buffer); - - protected: - - // - // Update the real cookie for the display. If called - // a further time, check if the auth file is changed - // and get the new cookie. - // - - int updateCookie(); - - // - // Find out which authorization file is to be used - // and query the cookie for the current display. - // - - int getCookie(); - - // - // Extract the binary data from the cookies so that - // data can be directly compared at the time it is - // taken from the X request. - // - - int validateCookie(); - - // - // Generate a fake random cookie and copy it to the - // provided string. - // - - void generateCookie(char *cookie); - - private: - - char *display_; - char *file_; - - T_timestamp last_; - - char *fakeCookie_; - char *realCookie_; - - char *fakeData_; - char *realData_; - - int dataSize_; - - int generatedCookie_; -}; - -#endif /* Auth_H */ diff --git a/nxcomp/Bitmap.cpp b/nxcomp/Bitmap.cpp deleted file mode 100644 index fbc34a55e..000000000 --- a/nxcomp/Bitmap.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Bitmap.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -int UnpackBitmap(T_geometry *geometry, unsigned char method, unsigned char *src_data, - int src_size, int dst_bpp, int dst_width, int dst_height, - unsigned char *dst_data, int dst_size) -{ - if (dst_bpp != 32) - { - #ifdef TEST - *logofs << "UnpackBitmap: Nothing to do with " - << "image of " << dst_bpp << " bits per plane " - << "and size " << src_size << ".\n" - << logofs_flush; - #endif - - if (src_size != dst_size) - { - #ifdef PANIC - *logofs << "UnpackBitmap: PANIC! Size mismatch with " - << src_size << " bytes in the source and " - << dst_size << " in the destination.\n" - << logofs_flush; - #endif - - return -1; - } - - memcpy(dst_data, src_data, src_size); - - return 1; - } - else if (src_size != dst_width * dst_height * 3 || - dst_size != dst_width * dst_height * 4) - { - #ifdef PANIC - *logofs << "UnpackBitmap: PANIC! Size mismatch with " - << src_size << " bytes in the source and " - << dst_size << " in the destination.\n" - << logofs_flush; - #endif - - return -1; - } - - /* - * Insert the 4th byte in the bitmap. - */ - - unsigned char *next_src = src_data; - unsigned char *next_dst = dst_data; - - if (geometry -> image_byte_order == LSBFirst) - { - while (next_src < src_data + src_size) - { - *next_dst++ = *next_src++; - *next_dst++ = *next_src++; - *next_dst++ = *next_src++; - - next_dst++; - } - } - else - { - while (next_src < src_data + src_size) - { - next_dst++; - - *next_dst++ = *next_src++; - *next_dst++ = *next_src++; - *next_dst++ = *next_src++; - } - } - - #ifdef TEST - *logofs << "UnpackBitmap: Unpacked " << src_size - << " bytes to a buffer of " << dst_size - << " with " << dst_bpp << " bits per plane.\n" - << logofs_flush; - #endif - - return 1; -} diff --git a/nxcomp/Bitmap.h b/nxcomp/Bitmap.h deleted file mode 100644 index 8143e3125..000000000 --- a/nxcomp/Bitmap.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Bitmap_H -#define Bitmap_H - -#include "Unpack.h" - -int UnpackBitmap(T_geometry *geometry, unsigned char method, - unsigned char *src_data, int src_size, int dst_bpp, - int dst_width, int dst_height, unsigned char *dst_data, - int dst_size); - -#endif /* Bitmap_H */ diff --git a/nxcomp/BlockCache.cpp b/nxcomp/BlockCache.cpp deleted file mode 100644 index 76f7fd797..000000000 --- a/nxcomp/BlockCache.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include "BlockCache.h" - - -int BlockCache::compare(unsigned int size, const unsigned char *data, - int overwrite) -{ - int match = 0; - if (size == size_) - { - match = 1; - for (unsigned int i = 0; i < size_; i++) - if (data[i] != buffer_[i]) - { - match = 0; - break; - } - } - if (!match && overwrite) - set(size, data); - return match; -} - - -void BlockCache::set(unsigned int size, const unsigned char *data) -{ - if (size_ < size) - { - delete[]buffer_; - buffer_ = new unsigned char[size]; - } - size_ = size; - memcpy(buffer_, data, size); - checksum_ = checksum(size, data); -} - - -unsigned int BlockCache::checksum(unsigned int size, const unsigned char *data) -{ - unsigned int sum = 0; - unsigned int shift = 0; - const unsigned char *next = data; - for (unsigned int i = 0; i < size; i++) - { - unsigned int value = (unsigned int) *next++; - sum += (value << shift); - shift++; - if (shift == 8) - shift = 0; - } - return sum; -} diff --git a/nxcomp/BlockCache.h b/nxcomp/BlockCache.h deleted file mode 100644 index 48e586966..000000000 --- a/nxcomp/BlockCache.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef BlockCache_H -#define BlockCache_H - - -// Cache to hold an arbitrary-length block of bytes - -class BlockCache -{ - public: - BlockCache():buffer_(0), size_(0), checksum_(0) - { - } - ~BlockCache() - { - delete[]buffer_; - } - int compare(unsigned int size, const unsigned char *data, - int overwrite = 1); - void set(unsigned int size, const unsigned char *data); - - unsigned int getLength() const - { - return size_; - } - unsigned int getChecksum() const - { - return checksum_; - } - const unsigned char *getData() const - { - return buffer_; - } - - static unsigned int checksum(unsigned int size, const unsigned char *data); - -private: - unsigned char *buffer_; - unsigned int size_; - unsigned int checksum_; -}; - -#endif /* BlockCache_H */ diff --git a/nxcomp/BlockCacheSet.cpp b/nxcomp/BlockCacheSet.cpp deleted file mode 100644 index 3fd5e1ac7..000000000 --- a/nxcomp/BlockCacheSet.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "BlockCacheSet.h" - - -BlockCacheSet::BlockCacheSet(unsigned int numCaches): - caches_(new BlockCache *[numCaches]), size_(numCaches), - length_(0) -{ - for (unsigned int i = 0; i < numCaches; i++) - caches_[i] = new BlockCache(); -} - - -BlockCacheSet::~BlockCacheSet() -{ - // - // TODO: There is still a strange segfault occurring - // at random time under Cygwin, when proxy is being - // shutdown. Problem appeared just after upgrading - // to the latest version of the Cygwin DLL. A stack - // trace, obtained at the last minute, reveals that - // failure happens in this destructor. - // - - #ifndef __CYGWIN32__ - - for (unsigned int i = 0; i < size_; i++) - delete caches_[i]; - delete[]caches_; - - #endif /* ifdef __CYGWIN32__ */ -} - - -int -BlockCacheSet::lookup(unsigned int dataLength, const unsigned char *data, - unsigned int &index) -{ - unsigned int checksum = BlockCache::checksum(dataLength, data); - for (unsigned int i = 0; i < length_; i++) - if ((caches_[i]->getChecksum() == checksum) && - (caches_[i]->compare(dataLength, data, 0))) - { - // match - index = i; - if (i) - { - BlockCache *save = caches_[i]; - unsigned int target = (i >> 1); - do - { - caches_[i] = caches_[i - 1]; - i--; - } - while (i > target); - caches_[target] = save; - } - return 1; - } - // no match - unsigned int insertionPoint = (length_ >> 1); - unsigned int start; - if (length_ >= size_) - start = size_ - 1; - else - { - start = length_; - length_++; - } - BlockCache *save = caches_[start]; - for (unsigned int k = start; k > insertionPoint; k--) - caches_[k] = caches_[k - 1]; - caches_[insertionPoint] = save; - save->set(dataLength, data); - return 0; -} - - -void -BlockCacheSet::get(unsigned index, unsigned int &size, - const unsigned char *&data) -{ - size = caches_[index]->getLength(); - data = caches_[index]->getData(); - if (index) - { - BlockCache *save = caches_[index]; - unsigned int target = (index >> 1); - do - { - caches_[index] = caches_[index - 1]; - index--; - } - while (index > target); - caches_[target] = save; - } -} - - - -void -BlockCacheSet::set(unsigned int dataLength, const unsigned char *data) -{ - unsigned int insertionPoint = (length_ >> 1); - unsigned int start; - if (length_ >= size_) - start = size_ - 1; - else - { - start = length_; - length_++; - } - BlockCache *save = caches_[start]; - for (unsigned int k = start; k > insertionPoint; k--) - caches_[k] = caches_[k - 1]; - caches_[insertionPoint] = save; - save->set(dataLength, data); -} diff --git a/nxcomp/BlockCacheSet.h b/nxcomp/BlockCacheSet.h deleted file mode 100644 index 97273b0e0..000000000 --- a/nxcomp/BlockCacheSet.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef BlockCacheSet_H -#define BlockCacheSet_H - -#include "BlockCache.h" - - -class BlockCacheSet -{ - public: - BlockCacheSet(unsigned int numCaches); - ~BlockCacheSet(); - - int lookup(unsigned int size, const unsigned char *data, - unsigned int &index); - void get(unsigned int index, unsigned int &size, const unsigned char *&data); - void set(unsigned int size, const unsigned char *data); - - private: - BlockCache ** caches_; - unsigned int size_; - unsigned int length_; -}; - -#endif /* BlockCacheSet_H */ diff --git a/nxcomp/ChangeGC.cpp b/nxcomp/ChangeGC.cpp deleted file mode 100644 index f06984a10..000000000 --- a/nxcomp/ChangeGC.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ChangeGC.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int ChangeGCStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ChangeGCMessage *changeGC = (ChangeGCMessage *) message; - - // - // Here is the fingerprint. - // - - changeGC -> gcontext = GetULONG(buffer + 4, bigEndian); - changeGC -> value_mask = GetULONG(buffer + 8, bigEndian); - - // - // Clear the unused bytes carried in the - // payload to increase the effectiveness - // of the caching algorithm. - // - - if ((int) size > dataOffset) - { - #ifdef DEBUG - *logofs << name() << ": Removing unused bytes from the " - << "data payload.\n" << logofs_flush; - #endif - - changeGC -> value_mask &= (1 << 23) - 1; - - unsigned int mask = 0x1; - unsigned char *source = (unsigned char *) buffer + CHANGEGC_DATA_OFFSET; - unsigned long value = 0; - - for (unsigned int i = 0; i < 23; i++) - { - if (changeGC -> value_mask & mask) - { - value = GetULONG(source, bigEndian); - - value &= (0xffffffff >> (32 - CREATEGC_FIELD_WIDTH[i])); - - PutULONG(value, source, bigEndian); - - source += 4; - } - - mask <<= 1; - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ChangeGCStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ChangeGCMessage *changeGC = (ChangeGCMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(changeGC -> gcontext, buffer + 4, bigEndian); - PutULONG(changeGC -> value_mask, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void ChangeGCStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - ChangeGCMessage *changeGC = (ChangeGCMessage *) message; - - *logofs << name() << ": Identity gcontext " << changeGC -> gcontext - << ", mask " << changeGC -> value_mask << ", size " - << changeGC -> size_ << ".\n" << logofs_flush; - #endif -} - -void ChangeGCStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -/* - md5_append(md5_state_, buffer + 4, 8); -*/ - md5_append(md5_state_, buffer + 8, 4); -} - -void ChangeGCStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - ChangeGCMessage *changeGC = (ChangeGCMessage *) message; - ChangeGCMessage *cachedChangeGC = (ChangeGCMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << changeGC -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(changeGC -> gcontext, clientCache -> gcCache); - - cachedChangeGC -> gcontext = changeGC -> gcontext; -} - -void ChangeGCStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - ChangeGCMessage *changeGC = (ChangeGCMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - changeGC -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << changeGC -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/ChangeGC.h b/nxcomp/ChangeGC.h deleted file mode 100644 index 9cac90e66..000000000 --- a/nxcomp/ChangeGC.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ChangeGC_H -#define ChangeGC_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define CHANGEGC_ENABLE_CACHE 1 -#define CHANGEGC_ENABLE_DATA 0 -#define CHANGEGC_ENABLE_SPLIT 0 -#define CHANGEGC_ENABLE_COMPRESS 0 - -#define CHANGEGC_DATA_LIMIT 144 -#define CHANGEGC_DATA_OFFSET 12 - -#define CHANGEGC_CACHE_SLOTS 3000 -#define CHANGEGC_CACHE_THRESHOLD 3 -#define CHANGEGC_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class ChangeGCMessage : public Message -{ - friend class ChangeGCStore; - - public: - - ChangeGCMessage() - { - } - - ~ChangeGCMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int gcontext; - unsigned int value_mask; -}; - -class ChangeGCStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - ChangeGCStore() : MessageStore() - { - enableCache = CHANGEGC_ENABLE_CACHE; - enableData = CHANGEGC_ENABLE_DATA; - enableSplit = CHANGEGC_ENABLE_SPLIT; - enableCompress = CHANGEGC_ENABLE_COMPRESS; - - dataLimit = CHANGEGC_DATA_LIMIT; - dataOffset = CHANGEGC_DATA_OFFSET; - - cacheSlots = CHANGEGC_CACHE_SLOTS; - cacheThreshold = CHANGEGC_CACHE_THRESHOLD; - cacheLowerThreshold = CHANGEGC_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~ChangeGCStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "ChangeGC"; - } - - virtual unsigned char opcode() const - { - return X_ChangeGC; - } - - virtual unsigned int storage() const - { - return sizeof(ChangeGCMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new ChangeGCMessage(); - } - - virtual Message *create(const Message &message) const - { - return new ChangeGCMessage((const ChangeGCMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (ChangeGCMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; -}; - -#endif /* ChangeGC_H */ diff --git a/nxcomp/ChangeProperty.cpp b/nxcomp/ChangeProperty.cpp deleted file mode 100644 index dbfb8f5d7..000000000 --- a/nxcomp/ChangeProperty.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ChangeProperty.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int ChangePropertyStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; - - changeProperty -> mode = *(buffer + 1); - changeProperty -> format = *(buffer + 16); - - changeProperty -> window = GetULONG(buffer + 4, bigEndian); - changeProperty -> property = GetULONG(buffer + 8, bigEndian); - changeProperty -> type = GetULONG(buffer + 12, bigEndian); - changeProperty -> length = GetULONG(buffer + 20, bigEndian); - - // - // Cleanup the padding bytes. - // - - unsigned int uiFormat; - unsigned int uiLengthInBytes; - - if ((int) size > CHANGEPROPERTY_DATA_OFFSET) - { - uiFormat = *(buffer + 16); - - uiLengthInBytes = changeProperty -> length; - - #ifdef DEBUG - *logofs << name() << ": length " << uiLengthInBytes - << ", format " << uiFormat << ", size " - << size << ".\n" << logofs_flush; - #endif - - if (uiFormat == 16) - { - uiLengthInBytes <<= 1; - } - else if (uiFormat == 32) - { - uiLengthInBytes <<= 2; - } - - unsigned char *end = ((unsigned char *) buffer) + size; - unsigned char *pad = ((unsigned char *) buffer) + CHANGEPROPERTY_DATA_OFFSET + uiLengthInBytes; - - CleanData((unsigned char *) pad, end - pad); - } - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ChangePropertyStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; - - *(buffer + 1) = changeProperty -> mode; - *(buffer + 16) = changeProperty -> format; - - PutULONG(changeProperty -> window, buffer + 4, bigEndian); - PutULONG(changeProperty -> property, buffer + 8, bigEndian); - PutULONG(changeProperty -> type, buffer + 12, bigEndian); - PutULONG(changeProperty -> length, buffer + 20, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void ChangePropertyStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; - - *logofs << name() << ": Identity mode " << (unsigned int) changeProperty -> mode << ", format " - << (unsigned int) changeProperty -> format << ", window " << changeProperty -> window - << ", property " << changeProperty -> property << ", type " << changeProperty -> type - << ", length " << changeProperty -> length << ", size " << changeProperty -> size_ - << ".\n" << logofs_flush; - - #endif -} - -void ChangePropertyStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 16, 1); - - md5_append(md5_state_, buffer + 8, 4); - md5_append(md5_state_, buffer + 12, 4); - md5_append(md5_state_, buffer + 20, 4); -} - -void ChangePropertyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; - ChangePropertyMessage *cachedChangeProperty = (ChangePropertyMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << changeProperty -> window - << " as window field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(changeProperty -> window, clientCache -> windowCache); - - cachedChangeProperty -> window = changeProperty -> window; -} - -void ChangePropertyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> windowCache); - - changeProperty -> window = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << changeProperty -> window - << " as window field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/ChangeProperty.h b/nxcomp/ChangeProperty.h deleted file mode 100644 index c06ce10fc..000000000 --- a/nxcomp/ChangeProperty.h +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ChangeProperty_H -#define ChangeProperty_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define CHANGEPROPERTY_ENABLE_CACHE 1 -#define CHANGEPROPERTY_ENABLE_DATA 0 -#define CHANGEPROPERTY_ENABLE_SPLIT 0 -#define CHANGEPROPERTY_ENABLE_COMPRESS 0 - -#define CHANGEPROPERTY_DATA_LIMIT 28688 -#define CHANGEPROPERTY_DATA_OFFSET 24 - -#define CHANGEPROPERTY_CACHE_SLOTS 2000 -#define CHANGEPROPERTY_CACHE_THRESHOLD 2 -#define CHANGEPROPERTY_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class ChangePropertyMessage : public Message -{ - friend class ChangePropertyStore; - - public: - - ChangePropertyMessage() - { - } - - ~ChangePropertyMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char mode; - unsigned char format; - unsigned int window; - unsigned int property; - unsigned int type; - unsigned int length; -}; - -class ChangePropertyStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - ChangePropertyStore() : MessageStore() - { - enableCache = CHANGEPROPERTY_ENABLE_CACHE; - enableData = CHANGEPROPERTY_ENABLE_DATA; - enableSplit = CHANGEPROPERTY_ENABLE_SPLIT; - enableCompress = CHANGEPROPERTY_ENABLE_COMPRESS; - - dataLimit = CHANGEPROPERTY_DATA_LIMIT; - dataOffset = CHANGEPROPERTY_DATA_OFFSET; - - cacheSlots = CHANGEPROPERTY_CACHE_SLOTS; - cacheThreshold = CHANGEPROPERTY_CACHE_THRESHOLD; - cacheLowerThreshold = CHANGEPROPERTY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~ChangePropertyStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "ChangeProperty"; - } - - virtual unsigned char opcode() const - { - return X_ChangeProperty; - } - - virtual unsigned int storage() const - { - return sizeof(ChangePropertyMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new ChangePropertyMessage(); - } - - virtual Message *create(const Message &message) const - { - return new ChangePropertyMessage((const ChangePropertyMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (ChangePropertyMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* ChangeProperty_H */ diff --git a/nxcomp/Channel.cpp b/nxcomp/Channel.cpp deleted file mode 100644 index 41a09e951..000000000 --- a/nxcomp/Channel.cpp +++ /dev/null @@ -1,2035 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Channel.h" - -#include "List.h" -#include "Proxy.h" -#include "Statistics.h" - -#include "StaticCompressor.h" - -#include "NXalert.h" - -extern Proxy *proxy; - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Log the operations related to splits. -// - -#undef SPLIT - -#undef COUNT - -#define COUNT_MAJOR_OPCODE 154 - -#undef MONITOR - -#define MONITOR_MAJOR_OPCODE 154 -#define MONITOR_MINOR_OPCODE 23 - -#undef CLEAR - -#define CLEAR_MAJOR_OPCODE 154 -#define CLEAR_MINOR_OPCODE 23 - -// -// Define this to know how many messages -// are allocated and deallocated. -// - -#undef REFERENCES - -// -// Set to the descriptor of the first X -// channel successfully connected. -// - -int Channel::firstClient_ = -1; - -// -// Port used for font server connections. -// - -int Channel::fontPort_ = -1; - -// -// This is used for reference count. -// - -#ifdef REFERENCES - -int Channel::references_ = 0; - -#endif - -Channel::Channel(Transport *transport, StaticCompressor *compressor) - - : transport_(transport), compressor_(compressor) -{ - fd_ = transport_ -> fd(); - - finish_ = 0; - closing_ = 0; - drop_ = 0; - congestion_ = 0; - priority_ = 0; - - alert_ = 0; - - firstRequest_ = 1; - firstReply_ = 1; - - enableCache_ = 1; - enableSplit_ = 1; - enableSave_ = 1; - enableLoad_ = 1; - - // - // Must be set by proxy. - // - - opcodeStore_ = NULL; - - clientStore_ = NULL; - serverStore_ = NULL; - - clientCache_ = NULL; - serverCache_ = NULL; - - #ifdef REFERENCES - *logofs << "Channel: Created new Channel at " - << this << " out of " << ++references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -Channel::~Channel() -{ - if (firstClient_ == fd_) - { - firstClient_ = -1; - } - - #ifdef REFERENCES - *logofs << "Channel: Deleted Channel at " - << this << " out of " << --references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -int Channel::handleEncode(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, - MessageStore *store, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - #ifdef MONITOR - - static float totalMessages = 0; - static float totalBits = 0; - - int bits; - int diff; - - bits = encodeBuffer.getBits(); - - #endif - - // - // Check if message can be differentially - // encoded using a similar message in the - // message store. - // - - #ifdef COUNT - - if (*(buffer) == COUNT_MAJOR_OPCODE) - { - if (*(buffer) < 128) - { - *logofs << "handleEncode: Handling OPCODE#" << (unsigned int) *(buffer) - << ".\n" << logofs_flush; - } - else - { - *logofs << "handleEncode: Handling OPCODE#" << (unsigned int) *(buffer) - << " MINOR#" << (unsigned int) *(buffer + 1) << ".\n" - << logofs_flush; - } - } - - #endif - - #ifdef CLEAR - - if (*(buffer) == CLEAR_MAJOR_OPCODE && - (CLEAR_MINOR_OPCODE == -1 || *(buffer + 1) == CLEAR_MINOR_OPCODE)) - { - *((unsigned char *) buffer) = X_NoOperation; - - *((unsigned char *) buffer + 1) = '\0'; - - CleanData((unsigned char *) buffer + 4, size - 4); - } - - #endif - - if (handleEncodeCached(encodeBuffer, channelCache, - store, buffer, size) == 1) - { - #ifdef MONITOR - - diff = encodeBuffer.getBits() - bits; - - if (*(buffer) == MONITOR_MAJOR_OPCODE && - (MONITOR_MINOR_OPCODE == -1 || *(buffer + 1) == MONITOR_MINOR_OPCODE)) - { - totalMessages++; - - totalBits += diff; - - *logofs << "handleEncode: Handled cached OPCODE#" << (unsigned int) *(buffer) - << " MINOR#" << (unsigned int) *(buffer + 1) << ". " << size - << " bytes in, " << diff << " bits (" << ((float) diff) / 8 - << " bytes) out. Average " << totalBits / totalMessages - << "/1.\n" << logofs_flush; - } - - #endif - - // - // Let the channel update the split store - // and notify the agent in the case of a - // cache hit. - // - - if (store -> enableSplit) - { - handleSplit(encodeBuffer, store, store -> lastAction, - store -> lastHit, opcode, buffer, size); - } - - return 1; - } - - // - // A similar message could not be found in - // cache or message must be discarded. Must - // transmit the message using the field by - // field differential encoding. - // - - handleEncodeIdentity(encodeBuffer, channelCache, - store, buffer, size, bigEndian_); - - // - // Check if message has a distinct data part. - // - - if (store -> enableData) - { - // - // If message split was requested by agent then send data - // out-of-band, dividing it in small chunks. Until message - // is completely transferred, keep in the split store a - // dummy version of the message, with data replaced with a - // pattern. - // - // While data is being transferred, agent should have put - // the resource (for example its client) asleep. It can - // happen, though, that a different client would reference - // the same message. We cannot issue a cache hit for images - // being split (such images are put in store in 'incomplete' - // state), so we need to handle this case. - // - - if (store -> enableSplit == 1) - { - // - // Let the channel decide what to do with the - // message. If the split can't take place be- - // cause the split store is full, the channel - // will tell the remote side that the data is - // going to follow. - // - - if (handleSplit(encodeBuffer, store, store -> lastAction, - (store -> lastAction == IS_ADDED ? store -> lastAdded : 0), - opcode, buffer, size) == 1) - { - #ifdef MONITOR - - diff = encodeBuffer.getBits() - bits; - - if (*(buffer) == MONITOR_MAJOR_OPCODE && - (MONITOR_MINOR_OPCODE == -1 || *(buffer + 1) == MONITOR_MINOR_OPCODE)) - { - totalMessages++; - - totalBits += diff; - - *logofs << "handleEncode: Handled split OPCODE#" << (unsigned int) *(buffer) - << " MINOR#" << (unsigned int) *(buffer + 1) << ". " << size - << " bytes in, " << diff << " bits (" << ((float) diff) / 8 - << " bytes) out. Average " << totalBits / totalMessages - << "/1.\n" << logofs_flush; - } - - #endif - - return 0; - } - } - - // - // The split did not take place and we are going - // to transfer the data part. Check if the static - // compression of the data section is enabled. - // This is the case of all messages not having a - // special differential encoding or messages that - // we want to store in cache in compressed form. - // - - unsigned int offset = store -> identitySize(buffer, size); - - if (store -> enableCompress) - { - unsigned char *data = NULL; - unsigned int dataSize = 0; - - int compressed = handleCompress(encodeBuffer, opcode, offset, - buffer, size, data, dataSize); - if (compressed < 0) - { - return -1; - } - else if (compressed > 0) - { - // - // Update the size of the message according - // to the result of the data compression. - // - - handleUpdate(store, size - offset, dataSize); - } - } - else - { - handleCopy(encodeBuffer, opcode, offset, buffer, size); - } - } - - #ifdef MONITOR - - diff = encodeBuffer.getBits() - bits; - - if (*(buffer) == MONITOR_MAJOR_OPCODE && - (MONITOR_MINOR_OPCODE == -1 || *(buffer + 1) == MONITOR_MINOR_OPCODE)) - { - totalMessages++; - - totalBits += diff; - - *logofs << "handleEncode: Handled OPCODE#" << (unsigned int) *(buffer) - << " MINOR#" << (unsigned int) *(buffer + 1) << ". " << size - << " bytes in, " << diff << " bits (" << ((float) diff) / 8 - << " bytes) out. Average " << totalBits / totalMessages - << "/1.\n" << logofs_flush; - } - - #endif - - return 0; -} - -int Channel::handleDecode(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, - MessageStore *store, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - // - // Check first if the message is in the - // message store. - // - - unsigned int split = 0; - - if (handleDecodeCached(decodeBuffer, channelCache, - store, buffer, size) == 1) - { - // - // Let the channel update the split store - // in the case of a message being cached. - // - - if (store -> enableSplit == 1) - { - // Since ProtoStep7 (#issue 108) - #ifdef DEBUG - *logofs << "handleDecode: " << store -> name() - << ": Checking if the message was split.\n" - << logofs_flush; - #endif - - decodeBuffer.decodeBoolValue(split); - - if (split == 1) - { - handleSplit(decodeBuffer, store, store -> lastAction, - store -> lastHit, opcode, buffer, size); - - handleCleanAndNullRequest(opcode, buffer, size); - } - } - - return 1; - } - - // - // Decode the full identity. - // - - handleDecodeIdentity(decodeBuffer, channelCache, store, buffer, - size, bigEndian_, &writeBuffer_); - - // - // Check if the message has a distinct - // data part. - // - - if (store -> enableData) - { - // - // Check if message has been split. - // - - if (store -> enableSplit) - { - #ifdef DEBUG - *logofs << "handleDecode: " << store -> name() - << ": Checking if the message was split.\n" - << logofs_flush; - #endif - - decodeBuffer.decodeBoolValue(split); - - if (split == 1) - { - // - // If the message was added to the store, - // create the entry without the data part. - // - - handleSaveSplit(store, buffer, size); - - handleSplit(decodeBuffer, store, store -> lastAction, - (store -> lastAction == IS_ADDED ? store -> lastAdded : 0), - opcode, buffer, size); - - handleCleanAndNullRequest(opcode, buffer, size); - - return 0; - } - } - - // - // Decode the data part. - // - - unsigned int offset = store -> identitySize(buffer, size); - - if (store -> enableCompress) - { - const unsigned char *data = NULL; - unsigned int dataSize = 0; - - int decompressed = handleDecompress(decodeBuffer, opcode, offset, - buffer, size, data, dataSize); - if (decompressed < 0) - { - return -1; - } - else if (decompressed > 0) - { - // - // The message has been transferred - // in compressed format. - // - - handleSave(store, buffer, size, data, dataSize); - - if (store -> enableSplit) - { - if (split == 1) - { - handleSplit(decodeBuffer, store, store -> lastAction, - (store -> lastAction == IS_ADDED ? store -> lastAdded : 0), - opcode, buffer, size); - - handleCleanAndNullRequest(opcode, buffer, size); - } - } - - return 0; - } - } - else - { - // - // Static compression of the data part - // was not enabled for this message. - // - - handleCopy(decodeBuffer, opcode, offset, buffer, size); - } - } - - // - // The message doesn't have a data part - // or the data was not compressed. - // - - handleSave(store, buffer, size); - - if (store -> enableSplit) - { - if (split == 1) - { - handleSplit(decodeBuffer, store, store -> lastAction, - (store -> lastAction == IS_ADDED ? store -> lastAdded : 0), - opcode, buffer, size); - - handleCleanAndNullRequest(opcode, buffer, size); - } - } - - return 0; -} - -int Channel::handleEncodeCached(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, - MessageStore *store, const unsigned char *buffer, - const unsigned int size) -{ - if (control -> LocalDeltaCompression == 0 || - enableCache_ == 0 || store -> enableCache == 0) - { - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeActionValue(is_discarded, - store -> lastActionCache); - - store -> lastAction = is_discarded; - - return 0; - } - - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() - << ": Going to handle a new message of this class.\n" - << logofs_flush; - #endif - - // - // Check if the estimated size of cache is greater - // than the requested limit. If it is the case make - // some room by deleting one or more messages. - // - - int position; - - while (mustCleanStore(store) == 1 && canCleanStore(store) == 1) - { - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() - << ": Trying to reduce size of message store.\n" - << logofs_flush; - #endif - - position = store -> clean(use_checksum); - - if (position == nothing) - { - #ifdef TEST - *logofs << "handleEncodeCached: " << store -> name() - << ": WARNING! No message found to be " - << "actually removed.\n" << logofs_flush; - #endif - - break; - } - - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() - << ": Message at position " << position - << " will be removed.\n" << logofs_flush; - #endif - - // - // Encode the position of message to - // be discarded. - // - - store -> lastRemoved = position; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeActionValue(is_removed, store -> lastRemoved, - store -> lastActionCache); - - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() << ": Going to " - << "clean up message at position " << position << ".\n" - << logofs_flush; - #endif - - store -> remove(position, use_checksum, discard_data); - - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() << ": There are " - << store -> getSize() << " messages in the store out of " - << store -> cacheSlots << " slots.\n" << logofs_flush; - - *logofs << "handleEncodeCached: " << store -> name() - << ": Size of store is " << store -> getLocalStorageSize() - << " bytes locally and " << store -> getRemoteStorageSize() - << " bytes remotely.\n" << logofs_flush; - - *logofs << "handleEncodeCached: " << store -> name() - << ": Size of total cache is " << store -> getLocalTotalStorageSize() - << " bytes locally and " << store -> getRemoteTotalStorageSize() - << " bytes remotely.\n" << logofs_flush; - #endif - } - - #ifdef DEBUG - - if (mustCleanStore(store) == 1 && canCleanStore(store) == 0) - { - *logofs << "handleEncodeCached: " << store -> name() - << ": Store would need a clean but operation will be delayed.\n" - << logofs_flush; - - *logofs << "handleEncodeCached: " << store -> name() << ": There are " - << store -> getSize() << " messages in the store out of " - << store -> cacheSlots << " slots.\n" << logofs_flush; - - *logofs << "handleEncodeCached: " << store -> name() - << ": Size of store is " << store -> getLocalStorageSize() - << " bytes locally and " << store -> getRemoteStorageSize() - << " bytes remotely.\n" << logofs_flush; - - *logofs << "handleEncodeCached: " << store -> name() - << ": Size of total cache is " << store -> getLocalTotalStorageSize() - << " bytes locally and " << store -> getRemoteTotalStorageSize() - << " bytes remotely.\n" << logofs_flush; - } - - #endif - - // - // If 'on the wire' size of message exceeds the - // allowed limit then avoid to store it in the - // cache. - // - - if (store -> validateMessage(buffer, size) == 0) - { - #ifdef TEST - *logofs << "handleEncodeCached: " << store -> name() - << ": Message with size " << size << " ignored.\n" - << logofs_flush; - #endif - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeActionValue(is_discarded, - store -> lastActionCache); - - store -> lastAction = is_discarded; - - return 0; - } - - // - // Fill the message object with the - // received data. - // - - Message *message = store -> getTemporary(); - - if (message == NULL) - { - #ifdef PANIC - *logofs << "handleEncodeCached: " << store -> name() - << ": PANIC! Can't allocate memory for " - << "a new message.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "a new message in context [D].\n"; - - HandleCleanup(); - } - - // - // As we are at encoding side, it is enough to store the - // checksum for the object while data can be erased. Both - // the identity and the data will never be sent through - // the wire again as long as they are stored in the cache - // at the decoding side. The split parameter is always - // set to 0 as the data will not be stored in any case. - // - - store -> parse(message, 0, buffer, size, use_checksum, - discard_data, bigEndian_); - - #ifdef DUMP - - store -> dump(message); - - #endif - - // - // Search the object in the message - // store. If found get the position. - // - - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() - << ": Searching object of size " << size - << " in the cache.\n" << logofs_flush; - #endif - - int added; - int locked; - - position = store -> findOrAdd(message, use_checksum, - discard_data, added, locked); - - if (position == nothing) - { - #ifdef WARNING - *logofs << "handleEncodeCached: " << store -> name() - << ": WARNING! Can't store object in the cache.\n" - << logofs_flush; - #endif - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeActionValue(is_discarded, - store -> lastActionCache); - - store -> lastAction = is_discarded; - - return 0; - } - else if (locked == 1) - { - // - // We can't issue a cache hit. Encoding identity - // differences while message it's being split - // would later result in agent to commit a wrong - // version of message. - // - - #ifdef WARNING - *logofs << "handleEncodeCached: " << store -> name() - << ": WARNING! Message of size " << store -> plainSize(position) - << " at position " << position << " is locked.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Message of size " << store -> plainSize(position) - << " at position " << position << " is locked.\n"; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeActionValue(is_discarded, - store -> lastActionCache); - - store -> lastAction = is_discarded; - - return 0; - } - else if (added == 1) - { - store -> resetTemporary(); - - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() << ": Message of size " - << store -> plainSize(position) << " has been stored at position " - << position << ".\n" << logofs_flush; - - *logofs << "handleEncodeCached: " << store -> name() << ": There are " - << store -> getSize() << " messages in the store out of " - << store -> cacheSlots << " slots.\n" << logofs_flush; - - *logofs << "handleEncodeCached: " << store -> name() - << ": Size of store is " << store -> getLocalStorageSize() - << " bytes locally and " << store -> getRemoteStorageSize() - << " bytes remotely.\n" << logofs_flush; - - *logofs << "handleEncodeCached: " << store -> name() - << ": Size of total cache is " << store -> getLocalTotalStorageSize() - << " bytes locally and " << store -> getRemoteTotalStorageSize() - << " bytes remotely.\n" << logofs_flush; - #endif - - // - // Inform the decoding side that message - // must be inserted in cache and encode - // the position where the insertion took - // place. - // - - store -> lastAction = IS_ADDED; - - store -> lastAdded = position; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeActionValue(IS_ADDED, store -> lastAdded, - store -> lastActionCache); - - return 0; - } - else - { - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() - << ": Cache hit. Found object at position " - << position << ".\n" << logofs_flush; - #endif - - // - // Must abort the connection if the - // the position is invalid. - // - - Message *cachedMessage = store -> get(position); - - // - // Increase the rating of the cached - // message. - // - - store -> touch(cachedMessage); - - #ifdef DEBUG - *logofs << "handleEncodeCached: " << store -> name() << ": Hits for " - << "object at position " << position << " are now " - << store -> getTouches(position) << ".\n" - << logofs_flush; - #endif - - // - // Send to the decoding side position - // where object can be found in cache. - // - - store -> lastAction = IS_HIT; - - store -> lastHit = position; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeActionValue(IS_HIT, store -> lastHit, - store -> lastActionCache); - - // - // Send the field by field differences in - // respect to the original message stored - // in cache. - // - - store -> updateIdentity(encodeBuffer, message, cachedMessage, channelCache); - - return 1; - } -} - -void Channel::handleUpdateAdded(MessageStore *store, unsigned int dataSize, - unsigned int compressedDataSize) -{ - #ifdef TEST - - if (store -> lastAction != IS_ADDED) - { - #ifdef PANIC - *logofs << "handleUpdateAdded: " << store -> name() - << ": PANIC! Function called for action '" - << store -> lastAction << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Update function called for " - << "store '" << store -> name() << "' with " - << "action '" << store -> lastAction - << "'.\n"; - - HandleCleanup(); - } - - #endif - - #ifdef DEBUG - *logofs << "handleUpdateAdded: " << store -> name() << ": Updating " - << "object at position " << store -> lastAdded << " of size " - << store -> plainSize(store -> lastAdded) << " (" << dataSize - << "/" << compressedDataSize << ").\n" << logofs_flush; - #endif - - store -> updateData(store -> lastAdded, dataSize, compressedDataSize); - - #ifdef DEBUG - *logofs << "handleUpdateAdded: " << store -> name() << ": There are " - << store -> getSize() << " messages in the store out of " - << store -> cacheSlots << " slots.\n" << logofs_flush; - - *logofs << "handleUpdateAdded: " << store -> name() - << ": Size of store is " << store -> getLocalStorageSize() - << " bytes locally and " << store -> getRemoteStorageSize() - << " bytes remotely.\n" << logofs_flush; - - *logofs << "handleUpdateAdded: " << store -> name() - << ": Size of total cache is " << store -> getLocalTotalStorageSize() - << " bytes locally and " << store -> getRemoteTotalStorageSize() - << " bytes remotely.\n" << logofs_flush; - #endif -} - -int Channel::handleDecodeCached(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, - MessageStore *store, unsigned char *&buffer, - unsigned int &size) -{ - // - // Create a new message object and - // fill it with received data. - // - - #ifdef DEBUG - *logofs << "handleDecodeCached: " << store -> name() - << ": Going to handle a new message of this class.\n" - << logofs_flush; - #endif - - // - // Decode bits telling how to handle - // this message. - // - - unsigned char action; - unsigned short int position; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeActionValue(action, position, - store -> lastActionCache); - - // - // Clean operations must always come - // before any operation on message. - // - - while (action == is_removed) - { - // Since ProtoStep7 (#issue 108) - store -> lastRemoved = position; - - #ifdef DEBUG - - if (store -> get(store -> lastRemoved)) - { - *logofs << "handleDecodeCached: " << store -> name() << ": Cleaning up " - << "object at position " << store -> lastRemoved - << " of size " << store -> plainSize(store -> lastRemoved) - << " (" << store -> plainSize(store -> lastRemoved) << "/" - << store -> compressedSize(store -> lastRemoved) << ").\n" - << logofs_flush; - } - - #endif - - // - // If the message can't be found we - // will abort the connection. - // - - store -> remove(store -> lastRemoved, discard_checksum, use_data); - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeActionValue(action, position, - store -> lastActionCache); - } - - // - // If it's a cache hit, the position - // where object can be found follows. - // - - if ((T_store_action) action == IS_HIT) - { - // Since ProtoStep7 (#issue 108) - store -> lastHit = position; - - // - // Get data from the cache at given position. - // - - #ifdef DEBUG - - if (store -> get(store -> lastHit)) - { - *logofs << "handleDecodeCached: " << store -> name() << ": Retrieving " - << "object at position " << store -> lastHit - << " of size " << store -> plainSize(store -> lastHit) - << " (" << store -> plainSize(store -> lastHit) << "/" - << store -> compressedSize(store -> lastHit) << ").\n" - << logofs_flush; - } - - #endif - - // - // Must abort the connection if the - // the position is invalid. - // - - Message *message = store -> get(store -> lastHit); - - // - // Make room for the outgoing message. - // - - size = store -> plainSize(store -> lastHit); - - buffer = writeBuffer_.addMessage(size); - - #ifdef DEBUG - *logofs << "handleDecodeCached: " << store -> name() - << ": Prepared an outgoing buffer of " - << size << " bytes.\n" << logofs_flush; - #endif - - // - // Decode the variant part. Pass client - // or server cache to the message store. - // - - store -> updateIdentity(decodeBuffer, message, channelCache); - - // - // Write each field in the outgoing buffer. - // - - store -> unparse(message, buffer, size, bigEndian_); - - #ifdef DUMP - - store -> dump(message); - - #endif - - store -> lastAction = IS_HIT; - - return 1; - } - else if ((T_store_action) action == IS_ADDED) - { - // Since ProtoStep7 (#issue 108) - store -> lastAdded = position; - - #ifdef DEBUG - *logofs << "handleDecodeCached: " << store -> name() - << ": Message will be later stored at position " - << store -> lastAdded << ".\n" << logofs_flush; - #endif - - store -> lastAction = IS_ADDED; - - return 0; - } - else - { - #ifdef DEBUG - *logofs << "handleDecodeCached: " << store -> name() - << ": Message will be later discarded.\n" - << logofs_flush; - #endif - - store -> lastAction = is_discarded; - - return 0; - } -} - -void Channel::handleSaveAdded(MessageStore *store, int split, unsigned char *buffer, - unsigned int size, const unsigned char *compressedData, - const unsigned int compressedDataSize) -{ - #ifdef TEST - - if (store -> lastAction != IS_ADDED) - { - #ifdef PANIC - *logofs << "handleSaveAdded: " << store -> name() - << ": PANIC! Function called for action '" - << store -> lastAction << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Save function called for " - << "store '" << store -> name() << "' with " - << "action '" << store -> lastAction - << "'.\n"; - - HandleCleanup(); - } - - #endif - - Message *message = store -> getTemporary(); - - if (message == NULL) - { - #ifdef PANIC - *logofs << "handleSaveAdded: " << store -> name() - << ": PANIC! Can't access temporary storage " - << "for message at position " << store -> lastAdded - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't access temporary storage " - << "for message at position " << store -> lastAdded - << ".\n"; - - HandleCleanup(); - } - - if (compressedData == NULL) - { - // - // If the data part has been split - // avoid to copy it into the message. - // - - store -> parse(message, split, buffer, size, discard_checksum, - use_data, bigEndian_); - } - else - { - store -> parse(message, buffer, size, compressedData, - compressedDataSize, discard_checksum, - use_data, bigEndian_); - } - - if (store -> add(message, store -> lastAdded, - discard_checksum, use_data) == nothing) - { - #ifdef PANIC - *logofs << "handleSaveAdded: " << store -> name() - << ": PANIC! Can't store message in the cache " - << "at position " << store -> lastAdded << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't store message of type " - << store -> name() << "in the cache at position " - << store -> lastAdded << ".\n"; - - HandleCleanup(); - } - else - { - store -> resetTemporary(); - - #ifdef DEBUG - *logofs << "handleSaveAdded: " << store -> name() << ": Stored " - << (compressedData == NULL ? "plain" : "compressed") - << " object at position " << store -> lastAdded - << " of size " << store -> plainSize(store -> lastAdded) - << " (" << store -> plainSize(store -> lastAdded) << "/" - << store -> compressedSize(store -> lastAdded) << ").\n" - << logofs_flush; - #endif - } - - #ifdef DEBUG - *logofs << "handleSaveAdded: " << store -> name() - << ": Size of store is " << store -> getLocalStorageSize() - << " bytes locally and " << store -> getRemoteStorageSize() - << " bytes remotely.\n" << logofs_flush; - - *logofs << "handleSaveAdded: " << store -> name() - << ": Size of total cache is " << store -> getLocalTotalStorageSize() - << " bytes locally and " << store -> getRemoteTotalStorageSize() - << " bytes remotely.\n" << logofs_flush; - #endif -} - -int Channel::handleWait(int timeout) -{ - #ifdef TEST - *logofs << "handleWait: Going to wait for more data " - << "on FD#" << fd_ << " at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - T_timestamp startTs = getNewTimestamp(); - - T_timestamp nowTs = startTs; - - int readable; - int remaining; - - for (;;) - { - remaining = timeout - diffTimestamp(startTs, nowTs); - - if (transport_ -> blocked() == 1) - { - #ifdef WARNING - *logofs << "handleWait: WARNING! Having to drain with " - << "channel " << "for FD#" << fd_ << " blocked.\n" - << logofs_flush; - #endif - - handleDrain(0, remaining); - - continue; - } - - if (remaining <= 0) - { - #ifdef TEST - *logofs << "handleWait: Timeout raised while waiting " - << "for more data for FD#" << fd_ << " at " - << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - return 0; - } - - #ifdef TEST - *logofs << "handleWait: Waiting " << remaining << " Ms " - << "for a new message on FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - readable = transport_ -> wait(remaining); - - if (readable > 0) - { - #ifdef TEST - *logofs << "handleWait: WARNING! Encoding more data " - << "for FD#" << fd_ << " at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - if (proxy -> handleAsyncRead(fd_) < 0) - { - return -1; - } - - return 1; - } - else if (readable == -1) - { - return -1; - } - - nowTs = getNewTimestamp(); - } -} - -int Channel::handleDrain(int limit, int timeout) -{ - #ifdef TEST - *logofs << "handleDrain: Going to drain FD#" << fd_ - << " with a limit of " << limit << " bytes " - << "at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - T_timestamp startTs = getNewTimestamp(); - - T_timestamp nowTs = startTs; - - int drained; - int remaining; - - int result; - - for (;;) - { - remaining = timeout - diffTimestamp(startTs, nowTs); - - if (remaining <= 0) - { - #ifdef TEST - *logofs << "handleDrain: Timeout raised while draining " - << "FD#" << fd_ << " at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - result = 0; - - goto ChannelDrainEnd; - } - - #ifdef TEST - *logofs << "handleDrain: Trying to write to FD#" - << fd_ << " with " << remaining << " Ms " - << "remaining.\n" << logofs_flush; - #endif - - drained = transport_ -> drain(limit, remaining); - - if (drained == 1) - { - #ifdef TEST - *logofs << "handleDrain: Transport for FD#" << fd_ - << " drained to " << transport_ -> length() - << " bytes at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - result = 1; - - goto ChannelDrainEnd; - } - else if (drained == 0 && transport_ -> readable() > 0) - { - #ifdef TEST - *logofs << "handleDrain: WARNING! Encoding more data " - << "for FD#" << fd_ << " at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - if (proxy -> handleAsyncRead(fd_) < 0) - { - goto ChannelDrainError; - } - } - else if (drained == -1) - { - goto ChannelDrainError; - } - - nowTs = getNewTimestamp(); - - if (diffTimestamp(startTs, nowTs) >= control -> ChannelTimeout) - { - int seconds = (remaining + control -> LatencyTimeout * 10) / 1000; - - #ifdef WARNING - *logofs << "handleDrain: WARNING! Could not drain FD#" - << fd_ << " within " << seconds << " seconds.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Can't write to connection on FD#" - << fd_ << " since " << seconds << " seconds.\n"; - - if (alert_ == 0) - { - if (control -> ProxyMode == proxy_client) - { - alert_ = CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT; - } - else - { - alert_ = CLOSE_DEAD_X_CONNECTION_SERVER_ALERT; - } - - HandleAlert(alert_, 1); - } - } - } - -ChannelDrainEnd: - - // - // Maybe we drained the channel and are - // now out of the congestion state. - // - - handleCongestion(); - - return result; - -ChannelDrainError: - - finish_ = 1; - - return -1; -} - -int Channel::handleCongestion() -{ - // - // Send a begin congestion control code - // if the local end of the channel does - // not consume its data. - // - - if (isCongested() == 1) - { - if (congestion_ == 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleCongestion: Sending congestion for FD#" - << fd_ << " with length " << transport_ -> length() - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - congestion_ = 1; - - // - // Use the callback to send the control - // code immediately. - // - - if (proxy -> handleAsyncCongestion(fd_) < 0) - { - finish_ = 1; - - return -1; - } - } - } - else - { - // - // If the channel was in congestion state - // send an end congestion control code. - // - - if (congestion_ == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleCongestion: Sending decongestion for FD#" - << fd_ << " with length " << transport_ -> length() - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - congestion_ = 0; - - if (proxy -> handleAsyncDecongestion(fd_) < 0) - { - finish_ = 1; - - return -1; - } - } - - // - // Remove the "channel unresponsive" - // dialog. - // - - if (alert_ != 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleCongestion: Displacing the dialog " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - HandleAlert(DISPLACE_MESSAGE_ALERT, 1); - } - } - - return 1; -} - -int Channel::handleFlush(T_flush type, int bufferLength, int scratchLength) -{ - if (finish_ == 1) - { - #ifdef TEST - *logofs << "handleFlush: Not flushing data for " - << "finishing channel for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - writeBuffer_.fullReset(); - - return -1; - } - - #ifdef TEST - *logofs << "handleFlush: Flushing " << bufferLength - << " + " << scratchLength << " bytes " - << "to FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - // - // Check if the channel has data available. - // Recent Linux kernels are very picky. - // They require that we read often or they - // assume that the process is non-interact- - // ive. - // - - int result = 0; - - if (handleAsyncEvents() < 0) - { - goto ChannelFlushError; - } - - // - // Write the data in the main buffer first, - // followed by the data in the scratch buffer. - // - - if (bufferLength > 0) - { - result = transport_ -> write(write_immediate, - writeBuffer_.getData(), bufferLength); - } - - if (result >= 0 && scratchLength > 0) - { - result = transport_ -> write(write_immediate, - writeBuffer_.getScratchData(), scratchLength); - } - - if (type == flush_if_any) - { - writeBuffer_.fullReset(); - } - else - { - writeBuffer_.partialReset(); - } - - // - // If we failed to write to the X connection then - // set the finish flag. The caller should continue - // to handle all the remaining messages or it will - // corrupt the decode buffer. At the real end, an - // error will be propagated to the upper layers - // which will perform any needed cleanup. - // - - if (result < 0) - { - goto ChannelFlushError; - } - - // - // Reset transport buffers. - // - - transport_ -> partialReset(); - - // - // Check if the X server has generated - // any event in response to our data. - // - - if (handleAsyncEvents() < 0) - { - goto ChannelFlushError; - } - - // - // Check if the channel has entered in - // congestion state and, in this case, - // send an immediate congestion control - // code to the remote. - // - - handleCongestion(); - - // - // We could optionally drain the output - // buffer if this is X11 channel. - // - // if (isCongested() == 1 && isReliable() == 1) - // { - // if (handleDrain(0, control -> ChannelTimeout) < 0) - // { - // goto ChannelFlushError; - // } - // } - // - - return 1; - -ChannelFlushError: - - finish_ = 1; - - return -1; -} - -int Channel::handleFlush() -{ - #ifdef TEST - *logofs << "handleFlush: Flushing " - << transport_ -> length() << " bytes to FD#" - << fd_ << " with descriptor writable.\n" - << logofs_flush; - #endif - - // - // Check if there is anything to read - // before anf after having written to - // the socket. - // - - if (handleAsyncEvents() < 0) - { - goto ChannelFlushError; - } - - if (transport_ -> flush() < 0) - { - #ifdef TEST - *logofs << "handleFlush: Failure detected " - << "flushing data to FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - goto ChannelFlushError; - } - - if (handleAsyncEvents() < 0) - { - goto ChannelFlushError; - } - - // - // Reset channel's transport buffers. - // - - transport_ -> partialReset(); - - // - // Check if the channel went out of the - // congestion state. - // - - handleCongestion(); - - return 1; - -ChannelFlushError: - - finish_ = 1; - - return -1; -} - -void Channel::handleResetAlert() -{ - if (alert_ != 0) - { - #ifdef TEST - *logofs << "handleResetAlert: The channel alert '" - << alert_ << "' was displaced.\n" - << logofs_flush; - #endif - - alert_ = 0; - } -} - -int Channel::handleCompress(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned int offset, const unsigned char *buffer, - const unsigned int size, unsigned char *&compressedData, - unsigned int &compressedDataSize) -{ - if (size <= offset) - { - #ifdef DEBUG - *logofs << "handleCompress: Not compressing data for FD#" << fd_ - << " as offset is " << offset << " with data size " - << size << ".\n" << logofs_flush; - #endif - - return 0; - } - - #ifdef DEBUG - *logofs << "handleCompress: Compressing data for FD#" << fd_ - << " with data size " << size << " and offset " - << offset << ".\n" << logofs_flush; - #endif - - // - // It is responsibility of the compressor to - // mark the buffer as such if the compression - // couldn't take place. - // - - if (compressor_ -> compressBuffer(buffer + offset, size - offset, compressedData, - compressedDataSize, encodeBuffer) <= 0) - { - #ifdef DEBUG - *logofs << "handleCompress: Sent " << size - offset - << " bytes of plain data for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - return 0; - } - else - { - #ifdef DEBUG - *logofs << "handleCompress: Sent " << compressedDataSize - << " bytes of compressed data for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - return 1; - } -} - -int Channel::handleDecompress(DecodeBuffer &decodeBuffer, const unsigned char opcode, - const unsigned int offset, unsigned char *buffer, - const unsigned int size, const unsigned char *&compressedData, - unsigned int &compressedDataSize) -{ - if (size <= offset) - { - return 0; - } - - int result = compressor_ -> decompressBuffer(buffer + offset, size - offset, - compressedData, compressedDataSize, - decodeBuffer); - if (result < 0) - { - #ifdef PANIC - *logofs << "handleDecompress: PANIC! Failed to decompress " - << size - offset << " bytes of data for FD#" << fd_ - << " with OPCODE#" << (unsigned int) opcode << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Data decompression failed for OPCODE#" - << (unsigned int) opcode << ".\n"; - - return -1; - } - else if (result == 0) - { - #ifdef DEBUG - *logofs << "handleDecompress: Received " << size - offset - << " bytes of plain data for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - return 0; - } - else - { - #ifdef DEBUG - *logofs << "handleDecompress: Received " << compressedDataSize - << " bytes of compressed data for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - return 1; - } -} - -int Channel::handleCleanAndNullRequest(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size) -{ - #ifdef TEST - *logofs << "handleCleanAndNullRequest: Removing the previous data " - << "and sending an X_NoOperation " << "for FD#" << fd_ - << " due to OPCODE#" << (unsigned int) opcode << " (" - << DumpOpcode(opcode) << ").\n" << logofs_flush; - #endif - - writeBuffer_.removeMessage(size - 4); - - size = 4; - opcode = X_NoOperation; - - return 1; -} - -int Channel::handleNullRequest(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size) -{ - #ifdef TEST - *logofs << "handleNullRequest: Sending an X_NoOperation for FD#" - << fd_ << " due to OPCODE#" << (unsigned int) opcode - << " (" << DumpOpcode(opcode) << ").\n" - << logofs_flush; - #endif - - size = 4; - buffer = writeBuffer_.addMessage(size); - opcode = X_NoOperation; - - return 1; -} - -void Channel::handleSplitStoreError(int resource) -{ - if (resource < 0 || resource >= CONNECTIONS_LIMIT) - { - #ifdef PANIC - *logofs << "handleSplitStoreError: PANIC! Resource " - << resource << " is out of range with limit " - << "set to " << CONNECTIONS_LIMIT << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Resource " << resource - << " is out of range with limit set to " - << CONNECTIONS_LIMIT << ".\n"; - - HandleCleanup(); - } - else - { - #ifdef PANIC - *logofs << "handleSplitStoreError: PANIC! Cannot " - << "allocate the split store for resource " - << resource << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot allocate the " - << "split store for resource " << resource - << ".\n"; - - HandleCleanup(); - } -} - -void Channel::handleSplitStoreAlloc(List *list, int resource) -{ - if (resource < 0 || resource >= CONNECTIONS_LIMIT) - { - handleSplitStoreError(resource); - } - - if (clientStore_ -> getSplitStore(resource) == NULL) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitStoreAlloc: Allocating a new " - << "split store for resource " << resource - << ".\n" << logofs_flush; - #endif - - SplitStore *splitStore = clientStore_ -> createSplitStore(resource); - - if (splitStore == NULL) - { - handleSplitStoreError(resource); - } - - list -> add(resource); - } - #if defined(TEST) || defined(SPLIT) - else - { - // - // Old proxy versions only use a single - // split store. - // - - if (resource != 0) - { - *logofs << "handleSplitStoreAlloc: WARNING! A split " - << "store for resource " << resource - << " already exists.\n" << logofs_flush; - } - } - #endif -} - -void Channel::handleSplitStoreRemove(List *list, int resource) -{ - if (resource < 0 || resource >= CONNECTIONS_LIMIT) - { - handleSplitStoreError(resource); - } - - SplitStore *splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore != NULL) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitStoreRemove: Deleting the " - << "split store for resource " << resource - << ".\n" << logofs_flush; - #endif - - clientStore_ -> destroySplitStore(resource); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitStoreRemove: Deleting resource " - << resource << " from the list " << ".\n" - << logofs_flush; - #endif - - list -> remove(resource); - } - #if defined(TEST) || defined(SPLIT) - else - { - *logofs << "handleSplitStoreRemove: WARNING! A split " - << "store for resource " << resource - << " does not exist.\n" << logofs_flush; - } - #endif -} - -Split *Channel::handleSplitCommitRemove(int request, int resource, int position) -{ - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitCommitRemove: SPLIT! Checking split " - << "commit with resource " << resource << " request " - << request << " and position " << position - << ".\n" << logofs_flush; - #endif - - // - // Remove the split from the split queue. - // - - CommitStore *commitStore = clientStore_ -> getCommitStore(); - - Split *split = commitStore -> pop(); - - if (split == NULL) - { - #ifdef PANIC - *logofs << "handleSplitCommitRemove: PANIC! Can't " - << "find the split in the commit queue.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't find the " - << "split in the commit queue.\n"; - - HandleCleanup(); - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitCommitRemove: SPLIT! Element from " - << "the queue has resource " << split -> getResource() - << " request " << split -> getRequest() << " and " - << "position " << split -> getPosition() - << ".\n" << logofs_flush; - #endif - - // Since ProtoStep7 (#issue 108) - if (resource != split -> getResource() || - request != split -> getRequest() || - position != split -> getPosition()) - { - #ifdef PANIC - *logofs << "handleSplitCommitRemove: PANIC! The data in " - << "the split doesn't match the commit request.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": The data in the split doesn't " - << "match the commit request.\n"; - - return NULL; - } - - #if defined(TEST) || defined(SPLIT) - - commitStore -> dump(); - - #endif - - return split; -} - -int Channel::setReferences() -{ - #ifdef TEST - *logofs << "Channel: Initializing the static " - << "members for the base class.\n" - << logofs_flush; - #endif - - firstClient_ = -1; - - fontPort_ = -1; - - #ifdef REFERENCES - - references_ = 0; - - #endif - - return 1; -} - -int Channel::setOpcodes(OpcodeStore *opcodeStore) -{ - opcodeStore_ = opcodeStore; - - #ifdef TEST - *logofs << "setOpcodes: Propagated opcodes store to channel " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - return 1; -} - -int Channel::setStores(ClientStore *clientStore, ServerStore *serverStore) -{ - clientStore_ = clientStore; - serverStore_ = serverStore; - - #ifdef TEST - *logofs << "setStores: Propagated message stores to channel " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - return 1; -} - -int Channel::setCaches(ClientCache *clientCache, ServerCache *serverCache) -{ - clientCache_ = clientCache; - serverCache_ = serverCache; - - #ifdef TEST - *logofs << "setCaches: Propagated encode caches to channel " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - return 1; -} diff --git a/nxcomp/Channel.h b/nxcomp/Channel.h deleted file mode 100644 index 93b022630..000000000 --- a/nxcomp/Channel.h +++ /dev/null @@ -1,664 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Channel_H -#define Channel_H - -#include "Transport.h" - -#include "WriteBuffer.h" - -#include "OpcodeStore.h" - -#include "ClientStore.h" -#include "ServerStore.h" - -#include "ClientCache.h" -#include "ServerCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Forward declaration of referenced classes. -// - -class List; - -class StaticCompressor; - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Define this to log a line when a channel -// is created or destroyed. -// - -#undef REFERENCES - -// -// Type of traffic carried by channel. -// - -typedef enum -{ - channel_none = -1, - channel_x11, - channel_cups, - channel_smb, - channel_media, - channel_http, - channel_font, - channel_slave, - channel_last_tag - -} T_channel_type; - -// -// Type of notification event to be sent -// by proxy to the X channel. -// - -typedef enum -{ - notify_no_split, - notify_start_split, - notify_commit_split, - notify_end_split, - notify_empty_split, - -} T_notification_type; - -class Channel -{ - public: - - // - // Maximum number of X connections supported. - // - - static const int CONNECTIONS_LIMIT = 256; - - Channel(Transport *transport, StaticCompressor *compressor); - - virtual ~Channel(); - - // - // Read any X message available on the X - // connection and encode it to the encode - // buffer. - // - - virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, - unsigned int length) = 0; - - // - // Decode any X message encoded in the - // proxy message and write it to the X - // connection. - // - - virtual int handleWrite(const unsigned char *message, unsigned int length) = 0; - - // - // Other methods to be implemented in - // client, server and generic channel - // classes. - // - - virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, - T_store_action action, int position, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) = 0; - - virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, - T_store_action action, int position, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) = 0; - - virtual int handleSplit(EncodeBuffer &encodeBuffer) = 0; - - virtual int handleSplit(DecodeBuffer &decodeBuffer) = 0; - - virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split) = 0; - - virtual int handleSplitEvent(DecodeBuffer &decodeBuffer) = 0; - - virtual int handleMotion(EncodeBuffer &encodeBuffer) = 0; - - virtual int handleCompletion(EncodeBuffer &encodeBuffer) = 0; - - virtual int handleConfiguration() = 0; - - virtual int handleFinish() = 0; - - // - // Interleave reads of the available - // events while writing data to the - // channel socket. - // - - virtual int handleAsyncEvents() = 0; - - // - // Handle the channel tear down. - // - - int handleClosing() - { - closing_ = 1; - - return 1; - } - - int handleDrop() - { - drop_ = 1; - - return 1; - } - - // - // Try to read more data from the socket. In - // the meanwhile flush any enqueued data if - // the channel is blocked. Return as soon as - // more data has been read or the timeout has - // been exceeded. - // - - int handleWait(int timeout); - - // - // Drain the output buffer while handling the - // data that may become readable. - // - - int handleDrain(int timeout, int limit); - - // - // Flush any remaining data in the transport - // buffer. - // - - int handleFlush(); - - // - // Called when the loop has replaced or - // closed a previous alert. - // - - void handleResetAlert(); - - // - // Initialize all the static members. - // - - static int setReferences(); - - // - // Set pointer to object mapping opcodes - // of NX specific messages. - // - - int setOpcodes(OpcodeStore *opcodeStore); - - // - // Update pointers to message stores in - // channels. - // - - int setStores(ClientStore *clientStore, ServerStore *serverStore); - - // - // The same for channels caches. - // - - int setCaches(ClientCache *clientCache, ServerCache *serverCache); - - // - // Set the port used for tunneling of the - // font server connections. - // - - void setPorts(int fontPort) - { - fontPort_ = fontPort; - } - - // - // Check if there are pending split - // to send to the remote side. - // - - virtual int needSplit() const = 0; - - // - // Check if there are motion events - // to flush. - // - - virtual int needMotion() const = 0; - - // - // Return the type of traffic carried - // by this channel. - // - - virtual T_channel_type getType() const = 0; - - // - // Check if the channel has been marked - // as closing down. - // - - int getFinish() const - { - return finish_; - } - - int getClosing() - { - return closing_; - } - - int getDrop() - { - return drop_; - } - - int getCongestion() - { - return congestion_; - } - - protected: - - int handleFlush(T_flush type) - { - // - // We could write the data immediately if there - // is already something queued to the low level - // TCP buffers. - // - // if (... || transport_ -> queued() > 0) - // { - // ... - // } - // - - if (writeBuffer_.getScratchLength() > 0 || - (type == flush_if_any && writeBuffer_.getLength() > 0) || - writeBuffer_.getLength() >= (unsigned int) - control -> TransportFlushBufferSize) - { - return handleFlush(type, writeBuffer_.getLength(), - writeBuffer_.getScratchLength()); - } - - return 0; - } - - // - // Actually flush the data to the - // channel descriptor. - // - - int handleFlush(T_flush type, int bufferLength, int scratchLength); - - // - // Handle the congestion changes. - // - - int handleCongestion(); - - // - // Encode and decode X messages. - // - - int handleEncode(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, - MessageStore *store, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - int handleDecode(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, - MessageStore *store, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - // - // Encode the message based on its - // message store. - // - - int handleEncodeCached(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, - MessageStore *store, const unsigned char *buffer, - const unsigned int size); - - int handleDecodeCached(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, - MessageStore *store, unsigned char *&buffer, - unsigned int &size); - - int handleEncodeIdentity(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, - MessageStore *store, const unsigned char *buffer, - const unsigned int size, int bigEndian) - { - return (store -> encodeIdentity(encodeBuffer, buffer, size, - bigEndian, channelCache)); - } - - int handleDecodeIdentity(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, - MessageStore *store, unsigned char *&buffer, - unsigned int &size, int bigEndian, - WriteBuffer *writeBuffer) - { - return (store -> decodeIdentity(decodeBuffer, buffer, size, bigEndian, - writeBuffer, channelCache)); - } - - // - // Other utility functions used by - // the encoding and decoding methods. - // - - void handleCopy(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned int offset, const unsigned char *buffer, - const unsigned int size) - { - if (size > offset) - { - encodeBuffer.encodeMemory(buffer + offset, size - offset); - } - } - - void handleCopy(DecodeBuffer &decodeBuffer, const unsigned char opcode, - const unsigned int offset, unsigned char *buffer, - const unsigned int size) - { - if (size > offset) - { - memcpy(buffer + offset, decodeBuffer.decodeMemory(size - offset), size - offset); - } - } - - void handleUpdate(MessageStore *store, const unsigned int dataSize, - const unsigned int compressedDataSize) - { - if (store -> lastAction == IS_ADDED) - { - handleUpdateAdded(store, dataSize, compressedDataSize); - } - } - - void handleSave(MessageStore *store, unsigned char *buffer, unsigned int size, - const unsigned char *compressedData = NULL, - const unsigned int compressedDataSize = 0) - { - if (store -> lastAction == IS_ADDED) - { - handleSaveAdded(store, 0, buffer, size, compressedData, compressedDataSize); - } - } - - void handleSaveSplit(MessageStore *store, unsigned char *buffer, - unsigned int size) - { - if (store -> lastAction == IS_ADDED) - { - return handleSaveAdded(store, 1, buffer, size, 0, 0); - } - } - - void handleUpdateAdded(MessageStore *store, const unsigned int dataSize, - const unsigned int compressedDataSize); - - void handleSaveAdded(MessageStore *store, int split, unsigned char *buffer, - unsigned int size, const unsigned char *compressedData, - const unsigned int compressedDataSize); - - // - // Compress the data part of a message - // using ZLIB or another compressor - // and send it over the network. - // - - int handleCompress(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned int offset, const unsigned char *buffer, - const unsigned int size, unsigned char *&compressedData, - unsigned int &compressedDataSize); - - int handleDecompress(DecodeBuffer &decodeBuffer, const unsigned char opcode, - const unsigned int offset, unsigned char *buffer, - const unsigned int size, const unsigned char *&compressedData, - unsigned int &compressedDataSize); - - // - // Send an X_NoOperation to the X server. - // The second version also removes any - // previous data in the write buffer. - // - - int handleNullRequest(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size); - - int handleCleanAndNullRequest(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size); - - // - // X11 channels are considered to be in - // congestion state when there was a - // blocking write and, since then, the - // local end didn't consume all the data. - // - - virtual int isCongested() - { - return (transport_ -> getType() != - transport_agent && transport_ -> length() > - control -> TransportFlushBufferSize); - } - - virtual int isReliable() - { - return 1; - } - - // - // Determine how to handle allocation - // of new messages in the message - // stores. - // - - int mustCleanStore(MessageStore *store) - { - return (store -> getRemoteTotalStorageSize() > control -> - RemoteTotalStorageSize || store -> getLocalTotalStorageSize() > - control -> LocalTotalStorageSize || (store -> getRemoteStorageSize() > - (control -> RemoteTotalStorageSize / 100 * store -> - cacheThreshold)) || (store -> getLocalStorageSize() > - (control -> LocalTotalStorageSize / 100 * store -> - cacheThreshold))); - } - - int canCleanStore(MessageStore *store) - { - return ((store -> getSize() > 0 && (store -> getRemoteStorageSize() > - (control -> RemoteTotalStorageSize / 100 * store -> - cacheLowerThreshold))) || (store -> getLocalStorageSize() > - (control -> LocalTotalStorageSize / 100 * store -> - cacheLowerThreshold))); - } - - protected: - - // - // Set up the split stores. - // - - void handleSplitStoreError(int resource); - - void handleSplitStoreAlloc(List *list, int resource); - void handleSplitStoreRemove(List *list, int resource); - - Split *handleSplitCommitRemove(int request, int resource, int position); - - void validateSize(const char *name, int input, int output, - int offset, int size) - { - if (size < offset || size > control -> MaximumMessageSize || - size != (int) RoundUp4(input) + offset || - output > control -> MaximumMessageSize) - { - *logofs << "Channel: PANIC! Invalid size " << size - << " for " << name << " output with data " - << input << "/" << output << "/" << offset - << "/" << size << ".\n" << logofs_flush; - - cerr << "Error" << ": Invalid size " << size - << " for " << name << " output.\n"; - - HandleAbort(); - } - } - - // - // Is the X client big endian? - // - - int bigEndian() const - { - return bigEndian_; - } - - int bigEndian_; - - // - // Other X server's features - // saved at session startup. - // - - unsigned int imageByteOrder_; - unsigned int bitmapBitOrder_; - unsigned int scanlineUnit_; - unsigned int scanlinePad_; - - int firstRequest_; - int firstReply_; - - // - // Use this class for IO operations. - // - - Transport *transport_; - - // - // The static compressor is created by the - // proxy and shared among channels. - // - - StaticCompressor *compressor_; - - // - // Map NX operations to opcodes. Propagated - // by proxy to all channels on the same X - // server. - // - - OpcodeStore *opcodeStore_; - - // - // Also stores are shared between channels. - // - - ClientStore *clientStore_; - ServerStore *serverStore_; - - // - // Caches are specific for each channel. - // - - ClientCache *clientCache_; - ServerCache *serverCache_; - - // - // Data going to X connection. - // - - WriteBuffer writeBuffer_; - - // - // Other data members. - // - - int fd_; - - int finish_; - int closing_; - int drop_; - int congestion_; - int priority_; - - int alert_; - - // - // It will be set to the descriptor of the - // first X channel that is successfully con- - // nected and will print an info message on - // standard error. - // - - static int firstClient_; - - // - // Port used for font server connections. - // - - static int fontPort_; - - // - // Track which cache operations have been - // enabled by the agent. - // - - int enableCache_; - int enableSplit_; - int enableSave_; - int enableLoad_; - - // - // Keep track of object creation and - // deletion. - // - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -#endif /* Channel_H */ diff --git a/nxcomp/ChannelCache.cpp b/nxcomp/ChannelCache.cpp deleted file mode 100644 index 5c4c360b9..000000000 --- a/nxcomp/ChannelCache.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ChannelCache.h" - -const unsigned int CONFIGUREWINDOW_FIELD_WIDTH[7] = -{ - 16, // x - 16, // y - 16, // width - 16, // height - 16, // border width - 29, // sibling window - 3 // stack mode -}; - -const unsigned int CREATEGC_FIELD_WIDTH[23] = -{ - 4, // function - 32, // plane mask - 32, // foreground - 32, // background - 16, // line width - 2, // line style - 2, // cap style - 2, // join style - 2, // fill style - 1, // fill rule - 29, // tile - 29, // stipple - 16, // tile/stipple x origin - 16, // tile/stipple y origin - 29, // font - 1, // subwindow mode - 1, // graphics exposures - 16, // clip x origin - 16, // clip y origin - 29, // clip mask - 16, // card offset - 8, // dashes - 1 // arc mode -}; diff --git a/nxcomp/ChannelCache.h b/nxcomp/ChannelCache.h deleted file mode 100644 index 6a29c3847..000000000 --- a/nxcomp/ChannelCache.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ChannelCache_H -#define ChannelCache_H - -// -// Sizes of optional fields for ConfigureWindow -// request. -// - -extern const unsigned int CONFIGUREWINDOW_FIELD_WIDTH[7]; - -// -// Sizes of optional fields for CreateGC request. -// - -extern const unsigned int CREATEGC_FIELD_WIDTH[23]; - -// -// This is just needed to provide a pointer -// to the base cache class in encoding and -// decoding procedures of message stores. -// - -class ChannelCache -{ - public: - - ChannelCache() - { - } - - ~ChannelCache() - { - } -}; - -#endif /* ChannelCache_H */ diff --git a/nxcomp/ChannelEndPoint.cpp b/nxcomp/ChannelEndPoint.cpp deleted file mode 100644 index 286210dc7..000000000 --- a/nxcomp/ChannelEndPoint.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include -#include - -#include "ChannelEndPoint.h" - -#include "NXalert.h" - -ChannelEndPoint::ChannelEndPoint(const char *spec) - : defaultTCPPort_(0), defaultTCPInterface_(0), - defaultUnixPath_(NULL), spec_(NULL) { - setSpec(spec); -} - -ChannelEndPoint::~ChannelEndPoint() -{ - char *unixPath = NULL; - - if (getUnixPath(&unixPath)) - { - struct stat st; - lstat(unixPath, &st); - if(S_ISSOCK(st.st_mode)) - unlink(unixPath); - } -} - -void -ChannelEndPoint::setSpec(const char *spec) { - if (spec_) free(spec_); - - if (spec && strlen(spec)) - { - spec_ = strdup(spec); - isUnix_ = getUnixPath(); - isTCP_ = getTCPHostAndPort(); - } - else - { - spec_ = NULL; - isUnix_ = false; - isTCP_ = false; - } -} - -void -ChannelEndPoint::setSpec(long port) { - if (port >= 0) { - char tmp[20]; - sprintf(tmp, "%ld", port); - setSpec(tmp); - } - else { - disable(); - } -} - -void -ChannelEndPoint::setSpec(const char *hostName, long port) { - int length; - - if (spec_) free(spec_); - isUnix_ = false; - isTCP_ = false; - - if (hostName && strlen(hostName) && port >= 1) - { - length = snprintf(NULL, 0, "tcp:%s:%ld", hostName, port); - spec_ = (char *)calloc(length + 1, sizeof(char)); - snprintf(spec_, length+1, "tcp:%s:%ld", hostName, port); - isTCP_ = true; - } - else setSpec((char*)NULL); -} - -bool -ChannelEndPoint::getSpec(char **socketUri) const { - - if (socketUri) *socketUri = NULL; - - char *unixPath = NULL; - char *hostName = NULL; - long port = -1; - - char *newSocketUri = NULL; - int length = -1; - - if (getUnixPath(&unixPath)) - { - length = snprintf(NULL, 0, "unix:%s", unixPath); - } - else if (getTCPHostAndPort(&hostName, &port)) - { - length = snprintf(NULL, 0, "tcp:%s:%ld", hostName, port); - } - - if (length > 0) - { - newSocketUri = (char *)calloc(length + 1, sizeof(char)); - if (isUnixSocket()) - snprintf(newSocketUri, length+1, "unix:%s", unixPath); - else - snprintf(newSocketUri, length+1, "tcp:%s:%ld", hostName, port); - - if (socketUri) - *socketUri = strdup(newSocketUri); - } - - free(newSocketUri); - free(unixPath); - free(hostName); - - if (NULL != *socketUri) - return true; - - return false; -} - -void -ChannelEndPoint::setDefaultTCPPort(long port) { - defaultTCPPort_ = port; -} - -void -ChannelEndPoint::setDefaultTCPInterface(int publicInterface) { - defaultTCPInterface_ = publicInterface; -} - -void -ChannelEndPoint::setDefaultUnixPath(char *path) { - if (defaultUnixPath_) free(defaultUnixPath_); - - if (path && strlen(path)) - defaultUnixPath_ = strdup(path); - else - defaultUnixPath_ = NULL; -} - -void -ChannelEndPoint::disable() { - setSpec("0"); -} - -bool -ChannelEndPoint::getPort(long *port) const { - if (port) *port = 0; - long p = -1; - if (spec_) { - char *end; - p = strtol(spec_, &end, 10); - if ((end == spec_) || (*end != '\0')) - return false; - } - - if (port) *port = p; - return true; -} - -bool -ChannelEndPoint::getUnixPath(char **unixPath) const { - - if (unixPath) *unixPath = 0; - - long p; - char *path = NULL; - - if (getPort(&p)) { - if (p != 1) return false; - } - else if (spec_ && (strncmp("unix:", spec_, 5) == 0)) { - path = spec_ + 5; - } - else - return false; - - if (!path || (*path == '\0')) { - path = defaultUnixPath_; - if (!path) - return false; - } - - if (unixPath) - *unixPath = strdup(path); - - return true; -} - -bool -ChannelEndPoint::isUnixSocket() const { - return isUnix_; -} - -// FIXME!!! -static const char * -getComputerName() { - // - // Strangely enough, under some Windows OSes SMB - // service doesn't bind to localhost. Fall back - // to localhost if can't find computer name in - // the environment. In future we should try to - // bind to localhost and then try the other IPs. - // - - const char *hostname = NULL; - - #ifdef __CYGWIN32__ - - hostname = getenv("COMPUTERNAME"); - - #endif - - if (hostname == NULL) - { - hostname = "localhost"; - } - - return hostname; -} - -bool -ChannelEndPoint::getTCPHostAndPort(char **host, long *port) const { - long p; - char *h = NULL; - ssize_t h_len; - - if (host) *host = NULL; - if (port) *port = 0; - - if (getPort(&p)) { - h_len = 0; - } - else if (spec_ && (strncmp("tcp:", spec_, 4) == 0)) { - h = spec_ + 4; - char *colon = strrchr(h, ':'); - if (colon) { - char *end; - h_len = colon++ - h; - p = strtol(colon, &end, 10); - if ((end == colon) || (*end != '\0')) - return false; - } - else { - h_len = strlen(h); - p = 1; - } - } - else - return false; - - if (p == 1) p = defaultTCPPort_; - if (p < 1) return false; - - if (port) - *port = p; - - if (host) - *host = ( h_len - ? strndup(h, h_len) - : strdup(defaultTCPInterface_ ? getComputerName() : "localhost")); - - return true; -} - -bool -ChannelEndPoint::isTCPSocket() const { - return isTCP_; -} - -long ChannelEndPoint::getTCPPort() const { - long port; - if (getTCPHostAndPort(NULL, &port)) return port; - return -1; -} - -bool -ChannelEndPoint::enabled() const { - return (isUnixSocket() || isTCPSocket()); -} - -bool -ChannelEndPoint::validateSpec() { - isTCP_ = getTCPHostAndPort(); - isUnix_ = getUnixPath(); - return ( getPort() || isUnix_ || isTCP_ ); -} - -ChannelEndPoint &ChannelEndPoint::operator=(const ChannelEndPoint &other) { - char *old; - defaultTCPPort_ = other.defaultTCPPort_; - defaultTCPInterface_ = other.defaultTCPInterface_; - old = defaultUnixPath_; - defaultUnixPath_ = (other.defaultUnixPath_ ? strdup(other.defaultUnixPath_) : NULL); - free(old); - old = spec_; - spec_ = (other.spec_ ? strdup(other.spec_) : NULL); - free(old); - isUnix_ = getUnixPath(); - isTCP_ = getTCPHostAndPort(); - return *this; -} - -std::ostream& operator<<(std::ostream& os, const ChannelEndPoint& endPoint) { - if (endPoint.enabled()) { - char* endPointSpec = NULL; - if (endPoint.getSpec(&endPointSpec)) - { - os << endPointSpec; - free(endPointSpec); - } - else - os << "(invalid)"; - } - else - { - os << "(disabled)"; - } - return os; -} diff --git a/nxcomp/ChannelEndPoint.h b/nxcomp/ChannelEndPoint.h deleted file mode 100644 index 4c0c728f3..000000000 --- a/nxcomp/ChannelEndPoint.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ChannelEndPoint_H -#define ChannelEndPoint_H - -#include -#include - -class ChannelEndPoint -{ - private: - long defaultTCPPort_; - int defaultTCPInterface_; // 0=localhost, otherwise IP of public interface. - char *defaultUnixPath_; - char *spec_; - bool isUnix_; - bool isTCP_; - - bool getPort(long *port = NULL) const; - - public: - ChannelEndPoint(const char *spec = NULL); - ~ChannelEndPoint(); - ChannelEndPoint &operator=(const ChannelEndPoint &other); - - bool enabled() const; - bool disabled() { return !enabled(); } - void disable(); - void setSpec(const char *spec); - void setSpec(long port); - void setSpec(const char *hostName, long port); - bool getSpec(char **socketUri) const; - void setDefaultTCPPort(long port); - void setDefaultTCPInterface(int publicInterface); - void setDefaultUnixPath(char *path); - - bool getUnixPath(char **path = NULL) const; - bool isUnixSocket() const; - bool getTCPHostAndPort(char **hostname = NULL, long *port = NULL) const; - long getTCPPort() const; - bool isTCPSocket() const; - - bool validateSpec(); -}; - -std::ostream& operator<<(std::ostream& os, const ChannelEndPoint& endPoint); - -#endif diff --git a/nxcomp/ChannelStore.h b/nxcomp/ChannelStore.h deleted file mode 100644 index 53bb60f73..000000000 --- a/nxcomp/ChannelStore.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ChannelStore_H -#define ChannelStore_H - -// -// One message store for each opcode. -// - -#define CHANNEL_STORE_OPCODE_LIMIT 256 - -// -// One split store for each resource. -// - -#define CHANNEL_STORE_RESOURCE_LIMIT 256 - -class ChannelStore -{ - public: - - ChannelStore() - { - } - - virtual ~ChannelStore() - { - } -}; - -#endif /* ChannelStore_H */ diff --git a/nxcomp/CharCache.cpp b/nxcomp/CharCache.cpp deleted file mode 100644 index 88e66e3da..000000000 --- a/nxcomp/CharCache.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "CharCache.h" - -int CharCache::lookup(unsigned char value, unsigned int &index) -{ - for (unsigned int i = 0; i < length_; i++) - if (value == buffer_[i]) - { - index = i; - if (i) - { - unsigned int target = (i >> 1); - do - { - buffer_[i] = buffer_[i - 1]; - i--; - } - while (i > target); - buffer_[target] = value; - } - return 1; - } - insert(value); - return 0; -} - -void CharCache::insert(unsigned char value) -{ - unsigned int insertionPoint = 0; - if (2 >= length_) - insertionPoint = length_; - else - insertionPoint = 2; - unsigned int start; - if (length_ >= 7) - start = 7 - 1; - else - { - start = length_; - length_++; - } - for (unsigned int k = start; k > insertionPoint; k--) - buffer_[k] = buffer_[k - 1]; - buffer_[insertionPoint] = value; -} diff --git a/nxcomp/CharCache.h b/nxcomp/CharCache.h deleted file mode 100644 index b8891d2df..000000000 --- a/nxcomp/CharCache.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef CharCache_H -#define CharCache_H - -// -// CharCache is a counterpart of IntCache that is -// optimized for use in compressing text composed -// of 8-bit characters. -// - -class CharCache -{ - public: - - CharCache() : length_(0) - { - } - - ~CharCache() - { - } - - unsigned int getSize() const - { - return (unsigned int) length_; - } - - int lookup(unsigned char value, unsigned int &index); - - // - // This can be inlined as it is only - // called by decodeCachedValue(). - // - - unsigned int get(unsigned int index) - { - unsigned char result = buffer_[index]; - - if (index != 0) - { - unsigned int i = index; - unsigned int target = (i >> 1); - - do - { - buffer_[i] = buffer_[i - 1]; - - i--; - } - while (i > target); - - buffer_[target] = result; - } - - return (unsigned int) result; - } - - void insert(unsigned char value); - - private: - - unsigned char length_; - - unsigned char buffer_[7]; -}; - -#endif /* CharCache_H */ diff --git a/nxcomp/Children.cpp b/nxcomp/Children.cpp deleted file mode 100644 index 265ba4e37..000000000 --- a/nxcomp/Children.cpp +++ /dev/null @@ -1,1055 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include - -#include "NX.h" - -#include "Misc.h" - -#include "Types.h" -#include "Timestamp.h" - -#include "Control.h" -#include "Statistics.h" -#include "Proxy.h" - -#include "Keeper.h" -#include "Fork.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#define DISPLAY_LENGTH_LIMIT 256 -#define DEFAULT_STRING_LIMIT 512 - -// -// These are from the main loop. -// - -extern Keeper *keeper; - -extern int (*handler)(int); - -extern int useUnixSocket; - -extern int lastDialog; -extern int lastWatchdog; -extern int lastKeeper; - -extern void CleanupListeners(); -extern void CleanupSockets(); -extern void CleanupAgent(); -extern void CleanupGlobal(); - -extern void InstallSignals(); - -extern char *GetClientPath(); - -extern int CheckParent(const char *name, const char *type, - int parent); - -#ifdef __sun -extern char **environ; -#endif - -// -// Close all the unused descriptors and -// install any signal handler that might -// have been disabled in the main process. -// - -static void SystemCleanup(const char *name); - -// -// Release all objects allocated in the -// heap. - -static void MemoryCleanup(const char *name); - -// -// Remove 'name' from the environment. -// - -static int UnsetEnv(const char *name); - -static int NXTransKeeperHandler(int signal); -static void NXTransKeeperCheck(); - - -// -// Start a nxclient process in dialog mode. -// - -int NXTransDialog(const char *caption, const char *message, - const char *window, const char *type, int local, - const char* display) -{ - // - // Be sure log file is valid. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - int pid; - - #ifdef TEST - *logofs << "NXTransDialog: Going to fork with NX pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - pid = Fork(); - - if (pid != 0) - { - if (pid < 0) - { - #ifdef TEST - *logofs << "NXTransDialog: WARNING! Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - } - #ifdef TEST - else - { - *logofs << "NXTransDialog: Created NX dialog process " - << "with pid '" << pid << "'.\n" - << logofs_flush; - } - #endif - - return pid; - } - - #ifdef TEST - *logofs << "NXTransDialog: Executing child with pid '" - << getpid() << "' and parent '" << getppid() - << "'.\n" << logofs_flush; - #endif - - SystemCleanup("NXTransDialog"); - - // - // Copy the client command before - // freeing up the control class. - // - - char command[DEFAULT_STRING_LIMIT]; - - if (control != NULL) - { - strcpy(command, control -> ClientPath); - } - else - { - char *path = GetClientPath(); - - strcpy(command, path); - - delete [] path; - } - - // - // Get rid of the unused resources. - // - - MemoryCleanup("NXTransDialog"); - - #ifdef TEST - *logofs << "NXTransDialog: Running external NX dialog with caption '" - << caption << "' message '" << message << "' type '" - << type << "' local '" << local << "' display '" - << display << "'.\n" - << logofs_flush; - #endif - - int pulldown = (strcmp(type, "pulldown") == 0); - - char parent[DEFAULT_STRING_LIMIT]; - - snprintf(parent, DEFAULT_STRING_LIMIT, "%d", getppid()); - - parent[DEFAULT_STRING_LIMIT - 1] = '\0'; - - UnsetEnv("LD_LIBRARY_PATH"); - - for (int i = 0; i < 2; i++) - { - if (local != 0) - { - if (pulldown) - { - execlp(command, command, "--dialog", type, "--caption", caption, - "--window", window, "--local", "--parent", parent, - "--display", display, NULL); - } - else - { - execlp(command, command, "--dialog", type, "--caption", caption, - "--message", message, "--local", "--parent", parent, - "--display", display, NULL); - } - } - else - { - if (pulldown) - { - execlp(command, command, "--dialog", type, "--caption", caption, - "--window", window, "--parent", parent, - "--display", display, NULL); - } - else - { - execlp(command, command, "--dialog", type, "--caption", caption, - "--message", message, "--parent", parent, - "--display", display, NULL); - } - } - - #ifdef WARNING - *logofs << "NXTransDialog: WARNING! Couldn't start '" - << command << "'. " << "Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Couldn't start '" << command - << "'. Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - // - // Retry by looking for the default name - // in the default NX path. - // - - if (i == 0) - { - - strcpy(command, "nxclient"); - - char newPath[DEFAULT_STRING_LIMIT]; - - strcpy(newPath, "/usr/NX/bin:/opt/NX/bin:/usr/local/NX/bin:"); - - #ifdef __APPLE__ - - strcat(newPath, "/Applications/NX Client for OSX.app/Contents/MacOS:"); - - #endif - - #ifdef __CYGWIN32__ - - strcat(newPath, ".:"); - - #endif - - int newLength = strlen(newPath); - - char *oldPath = getenv("PATH"); - - strncpy(newPath + newLength, oldPath, DEFAULT_STRING_LIMIT - newLength - 1); - - newPath[DEFAULT_STRING_LIMIT - 1] = '\0'; - - #ifdef WARNING - *logofs << "NXTransDialog: WARNING! Trying with path '" - << newPath << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Trying with path '" << newPath - << "'.\n"; - - // - // Solaris doesn't seem to have - // function setenv(). - // - - #ifdef __sun - - char newEnv[DEFAULT_STRING_LIMIT + 5]; - - sprintf(newEnv,"PATH=%s", newPath); - - putenv(newEnv); - - #else - - setenv("PATH", newPath, 1); - - #endif - - } - } - - // - // Hopefully useless. - // - - exit(0); -} - -// -// Start a nxclient process in dialog mode. -// - -int NXTransClient(const char* display) -{ - // - // Be sure log file is valid. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - int pid; - - #ifdef TEST - *logofs << "NXTransClient: Going to fork with NX pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - pid = Fork(); - - if (pid != 0) - { - if (pid < 0) - { - #ifdef TEST - *logofs << "NXTransClient: WARNING! Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - } - #ifdef TEST - else - { - *logofs << "NXTransClient: Created NX client process " - << "with pid '" << pid << "'.\n" - << logofs_flush; - } - #endif - - return pid; - } - - #ifdef TEST - *logofs << "NXTransClient: Executing child with pid '" - << getpid() << "' and parent '" << getppid() - << "'.\n" << logofs_flush; - #endif - - SystemCleanup("NXTransClient"); - - // - // Copy the client command before - // freeing up the control class. - // - - char command[DEFAULT_STRING_LIMIT]; - - if (control != NULL) - { - strcpy(command, control -> ClientPath); - } - else - { - char *path = GetClientPath(); - - strcpy(command, path); - - delete [] path; - } - - // - // Get rid of unused resources. - // - - MemoryCleanup("NXTransClient"); - - #ifdef TEST - *logofs << "NXTransClient: Running external NX client with display '" - << display << "'.\n" << logofs_flush; - #endif - - // - // Provide the display in the environment. - // - - char newDisplay[DISPLAY_LENGTH_LIMIT]; - - #ifdef __sun - - snprintf(newDisplay, DISPLAY_LENGTH_LIMIT - 1, "DISPLAY=%s", display); - - newDisplay[DISPLAY_LENGTH_LIMIT - 1] = '\0'; - - putenv(newDisplay); - - #else - - strncpy(newDisplay, display, DISPLAY_LENGTH_LIMIT - 1); - - newDisplay[DISPLAY_LENGTH_LIMIT - 1] = '\0'; - - setenv("DISPLAY", newDisplay, 1); - - #endif - - UnsetEnv("LD_LIBRARY_PATH"); - - for (int i = 0; i < 2; i++) - { - execlp(command, command, NULL); - - #ifdef WARNING - *logofs << "NXTransClient: WARNING! Couldn't start '" - << command << "'. Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Couldn't start '" << command - << "'. Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - // - // Retry by looking for the default name - // in the default NX path. - // - - if (i == 0) - { - - strcpy(command, "nxclient"); - - char newPath[DEFAULT_STRING_LIMIT]; - - strcpy(newPath, "/usr/NX/bin:/opt/NX/bin:/usr/local/NX/bin:"); - - #ifdef __APPLE__ - - strcat(newPath, "/Applications/NX Client for OSX.app/Contents/MacOS:"); - - #endif - - #ifdef __CYGWIN32__ - - strcat(newPath, ".:"); - - #endif - - int newLength = strlen(newPath); - - char *oldPath = getenv("PATH"); - - strncpy(newPath + newLength, oldPath, DEFAULT_STRING_LIMIT - newLength - 1); - - newPath[DEFAULT_STRING_LIMIT - 1] = '\0'; - - #ifdef WARNING - *logofs << "NXTransClient: WARNING! Trying with path '" - << newPath << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Trying with path '" << newPath - << "'.\n"; - - // - // Solaris doesn't seem to have - // function setenv(). - // - - #ifdef __sun - - char newEnv[DEFAULT_STRING_LIMIT + 5]; - - sprintf(newEnv,"PATH=%s", newPath); - - putenv(newEnv); - - #else - - setenv("PATH", newPath, 1); - - #endif - } - - } - // - // Hopefully useless. - // - - exit(0); -} - -// -// Wait until the timeout is expired. -// The timeout is expressed in milli- -// seconds. -// - -int NXTransWatchdog(int timeout) -{ - // - // Be sure log file is valid. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - int pid; - - #ifdef TEST - *logofs << "NXTransWatchdog: Going to fork with NX pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - pid = Fork(); - - if (pid != 0) - { - if (pid < 0) - { - #ifdef TEST - *logofs << "NXTransWatchdog: WARNING! Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - } - #ifdef TEST - else - { - *logofs << "NXTransWatchdog: Created NX watchdog process " - << "with pid '" << pid << "'.\n" << logofs_flush; - } - #endif - - return pid; - } - - int parent = getppid(); - - #ifdef TEST - *logofs << "NXTransWatchdog: Executing child with pid '" - << getpid() << "' and parent '" << parent - << "'.\n" << logofs_flush; - #endif - - SystemCleanup("NXTransWatchdog"); - - // - // Get rid of unused resources. - // - - MemoryCleanup("NXTransWatchdog"); - - // - // Run until the timeout is expired - // or forever, if no timeout is - // provided. - // - - T_timestamp startTs = getTimestamp(); - - int diffTs = 0; - - for (;;) - { - // - // Complain if the parent is dead. - // - - if (CheckParent("NXTransWatchdog", "watchdog", parent) == 0) - { - #ifdef TEST - *logofs << "NXTransWatchdog: Exiting with no parent " - << "running.\n" << logofs_flush; - #endif - - HandleCleanup(); - } - - if (timeout > 0) - { - if (diffTs >= timeout) - { - #ifdef TEST - *logofs << "NXTransWatchdog: Timeout of " << timeout - << " Ms raised in watchdog.\n" << logofs_flush; - #endif - - // - // We will just exit. Our parent should be - // monitoring us and detect that the process - // is gone. - // - - HandleCleanup(); - } - } - - if (timeout > 0) - { - #ifdef TEST - *logofs << "NXTransWatchdog: Waiting for the timeout " - << "with " << timeout - diffTs << " Ms to run.\n" - << logofs_flush; - #endif - - usleep((timeout - diffTs) * 1000); - - diffTs = diffTimestamp(startTs, getNewTimestamp()); - } - else - { - #ifdef TEST - *logofs << "NXTransWatchdog: Waiting for a signal.\n" - << logofs_flush; - #endif - - sleep(10); - } - } - - // - // Hopefully useless. - // - - exit(0); -} - -int NXTransKeeperHandler(int signal) -{ - if (keeper != NULL) - { - switch (signal) - { - case SIGTERM: - case SIGINT: - case SIGHUP: - { - #ifdef TEST - *logofs << "NXTransKeeperHandler: Requesting giveup " - << "because of signal " << signal << " ,'" - << DumpSignal(signal) << "'.\n" - << logofs_flush; - #endif - - keeper -> setSignal(signal); - - return 0; - } - } - } - - return 1; -} - -void NXTransKeeperCheck() -{ - if (CheckParent("NXTransKeeper", "keeper", - keeper -> getParent()) == 0 || keeper -> getSignal() != 0) - { - #ifdef TEST - *logofs << "NXTransKeeperCheck: Exiting because of signal " - << "or no parent running.\n" << logofs_flush; - #endif - - HandleCleanup(); - } -} - -int NXTransKeeper(int caches, int images, const char *root) -{ - // - // Be sure log file is valid. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - if (caches == 0 && images == 0) - { - #ifdef TEST - *logofs << "NXTransKeeper: No NX cache house-keeping needed.\n" - << logofs_flush; - #endif - - return 0; - } - - int pid; - - #ifdef TEST - *logofs << "NXTransKeeper: Going to fork with NX pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - pid = Fork(); - - if (pid != 0) - { - if (pid < 0) - { - #ifdef TEST - *logofs << "NXTransKeeper: WARNING! Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - } - #ifdef TEST - else - { - *logofs << "NXTransKeeper: Created NX keeper process " - << "with pid '" << pid << "'.\n" - << logofs_flush; - } - #endif - - return pid; - } - - int parent = getppid(); - - #ifdef TEST - *logofs << "NXTransKeeper: Executing child with pid '" - << getpid() << "' and parent '" << parent - << "'.\n" << logofs_flush; - #endif - - SystemCleanup("NXTransKeeper"); - - #ifdef TEST - *logofs << "NXTransKeeper: Going to run with caches " << caches - << " images " << images << " and root " << root - << " at " << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - // - // Create the house-keeper class. - // - - int timeout = control -> KeeperTimeout; - - keeper = new Keeper(caches, images, root, 100, parent); - - handler = NXTransKeeperHandler; - - if (keeper == NULL) - { - #ifdef PANIC - *logofs << "NXTransKeeper: PANIC! Failed to create the keeper object.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to create the keeper object.\n"; - - HandleCleanup(); - } - - // - // Get rid of unused resources. Root path - // must be copied in keeper's constructor - // before control is deleted. - // - - MemoryCleanup("NXTransKeeper"); - - // - // Decrease the priority of this process. - // - // The following applies to Cygwin: "Cygwin processes can be - // set to IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, HIGH_- - // PRIORITY_CLASS, or REALTIME_PRIORITY_CLASS with the nice - // call. If you pass a positive number to nice(), then the - // priority level will decrease by one (within the above list - // of priorities). A negative number would make it increase - // by one. It is not possible to change it by more than one - // at a time without making repeated calls". - // - - if (nice(5) < 0 && errno != 0) - { - #ifdef WARNING - *logofs << "NXTransKeeper: WARNING! Failed to renice process to +5. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Failed to renice process to +5. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - } - - // - // Delay a bit the first run to give - // a boost to the session startup. - // - - #ifdef TEST - *logofs << "NXTransKeeper: Going to sleep for " - << timeout / 20 << " Ms.\n" << logofs_flush; - #endif - - usleep(timeout / 20 * 1000); - - NXTransKeeperCheck(); - - // - // The house keeping of the persistent - // caches is performed only once. - // - - if (caches != 0) - { - #ifdef TEST - *logofs << "NXTransKeeper: Going to cleanup the NX cache " - << "directories at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - keeper -> cleanupCaches(); - - #ifdef TEST - *logofs << "NXTransKeeper: Completed cleanup of NX cache " - << "directories at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - } - #ifdef TEST - else - { - *logofs << "NXTransKeeper: Nothing to do for the " - << "persistent caches.\n" << logofs_flush; - } - #endif - - if (images == 0) - { - #ifdef TEST - *logofs << "NXTransKeeper: Nothing to do for the " - << "persistent images.\n" << logofs_flush; - #endif - - HandleCleanup(); - } - - // - // Take care of the persisten image cache. - // Run a number of iterations and then exit, - // so we can keep the memory consumption - // low. The parent will check our exit code - // and will eventually restart us. - // - - for (int iterations = 0; iterations < 100; iterations++) - { - #ifdef TEST - *logofs << "NXTransKeeper: Running iteration " << iterations - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - NXTransKeeperCheck(); - - #ifdef TEST - *logofs << "NXTransKeeper: Going to cleanup the NX images " - << "directories at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - if (keeper -> cleanupImages() < 0) - { - #ifdef TEST - *logofs << "NXTransKeeper: Exiting because of error " - << "handling the image cache.\n" << logofs_flush; - #endif - - HandleCleanup(); - } - - #ifdef TEST - *logofs << "NXTransKeeper: Completed cleanup of NX images " - << "directories at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - NXTransKeeperCheck(); - - #ifdef TEST - *logofs << "NXTransKeeper: Going to sleep for " << timeout - << " Ms.\n" << logofs_flush; - #endif - - usleep(timeout * 1000); - } - - HandleCleanup(2); - - // - // Hopefully useless. - // - - exit(0); -} - -void SystemCleanup(const char *name) -{ - #ifdef TEST - *logofs << name << ": Performing system cleanup in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - // - // Reinstall signals that might - // have been restored by agents. - // - - InstallSignals(); -} - -void MemoryCleanup(const char *name) -{ - #ifdef TEST - *logofs << name << ": Performing memory cleanup in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - DisableSignals(); - - // - // Prevent deletion of unix socket - // and lock file. - // - - useUnixSocket = 0; - - // - // Don't let cleanup kill other - // children. - // - - lastDialog = 0; - lastWatchdog = 0; - lastKeeper = 0; - - CleanupListeners(); - - CleanupSockets(); - - CleanupGlobal(); - - EnableSignals(); -} - -int UnsetEnv(const char *name) -{ - int result; - - #ifdef __sun - - char **pEnv = environ; - - int nameLen = strlen(name) + 1; - - char *varName = new char[nameLen + 1]; - - strcpy(varName, name); - - strcat(varName, "="); - - pEnv = environ; - - while (*pEnv != NULL) - { - if (!strncmp(varName, *pEnv, nameLen)) - { - break; - } - - *pEnv++; - } - - while (*pEnv != NULL) - { - *pEnv = *(pEnv + 1); - - pEnv++; - } - - result = 0; - - #else - - #ifdef __APPLE__ - - unsetenv(name); - result = 0; - - #else - - result = unsetenv(name); - - #endif - - #endif - - return result; -} diff --git a/nxcomp/ClearArea.cpp b/nxcomp/ClearArea.cpp deleted file mode 100644 index b76e750a4..000000000 --- a/nxcomp/ClearArea.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ClearArea.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int ClearAreaStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ClearAreaMessage *clearArea = (ClearAreaMessage *) message; - - // - // Here is the fingerprint. - // - - clearArea -> exposures = *(buffer + 1); - - clearArea -> window = GetULONG(buffer + 4, bigEndian); - - clearArea -> x = GetUINT(buffer + 8, bigEndian); - clearArea -> y = GetUINT(buffer + 10, bigEndian); - clearArea -> width = GetUINT(buffer + 12, bigEndian); - clearArea -> height = GetUINT(buffer + 14, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ClearAreaStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ClearAreaMessage *clearArea = (ClearAreaMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = clearArea -> exposures; - - PutULONG(clearArea -> window, buffer + 4, bigEndian); - - PutUINT(clearArea -> x, buffer + 8, bigEndian); - PutUINT(clearArea -> y, buffer + 10, bigEndian); - PutUINT(clearArea -> width, buffer + 12, bigEndian); - PutUINT(clearArea -> height, buffer + 14, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void ClearAreaStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - ClearAreaMessage *clearArea = (ClearAreaMessage *) message; - - *logofs << name() << ": Identity exposures " << (unsigned int) clearArea -> exposures - << ", window " << clearArea -> window << ", x " << clearArea -> x - << ", y " << clearArea -> y << ", width " << clearArea -> width - << ", height " << clearArea -> height << ", size " << clearArea -> size_ - << ".\n"; - - #endif -} - -void ClearAreaStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 4, 4); - md5_append(md5_state_, buffer + 8, 2); - md5_append(md5_state_, buffer + 10, 2); - md5_append(md5_state_, buffer + 12, 2); - md5_append(md5_state_, buffer + 14, 2); -} diff --git a/nxcomp/ClearArea.h b/nxcomp/ClearArea.h deleted file mode 100644 index 8067edffd..000000000 --- a/nxcomp/ClearArea.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ClearArea_H -#define ClearArea_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define CLEARAREA_ENABLE_CACHE 1 -#define CLEARAREA_ENABLE_DATA 0 -#define CLEARAREA_ENABLE_SPLIT 0 -#define CLEARAREA_ENABLE_COMPRESS 0 - -#define CLEARAREA_DATA_LIMIT 0 -#define CLEARAREA_DATA_OFFSET 16 - -#define CLEARAREA_CACHE_SLOTS 3000 -#define CLEARAREA_CACHE_THRESHOLD 5 -#define CLEARAREA_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class ClearAreaMessage : public Message -{ - friend class ClearAreaStore; - - public: - - ClearAreaMessage() - { - } - - ~ClearAreaMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char exposures; - unsigned int window; - unsigned short x; - unsigned short y; - unsigned short width; - unsigned short height; -}; - -class ClearAreaStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - ClearAreaStore() : MessageStore() - { - enableCache = CLEARAREA_ENABLE_CACHE; - enableData = CLEARAREA_ENABLE_DATA; - enableSplit = CLEARAREA_ENABLE_SPLIT; - enableCompress = CLEARAREA_ENABLE_COMPRESS; - - dataLimit = CLEARAREA_DATA_LIMIT; - dataOffset = CLEARAREA_DATA_OFFSET; - - cacheSlots = CLEARAREA_CACHE_SLOTS; - cacheThreshold = CLEARAREA_CACHE_THRESHOLD; - cacheLowerThreshold = CLEARAREA_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~ClearAreaStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "ClearArea"; - } - - virtual unsigned char opcode() const - { - return X_ClearArea; - } - - virtual unsigned int storage() const - { - return sizeof(ClearAreaMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new ClearAreaMessage(); - } - - virtual Message *create(const Message &message) const - { - return new ClearAreaMessage((const ClearAreaMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (ClearAreaMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* ClearArea_H */ diff --git a/nxcomp/ClientCache.cpp b/nxcomp/ClientCache.cpp deleted file mode 100644 index b6c04dd0b..000000000 --- a/nxcomp/ClientCache.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ClientCache.h" - -ClientCache::ClientCache() : - - freeGCCache(16), freeDrawableCache(16), freeWindowCache(16), - - cursorCache(16), colormapCache(16), visualCache(16), lastFont(0), - - changePropertyPropertyCache(16), changePropertyTypeCache(16), - changePropertyData32Cache(16), - - configureWindowBitmaskCache(4), - - convertSelectionRequestorCache(16), - convertSelectionLastTimestamp(0), - - copyPlaneBitPlaneCache(8), - - createGCBitmaskCache(8), - - createPixmapIdCache(16), createPixmapLastId(0), - createPixmapXCache(8), createPixmapYCache(8), - - createWindowBitmaskCache(8), - - fillPolyNumPointsCache(8), fillPolyIndex(0), - - getSelectionOwnerSelectionCache(8), - - grabButtonEventMaskCache(8), grabButtonConfineCache(8), - grabButtonModifierCache(8), - - grabKeyboardLastTimestamp(0), - - imageTextLengthCache(8), - imageTextLastX(0), imageTextLastY(0), - imageTextCacheX(8), imageTextCacheY(8), - - polySegmentCacheX(8), polySegmentCacheY(8), polySegmentCacheIndex(0), - - polyTextLastX(0), polyTextLastY(0), polyTextCacheX(8), - polyTextCacheY(8), polyTextFontCache(8), - - putImageWidthCache(8), putImageHeightCache(8), putImageLastX(0), - putImageLastY(0), putImageXCache(8), putImageYCache(8), - - getImagePlaneMaskCache(8), - - queryColorsLastPixel(0), - - setClipRectanglesXCache(8), setClipRectanglesYCache(8), - - setDashesLengthCache(8), setDashesOffsetCache(8), - - setSelectionOwnerCache(8), setSelectionOwnerTimestampCache(8), - - translateCoordsSrcCache(8), translateCoordsDstCache(8), - translateCoordsXCache(8), translateCoordsYCache(8), - - sendEventMaskCache(16), sendEventLastSequence(0), - sendEventIntDataCache(16), - - putPackedImageSrcLengthCache(16), putPackedImageDstLengthCache(16), - - // - // RenderExtension requests. - // - - renderFreePictureCache(16), - - renderGlyphSetCache(16), - renderFreeGlyphSetCache(16), - - renderIdCache(8), - - renderLengthCache(16), renderFormatCache(16), - renderValueMaskCache(8), renderNumGlyphsCache(8), - - renderXCache(16), renderYCache(16), - renderLastX(0), renderLastY(0), - - renderWidthCache(16), renderHeightCache(16), - - renderLastId(0), - - renderGlyphXCache(16), renderGlyphYCache(16), - renderGlyphX(0), renderGlyphY(0), - - renderLastCompositeGlyphsData(0), - - setCacheParametersCache(8), - - lastIdCache(16), lastId(0) - -{ - unsigned int i; - - for (i = 0; i < 3; i++) - { - allocColorRGBCache[i] = new IntCache(8); - - convertSelectionAtomCache[i] = new IntCache(8); - } - - for (i = 0; i < 4; i++) - { - clearAreaGeomCache[i] = new IntCache(8); - } - - for (i = 0; i < 7; i++) - { - configureWindowAttrCache[i] = new IntCache(8); - } - - for (i = 0; i < 6; i++) - { - copyAreaGeomCache[i] = new IntCache(8); - copyPlaneGeomCache[i] = new IntCache(8); - } - - for (i = 0; i < 23; i++) - { - if (CREATEGC_FIELD_WIDTH[i] > 16) - { - createGCAttrCache[i] = new IntCache(16); - } - else - { - createGCAttrCache[i] = new IntCache(CREATEGC_FIELD_WIDTH[i]); - } - } - - for (i = 0; i < 6; i++) - { - createWindowGeomCache[i] = new IntCache(8); - } - - for (i = 0; i < 15; i++) - { - createWindowAttrCache[i] = new IntCache(8); - } - - for (i = 0; i < 10; i++) - { - fillPolyXRelCache[i] = new IntCache(8); - fillPolyXAbsCache[i] = new IntCache(8); - fillPolyYRelCache[i] = new IntCache(8); - fillPolyYAbsCache[i] = new IntCache(8); - } - - for (i = 0; i < 8; i++) - { - fillPolyRecentX[i] = 0; - fillPolyRecentY[i] = 0; - } - - for (i = 0; i < 4; i++) - { - polyFillRectangleCacheX[i] = new IntCache(8); - polyFillRectangleCacheY[i] = new IntCache(8); - polyFillRectangleCacheWidth[i] = new IntCache(8); - polyFillRectangleCacheHeight[i] = new IntCache(8); - } - - for (i = 0; i < 2; i++) - { - polyLineCacheX[i] = new IntCache(8); - polyLineCacheY[i] = new IntCache(8); - } - - for (i = 0; i < 2; i++) - { - polyPointCacheX[i] = new IntCache(8); - polyPointCacheY[i] = new IntCache(8); - } - - for (i = 0; i < 4; i++) - { - polyRectangleGeomCache[i] = new IntCache(8); - } - - for (i = 0; i < 2; i++) - { - polySegmentLastX[i] = 0; - polySegmentLastY[i] = 0; - } - - for (i = 0; i < 4; i++) - { - setClipRectanglesGeomCache[i] = new IntCache(8); - } - - for (i = 0; i < 2; i++) - { - polyFillArcCacheX[i] = new IntCache(8); - polyFillArcCacheY[i] = new IntCache(8); - polyFillArcCacheWidth[i] = new IntCache(8); - polyFillArcCacheHeight[i] = new IntCache(8); - polyFillArcCacheAngle1[i] = new IntCache(8); - polyFillArcCacheAngle2[i] = new IntCache(8); - } - - for (i = 0; i < 2; i++) - { - polyArcCacheX[i] = new IntCache(8); - polyArcCacheY[i] = new IntCache(8); - polyArcCacheWidth[i] = new IntCache(8); - polyArcCacheHeight[i] = new IntCache(8); - polyArcCacheAngle1[i] = new IntCache(8); - polyArcCacheAngle2[i] = new IntCache(8); - } - - for (i = 0; i < 8; i++) - { - shapeDataCache[i] = new IntCache(8); - } - - for (i = 0; i < 8; i++) - { - genericRequestDataCache[i] = new IntCache(8); - } - - for (i = 0; i < 16; i++) - { - renderDataCache[i] = new IntCache(16); - } - - for (i = 0; i < 16; i++) - { - renderCompositeGlyphsDataCache[i] = new IntCache(16); - } - - for (i = 0; i < 3; i++) - { - renderCompositeDataCache[i] = new IntCache(16); - } -} - - -ClientCache::~ClientCache() -{ - unsigned int i; - - for (i = 0; i < 3; i++) - { - delete allocColorRGBCache[i]; - delete convertSelectionAtomCache[i]; - } - - for (i = 0; i < 4; i++) - { - delete clearAreaGeomCache[i]; - } - - for (i = 0; i < 7; i++) - { - delete configureWindowAttrCache[i]; - } - - for (i = 0; i < 6; i++) - { - delete copyAreaGeomCache[i]; - delete copyPlaneGeomCache[i]; - } - - for (i = 0; i < 23; i++) - { - delete createGCAttrCache[i]; - } - - for (i = 0; i < 6; i++) - { - delete createWindowGeomCache[i]; - } - - for (i = 0; i < 15; i++) - { - delete createWindowAttrCache[i]; - } - - for (i = 0; i < 10; i++) - { - delete fillPolyXRelCache[i]; - delete fillPolyXAbsCache[i]; - delete fillPolyYRelCache[i]; - delete fillPolyYAbsCache[i]; - } - - for (i = 0; i < 4; i++) - { - delete polyFillRectangleCacheX[i]; - delete polyFillRectangleCacheY[i]; - delete polyFillRectangleCacheWidth[i]; - delete polyFillRectangleCacheHeight[i]; - } - - for (i = 0; i < 2; i++) - { - delete polyLineCacheX[i]; - delete polyLineCacheY[i]; - } - - for (i = 0; i < 2; i++) - { - delete polyPointCacheX[i]; - delete polyPointCacheY[i]; - } - - for (i = 0; i < 4; i++) - { - delete polyRectangleGeomCache[i]; - } - - for (i = 0; i < 4; i++) - { - delete setClipRectanglesGeomCache[i]; - } - - for (i = 0; i < 2; i++) - { - delete polyFillArcCacheX[i]; - delete polyFillArcCacheY[i]; - delete polyFillArcCacheWidth[i]; - delete polyFillArcCacheHeight[i]; - delete polyFillArcCacheAngle1[i]; - delete polyFillArcCacheAngle2[i]; - } - - for (i = 0; i < 2; i++) - { - delete polyArcCacheX[i]; - delete polyArcCacheY[i]; - delete polyArcCacheWidth[i]; - delete polyArcCacheHeight[i]; - delete polyArcCacheAngle1[i]; - delete polyArcCacheAngle2[i]; - } - - for (i = 0; i < 8; i++) - { - delete shapeDataCache[i]; - } - - for (i = 0; i < 8; i++) - { - delete genericRequestDataCache[i]; - } - - for (i = 0; i < 16; i++) - { - delete renderDataCache[i]; - } - - for (i = 0; i < 16; i++) - { - delete renderCompositeGlyphsDataCache[i]; - } - - for (i = 0; i < 3; i++) - { - delete renderCompositeDataCache[i]; - } -} diff --git a/nxcomp/ClientCache.h b/nxcomp/ClientCache.h deleted file mode 100644 index ed3361097..000000000 --- a/nxcomp/ClientCache.h +++ /dev/null @@ -1,417 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ClientCache_H -#define ClientCache_H - -#include "Misc.h" - -#include "IntCache.h" -#include "CharCache.h" -#include "OpcodeCache.h" -#include "XidCache.h" -#include "FreeCache.h" - -#include "ChannelCache.h" - -class ClientCache : public ChannelCache -{ - public: - - ClientCache(); - - ~ClientCache(); - - // - // Opcode prediction caches. - // - - OpcodeCache opcodeCache; - - // - // GC and drawables caches. - // - - XidCache gcCache; - FreeCache freeGCCache; - - XidCache drawableCache; - FreeCache freeDrawableCache; - - XidCache windowCache; - FreeCache freeWindowCache; - - // - // General-purpose caches. - // - - IntCache cursorCache; - IntCache colormapCache; - IntCache visualCache; - CharCache depthCache; - CharCache resourceCache; - CharCache methodCache; - - unsigned int lastFont; - - // - // AllocColor request. - // - - IntCache *allocColorRGBCache[3]; - - // - // ChangeProperty request. - // - - CharCache changePropertyFormatCache; - IntCache changePropertyPropertyCache; - IntCache changePropertyTypeCache; - IntCache changePropertyData32Cache; - - // - // ClearArea request. - // - - IntCache *clearAreaGeomCache[4]; - - // - // ConfigureWindow request. - // - - IntCache configureWindowBitmaskCache; - IntCache *configureWindowAttrCache[7]; - - // - // ConvertSelection request. - // - - IntCache convertSelectionRequestorCache; - IntCache* convertSelectionAtomCache[3]; - unsigned int convertSelectionLastTimestamp; - - // - // CopyArea request. - // - - IntCache *copyAreaGeomCache[6]; - - // - // CopyPlane request. - // - - IntCache *copyPlaneGeomCache[6]; - IntCache copyPlaneBitPlaneCache; - - // - // CreateGC request. - // - - IntCache createGCBitmaskCache; - IntCache *createGCAttrCache[23]; - - // - // CreatePixmap request. - // - - IntCache createPixmapIdCache; - unsigned int createPixmapLastId; - IntCache createPixmapXCache; - IntCache createPixmapYCache; - - // - // CreateWindow request. - // - - IntCache *createWindowGeomCache[6]; - IntCache createWindowBitmaskCache; - IntCache *createWindowAttrCache[15]; - - // - // FillPoly request. - // - - IntCache fillPolyNumPointsCache; - IntCache *fillPolyXRelCache[10]; - IntCache *fillPolyXAbsCache[10]; - IntCache *fillPolyYRelCache[10]; - IntCache *fillPolyYAbsCache[10]; - unsigned int fillPolyRecentX[8]; - unsigned int fillPolyRecentY[8]; - unsigned int fillPolyIndex; - - // - // GetSelectionOwner request. - // - - IntCache getSelectionOwnerSelectionCache; - - // - // GrabButton request (also used for GrabPointer). - // - - IntCache grabButtonEventMaskCache; - IntCache grabButtonConfineCache; - CharCache grabButtonButtonCache; - IntCache grabButtonModifierCache; - - // - // GrabKeyboard request. - // - - unsigned int grabKeyboardLastTimestamp; - - // - // ImageText8/16 request. - // - - IntCache imageTextLengthCache; - unsigned int imageTextLastX; - unsigned int imageTextLastY; - IntCache imageTextCacheX; - IntCache imageTextCacheY; - - // - // PolyFillRectangle request. - // - - IntCache *polyFillRectangleCacheX[4]; - IntCache *polyFillRectangleCacheY[4]; - IntCache *polyFillRectangleCacheWidth[4]; - IntCache *polyFillRectangleCacheHeight[4]; - - // - // PolyLine request. - // - - IntCache *polyLineCacheX[2]; - IntCache *polyLineCacheY[2]; - - // - // PolyPoint request. - // - - IntCache *polyPointCacheX[2]; - IntCache *polyPointCacheY[2]; - - // - // PolyRectangle request. - // - - IntCache *polyRectangleGeomCache[4]; - - // - // PolySegment request. - // - - IntCache polySegmentCacheX; - IntCache polySegmentCacheY; - unsigned int polySegmentLastX[2]; - unsigned int polySegmentLastY[2]; - unsigned int polySegmentCacheIndex; - - // - // PolyText8/16 request. - // - - unsigned int polyTextLastX; - unsigned int polyTextLastY; - IntCache polyTextCacheX; - IntCache polyTextCacheY; - IntCache polyTextFontCache; - CharCache polyTextDeltaCache; - - // - // PutImage request. - // - - IntCache putImageWidthCache; - IntCache putImageHeightCache; - unsigned int putImageLastX; - unsigned int putImageLastY; - IntCache putImageXCache; - IntCache putImageYCache; - CharCache putImageLeftPadCache; - - // - // GetImage request. - // - - IntCache getImagePlaneMaskCache; - - // - // QueryColors request. - // - - unsigned int queryColorsLastPixel; - - // - // SetClipRectangles request. - // - - IntCache setClipRectanglesXCache; - IntCache setClipRectanglesYCache; - IntCache *setClipRectanglesGeomCache[4]; - - // - // SetDashes request. - // - - IntCache setDashesLengthCache; - IntCache setDashesOffsetCache; - CharCache setDashesDashCache_[2]; - - // - // SetSelectionOwner request. - // - - IntCache setSelectionOwnerCache; - IntCache setSelectionOwnerTimestampCache; - - // - // TranslateCoords request. - // - - IntCache translateCoordsSrcCache; - IntCache translateCoordsDstCache; - IntCache translateCoordsXCache; - IntCache translateCoordsYCache; - - // - // SendEvent request. - // - - IntCache sendEventMaskCache; - CharCache sendEventCodeCache; - CharCache sendEventByteDataCache; - unsigned int sendEventLastSequence; - IntCache sendEventIntDataCache; - CharCache sendEventEventCache; - - // - // PolyFillArc request. - // - - IntCache *polyFillArcCacheX[2]; - IntCache *polyFillArcCacheY[2]; - IntCache *polyFillArcCacheWidth[2]; - IntCache *polyFillArcCacheHeight[2]; - IntCache *polyFillArcCacheAngle1[2]; - IntCache *polyFillArcCacheAngle2[2]; - - // - // PolyArc request. - // - - IntCache *polyArcCacheX[2]; - IntCache *polyArcCacheY[2]; - IntCache *polyArcCacheWidth[2]; - IntCache *polyArcCacheHeight[2]; - IntCache *polyArcCacheAngle1[2]; - IntCache *polyArcCacheAngle2[2]; - - // - // PutPackedImage request. - // - - IntCache putPackedImageSrcLengthCache; - IntCache putPackedImageDstLengthCache; - - // - // Shape extension requests. - // - - CharCache shapeOpcodeCache; - IntCache *shapeDataCache[8]; - - // - // Generic requests. - // - - CharCache genericRequestOpcodeCache; - IntCache *genericRequestDataCache[8]; - - // - // Render extension requests. - // - - OpcodeCache renderOpcodeCache; - - CharCache renderOpCache; - - XidCache renderSrcPictureCache; - XidCache renderMaskPictureCache; - XidCache renderDstPictureCache; - FreeCache renderFreePictureCache; - - IntCache renderGlyphSetCache; - FreeCache renderFreeGlyphSetCache; - - IntCache renderIdCache; - IntCache renderLengthCache; - IntCache renderFormatCache; - IntCache renderValueMaskCache; - IntCache renderNumGlyphsCache; - - IntCache renderXCache; - IntCache renderYCache; - - unsigned int renderLastX; - unsigned int renderLastY; - - IntCache renderWidthCache; - IntCache renderHeightCache; - - unsigned int renderLastId; - - IntCache *renderDataCache[16]; - - IntCache renderGlyphXCache; - IntCache renderGlyphYCache; - - unsigned int renderGlyphX; - unsigned int renderGlyphY; - - IntCache *renderCompositeGlyphsDataCache[16]; - unsigned int renderLastCompositeGlyphsData; - - IntCache *renderCompositeDataCache[3]; - - // - // SetCacheParameters request. - // - - IntCache setCacheParametersCache; - - // - // Encode new XID values based - // on the last value encoded. - // - - IntCache lastIdCache; - unsigned int lastId; -}; - -#endif /* ClientCache_H */ diff --git a/nxcomp/ClientChannel.cpp b/nxcomp/ClientChannel.cpp deleted file mode 100644 index dbf5f6986..000000000 --- a/nxcomp/ClientChannel.cpp +++ /dev/null @@ -1,7877 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include - -#include -#include - -#include "NXproto.h" -#include "NXrender.h" - -#include "ClientChannel.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "StaticCompressor.h" - -#include "Statistics.h" -#include "Proxy.h" - -#include "PutImage.h" -#include "PutPackedImage.h" - -extern Proxy *proxy; - -// -// Set the verbosity level. You also -// need to define OPCODES in Misc.cpp -// if you want literals instead of -// opcodes' numbers. -// - -#define PANIC -#define WARNING -#undef OPCODES -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Log the important tracepoints related -// to writing packets to the peer proxy. -// - -#undef FLUSH - -// -// Log the operations related to splits. -// - -#undef SPLIT - -// -// Define this to trace the invocations -// of the agent's callbacks. -// - -#undef CALLBACK - -// -// By defining this, a simple procedure is activated at -// startup which just allocates and deallocates plenty -// of cache objects. This is used to help determine the -// current memory requirements. -// - -#undef MEMORY - -// -// Inspects target of common X operations. -// - -#undef TARGETS - -#ifdef TARGETS - -#include -#include - -typedef set < unsigned int, less > T_windows; -typedef set < unsigned int, less > T_pixmaps; -typedef map < unsigned int, unsigned int, less > T_gcontexts; - -T_windows windows; -T_pixmaps pixmaps; -T_gcontexts gcontexts; - -#endif - -// -// Define this to log when a channel -// is created or destroyed. -// - -#undef REFERENCES - -// -// Here are the static members. -// - -#ifdef REFERENCES - -int ClientChannel::references_ = 0; - -#endif - -ClientChannel::ClientChannel(Transport *transport, StaticCompressor *compressor) - - : Channel(transport, compressor), readBuffer_(transport_, this) -{ - // - // Sequence number of the next message - // being encoded or decoded. - // - - clientSequence_ = 0; - serverSequence_ = 0; - - // - // Current sequence known by NX agent. - // - - lastSequence_ = 0; - - // - // This is used to test the synchronous - // flush in the proxy. - // - - lastRequest_ = 0; - - // - // Store information about the images - // being streamed. - // - - splitState_.resource = nothing; - splitState_.pending = 0; - splitState_.commit = 0; - splitState_.mode = split_none; - - // - // Number of outstanding tainted replies. - // - - taintCounter_ = 0; - - #ifdef MEMORY - - *logofs << "ClientChannel: Created 1 ClientCache and 1 ServerCache. " - << "You have 30 seconds to check the allocated size.\n" - << logofs_flush; - - sleep(30); - - ClientCache *clientCacheTestArray[100]; - ServerCache *serverCacheTestArray[100]; - - for (int i = 0; i < 100; i++) - { - clientCacheTestArray[i] = new ClientCache(); - } - - *logofs << "ClientChannel: Created further 100 ClientCache. " - << "You have 30 seconds to check the allocated size.\n" - << logofs_flush; - - sleep(30); - - for (int i = 0; i < 100; i++) - { - serverCacheTestArray[i] = new ServerCache(); - } - - *logofs << "ClientChannel: Created further 100 ServerCache. " - << "You have 30 seconds to check the allocated size.\n" - << logofs_flush; - - sleep(30); - - for (int i = 0; i < 100; i++) - { - delete clientCacheTestArray[i]; - delete serverCacheTestArray[i]; - } - - *logofs << "ClientChannel: Deleted 100 ClientCache and 100 ServerCache. " - << "You have 30 seconds to check the allocated size.\n" - << logofs_flush; - - sleep(30); - - #endif - - #ifdef REFERENCES - *logofs << "ClientChannel: Created new object at " - << this << " for FD#" << fd_ << " out of " - << ++references_ << " allocated channels.\n" - << logofs_flush; - #endif -} - -ClientChannel::~ClientChannel() -{ - #ifdef REFERENCES - *logofs << "ClientChannel: Deleted object at " - << this << " for FD#" << fd_ << " out of " - << --references_ << " allocated channels.\n" - << logofs_flush; - #endif -} - -// -// Beginning of handleRead(). -// - -int ClientChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, - unsigned int length) -{ - #ifdef TEST - *logofs << "handleRead: Called for FD#" << fd_ - << " with " << encodeBuffer.getLength() - << " bytes already encoded.\n" - << logofs_flush; - #endif - - // - // Pointer to located message and - // its size in bytes. - // - - const unsigned char *inputMessage; - unsigned int inputLength; - - // - // Set when message is found in - // cache. - // - - int hit; - - // - // Check if we can borrow the buffer - // from the caller. - // - - if (message != NULL && length != 0) - { - readBuffer_.readMessage(message, length); - } - else - { - // - // Get the data from the transport. - // - - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: Trying to read from FD#" - << fd_ << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - int result = readBuffer_.readMessage(); - - #ifdef DEBUG - *logofs << "handleRead: Read result on FD#" << fd_ - << " is " << result << ".\n" - << logofs_flush; - #endif - - if (result < 0) - { - // - // Let the proxy close the channel. - // - - return -1; - } - else if (result == 0) - { - #if defined(TEST) || defined(INFO) - - *logofs << "handleRead: PANIC! No data read from FD#" - << fd_ << " while encoding messages.\n" - << logofs_flush; - - HandleCleanup(); - - #endif - - return 0; - } - } - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "handleRead: Encoding messages for FD#" << fd_ - << " with " << readBuffer_.getLength() << " bytes " - << "in the buffer.\n" << logofs_flush; - #endif - - // - // Extract any complete message which - // is available in the buffer. - // - - if (proxy -> handleAsyncSwitch(fd_) < 0) - { - return -1; - } - - while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) - { - hit = 0; - - if (firstRequest_) - { - // - // Need to add the length of the first - // request as it was not present in - // previous versions. - // - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeValue(inputLength, 8); - - for (unsigned int i = 0; i < inputLength; i++) - { - encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8); - } - - firstRequest_ = 0; - - #if defined(TEST) || defined(OPCODES) - - int bits = encodeBuffer.diffBits(); - - *logofs << "handleRead: Handled first request. " << inputLength - << " bytes in, " << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - #endif - - priority_++; - } - else - { - // - // First of all we get the opcode. - // - - unsigned char inputOpcode = *inputMessage; - - #if defined(TEST) || defined(INFO) - - // - // This is used to test the synchronous - // flush in the parent proxy. - // - - lastRequest_ = inputOpcode; - - #endif - - // - // Check if the request is supported by the - // remote. If not, only handle it locally and - // taint the opcode as a X_NoOperation. Also - // try to short-circuit some replies at this - // side. XSync requests, for example, weight - // for half of the total round-trips. - // - - if (handleTaintRequest(inputOpcode, inputMessage, - inputLength) < 0) - { - return -1; - } - - encodeBuffer.encodeOpcodeValue(inputOpcode, clientCache_ -> opcodeCache); - - // - // Update the current sequence. - // - - clientSequence_++; - clientSequence_ &= 0xffff; - - #ifdef DEBUG - *logofs << "handleRead: Last client sequence number for FD#" - << fd_ << " is " << clientSequence_ << ".\n" - << logofs_flush; - #endif - - // - // If differential compression is disabled - // then use the most simple encoding. - // - - if (control -> LocalDeltaCompression == 0) - { - int result = handleFastReadRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength); - if (result < 0) - { - return -1; - } - else if (result > 0) - { - continue; - } - } - - // - // Go to the message's specific encoding. - // - - switch (inputOpcode) - { - case X_AllocColor: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, - clientCache_ -> colormapCache); - const unsigned char *nextSrc = inputMessage + 8; - unsigned int colorData[3]; - for (unsigned int i = 0; i < 3; i++) - { - unsigned int value = GetUINT(nextSrc, bigEndian_); - encodeBuffer.encodeCachedValue(value, 16, - *(clientCache_ -> allocColorRGBCache[i]), 4); - colorData[i] = value; - nextSrc += 2; - } - - sequenceQueue_.push(clientSequence_, inputOpcode, - colorData[0], colorData[1], colorData[2]); - - priority_++; - } - break; - case X_ReparentWindow: - { - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, bigEndian_), - clientCache_ -> windowCache); - encodeBuffer.encodeValue(GetUINT(inputMessage + 12, bigEndian_), 16, 11); - encodeBuffer.encodeValue(GetUINT(inputMessage + 14, bigEndian_), 16, 11); - } - break; - case X_ChangeProperty: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ChangeProperty); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - unsigned char format = inputMessage[16]; - encodeBuffer.encodeCachedValue(format, 8, - clientCache_ -> changePropertyFormatCache); - unsigned int dataLength = GetULONG(inputMessage + 20, bigEndian_); - encodeBuffer.encodeValue(dataLength, 32, 6); - encodeBuffer.encodeValue(inputMessage[1], 2); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, - clientCache_ -> changePropertyPropertyCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 29, - clientCache_ -> changePropertyTypeCache, 9); - const unsigned char *nextSrc = inputMessage + 24; - if (format == 8) - { - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, dataLength); - } - else if (format == 32) - { - for (unsigned int i = 0; i < dataLength; i++) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 32, - clientCache_ -> changePropertyData32Cache); - nextSrc += 4; - } - } - else - { - for (unsigned int i = 0; i < dataLength; i++) - { - encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16); - nextSrc += 2; - } - } - } - break; - case X_SendEvent: - { - // - // TODO: This can be improved. In the worst - // cases, it appears to provide a poor 1.6:1 - // ratio. - // - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_SendEvent); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - unsigned int window = GetULONG(inputMessage + 4, bigEndian_); - - if (window == 0 || window == 1) - { - encodeBuffer.encodeBoolValue(1); - encodeBuffer.encodeBoolValue(window); - } - else - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeXidValue(window, clientCache_ -> windowCache); - } - - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 32, - clientCache_ -> sendEventMaskCache, 9); - encodeBuffer.encodeCachedValue(*(inputMessage + 12), 8, - clientCache_ -> sendEventCodeCache); - encodeBuffer.encodeCachedValue(*(inputMessage + 13), 8, - clientCache_ -> sendEventByteDataCache); - - unsigned int newSeq = GetUINT(inputMessage + 14, bigEndian_); - unsigned int diffSeq = newSeq - clientCache_ -> sendEventLastSequence; - clientCache_ -> sendEventLastSequence = newSeq; - encodeBuffer.encodeValue(diffSeq, 16, 4); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), 32, - clientCache_ -> sendEventIntDataCache); - - for (unsigned int i = 20; i < 44; i++) - { - encodeBuffer.encodeCachedValue((unsigned int) inputMessage[i], 8, - clientCache_ -> sendEventEventCache); - } - } - break; - case X_ChangeWindowAttributes: - { - encodeBuffer.encodeValue((inputLength - 12) >> 2, 4); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - unsigned int bitmask = GetULONG(inputMessage + 8, bigEndian_); - encodeBuffer.encodeCachedValue(bitmask, 15, - clientCache_ -> createWindowBitmaskCache); - const unsigned char *nextSrc = inputMessage + 12; - unsigned int mask = 0x1; - for (unsigned int j = 0; j < 15; j++) - { - if (bitmask & mask) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 32, - *clientCache_ -> createWindowAttrCache[j]); - nextSrc += 4; - } - mask <<= 1; - } - } - break; - case X_ClearArea: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_ClearArea target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_ClearArea target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_ClearArea target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ClearArea); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - const unsigned char *nextSrc = inputMessage + 8; - for (unsigned int i = 0; i < 4; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *clientCache_ -> clearAreaGeomCache[i], 8); - nextSrc += 2; - } - } - break; - case X_CloseFont: - { - unsigned int font = GetULONG(inputMessage + 4, bigEndian_); - encodeBuffer.encodeValue(font - clientCache_ -> lastFont, 29, 5); - clientCache_ -> lastFont = font; - } - break; - case X_ConfigureWindow: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ConfigureWindow); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - unsigned int bitmask = GetUINT(inputMessage + 8, bigEndian_); - encodeBuffer.encodeCachedValue(bitmask, 7, - clientCache_ -> configureWindowBitmaskCache); - unsigned int mask = 0x1; - const unsigned char *nextSrc = inputMessage + 12; - for (unsigned int i = 0; i < 7; i++) - { - if (bitmask & mask) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), - CONFIGUREWINDOW_FIELD_WIDTH[i], - *clientCache_ -> configureWindowAttrCache[i], 8); - nextSrc += 4; - } - mask <<= 1; - } - } - break; - case X_ConvertSelection: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, - clientCache_ -> convertSelectionRequestorCache, 9); - const unsigned char* nextSrc = inputMessage + 8; - for (unsigned int i = 0; i < 3; i++) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29, - *(clientCache_ -> convertSelectionAtomCache[i]), 9); - nextSrc += 4; - } - unsigned int timestamp = GetULONG(nextSrc, bigEndian_); - encodeBuffer.encodeValue(timestamp - - clientCache_ -> convertSelectionLastTimestamp, 32, 4); - clientCache_ -> convertSelectionLastTimestamp = timestamp; - } - break; - case X_CopyArea: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_CopyArea source id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_CopyArea source id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_CopyArea source id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - t_id = GetULONG(inputMessage + 8, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_CopyArea target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_CopyArea target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_CopyArea target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_CopyArea); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 12, - bigEndian_), clientCache_ -> gcCache); - const unsigned char *nextSrc = inputMessage + 16; - for (unsigned int i = 0; i < 6; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *clientCache_ -> copyAreaGeomCache[i], 8); - nextSrc += 2; - } - } - break; - case X_CopyGC: - { - #ifdef TARGETS - - unsigned int s_g_id = GetULONG(inputMessage + 4, bigEndian_); - unsigned int d_g_id = GetULONG(inputMessage + 8, bigEndian_); - - *logofs << "handleRead: X_CopyGC source gcontext id is " << s_g_id - << " destination gcontext id is " << d_g_id << ".\n" - << logofs_flush; - - #endif - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> gcCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, - bigEndian_), 23, clientCache_ -> createGCBitmaskCache); - } - break; - case X_CopyPlane: - { - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 12, - bigEndian_), clientCache_ -> gcCache); - const unsigned char *nextSrc = inputMessage + 16; - for (unsigned int i = 0; i < 6; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *clientCache_ -> copyPlaneGeomCache[i], 8); - nextSrc += 2; - } - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 28, bigEndian_), 32, - clientCache_ -> copyPlaneBitPlaneCache, 10); - } - break; - case X_CreateGC: - { - #ifdef TARGETS - - unsigned int g_id = GetULONG(inputMessage + 4, bigEndian_); - unsigned int t_id = GetULONG(inputMessage + 8, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_CreateGC id " << g_id - << " target id is pixmap " << t_id - << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_CreateGC id " << g_id - << " target id is window " << t_id - << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_CreateGC id " << g_id - << " target id is unrecognized.\n" - << logofs_flush; - } - - gcontexts.insert(T_gcontexts::value_type(g_id, t_id)); - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_CreateGC); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeNewXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> lastId, clientCache_ -> lastIdCache, - clientCache_ -> gcCache, - clientCache_ -> freeGCCache); - - const unsigned char *nextSrc = inputMessage + 8; - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> drawableCache); - nextSrc += 4; - unsigned int bitmask = GetULONG(nextSrc, bigEndian_); - nextSrc += 4; - encodeBuffer.encodeCachedValue(bitmask, 23, - clientCache_ -> createGCBitmaskCache); - unsigned int mask = 0x1; - for (unsigned int i = 0; i < 23; i++) - { - if (bitmask & mask) - { - unsigned int value = GetULONG(nextSrc, bigEndian_); - nextSrc += 4; - unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i]; - if (fieldWidth <= 4) - { - encodeBuffer.encodeValue(value, fieldWidth); - } - else - { - encodeBuffer.encodeCachedValue(value, fieldWidth, - *clientCache_ -> createGCAttrCache[i]); - } - } - mask <<= 1; - } - } - break; - case X_ChangeGC: - { - #ifdef TARGETS - - unsigned int g_id = GetULONG(inputMessage + 4, bigEndian_); - - T_gcontexts::iterator i = gcontexts.find(g_id); - - if (i != gcontexts.end()) - { - unsigned int t_id = i -> second; - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_ChangeGC gcontext id is " << g_id - << " target id is pixmap " << t_id << ".\n" - << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_ChangeGC gcontext id is " << g_id - << " target id is window " << t_id << ".\n" - << logofs_flush; - } - else - { - *logofs << "handleRead: X_ChangeGC gcontext is " << g_id - << " target id is unrecognized.\n" - << logofs_flush; - } - } - else - { - *logofs << "handleRead: X_ChangeGC gcontext id " << g_id - << " is unrecognized.\n" << logofs_flush; - } - - gcontexts.erase(g_id); - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ChangeGC); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> gcCache); - const unsigned char *nextSrc = inputMessage + 8; - unsigned int bitmask = GetULONG(nextSrc, bigEndian_); - nextSrc += 4; - encodeBuffer.encodeCachedValue(bitmask, 23, - clientCache_ -> createGCBitmaskCache); - unsigned int mask = 0x1; - for (unsigned int i = 0; i < 23; i++) - { - if (bitmask & mask) - { - unsigned int value = GetULONG(nextSrc, bigEndian_); - nextSrc += 4; - unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i]; - if (fieldWidth <= 4) - { - encodeBuffer.encodeValue(value, fieldWidth); - } - else - { - encodeBuffer.encodeCachedValue(value, fieldWidth, - *clientCache_ -> createGCAttrCache[i]); - } - } - mask <<= 1; - } - } - break; - case X_CreatePixmap: - { - #ifdef TARGETS - - *logofs << "handleRead: X_CreatePixmap depth " << (unsigned) inputMessage[1] - << ", pixmap id " << GetULONG(inputMessage + 4, bigEndian_) - << ", drawable " << GetULONG(inputMessage + 8, bigEndian_) - << ", width " << GetUINT(inputMessage + 12, bigEndian_) - << ", height " << GetUINT(inputMessage + 14, bigEndian_) - << ", size " << GetUINT(inputMessage + 2, bigEndian_) << 2 - << ".\n" << logofs_flush; - - unsigned int p_id = GetULONG(inputMessage + 4, bigEndian_); - unsigned short p_sx = GetUINT(inputMessage + 12, bigEndian_); - unsigned short p_sy = GetUINT(inputMessage + 14, bigEndian_); - - *logofs << "handleRead: X_CreatePixmap id is " << p_id - << " width is " << p_sx << " height is " << p_sy - << ".\n" << logofs_flush; - - if (p_sx * p_sy <= 64 * 64) - { - *logofs << "handleRead: X_CreatePixmap id " << p_id << " of size " - << p_sx << "x" << p_sy << "=" << p_sx * p_sy - << " will be painted at client side.\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_CreatePixmap id " << p_id << " of size " - << p_sx << "x" << p_sy << "=" << p_sx * p_sy - << " will be painted at server side.\n" << logofs_flush; - } - - pixmaps.insert(p_id); - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_CreatePixmap); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - } - break; - case X_CreateWindow: - { - #ifdef TARGETS - - unsigned int w_id = GetULONG(inputMessage + 4, bigEndian_); - - *logofs << "handleRead: X_CreateWindow id is " << w_id - << ".\n" << logofs_flush; - - windows.insert(w_id); - - #endif - - unsigned bitmask = GetULONG(inputMessage + 28, bigEndian_); - encodeBuffer.encodeCachedValue((unsigned int) inputMessage[1], 8, - clientCache_ -> depthCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, bigEndian_), - clientCache_ -> windowCache); - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeNewXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> lastId, clientCache_ -> lastIdCache, - clientCache_ -> windowCache, - clientCache_ -> freeWindowCache); - - const unsigned char *nextSrc = inputMessage + 12; - for (unsigned int i = 0; i < 6; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *clientCache_ -> createWindowGeomCache[i], 8); - nextSrc += 2; - } - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 24, - bigEndian_), 29, clientCache_ -> visualCache); - encodeBuffer.encodeCachedValue(bitmask, 15, - clientCache_ -> createWindowBitmaskCache); - nextSrc = inputMessage + 32; - unsigned int mask = 0x1; - for (unsigned int j = 0; j < 15; j++) - { - if (bitmask & mask) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 32, - *clientCache_ -> createWindowAttrCache[j]); - nextSrc += 4; - } - mask <<= 1; - } - } - break; - case X_DeleteProperty: - { - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - encodeBuffer.encodeValue(GetULONG(inputMessage + 8, bigEndian_), 29, 9); - } - break; - case X_FillPoly: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_FillPoly target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_FillPoly target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_FillPoly target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_FillPoly); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - unsigned int numPoints = ((inputLength - 16) >> 2); - - // Since ProtoStep10 (#issue 108) - encodeBuffer.encodeCachedValue(numPoints, 16, - clientCache_ -> fillPolyNumPointsCache, 4); - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, bigEndian_), - clientCache_ -> gcCache); - encodeBuffer.encodeValue((unsigned int) inputMessage[12], 2); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[13]); - int relativeCoordMode = (inputMessage[13] != 0); - const unsigned char *nextSrc = inputMessage + 16; - unsigned int pointIndex = 0; - - for (unsigned int i = 0; i < numPoints; i++) - { - if (relativeCoordMode) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *clientCache_ -> fillPolyXRelCache[pointIndex], 8); - nextSrc += 2; - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *clientCache_ -> fillPolyYRelCache[pointIndex], 8); - nextSrc += 2; - } - else - { - unsigned int x = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - unsigned int y = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - unsigned int j; - for (j = 0; j < 8; j++) - if ((x == clientCache_ -> fillPolyRecentX[j]) && - (y == clientCache_ -> fillPolyRecentY[j])) - break; - if (j < 8) - { - encodeBuffer.encodeBoolValue(1); - encodeBuffer.encodeValue(j, 3); - } - else - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeCachedValue(x, 16, - *clientCache_ -> fillPolyXAbsCache[pointIndex], 8); - encodeBuffer.encodeCachedValue(y, 16, - *clientCache_ -> fillPolyYAbsCache[pointIndex], 8); - clientCache_ -> fillPolyRecentX[clientCache_ -> fillPolyIndex] = x; - clientCache_ -> fillPolyRecentY[clientCache_ -> fillPolyIndex] = y; - clientCache_ -> fillPolyIndex++; - if (clientCache_ -> fillPolyIndex == 8) - clientCache_ -> fillPolyIndex = 0; - } - } - - if (++pointIndex == 10) pointIndex = 0; - } - } - break; - case X_FreeColors: - { - unsigned int numPixels = GetUINT(inputMessage + 2, bigEndian_) - 3; - encodeBuffer.encodeValue(numPixels, 16, 4); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, - clientCache_ -> colormapCache); - encodeBuffer.encodeValue(GetULONG(inputMessage + 8, bigEndian_), 32, 4); - const unsigned char *nextSrc = inputMessage + 12; - while (numPixels) - { - encodeBuffer.encodeValue(GetULONG(nextSrc, bigEndian_), 32, 8); - nextSrc += 4; - numPixels--; - } - } - break; - case X_FreeCursor: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, clientCache_ -> cursorCache, 9); - } - break; - case X_FreeGC: - { - #ifdef TARGETS - - unsigned int g_id = GetULONG(inputMessage + 4, bigEndian_); - - T_gcontexts::iterator i = gcontexts.find(g_id); - - if (i != gcontexts.end()) - { - unsigned int t_id = i -> second; - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_FreeGC gcontext id is " << g_id - << " target id is pixmap " << t_id << ".\n" - << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_FreeGC gcontext id is " << g_id - << " target id is window " << t_id << ".\n" - << logofs_flush; - } - else - { - *logofs << "handleRead: X_FreeGC gcontext id is " << g_id - << " target id is unrecognized.\n" - << logofs_flush; - } - } - else - { - *logofs << "handleRead: X_FreeGC gcontext id " << g_id - << " is unrecognized.\n" << logofs_flush; - } - - gcontexts.erase(g_id); - - #endif - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeFreeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> freeGCCache); - } - break; - case X_FreePixmap: - { - #ifdef TARGETS - - unsigned int p_id = GetULONG(inputMessage + 4, bigEndian_); - - *logofs << "handleRead: X_FreePixmap id is " << p_id << ".\n" << logofs_flush; - - pixmaps.erase(p_id); - - #endif - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeFreeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> freeDrawableCache); - } - break; - case X_GetAtomName: - { - encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 29, 9); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GetGeometry: - { - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> drawableCache); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GetInputFocus: - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GetModifierMapping: - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GetKeyboardMapping: - { - encodeBuffer.encodeValue((unsigned int) inputMessage[4], 8); - encodeBuffer.encodeValue((unsigned int) inputMessage[5], 8); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GetProperty: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_GetProperty); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - unsigned int property = GetULONG(inputMessage + 8, bigEndian_); - - sequenceQueue_.push(clientSequence_, inputOpcode, property); - - priority_++; - - hit = 1; - - break; - } - - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - unsigned int property = GetULONG(inputMessage + 8, bigEndian_); - encodeBuffer.encodeValue(property, 29, 9); - encodeBuffer.encodeValue(GetULONG(inputMessage + 12, bigEndian_), 29, 9); - encodeBuffer.encodeValue(GetULONG(inputMessage + 16, bigEndian_), 32, 2); - encodeBuffer.encodeValue(GetULONG(inputMessage + 20, bigEndian_), 32, 8); - - sequenceQueue_.push(clientSequence_, inputOpcode, property); - - priority_++; - } - break; - case X_GetSelectionOwner: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, - clientCache_ -> getSelectionOwnerSelectionCache, 9); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GrabButton: - { - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, - clientCache_ -> grabButtonEventMaskCache); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[10]); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[11]); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 29, - clientCache_ -> grabButtonConfineCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), 29, - clientCache_ -> cursorCache, 9); - encodeBuffer.encodeCachedValue(inputMessage[20], 8, - clientCache_ -> grabButtonButtonCache); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 22, bigEndian_), 16, - clientCache_ -> grabButtonModifierCache); - } - break; - case X_GrabPointer: - { - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, - clientCache_ -> grabButtonEventMaskCache); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[10]); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[11]); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, - bigEndian_), 29, - clientCache_ -> grabButtonConfineCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, - bigEndian_), 29, clientCache_ -> cursorCache, 9); - - unsigned int timestamp = GetULONG(inputMessage + 20, bigEndian_); - encodeBuffer.encodeValue(timestamp - - clientCache_ -> grabKeyboardLastTimestamp, 32, 4); - clientCache_ -> grabKeyboardLastTimestamp = timestamp; - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GrabKeyboard: - { - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - unsigned int timestamp = GetULONG(inputMessage + 8, bigEndian_); - encodeBuffer.encodeValue(timestamp - - clientCache_ -> grabKeyboardLastTimestamp, 32, 4); - clientCache_ -> grabKeyboardLastTimestamp = timestamp; - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[12]); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[13]); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GrabServer: - case X_UngrabServer: - case X_NoOperation: - { - } - break; - case X_PolyText8: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PolyText8 target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PolyText8 target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PolyText8 target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyText8); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - unsigned int x = GetUINT(inputMessage + 12, bigEndian_); - int xDiff = x - clientCache_ -> polyTextLastX; - clientCache_ -> polyTextLastX = x; - encodeBuffer.encodeCachedValue(xDiff, 16, - clientCache_ -> polyTextCacheX); - unsigned int y = GetUINT(inputMessage + 14, bigEndian_); - int yDiff = y - clientCache_ -> polyTextLastY; - clientCache_ -> polyTextLastY = y; - encodeBuffer.encodeCachedValue(yDiff, 16, - clientCache_ -> polyTextCacheY); - const unsigned char *end = inputMessage + inputLength - 1; - const unsigned char *nextSrc = inputMessage + 16; - while (nextSrc < end) - { - unsigned int textLength = (unsigned int) *nextSrc++; - encodeBuffer.encodeBoolValue(1); - encodeBuffer.encodeValue(textLength, 8); - if (textLength == 255) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, 1), 29, - clientCache_ -> polyTextFontCache); - nextSrc += 4; - } - else - { - encodeBuffer.encodeCachedValue(*nextSrc++, 8, - clientCache_ -> polyTextDeltaCache); - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, textLength); - nextSrc += textLength; - } - } - encodeBuffer.encodeBoolValue(0); - } - break; - case X_PolyText16: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PolyText16 target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PolyText16 target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PolyText16 target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyText16); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - unsigned int x = GetUINT(inputMessage + 12, bigEndian_); - int xDiff = x - clientCache_ -> polyTextLastX; - clientCache_ -> polyTextLastX = x; - encodeBuffer.encodeCachedValue(xDiff, 16, - clientCache_ -> polyTextCacheX); - unsigned int y = GetUINT(inputMessage + 14, bigEndian_); - int yDiff = y - clientCache_ -> polyTextLastY; - clientCache_ -> polyTextLastY = y; - encodeBuffer.encodeCachedValue(yDiff, 16, - clientCache_ -> polyTextCacheY); - const unsigned char *end = inputMessage + inputLength - 1; - const unsigned char *nextSrc = inputMessage + 16; - while (nextSrc < end) - { - unsigned int textLength = (unsigned int) *nextSrc++; - encodeBuffer.encodeBoolValue(1); - encodeBuffer.encodeValue(textLength, 8); - if (textLength == 255) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, 1), 29, - clientCache_ -> polyTextFontCache); - nextSrc += 4; - } - else - { - encodeBuffer.encodeCachedValue(*nextSrc++, 8, - clientCache_ -> polyTextDeltaCache); - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, textLength * 2); - nextSrc += textLength * 2; - } - } - encodeBuffer.encodeBoolValue(0); - } - break; - case X_ImageText8: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_ImageText8 target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_ImageText8 target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_ImageText8 target id " - << t_id << " is unrecognized.\n" - << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ImageText8); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - unsigned int textLength = (unsigned int) inputMessage[1]; - encodeBuffer.encodeCachedValue(textLength, 8, - clientCache_ -> imageTextLengthCache, 4); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - unsigned int x = GetUINT(inputMessage + 12, bigEndian_); - int xDiff = x - clientCache_ -> imageTextLastX; - clientCache_ -> imageTextLastX = x; - encodeBuffer.encodeCachedValue(xDiff, 16, - clientCache_ -> imageTextCacheX); - unsigned int y = GetUINT(inputMessage + 14, bigEndian_); - int yDiff = y - clientCache_ -> imageTextLastY; - clientCache_ -> imageTextLastY = y; - encodeBuffer.encodeCachedValue(yDiff, 16, - clientCache_ -> imageTextCacheY); - const unsigned char *nextSrc = inputMessage + 16; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, textLength); - } - break; - case X_ImageText16: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_ImageText16 target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_ImageText16 target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_ImageText16 target id " - << t_id << " is unrecognized.\n" - << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ImageText16); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - unsigned int textLength = (unsigned int) inputMessage[1]; - encodeBuffer.encodeCachedValue(textLength, 8, - clientCache_ -> imageTextLengthCache, 4); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - unsigned int x = GetUINT(inputMessage + 12, bigEndian_); - int xDiff = x - clientCache_ -> imageTextLastX; - clientCache_ -> imageTextLastX = x; - encodeBuffer.encodeCachedValue(xDiff, 16, - clientCache_ -> imageTextCacheX); - unsigned int y = GetUINT(inputMessage + 14, bigEndian_); - int yDiff = y - clientCache_ -> imageTextLastY; - clientCache_ -> imageTextLastY = y; - encodeBuffer.encodeCachedValue(yDiff, 16, - clientCache_ -> imageTextCacheY); - const unsigned char *nextSrc = inputMessage + 16; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, textLength * 2); - } - break; - case X_InternAtom: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_InternAtom); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - // - // Set the priority, also if doing so will - // penalize all the well written clients - // using XInternAtoms() to pipeline multi- - // ple replies. - // - - priority_++; - - hit = 1; - - break; - } - - unsigned int nameLength = GetUINT(inputMessage + 4, bigEndian_); - encodeBuffer.encodeValue(nameLength, 16, 6); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - const unsigned char *nextSrc = inputMessage + 8; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, nameLength); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_ListExtensions: - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_ListFonts: - { - unsigned int textLength = GetUINT(inputMessage + 6, bigEndian_); - encodeBuffer.encodeValue(textLength, 16, 6); - encodeBuffer.encodeValue(GetUINT(inputMessage + 4, bigEndian_), 16, 6); - const unsigned char* nextSrc = inputMessage + 8; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, textLength); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_LookupColor: - case X_AllocNamedColor: - { - unsigned int textLength = GetUINT(inputMessage + 8, bigEndian_); - encodeBuffer.encodeValue(textLength, 16, 6); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, clientCache_ -> colormapCache); - const unsigned char *nextSrc = inputMessage + 12; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, textLength); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_MapWindow: - case X_UnmapWindow: - case X_MapSubwindows: - case X_GetWindowAttributes: - case X_DestroyWindow: - case X_DestroySubwindows: - case X_QueryPointer: - case X_QueryTree: - { - #ifdef TARGETS - - if (inputOpcode == X_DestroyWindow) - { - unsigned int w_id = GetULONG(inputMessage + 4, bigEndian_); - - *logofs << "handleRead: X_DestroyWindow id is " - << w_id << ".\n" << logofs_flush; - - windows.erase(w_id); - } - - #endif - - if (inputOpcode == X_DestroyWindow) - { - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeFreeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> freeWindowCache); - } - else - { - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> windowCache); - } - - if ((inputOpcode == X_QueryPointer) || - (inputOpcode == X_GetWindowAttributes) || - (inputOpcode == X_QueryTree)) - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - } - break; - case X_OpenFont: - { - unsigned int nameLength = GetUINT(inputMessage + 8, bigEndian_); - encodeBuffer.encodeValue(nameLength, 16, 7); - unsigned int font = GetULONG(inputMessage + 4, bigEndian_); - encodeBuffer.encodeValue(font - clientCache_ -> lastFont, 29, 5); - clientCache_ -> lastFont = font; - const unsigned char *nextSrc = inputMessage + 12; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, nameLength); - } - break; - case X_PolyFillRectangle: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PolyFillRectangle target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PolyFillRectangle target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PolyFillRectangle target id " - << t_id << " is unrecognized.\n" - << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyFillRectangle); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0; - unsigned int lastWidth = 0, lastHeight = 0; - - // - // TODO: Could send the size at the beginning - // instead of a bool at each iteration. - // - - for (unsigned int i = 12; i < inputLength;) - { - unsigned int x = GetUINT(inputMessage + i, bigEndian_); - unsigned int newX = x; - x -= lastX; - lastX = newX; - encodeBuffer.encodeCachedValue(x, 16, - *clientCache_ -> polyFillRectangleCacheX[index], 8); - i += 2; - unsigned int y = GetUINT(inputMessage + i, bigEndian_); - unsigned int newY = y; - y -= lastY; - lastY = newY; - encodeBuffer.encodeCachedValue(y, 16, - *clientCache_ -> polyFillRectangleCacheY[index], 8); - i += 2; - unsigned int width = GetUINT(inputMessage + i, bigEndian_); - unsigned int newWidth = width; - width -= lastWidth; - lastWidth = newWidth; - encodeBuffer.encodeCachedValue(width, 16, - *clientCache_ -> polyFillRectangleCacheWidth[index], 8); - i += 2; - unsigned int height = GetUINT(inputMessage + i, bigEndian_); - unsigned int newHeight = height; - height -= lastHeight; - lastHeight = newHeight; - encodeBuffer.encodeCachedValue(height, 16, - *clientCache_ -> polyFillRectangleCacheHeight[index], 8); - i += 2; - - if (++index == 4) index = 0; - - encodeBuffer.encodeBoolValue((i < inputLength) ? 1 : 0); - } - } - break; - case X_PolyFillArc: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PolyFillArc target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PolyFillArc target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PolyFillArc target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyFillArc); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0; - unsigned int lastWidth = 0, lastHeight = 0; - unsigned int lastAngle1 = 0, lastAngle2 = 0; - - // - // TODO: Could send the size at the beginning - // instead of a bool at each iteration. - // - - for (unsigned int i = 12; i < inputLength;) - { - unsigned int x = GetUINT(inputMessage + i, bigEndian_); - unsigned int newX = x; - x -= lastX; - lastX = newX; - encodeBuffer.encodeCachedValue(x, 16, - *clientCache_ -> polyFillArcCacheX[index], 8); - i += 2; - unsigned int y = GetUINT(inputMessage + i, bigEndian_); - unsigned int newY = y; - y -= lastY; - lastY = newY; - encodeBuffer.encodeCachedValue(y, 16, - *clientCache_ -> polyFillArcCacheY[index], 8); - i += 2; - unsigned int width = GetUINT(inputMessage + i, bigEndian_); - unsigned int newWidth = width; - width -= lastWidth; - lastWidth = newWidth; - encodeBuffer.encodeCachedValue(width, 16, - *clientCache_ -> polyFillArcCacheWidth[index], 8); - i += 2; - unsigned int height = GetUINT(inputMessage + i, bigEndian_); - unsigned int newHeight = height; - height -= lastHeight; - lastHeight = newHeight; - encodeBuffer.encodeCachedValue(height, 16, - *clientCache_ -> polyFillArcCacheHeight[index], 8); - i += 2; - unsigned int angle1 = GetUINT(inputMessage + i, bigEndian_); - unsigned int newAngle1 = angle1; - angle1 -= lastAngle1; - lastAngle1 = newAngle1; - encodeBuffer.encodeCachedValue(angle1, 16, - *clientCache_ -> polyFillArcCacheAngle1[index], 8); - i += 2; - unsigned int angle2 = GetUINT(inputMessage + i, bigEndian_); - unsigned int newAngle2 = angle2; - angle2 -= lastAngle2; - lastAngle2 = newAngle2; - encodeBuffer.encodeCachedValue(angle2, 16, - *clientCache_ -> polyFillArcCacheAngle2[index], 8); - i += 2; - - if (++index == 2) index = 0; - - encodeBuffer.encodeBoolValue((i < inputLength) ? 1 : 0); - } - } - break; - case X_PolyArc: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PolyArc target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PolyArc target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PolyArc target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyArc); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0; - unsigned int lastWidth = 0, lastHeight = 0; - unsigned int lastAngle1 = 0, lastAngle2 = 0; - - // - // TODO: Could send the size at the beginning - // instead of a bool at each iteration. - // - - for (unsigned int i = 12; i < inputLength;) - { - unsigned int x = GetUINT(inputMessage + i, bigEndian_); - unsigned int newX = x; - x -= lastX; - lastX = newX; - encodeBuffer.encodeCachedValue(x, 16, - *clientCache_ -> polyArcCacheX[index], 8); - i += 2; - unsigned int y = GetUINT(inputMessage + i, bigEndian_); - unsigned int newY = y; - y -= lastY; - lastY = newY; - encodeBuffer.encodeCachedValue(y, 16, - *clientCache_ -> polyArcCacheY[index], 8); - i += 2; - unsigned int width = GetUINT(inputMessage + i, bigEndian_); - unsigned int newWidth = width; - width -= lastWidth; - lastWidth = newWidth; - encodeBuffer.encodeCachedValue(width, 16, - *clientCache_ -> polyArcCacheWidth[index], 8); - i += 2; - unsigned int height = GetUINT(inputMessage + i, bigEndian_); - unsigned int newHeight = height; - height -= lastHeight; - lastHeight = newHeight; - encodeBuffer.encodeCachedValue(height, 16, - *clientCache_ -> polyArcCacheHeight[index], 8); - i += 2; - unsigned int angle1 = GetUINT(inputMessage + i, bigEndian_); - unsigned int newAngle1 = angle1; - angle1 -= lastAngle1; - lastAngle1 = newAngle1; - encodeBuffer.encodeCachedValue(angle1, 16, - *clientCache_ -> polyArcCacheAngle1[index], 8); - i += 2; - unsigned int angle2 = GetUINT(inputMessage + i, bigEndian_); - unsigned int newAngle2 = angle2; - angle2 -= lastAngle2; - lastAngle2 = newAngle2; - encodeBuffer.encodeCachedValue(angle2, 16, - *clientCache_ -> polyArcCacheAngle2[index], 8); - i += 2; - - if (++index == 2) index = 0; - - encodeBuffer.encodeBoolValue((i < inputLength) ? 1 : 0); - } - } - break; - case X_PolyPoint: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PolyPoint target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PolyPoint target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PolyPoint target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyPoint); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeValue(GetUINT(inputMessage + 2, bigEndian_) - 3, 16, 4); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, bigEndian_), - clientCache_ -> gcCache); - const unsigned char *nextSrc = inputMessage + 12; - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0; - - for (unsigned int i = 12; i < inputLength; i += 4) - { - unsigned int x = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - unsigned int tmp = x; - x -= lastX; - lastX = tmp; - encodeBuffer.encodeCachedValue(x, 16, - *clientCache_ -> polyPointCacheX[index], 8); - unsigned int y = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - tmp = y; - y -= lastY; - lastY = tmp; - encodeBuffer.encodeCachedValue(y, 16, - *clientCache_ -> polyPointCacheY[index], 8); - - if (++index == 2) index = 0; - } - } - break; - case X_PolyLine: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PolyLine target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PolyLine target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PolyLine target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyLine); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeValue(GetUINT(inputMessage + 2, bigEndian_) - 3, 16, 4); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - const unsigned char *nextSrc = inputMessage + 12; - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0; - - for (unsigned int i = 12; i < inputLength; i += 4) - { - unsigned int x = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - unsigned int tmp = x; - x -= lastX; - lastX = tmp; - encodeBuffer.encodeCachedValue(x, 16, - *clientCache_ -> polyLineCacheX[index], 8); - unsigned int y = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - tmp = y; - y -= lastY; - lastY = tmp; - encodeBuffer.encodeCachedValue(y, 16, - *clientCache_ -> polyLineCacheY[index], 8); - - if (++index == 2) index = 0; - } - } - break; - case X_PolyRectangle: - { - encodeBuffer.encodeValue((GetUINT(inputMessage + 2, - bigEndian_) - 3) >> 1, 16, 3); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - const unsigned char *end = inputMessage + inputLength; - const unsigned char *nextSrc = inputMessage + 12; - while (nextSrc < end) - { - for (unsigned int i = 0; i < 4; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *clientCache_ -> polyRectangleGeomCache[i], 8); - nextSrc += 2; - } - } - } - break; - case X_PolySegment: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PolySegment target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PolySegment target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PolySegment target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolySegment); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - encodeBuffer.encodeValue((GetUINT(inputMessage + 2, - bigEndian_) - 3) >> 1, 16, 4); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, - bigEndian_), clientCache_ -> gcCache); - const unsigned char *end = inputMessage + inputLength; - const unsigned char *nextSrc = inputMessage + 12; - // unsigned int index = 0; - // unsigned int lastX1, lastY1, lastX2, lastY2; - while (nextSrc < end) - { - unsigned int x = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - unsigned int xDiff0 = - x - clientCache_ -> polySegmentLastX[0]; - unsigned int xDiff1 = - x - clientCache_ -> polySegmentLastX[1]; - int xDiff0Abs = (int) xDiff0; - if (xDiff0Abs < 0) - xDiff0Abs = -xDiff0Abs; - int xDiff1Abs = (int) xDiff1; - if (xDiff1Abs < 0) - xDiff1Abs = -xDiff1Abs; - - unsigned int y = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - unsigned int yDiff0 = - y - clientCache_ -> polySegmentLastY[0]; - unsigned int yDiff1 = - y - clientCache_ -> polySegmentLastY[1]; - int yDiff0Abs = (int) yDiff0; - if (yDiff0Abs < 0) - yDiff0Abs = -yDiff0Abs; - int yDiff1Abs = (int) yDiff1; - if (yDiff1Abs < 0) - yDiff1Abs = -yDiff1Abs; - - int diff0 = xDiff0Abs + yDiff0Abs; - int diff1 = xDiff1Abs + yDiff1Abs; - if (diff0 < diff1) - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeCachedValue(xDiff0, 16, - clientCache_ -> polySegmentCacheX, 6); - encodeBuffer.encodeCachedValue(yDiff0, 16, - clientCache_ -> polySegmentCacheY, 6); - } - else - { - encodeBuffer.encodeBoolValue(1); - encodeBuffer.encodeCachedValue(xDiff1, 16, - clientCache_ -> polySegmentCacheX, 6); - encodeBuffer.encodeCachedValue(yDiff1, 16, - clientCache_ -> polySegmentCacheY, 6); - } - - clientCache_ -> polySegmentLastX[clientCache_ -> polySegmentCacheIndex] = x; - clientCache_ -> polySegmentLastY[clientCache_ -> polySegmentCacheIndex] = y; - - clientCache_ -> polySegmentCacheIndex = - clientCache_ -> polySegmentCacheIndex == 1 ? 0 : 1; - } - } - break; - case X_PutImage: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_PutImage target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_PutImage target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_PutImage target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PutImage); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - } - break; - case X_QueryBestSize: - { - encodeBuffer.encodeValue((unsigned int)inputMessage[1], 2); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - encodeBuffer.encodeValue(GetUINT(inputMessage + 8, bigEndian_), 16, 8); - encodeBuffer.encodeValue(GetUINT(inputMessage + 10, bigEndian_), 16, 8); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_QueryColors: - { - // Differential encoding. - encodeBuffer.encodeBoolValue(1); - - unsigned int numColors = ((inputLength - 8) >> 2); - encodeBuffer.encodeValue(numColors, 16, 5); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, - clientCache_ -> colormapCache); - const unsigned char *nextSrc = inputMessage + 8; - unsigned int predictedPixel = clientCache_ -> queryColorsLastPixel; - for (unsigned int i = 0; i < numColors; i++) - { - unsigned int pixel = GetULONG(nextSrc, bigEndian_); - nextSrc += 4; - if (pixel == predictedPixel) - encodeBuffer.encodeBoolValue(1); - else - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeValue(pixel, 32, 9); - } - if (i == 0) - clientCache_ -> queryColorsLastPixel = pixel; - predictedPixel = pixel + 1; - } - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_QueryExtension: - { - #ifdef TEST - - char data[256]; - - int length = GetUINT(inputMessage + 4, bigEndian_); - - if (length > 256) - { - length = 256; - } - - strncpy(data, (char *) inputMessage + 8, length); - - *(data + length) = '\0'; - - *logofs << "handleRead: Going to query extension '" - << data << "' for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - unsigned int nameLength = GetUINT(inputMessage + 4, bigEndian_); - encodeBuffer.encodeValue(nameLength, 16, 6); - const unsigned char *nextSrc = inputMessage + 8; - - for (; nameLength; nameLength--) - { - encodeBuffer.encodeValue((unsigned int) *nextSrc++, 8); - } - - unsigned int extension = 0; - - if (strncmp((char *) inputMessage + 8, "SHAPE", 5) == 0) - { - extension = X_NXInternalShapeExtension; - } - else if (strncmp((char *) inputMessage + 8, "RENDER", 6) == 0) - { - extension = X_NXInternalRenderExtension; - } - - sequenceQueue_.push(clientSequence_, inputOpcode, extension); - - priority_++; - } - break; - case X_QueryFont: - { - unsigned int font = GetULONG(inputMessage + 4, bigEndian_); - encodeBuffer.encodeValue(font - clientCache_ -> lastFont, 29, 5); - clientCache_ -> lastFont = font; - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_SetClipRectangles: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_SetClipRectangles); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - hit = 1; - - break; - } - - unsigned int numRectangles = ((inputLength - 12) >> 3); - - // Since ProtoStep9 (#issue 108) - encodeBuffer.encodeValue(numRectangles, 15, 4); - - encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> gcCache); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, - clientCache_ -> setClipRectanglesXCache, 8); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 10, bigEndian_), 16, - clientCache_ -> setClipRectanglesYCache, 8); - const unsigned char *nextSrc = inputMessage + 12; - for (unsigned int i = 0; i < numRectangles; i++) - { - for (unsigned int j = 0; j < 4; j++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *clientCache_ -> setClipRectanglesGeomCache[j], 8); - nextSrc += 2; - } - } - } - break; - case X_SetDashes: - { - unsigned int numDashes = GetUINT(inputMessage + 10, bigEndian_); - encodeBuffer.encodeCachedValue(numDashes, 16, - clientCache_ -> setDashesLengthCache, 5); - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), - clientCache_ -> gcCache); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, - clientCache_ -> setDashesOffsetCache, 5); - const unsigned char *nextSrc = inputMessage + 12; - for (unsigned int i = 0; i < numDashes; i++) - encodeBuffer.encodeCachedValue(*nextSrc++, 8, - clientCache_ -> setDashesDashCache_[i & 1], 5); - } - break; - case X_SetSelectionOwner: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, - clientCache_ -> setSelectionOwnerCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, - clientCache_ -> getSelectionOwnerSelectionCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 32, - clientCache_ -> setSelectionOwnerTimestampCache, 9); - } - break; - case X_TranslateCoords: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_TranslateCoords source id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_TranslateCoords source id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_TranslateCoords source id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - t_id = GetULONG(inputMessage + 8, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_TranslateCoords target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_TranslateCoords target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_TranslateCoords target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_TranslateCoords); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - - hit = 1; - - break; - } - - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, - clientCache_ -> translateCoordsSrcCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, - clientCache_ -> translateCoordsDstCache, 9); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 12, bigEndian_), 16, - clientCache_ -> translateCoordsXCache, 8); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 14, bigEndian_), 16, - clientCache_ -> translateCoordsYCache, 8); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GetImage: - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_GetImage source id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_GetImage source id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_GetImage source id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_GetImage); - - if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, - inputMessage, inputLength)) - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - - hit = 1; - - break; - } - - // Format. - encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2); - // Drawable. - encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, - bigEndian_), clientCache_ -> drawableCache); - // X. - unsigned int x = GetUINT(inputMessage + 8, bigEndian_); - int xDiff = x - clientCache_ -> putImageLastX; - clientCache_ -> putImageLastX = x; - encodeBuffer.encodeCachedValue(xDiff, 16, - clientCache_ -> putImageXCache, 8); - // Y. - unsigned int y = GetUINT(inputMessage + 10, bigEndian_); - int yDiff = y - clientCache_ -> putImageLastY; - clientCache_ -> putImageLastY = y; - encodeBuffer.encodeCachedValue(yDiff, 16, - clientCache_ -> putImageYCache, 8); - // Width. - unsigned int width = GetUINT(inputMessage + 12, bigEndian_); - encodeBuffer.encodeCachedValue(width, 16, - clientCache_ -> putImageWidthCache, 8); - // Height. - unsigned int height = GetUINT(inputMessage + 14, bigEndian_); - encodeBuffer.encodeCachedValue(height, 16, - clientCache_ -> putImageHeightCache, 8); - // Plane mask. - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), 32, - clientCache_ -> getImagePlaneMaskCache, 5); - - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GetPointerMapping: - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - case X_GetKeyboardControl: - { - sequenceQueue_.push(clientSequence_, inputOpcode); - - priority_++; - } - break; - default: - { - if (inputOpcode == opcodeStore_ -> renderExtension) - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXInternalRenderExtension); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - } - else if (inputOpcode == opcodeStore_ -> shapeExtension) - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXInternalShapeExtension); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - } - else if (inputOpcode == opcodeStore_ -> putPackedImage) - { - #ifdef TARGETS - - unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); - - if (pixmaps.find(t_id) != pixmaps.end()) - { - *logofs << "handleRead: X_NXPutPackedImage target id is pixmap " - << t_id << ".\n" << logofs_flush; - } - else if (windows.find(t_id) != windows.end()) - { - *logofs << "handleRead: X_NXPutPackedImage target id is window " - << t_id << ".\n" << logofs_flush; - } - else - { - *logofs << "handleRead: X_NXPutPackedImage target id " << t_id - << " is unrecognized.\n" << logofs_flush; - } - - #endif - - #ifdef DEBUG - *logofs << "handleRead: Encoding packed image request for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - // - // The field carries the destination data - // length. We add the request's size of - // the final X_PutImage. - // - - unsigned int outputLength = GetULONG(inputMessage + 20, bigEndian_) + 24; - - statistics -> addPackedBytesIn(inputLength); - - statistics -> addPackedBytesOut(outputLength); - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXPutPackedImage); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - } - else if (inputOpcode == opcodeStore_ -> setUnpackColormap) - { - #ifdef DEBUG - *logofs << "handleRead: Encoding set unpack colormap request " - << "for FD#" << fd_ << " with size " << inputLength - << ".\n" << logofs_flush; - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXSetUnpackColormap); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - } - else if (inputOpcode == opcodeStore_ -> setUnpackAlpha) - { - #ifdef DEBUG - *logofs << "handleRead: Encoding set unpack alpha request " - << "for FD#" << fd_ << " with size " << inputLength - << ".\n" << logofs_flush; - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXSetUnpackAlpha); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - } - else if (inputOpcode == opcodeStore_ -> setUnpackGeometry) - { - #ifdef DEBUG - *logofs << "handleRead: Encoding set unpack geometry request " - << "for FD#" << fd_ << " with size " << inputLength - << ".\n" << logofs_flush; - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXSetUnpackGeometry); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - } - else if (inputOpcode == opcodeStore_ -> startSplit) - { - if (handleStartSplitRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - else if (inputOpcode == opcodeStore_ -> endSplit) - { - if (handleEndSplitRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - else if (inputOpcode == opcodeStore_ -> commitSplit) - { - if (handleCommitSplitRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - else if (inputOpcode == opcodeStore_ -> abortSplit) - { - if (handleAbortSplitRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - else if (inputOpcode == opcodeStore_ -> finishSplit) - { - if (handleFinishSplitRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - else if (inputOpcode == opcodeStore_ -> freeSplit) - { - #ifdef DEBUG - *logofs << "handleRead: Encoding free split request " - << "for FD#" << fd_ << " with size " << inputLength - << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(*(inputMessage + 1), 8, - clientCache_ -> resourceCache); - } - else if (inputOpcode == opcodeStore_ -> freeUnpack) - { - #ifdef DEBUG - *logofs << "handleRead: Encoding free unpack request " - << "for FD#" << fd_ << " with size " << inputLength - << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(*(inputMessage + 1), 8, - clientCache_ -> resourceCache); - } - else if (inputOpcode == opcodeStore_ -> getControlParameters) - { - #ifdef DEBUG - *logofs << "handleRead: Encoding get control parameters " - << "request for FD#" << fd_ << " with size " - << inputLength << ".\n" << logofs_flush; - #endif - - // - // Add the reply to the write buffer. If found - // to contain a message, it it will be flushed - // to the X client before leaving the loop. - // - - unsigned char *reply = writeBuffer_.addMessage(32); - - *(reply + 0) = X_Reply; - - PutUINT(clientSequence_, reply + 2, bigEndian_); - - PutULONG(0, reply + 4, bigEndian_); - - // - // Save the sequence number we used - // to auto-generate this reply. - // - - lastSequence_ = clientSequence_; - - #ifdef TEST - *logofs << "handleRead: Registered " << lastSequence_ - << " as last auto-generated sequence number.\n" - << logofs_flush; - #endif - - *(reply + 1) = control -> LinkMode; - - *(reply + 8) = control -> LocalVersionMajor; - *(reply + 9) = control -> LocalVersionMinor; - *(reply + 10) = control -> LocalVersionPatch; - - *(reply + 11) = control -> RemoteVersionMajor; - *(reply + 12) = control -> RemoteVersionMinor; - *(reply + 13) = control -> RemoteVersionPatch; - - PutUINT(control -> SplitTimeout, reply + 14, bigEndian_); - PutUINT(control -> MotionTimeout, reply + 16, bigEndian_); - - *(reply + 18) = control -> SplitMode; - - PutULONG(control -> SplitDataThreshold, reply + 20, bigEndian_); - - *(reply + 24) = control -> PackMethod; - *(reply + 25) = control -> PackQuality; - - *(reply + 26) = control -> LocalDataCompressionLevel; - *(reply + 27) = control -> LocalStreamCompressionLevel; - *(reply + 28) = control -> LocalDeltaCompression; - - *(reply + 29) = (control -> LocalDeltaCompression == 1 && - control -> PersistentCacheEnableLoad == 1); - *(reply + 30) = (control -> LocalDeltaCompression == 1 && - control -> PersistentCacheEnableSave == 1); - *(reply + 31) = (control -> LocalDeltaCompression == 1 && - control -> PersistentCacheEnableLoad == 1 && - control -> PersistentCacheName != NULL); - - if (handleFlush(flush_if_any) < 0) - { - return -1; - } - } - else if (inputOpcode == opcodeStore_ -> getCleanupParameters) - { - #ifdef WARNING - *logofs << "handleRead: WARNING! Encoding fake get cleanup " - << "parameters request for FD#" << fd_ << " with size " - << inputLength << ".\n" << logofs_flush; - #endif - } - else if (inputOpcode == opcodeStore_ -> getImageParameters) - { - #ifdef WARNING - *logofs << "handleRead: WARNING! Encoding fake get cleanup " - << "parameters request for FD#" << fd_ << " with size " - << inputLength << ".\n" << logofs_flush; - #endif - } - else if (inputOpcode == opcodeStore_ -> getUnpackParameters) - { - #ifdef DEBUG - *logofs << "handleRead: Encoding get unpack parameters " - << "request for FD#" << fd_ << " with size " - << inputLength << ".\n" << logofs_flush; - #endif - - sequenceQueue_.push(clientSequence_, inputOpcode); - } - else if (inputOpcode == opcodeStore_ -> getShmemParameters) - { - if (handleShmemRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - else if (inputOpcode == opcodeStore_ -> setExposeParameters) - { - // - // Enable or disable expose events - // coming from the real server. - // - - encodeBuffer.encodeBoolValue(*(inputMessage + 4)); - encodeBuffer.encodeBoolValue(*(inputMessage + 5)); - encodeBuffer.encodeBoolValue(*(inputMessage + 6)); - } - else if (inputOpcode == opcodeStore_ -> setCacheParameters) - { - if (handleCacheRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - else if (inputOpcode == opcodeStore_ -> getFontParameters) - { - if (handleFontRequest(encodeBuffer, inputOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - else - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXInternalGenericRequest); - - hit = handleEncode(encodeBuffer, clientCache_, messageStore, - inputOpcode, inputMessage, inputLength); - - // - // Don't flush if the opcode is unrecognized. - // We may optionally flush it is an extension - // but would penalize the well written clients. - // - // if (inputOpcode > 127) - // { - // priority_++; - // } - // - } - } - } // End of switch on opcode. - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - - const char *cacheString = (hit ? "cached " : ""); - - *logofs << "handleRead: Handled " << cacheString << "request OPCODE#" - << (unsigned int) inputOpcode << " (" << DumpOpcode(inputOpcode) - << ")" << " for FD#" << fd_ << " sequence " << clientSequence_ - << ". " << inputLength << " bytes in, " << bits << " bits (" - << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; - - #endif - - if (hit) - { - statistics -> addCachedRequest(inputOpcode); - } - - statistics -> addRequestBits(inputOpcode, inputLength << 3, bits); - - if (inputOpcode == opcodeStore_ -> renderExtension) - { - if (hit) - { - statistics -> addRenderCachedRequest(*(inputMessage + 1)); - } - - statistics -> addRenderRequestBits(*(inputMessage + 1), inputLength << 3, bits); - } - - } // End if (firstRequest_)... else ... - - } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != 0) ... - - // - // Check if we need to flush because of - // prioritized data. - // - - if (priority_ > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: WARNING! Requesting flush " - << "because of " << priority_ << " prioritized " - << "messages for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - if (proxy -> handleAsyncPriority() < 0) - { - return -1; - } - - // - // Reset the priority flag. - // - - priority_ = 0; - } - - // - // Flush if we exceeded the token length. - // - - if (proxy -> canAsyncFlush() == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: WARNING! Requesting flush " - << "because of token length exceeded.\n" - << logofs_flush; - #endif - - if (proxy -> handleAsyncFlush() < 0) - { - return -1; - } - } - - #if defined(TEST) || defined(INFO) - - if (transport_ -> pending() != 0 || - readBuffer_.checkMessage() != 0) - { - *logofs << "handleRead: PANIC! Buffer for X descriptor FD#" - << fd_ << " has " << transport_ -> pending() - << " bytes to read.\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - // - // Reset the read buffer. - // - - readBuffer_.fullReset(); - - return 1; -} - -// -// End of handleRead(). -// - -// -// Beginning of handleWrite(). -// - -int ClientChannel::handleWrite(const unsigned char *message, unsigned int length) -{ - #ifdef TEST - *logofs << "handleWrite: Called for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - // - // Create the buffer from which to - // decode messages. - // - - DecodeBuffer decodeBuffer(message, length); - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "handleWrite: Decoding messages for FD#" << fd_ - << " with " << length << " bytes in the buffer.\n" - << logofs_flush; - #endif - - if (firstReply_) - { - #ifdef TEST - *logofs << "handleWrite: First reply detected.\n" << logofs_flush; - #endif - - unsigned int outputOpcode; - - decodeBuffer.decodeValue(outputOpcode, 8); - unsigned int secondByte; - decodeBuffer.decodeValue(secondByte, 8); - unsigned int major; - decodeBuffer.decodeValue(major, 16); - unsigned int minor; - decodeBuffer.decodeValue(minor, 16); - unsigned int extraLength; - decodeBuffer.decodeValue(extraLength, 16); - unsigned int outputLength = 8 + (extraLength << 2); - - unsigned char *outputMessage = writeBuffer_.addMessage(outputLength); - *outputMessage = (unsigned char) outputOpcode; - outputMessage[1] = (unsigned char) secondByte; - PutUINT(major, outputMessage + 2, bigEndian_); - PutUINT(minor, outputMessage + 4, bigEndian_); - PutUINT(extraLength, outputMessage + 6, bigEndian_); - unsigned char *nextDest = outputMessage + 8; - unsigned int cached; - decodeBuffer.decodeBoolValue(cached); - - if (cached) - { - memcpy(nextDest, ServerCache::lastInitReply.getData(), outputLength - 8); - } - else - { - for (unsigned i = 8; i < outputLength; i++) - { - unsigned int nextByte; - decodeBuffer.decodeValue(nextByte, 8); - *nextDest++ = (unsigned char) nextByte; - } - - ServerCache::lastInitReply.set(outputLength - 8, outputMessage + 8); - } - - imageByteOrder_ = outputMessage[30]; - bitmapBitOrder_ = outputMessage[31]; - scanlineUnit_ = outputMessage[32]; - scanlinePad_ = outputMessage[33]; - - firstReply_ = 0; - - } // End of if (firstReply_) - - // - // This was previously in a 'else' block. - // Due to the way the first request was - // handled, we could not decode multiple - // messages in the first frame. - // - - { // Start of the decoding block. - - #ifdef DEBUG - *logofs << "handleWrite: Starting loop on opcodes.\n" - << logofs_flush; - #endif - - unsigned char outputOpcode; - - // - // NX client needs this line to consider - // the initialization phase successfully - // completed. - // - - if (firstClient_ == -1) - { - cerr << "Info" << ": Established X client connection.\n" ; - - firstClient_ = fd_; - } - - while (decodeBuffer.decodeOpcodeValue(outputOpcode, serverCache_ -> opcodeCache, 1)) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoded a new OPCODE#" - << (unsigned int) outputOpcode << ".\n" - << logofs_flush; - #endif - - unsigned char *outputMessage = NULL; - unsigned int outputLength = 0; - - // - // General-purpose temp variables - // for decoding ints and chars. - // - - unsigned int value = 0; - unsigned char cValue = 0; - - // - // Check first if we need to abort any split, - // then if this is a reply, finally if it is - // en event or error. - // - - if (outputOpcode == opcodeStore_ -> splitEvent) - { - // - // It's an abort split, not a normal - // burst of proxy data. - // - - handleSplitEvent(decodeBuffer); - - continue; - } - else if (outputOpcode == X_Reply) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoding sequence number of reply.\n" - << logofs_flush; - #endif - - unsigned int sequenceNum; - unsigned int sequenceDiff; - - decodeBuffer.decodeCachedValue(sequenceDiff, 16, - serverCache_ -> replySequenceCache, 7); - - sequenceNum = (serverSequence_ + sequenceDiff) & 0xffff; - - serverSequence_ = sequenceNum; - - #ifdef DEBUG - *logofs << "handleWrite: Last server sequence number for FD#" - << fd_ << " is " << serverSequence_ << " with " - << "difference " << sequenceDiff << ".\n" - << logofs_flush; - #endif - - // - // In case of reply we can follow the X server and - // override any event's sequence number generated - // by this side. - // - - #ifdef TEST - *logofs << "handleWrite: Updating last event's sequence " - << lastSequence_ << " to reply's sequence number " - << serverSequence_ << " for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - lastSequence_ = serverSequence_; - - unsigned short int requestSequenceNum; - unsigned char requestOpcode; - - #ifdef DEBUG - - requestSequenceNum = 0; - requestOpcode = 0; - - *logofs << "handleWrite: Peek of sequence number returns "; - - *logofs << sequenceQueue_.peek(requestSequenceNum, requestOpcode); - - *logofs << " with sequence " << requestSequenceNum << " and opcode " - << (unsigned int) requestOpcode << ".\n" << logofs_flush; - - #endif - - if (sequenceQueue_.peek(requestSequenceNum, requestOpcode) == 1 && - (requestSequenceNum == sequenceNum)) - { - unsigned int requestData[3]; - - sequenceQueue_.pop(requestSequenceNum, requestOpcode, - requestData[0], requestData[1], requestData[2]); - - #ifdef DEBUG - *logofs << "handleWrite: Identified reply to OPCODE#" - << (unsigned int) requestOpcode << ".\n" - << logofs_flush; - #endif - - // - // Is differential encoding disabled? - // - - if (control -> RemoteDeltaCompression == 0) - { - int result = handleFastWriteReply(decodeBuffer, requestOpcode, - outputMessage, outputLength); - if (result < 0) - { - return -1; - } - else if (result > 0) - { - continue; - } - } - - switch (requestOpcode) - { - case X_AllocColor: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - unsigned char *nextDest = outputMessage + 8; - for (unsigned int i = 0; i < 3; i++) - { - decodeBuffer.decodeBoolValue(value); - if (value) - { - PutUINT(requestData[i], nextDest, bigEndian_); - } - else - { - decodeBuffer.decodeValue(value, 16, 6); - PutUINT(requestData[i] + value, nextDest, bigEndian_); - } - nextDest += 2; - } - decodeBuffer.decodeValue(value, 32, 9); - PutULONG(value, outputMessage + 16, bigEndian_); - } - break; - case X_GetAtomName: - { - unsigned int nameLength; - decodeBuffer.decodeValue(nameLength, 16, 6); - outputLength = RoundUp4(nameLength) + 32; - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(nameLength, outputMessage + 8, bigEndian_); - unsigned char* nextDest = outputMessage + 32; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, nameLength); - } - break; - case X_GetGeometry: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(cValue, 8, - serverCache_ -> depthCache); - outputMessage[1] = cValue; - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> getGeometryRootCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - for (unsigned int i = 0; i < 5; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *serverCache_ -> getGeometryGeomCache[i], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - } - break; - case X_GetInputFocus: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 2); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> getInputFocusWindowCache); - PutULONG(value, outputMessage + 8, bigEndian_); - } - break; - case X_GetKeyboardMapping: - { - decodeBuffer.decodeBoolValue(value); - if (value) - { - unsigned int dataLength = - ServerCache::getKeyboardMappingLastMap.getLength(); - outputLength = 32 + dataLength; - outputMessage = writeBuffer_.addMessage(outputLength); - outputMessage[1] = - ServerCache::getKeyboardMappingLastKeysymsPerKeycode; - memcpy(outputMessage + 32, - ServerCache::getKeyboardMappingLastMap.getData(), - dataLength); - break; - } - unsigned int numKeycodes; - decodeBuffer.decodeValue(numKeycodes, 8); - unsigned int keysymsPerKeycode; - decodeBuffer.decodeValue(keysymsPerKeycode, 8, 4); - ServerCache::getKeyboardMappingLastKeysymsPerKeycode = - keysymsPerKeycode; - outputLength = 32 + numKeycodes * keysymsPerKeycode * 4; - outputMessage = writeBuffer_.addMessage(outputLength); - outputMessage[1] = (unsigned char) keysymsPerKeycode; - unsigned char *nextDest = outputMessage + 32; - unsigned char previous = 0; - for (unsigned int count = numKeycodes * keysymsPerKeycode; - count; --count) - { - decodeBuffer.decodeBoolValue(value); - if (value) - PutULONG((unsigned int) NoSymbol, nextDest, bigEndian_); - else - { - unsigned int keysym; - decodeBuffer.decodeCachedValue(keysym, 24, - serverCache_ -> getKeyboardMappingKeysymCache, 9); - decodeBuffer.decodeCachedValue(cValue, 8, - serverCache_ -> getKeyboardMappingLastByteCache, 5); - previous += cValue; - PutULONG((keysym << 8) | previous, nextDest, bigEndian_); - } - nextDest += 4; - } - ServerCache::getKeyboardMappingLastMap.set(outputLength - 32, - outputMessage + 32); - } - break; - case X_GetModifierMapping: - { - unsigned int keycodesPerModifier; - decodeBuffer.decodeValue(keycodesPerModifier, 8); - outputLength = 32 + (keycodesPerModifier << 3); - outputMessage = writeBuffer_.addMessage(outputLength); - outputMessage[1] = (unsigned char) keycodesPerModifier; - unsigned char *nextDest = outputMessage + 32; - decodeBuffer.decodeBoolValue(value); - if (value) - { - memcpy(outputMessage + 32, - ServerCache::getModifierMappingLastMap.getData(), - ServerCache::getModifierMappingLastMap.getLength()); - break; - } - for (unsigned int count = outputLength - 32; count; count--) - { - decodeBuffer.decodeBoolValue(value); - if (value) - *nextDest++ = 0; - else - { - decodeBuffer.decodeValue(value, 8); - *nextDest++ = value; - } - } - ServerCache::getModifierMappingLastMap.set(outputLength - 32, - outputMessage + 32); - } - break; - case X_GetProperty: - { - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_GetProperty); - - handleDecode(decodeBuffer, serverCache_, messageStore, - requestOpcode, outputMessage, outputLength); - } - break; - case X_GetSelectionOwner: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> getSelectionOwnerCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - } - break; - case X_GetWindowAttributes: - { - outputLength = 44; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 2); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> visualCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> getWindowAttributesClassCache, 3); - PutUINT(value, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(cValue, 8, - serverCache_ -> getWindowAttributesBitGravityCache); - outputMessage[14] = cValue; - decodeBuffer.decodeCachedValue(cValue, 8, - serverCache_ -> getWindowAttributesWinGravityCache); - outputMessage[15] = cValue; - decodeBuffer.decodeCachedValue(value, 32, - serverCache_ -> getWindowAttributesPlanesCache, 9); - PutULONG(value, outputMessage + 16, bigEndian_); - decodeBuffer.decodeCachedValue(value, 32, - serverCache_ -> getWindowAttributesPixelCache, 9); - PutULONG(value, outputMessage + 20, bigEndian_); - decodeBuffer.decodeBoolValue(value); - outputMessage[24] = (unsigned char) value; - decodeBuffer.decodeBoolValue(value); - outputMessage[25] = (unsigned char) value; - decodeBuffer.decodeValue(value, 2); - outputMessage[26] = (unsigned char) value; - decodeBuffer.decodeBoolValue(value); - outputMessage[27] = (unsigned char) value; - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> colormapCache, 9); - PutULONG(value, outputMessage + 28, bigEndian_); - decodeBuffer.decodeCachedValue(value, 32, - serverCache_ -> getWindowAttributesAllEventsCache); - PutULONG(value, outputMessage + 32, bigEndian_); - decodeBuffer.decodeCachedValue(value, 32, - serverCache_ -> getWindowAttributesYourEventsCache); - PutULONG(value, outputMessage + 36, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> getWindowAttributesDontPropagateCache); - PutUINT(value, outputMessage + 40, bigEndian_); - } - break; - case X_GrabKeyboard: - case X_GrabPointer: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 3); - outputMessage[1] = (unsigned char) value; - } - break; - case X_InternAtom: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 29, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - } - break; - case X_ListExtensions: - { - decodeBuffer.decodeValue(value, 32, 8); - outputLength = 32 + (value << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - unsigned int numExtensions; - decodeBuffer.decodeValue(numExtensions, 8); - outputMessage[1] = (unsigned char) numExtensions; - unsigned char *nextDest = outputMessage + 32; - for (; numExtensions; numExtensions--) - { - unsigned int length; - decodeBuffer.decodeValue(length, 8); - *nextDest++ = (unsigned char) length; - for (; length; length--) - { - decodeBuffer.decodeValue(value, 8); - *nextDest++ = value; - } - } - } - break; - case X_ListFonts: - { - // - // Differential compression can achieve a 12:1 to 14:1 - // ratio, while the best ZLIB compression can achieve - // a mere 4:1 to 5:1. In the first case, though, the - // huge amount of data constituting the message would - // be stored uncompressed at the remote side. We need - // to find a compromise. The solution is to use diffe- - // rential compression at startup and ZLIB compression - // later on. - // - - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_ListFonts); - - if (handleDecodeCached(decodeBuffer, serverCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - decodeBuffer.decodeValue(value, 32, 8); - outputLength = 32 + (value << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - unsigned int numFonts; - decodeBuffer.decodeValue(numFonts, 16, 6); - PutUINT(numFonts, outputMessage + 8, bigEndian_); - - // Differential or plain data compression? - decodeBuffer.decodeBoolValue(value); - - if (value) - { - unsigned char* nextDest = outputMessage + 32; - for (; numFonts; numFonts--) - { - unsigned int length; - decodeBuffer.decodeValue(length, 8); - *nextDest++ = (unsigned char)length; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, length); - nextDest += length; - } - - handleSave(messageStore, outputMessage, outputLength); - } - else - { - const unsigned char *compressedData = NULL; - unsigned int compressedDataSize = 0; - - int decompressed = handleDecompress(decodeBuffer, requestOpcode, messageStore -> dataOffset, - outputMessage, outputLength, compressedData, - compressedDataSize); - if (decompressed < 0) - { - return -1; - } - else if (decompressed > 0) - { - handleSave(messageStore, outputMessage, outputLength, - compressedData, compressedDataSize); - } - else - { - handleSave(messageStore, outputMessage, outputLength); - } - } - } - break; - case X_LookupColor: - case X_AllocNamedColor: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - unsigned char *nextDest = outputMessage + 8; - if (requestOpcode == X_AllocNamedColor) - { - decodeBuffer.decodeValue(value, 32, 9); - PutULONG(value, nextDest, bigEndian_); - nextDest += 4; - } - unsigned int count = 3; - do - { - decodeBuffer.decodeValue(value, 16, 9); - PutUINT(value, nextDest, bigEndian_); - unsigned int visualColor; - decodeBuffer.decodeValue(visualColor, 16, 5); - visualColor += value; - visualColor &= 0xffff; - PutUINT(visualColor, nextDest + 6, bigEndian_); - nextDest += 2; - } - while (--count); - } - break; - case X_QueryBestSize: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 16, 8); - PutUINT(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeValue(value, 16, 8); - PutUINT(value, outputMessage + 10, bigEndian_); - } - break; - case X_QueryColors: - { - // Differential or plain data compression? - decodeBuffer.decodeBoolValue(value); - - if (value) - { - decodeBuffer.decodeBoolValue(value); - if (value) - { - unsigned int numColors = - serverCache_ -> queryColorsLastReply.getLength() / 6; - outputLength = 32 + (numColors << 3); - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(numColors, outputMessage + 8, bigEndian_); - const unsigned char *nextSrc = - serverCache_ -> queryColorsLastReply.getData(); - unsigned char *nextDest = outputMessage + 32; - for (; numColors; numColors--) - { - for (unsigned int i = 0; i < 6; i++) - *nextDest++ = *nextSrc++; - nextDest += 2; - } - } - else - { - unsigned int numColors; - decodeBuffer.decodeValue(numColors, 16, 5); - outputLength = 32 + (numColors << 3); - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(numColors, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 32; - for (unsigned int c = 0; c < numColors; c++) - { - for (unsigned int i = 0; i < 3; i++) - { - decodeBuffer.decodeValue(value, 16); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - } - serverCache_ -> queryColorsLastReply.set(numColors * 6, - outputMessage + 32); - const unsigned char *nextSrc = nextDest - 1; - nextDest = outputMessage + 32 + ((numColors - 1) << 3) + 5; - for (; numColors > 1; numColors--) - { - for (unsigned int i = 0; i < 6; i++) - *nextDest-- = *nextSrc--; - nextDest -= 2; - } - } - } - else - { - // Reply length. - unsigned int numColors; - decodeBuffer.decodeValue(numColors, 16, 5); - outputLength = 32 + (numColors << 3); - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(numColors, outputMessage + 8, bigEndian_); - - const unsigned char *compressedData = NULL; - unsigned int compressedDataSize = 0; - - int decompressed = handleDecompress(decodeBuffer, requestOpcode, 32, - outputMessage, outputLength, compressedData, - compressedDataSize); - if (decompressed < 0) - { - return -1; - } - } - } - break; - case X_QueryExtension: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeBoolValue(value); - outputMessage[8] = (unsigned char) value; - decodeBuffer.decodeValue(value, 8); - outputMessage[9] = (unsigned char) value; - decodeBuffer.decodeValue(value, 8); - outputMessage[10] = (unsigned char) value; - decodeBuffer.decodeValue(value, 8); - outputMessage[11] = (unsigned char) value; - - // - // We use a predefined opcode to address - // extensions' message stores, while real - // opcodes are used for communication with - // X server and clients. - // - - if (requestData[0] == X_NXInternalShapeExtension) - { - opcodeStore_ -> shapeExtension = outputMessage[9]; - - #ifdef TEST - *logofs << "handleWrite: Shape extension opcode for FD#" << fd_ - << " is " << (unsigned int) opcodeStore_ -> shapeExtension - << ".\n" << logofs_flush; - #endif - } - else if (requestData[0] == X_NXInternalRenderExtension) - { - opcodeStore_ -> renderExtension = outputMessage[9]; - - #ifdef TEST - *logofs << "handleWrite: Render extension opcode for FD#" << fd_ - << " is " << (unsigned int) opcodeStore_ -> renderExtension - << ".\n" << logofs_flush; - #endif - } - } - break; - case X_QueryFont: - { - // - // Use differential compression at startup and plain - // data compression later. Check X_ListFonts message - // for an explaination. - // - - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_QueryFont); - - if (handleDecodeCached(decodeBuffer, serverCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - // Differential or plain data compression? - decodeBuffer.decodeBoolValue(value); - - if (value) - { - unsigned int numProperties; - unsigned int numCharInfos; - decodeBuffer.decodeValue(numProperties, 16, 8); - decodeBuffer.decodeValue(numCharInfos, 32, 10); - outputLength = 60 + numProperties * 8 + numCharInfos * 12; - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(numProperties, outputMessage + 46, bigEndian_); - PutULONG(numCharInfos, outputMessage + 56, bigEndian_); - handleDecodeCharInfo(decodeBuffer, outputMessage + 8); - handleDecodeCharInfo(decodeBuffer, outputMessage + 24); - decodeBuffer.decodeValue(value, 16, 9); - PutUINT(value, outputMessage + 40, bigEndian_); - decodeBuffer.decodeValue(value, 16, 9); - PutUINT(value, outputMessage + 42, bigEndian_); - decodeBuffer.decodeValue(value, 16, 9); - PutUINT(value, outputMessage + 44, bigEndian_); - decodeBuffer.decodeBoolValue(value); - outputMessage[48] = (unsigned char) value; - decodeBuffer.decodeValue(value, 8); - outputMessage[49] = (unsigned char) value; - decodeBuffer.decodeValue(value, 8); - outputMessage[50] = (unsigned char) value; - decodeBuffer.decodeBoolValue(value); - outputMessage[51] = (unsigned char) value; - decodeBuffer.decodeValue(value, 16, 9); - PutUINT(value, outputMessage + 52, bigEndian_); - decodeBuffer.decodeValue(value, 16, 9); - PutUINT(value, outputMessage + 54, bigEndian_); - unsigned char *nextDest = outputMessage + 60; - decodeBuffer.decodeBoolValue(value); - - int end = 0; - - if (value == 1) - { - unsigned int index; - decodeBuffer.decodeValue(index, 4); - unsigned int length; - const unsigned char *data; - ServerCache::queryFontFontCache.get(index, length, data); - memcpy(nextDest, data, length); - - end = 1; - } - - if (end == 0) - { - unsigned char *saveDest = nextDest; - unsigned int length = numProperties * 8 + numCharInfos * 12; - for (; numProperties; numProperties--) - { - decodeBuffer.decodeValue(value, 32, 9); - PutULONG(value, nextDest, bigEndian_); - decodeBuffer.decodeValue(value, 32, 9); - PutULONG(value, nextDest + 4, bigEndian_); - nextDest += 8; - } - for (; numCharInfos; numCharInfos--) - { - handleDecodeCharInfo(decodeBuffer, nextDest); - - nextDest += 12; - } - ServerCache::queryFontFontCache.set(length, saveDest); - } - - handleSave(messageStore, outputMessage, outputLength); - } - else - { - // Reply length. - unsigned int replyLength; - decodeBuffer.decodeValue(replyLength, 32, 16); - outputLength = 32 + (replyLength << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - - const unsigned char *compressedData = NULL; - unsigned int compressedDataSize = 0; - - int decompressed = handleDecompress(decodeBuffer, requestOpcode, messageStore -> dataOffset, - outputMessage, outputLength, compressedData, - compressedDataSize); - if (decompressed < 0) - { - return -1; - } - else if (decompressed > 0) - { - handleSave(messageStore, outputMessage, outputLength, - compressedData, compressedDataSize); - } - else - { - handleSave(messageStore, outputMessage, outputLength); - } - } - } - break; - case X_QueryPointer: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeBoolValue(value); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> queryPointerRootCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> queryPointerChildCache, 9); - PutULONG(value, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyRootXCache, 8); - serverCache_ -> motionNotifyLastRootX += value; - PutUINT(serverCache_ -> motionNotifyLastRootX, outputMessage + 16, - bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyRootYCache, 8); - serverCache_ -> motionNotifyLastRootY += value; - PutUINT(serverCache_ -> motionNotifyLastRootY, outputMessage + 18, - bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyEventXCache, 8); - PutUINT(serverCache_ -> motionNotifyLastRootX + value, - outputMessage + 20, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyEventYCache, 8); - PutUINT(serverCache_ -> motionNotifyLastRootY + value, - outputMessage + 22, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyStateCache); - PutUINT(value, outputMessage + 24, bigEndian_); - } - break; - case X_QueryTree: - { - unsigned int children; - decodeBuffer.decodeValue(children, 16, 8); - - outputLength = 32 + (children << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - - PutULONG(outputLength, outputMessage + 4, bigEndian_); - - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> queryTreeWindowCache); - - PutULONG(value, outputMessage + 8, bigEndian_); - - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> queryTreeWindowCache); - - PutULONG(value, outputMessage + 12, bigEndian_); - - unsigned char *next = outputMessage + 32; - - PutUINT(children, outputMessage + 16, bigEndian_); - - for (unsigned int i = 0; i < children; i++) - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> queryTreeWindowCache); - - PutULONG(value, next + (i * 4), bigEndian_); - } - } - break; - case X_TranslateCoords: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeBoolValue(value); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> translateCoordsChildCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> translateCoordsXCache, 8); - PutUINT(value, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> translateCoordsYCache, 8); - PutUINT(value, outputMessage + 14, bigEndian_); - } - break; - case X_GetImage: - { - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_GetImage); - - if (handleDecodeCached(decodeBuffer, serverCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - // Depth. - decodeBuffer.decodeCachedValue(cValue, 8, - serverCache_ -> depthCache); - // Reply length. - unsigned int replyLength; - decodeBuffer.decodeValue(replyLength, 32, 9); - outputLength = 32 + (replyLength << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - outputMessage[1] = (unsigned char) cValue; - // Visual. - unsigned int visual; - decodeBuffer.decodeCachedValue(visual, 29, - serverCache_ -> visualCache); - PutULONG(visual, outputMessage + 8, bigEndian_); - - // Since ProtoStep8 (#issue 108) - handleCopy(decodeBuffer, requestOpcode, messageStore -> - dataOffset, outputMessage, outputLength); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_GetPointerMapping: - { - unsigned int nextByte; - decodeBuffer.decodeValue(nextByte, 8, 4); - unsigned int replyLength; - decodeBuffer.decodeValue(replyLength, 32, 4); - outputLength = 32 + (replyLength << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - outputMessage[1] = (unsigned char) nextByte; - unsigned char *nextDest = outputMessage + 32; - for (unsigned int i = 32; i < outputLength; i++) - { - decodeBuffer.decodeValue(nextByte, 8, 4); - *nextDest++ = (unsigned char) nextByte; - } - } - break; - case X_GetKeyboardControl: - { - unsigned int nextByte; - decodeBuffer.decodeValue(nextByte, 8, 2); - unsigned int replyLength; - decodeBuffer.decodeValue(replyLength, 32, 8); - outputLength = 32 + (replyLength << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - outputMessage[1] = (unsigned char) nextByte; - unsigned char *nextDest = outputMessage + 8; - for (unsigned int i = 8; i < outputLength; i++) - { - decodeBuffer.decodeValue(nextByte, 8, 4); - *nextDest++ = (unsigned char) nextByte; - } - } - break; - default: - { - if (requestOpcode == opcodeStore_ -> getUnpackParameters) - { - #ifdef TEST - *logofs << "handleWrite: Received get unpack parameters reply " - << "OPCODE#" << (unsigned int) opcodeStore_ -> getUnpackParameters - << ".\n" << logofs_flush; - #endif - - outputLength = 32 + PACK_METHOD_LIMIT; - - outputMessage = writeBuffer_.addMessage(outputLength); - - unsigned int method; - - // - // Let agent use only the unpack methods - // implemented at both sides. - // - - for (int i = 0; i < PACK_METHOD_LIMIT; i++) - { - decodeBuffer.decodeBoolValue(method); - - control -> RemoteUnpackMethods[i] = method; - - *(outputMessage + 32 + i) = - (control -> LocalUnpackMethods[i] == 1 && - method == 1); - } - } - else if (requestOpcode == opcodeStore_ -> getShmemParameters) - { - if (handleShmemReply(decodeBuffer, requestOpcode, - outputMessage, outputLength) < 0) - { - return -1; - } - } - else if (requestOpcode == opcodeStore_ -> getFontParameters) - { - if (handleFontReply(decodeBuffer, requestOpcode, - outputMessage, outputLength) < 0) - { - return -1; - } - } - else - { - #ifdef PANIC - *logofs << "handleWrite: PANIC! No matching request for " - << "reply with sequence number " << sequenceNum - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": No matching request for " - << "reply with sequence number " << sequenceNum - << ".\n"; - - return -1; - } - } - } - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleWrite: Handled reply to OPCODE#" - << (unsigned) requestOpcode << " (" << DumpOpcode(requestOpcode) - << ")" << " for FD#" << fd_ << " with sequence " << serverSequence_ - << ". Output size is " << outputLength << ".\n" << logofs_flush; - #endif - - statistics -> addRepliedRequest(requestOpcode); - } - else // End of if (sequenceQueue_.peek() && ...) - { - // - // Reply didn't match any request opcode. - // Check again if differential encoding - // is disabled. - // - - #ifdef DEBUG - *logofs << "handleWrite: Identified generic reply.\n" - << logofs_flush; - #endif - - requestOpcode = X_Reply; - - if (control -> RemoteDeltaCompression == 0) - { - int result = handleFastWriteReply(decodeBuffer, requestOpcode, - outputMessage, outputLength); - if (result < 0) - { - return -1; - } - else if (result > 0) - { - continue; - } - } - - // - // All replies whose opcode is not pushed in - // sequence number queue are cached together. - // Among such replies are those to extension - // requests. - // - - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_NXInternalGenericReply); - - handleDecode(decodeBuffer, serverCache_, messageStore, - requestOpcode, outputMessage, outputLength); - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleWrite: Handled generic reply for FD#" << fd_ - << " with sequence " << serverSequence_ << ". Output size is " - << outputLength << ".\n" << logofs_flush; - #endif - - statistics -> addRepliedRequest(requestOpcode); - - } // End of if (sequenceQueue_.peek() && ...) else ... - - // - // If any output was produced then write opcode, - // sequence number and size to the buffer. - // - - if (outputLength > 0) - { - *outputMessage = outputOpcode; - - PutUINT(serverSequence_, outputMessage + 2, bigEndian_); - - PutULONG((outputLength - 32) >> 2, outputMessage + 4, bigEndian_); - } - - } // End of if (outputOpcode == 1)... - else - { - // - // It's an event or error. - // - - unsigned int sequenceNum; - unsigned int sequenceDiff; - - decodeBuffer.decodeCachedValue(sequenceDiff, 16, - serverCache_ -> eventSequenceCache, 7); - - sequenceNum = (serverSequence_ + sequenceDiff) & 0xffff; - - serverSequence_ = sequenceNum; - - #ifdef DEBUG - *logofs << "handleWrite: Last server sequence number for FD#" - << fd_ << " is " << serverSequence_ << " with " - << "difference " << sequenceDiff << ".\n" - << logofs_flush; - #endif - - // - // Check if this is an error that matches - // a sequence number for which we were - // expecting a reply. - // - - if (outputOpcode == X_Error) - { - unsigned short int errorSequenceNum; - unsigned char errorOpcode; - - if (sequenceQueue_.peek(errorSequenceNum, errorOpcode) && - ((unsigned) errorSequenceNum == serverSequence_)) - { - // - // Remove the queued sequence of the reply. - // - - #ifdef TEST - *logofs << "handleWrite: WARNING! Removing reply to OPCODE#" - << (unsigned) errorOpcode << " sequence " - << errorSequenceNum << " for FD#" << fd_ - << " due to error.\n" << logofs_flush; - #endif - - sequenceQueue_.pop(errorSequenceNum, errorOpcode); - - // - // Send to the client the current sequence - // number, not the number that matched the - // reply. Because we are generating replies - // at our side, Xlib can incur in a sequence - // lost if the error comes after the auto- - // generated reply. - // - - if (control -> SessionMode == session_proxy) - { - #ifdef TEST - *logofs << "handleWrite: Updating last event's sequence " - << lastSequence_ << " to X server's error sequence " - << "number " << serverSequence_ << " for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - lastSequence_ = serverSequence_; - } - } - - // - // In case of errors always send to client the - // original X server's sequence associated to - // the failing request. - // - - if (control -> SessionMode != session_proxy) - { - #ifdef TEST - *logofs << "handleWrite: Updating last event's sequence " - << lastSequence_ << " to X server's error sequence " - << "number " << serverSequence_ << " for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - lastSequence_ = serverSequence_; - } - } - - // - // Check if by producing events at client side we - // have modified the events' sequence numbering. - // In this case taint the original sequence to - // comply with the last one known by client. - // - -/* -FIXME: Recover the sequence number if the proxy - is not connected to an agent. -*/ - if (serverSequence_ > lastSequence_ || - control -> SessionMode != session_proxy) - { - #ifdef DEBUG - *logofs << "handleWrite: Updating last event's sequence " - << lastSequence_ << " to X server's sequence number " - << serverSequence_ << " for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - lastSequence_ = serverSequence_; - } - #ifdef DEBUG - else if (serverSequence_ < lastSequence_) - { - // - // Use our last auto-generated sequence. - // - - *logofs << "handleWrite: Tainting sequence number " - << serverSequence_ << " to last event's sequence " - << lastSequence_ << " for FD#" << fd_ << ".\n" - << logofs_flush; - } - #endif - - // - // Check if remote side used fast encoding. - // - - if (control -> RemoteDeltaCompression == 0) - { - int result = handleFastWriteEvent(decodeBuffer, outputOpcode, - outputMessage, outputLength); - if (result < 0) - { - return -1; - } - else if (result > 0) - { - continue; - } - } - - // - // Make space for message in the outgoing buffer - // and write opcode and sequence number. - // - - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - - *outputMessage = outputOpcode; - - PutUINT(lastSequence_, outputMessage + 2, bigEndian_); - - #ifdef DEBUG - *logofs << "handleWrite: Going to handle event or error OPCODE#" - << (unsigned int) outputOpcode << " for FD#" << fd_ - << " sequence " << lastSequence_ << " (real was " - << serverSequence_ << ").\n" << logofs_flush; - #endif - - switch (outputOpcode) - { - case X_Error: - { - unsigned char code; - decodeBuffer.decodeCachedValue(code, 8, - serverCache_ -> errorCodeCache); - outputMessage[1] = code; - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleWrite: Handled error ERR_CODE#" - << (unsigned int) code << " for FD#" << fd_; - #endif - - if ((code != 11) && (code != 8) && - (code != 15) && (code != 1)) - { - decodeBuffer.decodeValue(value, 32, 16); - PutULONG(value, outputMessage + 4, bigEndian_); - - #if defined(TEST) || defined(OPCODES) - *logofs << " RES_ID#" << value; - #endif - } - - if (code >= 18) - { - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> errorMinorCache); - PutUINT(value, outputMessage + 8, bigEndian_); - - #if defined(TEST) || defined(OPCODES) - *logofs << " MIN_OP#" << value; - #endif - } - - decodeBuffer.decodeCachedValue(cValue, 8, - serverCache_ -> errorMajorCache); - outputMessage[10] = cValue; - - #if defined(TEST) || defined(OPCODES) - *logofs << " MAJ_OP#" << (unsigned int) cValue; - #endif - - if (code >= 18) - { - unsigned char *nextDest = outputMessage + 11; - for (unsigned int i = 11; i < 32; i++) - { - decodeBuffer.decodeValue(value, 8); - *nextDest++ = (unsigned char) cValue; - } - } - - #if defined(TEST) || defined(OPCODES) - *logofs << " sequence " << lastSequence_ << " (real was " - << serverSequence_ << ") . Size is " - << (unsigned int) outputLength << ".\n" - << logofs_flush; - #endif - } - break; - case ButtonPress: - case ButtonRelease: - case KeyPress: - case KeyRelease: - case MotionNotify: - case EnterNotify: - case LeaveNotify: - { - if (outputOpcode == MotionNotify) - { - decodeBuffer.decodeBoolValue(value); - } - else if (outputOpcode == EnterNotify || outputOpcode == LeaveNotify) - { - decodeBuffer.decodeValue(value, 3); - } - else if (outputOpcode == KeyRelease) - { - decodeBuffer.decodeBoolValue(value); - if (value) - { - value = serverCache_ -> keyPressLastKey; - } - else - { - decodeBuffer.decodeValue(value, 8); - } - } - else if (outputOpcode == ButtonPress || outputOpcode == ButtonRelease) - { - decodeBuffer.decodeCachedValue(cValue, 8, - serverCache_ -> buttonCache); - value = (unsigned int) cValue; - } - else - { - decodeBuffer.decodeValue(value, 8); - } - - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeCachedValue(value, 32, - serverCache_ -> motionNotifyTimestampCache, 9); - serverCache_ -> lastTimestamp += value; - PutULONG(serverCache_ -> lastTimestamp, outputMessage + 4, - bigEndian_); - unsigned char *nextDest = outputMessage + 8; - int skipRest = 0; - if (outputOpcode == KeyRelease) - { - decodeBuffer.decodeBoolValue(value); - if (value) - { - for (unsigned int i = 0; i < 23; i++) - { - *nextDest++ = serverCache_ -> keyPressCache[i]; - } - skipRest = 1; - } - } - - if (!skipRest) - { - for (unsigned int i = 0; i < 3; i++) - { - decodeBuffer.decodeCachedValue(value, 29, - *serverCache_ -> motionNotifyWindowCache[i], 6); - PutULONG(value, nextDest, bigEndian_); - nextDest += 4; - } - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyRootXCache, 6); - serverCache_ -> motionNotifyLastRootX += value; - PutUINT(serverCache_ -> motionNotifyLastRootX, outputMessage + 20, - bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyRootYCache, 6); - serverCache_ -> motionNotifyLastRootY += value; - PutUINT(serverCache_ -> motionNotifyLastRootY, outputMessage + 22, - bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyEventXCache, 6); - PutUINT(serverCache_ -> motionNotifyLastRootX + value, - outputMessage + 24, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyEventYCache, 6); - PutUINT(serverCache_ -> motionNotifyLastRootY + value, - outputMessage + 26, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> motionNotifyStateCache); - PutUINT(value, outputMessage + 28, bigEndian_); - if (outputOpcode == EnterNotify || outputOpcode == LeaveNotify) - { - decodeBuffer.decodeValue(value, 2); - } - else - { - decodeBuffer.decodeBoolValue(value); - } - outputMessage[30] = (unsigned char) value; - if (outputOpcode == EnterNotify || outputOpcode == LeaveNotify) - { - decodeBuffer.decodeValue(value, 2); - outputMessage[31] = (unsigned char) value; - } - else if (outputOpcode == KeyPress) - { - serverCache_ -> keyPressLastKey = outputMessage[1]; - for (unsigned int i = 8; i < 31; i++) - { - serverCache_ -> keyPressCache[i - 8] = outputMessage[i]; - } - } - } - } - break; - case ColormapNotify: - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> colormapNotifyWindowCache, 8); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> colormapNotifyColormapCache, 8); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeBoolValue(value); - outputMessage[12] = (unsigned char) value; - decodeBuffer.decodeBoolValue(value); - outputMessage[13] = (unsigned char) value; - } - break; - case ConfigureNotify: - { - unsigned char *nextDest = outputMessage + 4; - for (unsigned int i = 0; i < 3; i++) - { - decodeBuffer.decodeCachedValue(value, 29, - *serverCache_ -> configureNotifyWindowCache[i], 9); - PutULONG(value, nextDest, bigEndian_); - nextDest += 4; - } - for (unsigned int j = 0; j < 5; j++) - { - decodeBuffer.decodeCachedValue(value, 16, - *serverCache_ -> configureNotifyGeomCache[j], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - decodeBuffer.decodeBoolValue(value); - *nextDest = value; - } - break; - case CreateNotify: - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> createNotifyWindowCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeValue(value, 29, 5); - serverCache_ -> createNotifyLastWindow += value; - serverCache_ -> createNotifyLastWindow &= 0x1fffffff; - PutULONG(serverCache_ -> createNotifyLastWindow, outputMessage + 8, - bigEndian_); - unsigned char* nextDest = outputMessage + 12; - for (unsigned int i = 0; i < 5; i++) - { - decodeBuffer.decodeValue(value, 16, 9); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - decodeBuffer.decodeBoolValue(value); - *nextDest = (unsigned char) value; - } - break; - case Expose: - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> exposeWindowCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned char *nextDest = outputMessage + 8; - for (unsigned int i = 0; i < 5; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *serverCache_ -> exposeGeomCache[i], 6); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - } - break; - case FocusIn: - case FocusOut: - { - decodeBuffer.decodeValue(value, 3); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> focusInWindowCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeValue(value, 2); - outputMessage[8] = (unsigned char) value; - } - break; - case KeymapNotify: - { - decodeBuffer.decodeBoolValue(value); - if (value) - memcpy(outputMessage + 1, ServerCache::lastKeymap.getData(), 31); - else - { - unsigned char *nextDest = outputMessage + 1; - for (unsigned int i = 1; i < 32; i++) - { - decodeBuffer.decodeValue(value, 8); - *nextDest++ = (unsigned char) value; - } - ServerCache::lastKeymap.set(31, outputMessage + 1); - } - } - break; - case MapNotify: - case UnmapNotify: - case DestroyNotify: - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> mapNotifyEventCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> mapNotifyWindowCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - if (outputOpcode == MapNotify || outputOpcode == UnmapNotify) - { - decodeBuffer.decodeBoolValue(value); - outputMessage[12] = (unsigned char) value; - } - } - break; - case NoExpose: - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> noExposeDrawableCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - serverCache_ -> noExposeMinorCache); - PutUINT(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(cValue, 8, - serverCache_ -> noExposeMajorCache); - outputMessage[10] = cValue; - } - break; - case PropertyNotify: - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> propertyNotifyWindowCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> propertyNotifyAtomCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeValue(value, 32, 9); - serverCache_ -> lastTimestamp += value; - PutULONG(serverCache_ -> lastTimestamp, outputMessage + 12, - bigEndian_); - decodeBuffer.decodeBoolValue(value); - outputMessage[16] = (unsigned char) value; - } - break; - case ReparentNotify: - { - unsigned char* nextDest = outputMessage + 4; - for (unsigned int i = 0; i < 3; i++) - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> reparentNotifyWindowCache, 9); - PutULONG(value, nextDest, bigEndian_); - nextDest += 4; - } - decodeBuffer.decodeValue(value, 16, 6); - PutUINT(value, nextDest, bigEndian_); - decodeBuffer.decodeValue(value, 16, 6); - PutUINT(value, nextDest + 2, bigEndian_); - decodeBuffer.decodeBoolValue(value); - outputMessage[20] = (unsigned char)value; - } - break; - case SelectionClear: - { - decodeBuffer.decodeValue(value, 32, 9); - serverCache_ -> lastTimestamp += value; - PutULONG(serverCache_ -> lastTimestamp, outputMessage + 4, - bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> selectionClearWindowCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> selectionClearAtomCache, 9); - PutULONG(value, outputMessage + 12, bigEndian_); - } - break; - case SelectionRequest: - { - decodeBuffer.decodeValue(value, 32, 9); - serverCache_ -> lastTimestamp += value; - PutULONG(serverCache_ -> lastTimestamp, outputMessage + 4, - bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> selectionClearWindowCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> selectionClearWindowCache, 9); - PutULONG(value, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> selectionClearAtomCache, 9); - PutULONG(value, outputMessage + 16, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> selectionClearAtomCache, 9); - PutULONG(value, outputMessage + 20, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> selectionClearAtomCache, 9); - PutULONG(value, outputMessage + 24, bigEndian_); - } - break; - case VisibilityNotify: - { - decodeBuffer.decodeCachedValue(value, 29, - serverCache_ -> visibilityNotifyWindowCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeValue(value, 2); - outputMessage[8] = (unsigned char) value; - } - break; - default: - { - #ifdef TEST - *logofs << "handleWrite: Using generic event compression " - << "for OPCODE#" << (unsigned int) outputOpcode - << ".\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(*(outputMessage + 1), 8, - serverCache_ -> genericEventCharCache); - - for (unsigned int i = 0; i < 14; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *serverCache_ -> genericEventIntCache[i]); - - PutUINT(value, outputMessage + i * 2 + 4, bigEndian_); - } - } - } // End of switch (outputOpcode)... - - #if defined(TEST) || defined(OPCODES) - if (outputOpcode != X_Error) - { - *logofs << "handleWrite: Handled event OPCODE#" - << (unsigned int) outputOpcode << " for FD#" - << fd_ << " sequence " << lastSequence_ << " (real was " - << serverSequence_ << "). Size is " << outputLength - << ".\n" << logofs_flush; - } - #endif - - // - // Check if we need to suppress the error. - // - - if (outputOpcode == X_Error && - handleTaintSyncError(*(outputMessage + 10)) > 0) - { - #if defined(TEST) || defined(OPCODES) - *logofs << "handleWrite: WARNING! Suppressed error OPCODE#" - << (unsigned int) outputOpcode << " for FD#" - << fd_ << " sequence " << lastSequence_ << ".\n" - << logofs_flush; - #endif - - writeBuffer_.removeMessage(32); - } - - } // End of if (outputOpcode == 1)... else ... - - // - // Check if we produced enough data. We need to - // decode all provided messages. Just update the - // finish flag in case of failure. - // - - handleFlush(flush_if_needed); - - } // End of while (decodeBuffer.decodeOpcodeValue(outputOpcode, 8, ... - - } // End of the decoding block. - - // - // Write any remaining data to the X connection. - // - - if (handleFlush(flush_if_any) < 0) - { - return -1; - } - - return 1; -} - -// -// End of handleWrite(). -// - -// -// Other members. -// - -int ClientChannel::handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, - T_store_action action, int position, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - #if defined(TEST) || defined(SPLIT) - - // Since ProtoStep8 (#issue 108) - *logofs << "handleSplit: PANIC! SPLIT! Split should " - << "not be enabled for message " << "OPCODE#" - << (unsigned int) store -> opcode() << ".\n" - << logofs_flush; - - HandleCleanup(); - - #endif - - // - // Refuse the split if it is not introduced - // by a start split. - // - - // Since ProtoStep7 (#issue 108) - if (splitState_.resource == nothing || enableSplit_ == 0) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Nothing to do for message " - << "OPCODE#" << (unsigned int) store -> opcode() - << " of size " << size << " position " << position - << " with action [" << DumpAction(action) << "] at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeBoolValue(0); - - return 0; - } - - // - // It's not advisable to allocate the store at - // the time we receive the start-split because - // we may process all the splits received and - // deallocate the store even before we receive - // the end split. Another message for the same - // split sequence may then come and we would - // have a null split store. - // - - handleSplitStoreAlloc(&splitResources_, splitState_.resource); - - // - // Check if the split was actually requested by - // the agent and if the request was saved in the - // message store. The split can also be refused - // if the message is smaller than the threshold - // or if the split store is already full. - // - - if (mustSplitMessage(splitState_.resource) == 0) - { - if (action == IS_HIT || canSplitMessage(splitState_.mode, size) == 0) - { - #if defined(TEST) || defined(SPLIT) - - if (splitState_.mode == split_none) - { - #ifdef PANIC - *logofs << "handleSplit: PANIC! SPLIT! Split state has " - << "mode 'none'.\n" << logofs_flush; - #endif - - HandleCleanup(); - } - - if (action != IS_HIT && (int) size >= - control -> SplitDataThreshold) - { - #ifdef WARNING - *logofs << "handleSplit: WARNING! SPLIT! Split stores have " - << clientStore_ -> getSplitTotalSize() << " messages " - << "and " << clientStore_ -> getSplitTotalStorageSize() - << " allocated bytes.\n" << logofs_flush; - #endif - } - - #endif - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Message OPCODE#" - << (unsigned int) store -> opcode() << " of size " << size - << " [not split] with resource " << splitState_.resource - << " mode " << splitState_.mode << " position " << position - << " and action [" << DumpAction(action) << "] at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeBoolValue(0); - - return 0; - } - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Message OPCODE#" - << (unsigned int) store -> opcode() << " of size " << size - << " [split] with resource " << splitState_.resource - << " mode " << splitState_.mode << " position " << position - << " and action [" << DumpAction(action) << "] at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeBoolValue(1); - - T_checksum checksum = NULL; - - if (action == IS_ADDED) - { - checksum = store -> getChecksum(position); - } - else if (action == is_discarded) - { - // - // Generate the checksum on the fly. - // - - checksum = store -> getChecksum(buffer, size, bigEndian_); - } - - // - // The method must abort the connection - // if it can't allocate the split. - // - - Split *splitMessage = clientStore_ -> getSplitStore(splitState_.resource) -> - add(store, splitState_.resource, splitState_.mode, - position, action, checksum, buffer, size); - - // - // Send the checksum. By using the checksum, - // the remote end will try to locate the - // message and load it from disk. - // - - if (action == IS_HIT) - { - splitMessage -> setState(split_loaded); - } - else if (handleSplitChecksum(encodeBuffer, checksum) == 0) - { - // - // If the checksum is not sent, for example - // because loading of messages from disk is - // disabled, then mark the split as missed. - // - - #ifdef WARNING - *logofs << "handleSplit: WARNING! Checksum not sent. " - << "Marking the split as [missed].\n" - << logofs_flush; - #endif - - splitMessage -> setState(split_missed); - } - - if (action == is_discarded) - { - delete [] checksum; - } - - // - // Check if we are ready to send a new split - // for this store. - // - - handleSplitPending(splitState_.resource); - - #if defined(TEST) || defined(SPLIT) - - *logofs << "handleSplit: SPLIT! There are " << clientStore_ -> - getSplitTotalSize() << " messages and " << clientStore_ -> - getSplitTotalStorageSize() << " bytes to send in " - << "the split stores.\n" << logofs_flush; - - clientStore_ -> dumpSplitStore(splitState_.resource); - - #endif - - return 1; -} - -int ClientChannel::handleSplit(EncodeBuffer &encodeBuffer) -{ - // - // Determine the maximum amount of bytes - // we can write in this iteration. - // - - int total = control -> SplitDataPacketLimit; - - int bytes = total; - int splits = 0; - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Handling splits " - << "for FD#" << fd_ << " with " << clientStore_ -> - getSplitTotalSize() << " elements and " << total - << " bytes to write at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - if (proxy -> handleAsyncSwitch(fd_) < 0) - { - return -1; - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Looping to find " - << "if there is any split to send.\n" - << logofs_flush; - #endif - - SplitStore *splitStore; - - Split *splitMessage; - - // - // Divide the available bandwidth among all the active - // split stores by implementing a simple round-robin - // mechanism. This can be extended by using an external - // function returning the number of bytes to be written - // based on the state of the split (splits which didn't - // receive yet a confirmation event could be delayed), - // the current bitrate, and by letting the agent asso- - // ciate a priority to the resource in the start split - // operation. - // - - splitState_.pending = 0; - - splitResources_.rotate(); - - // - // Copy the list since elements can be removed - // in the middle of the loop. - // - - T_list splitList = splitResources_.copyList(); - - for (T_list::iterator j = splitList.begin(); - j != splitList.end(); j++) - { - int resource = *j; - - #ifdef DEBUG - *logofs << "handleSplit: SPLIT! Looping with current " - << "resource " << resource << ".\n" - << logofs_flush; - #endif - - splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore != NULL) - { - // - // Don't send more than the the packet size - // bytes but ensure that we abort any split - // found in the disk cache. - // - - for (;;) - { - #if defined(TEST) || defined(SPLIT) - - clientStore_ -> dumpSplitStore(resource); - - #endif - - splitMessage = splitStore -> getFirstSplit(); - - if (splitMessage == NULL) - { - // - // We have created the store after a start - // split but no message was added yet. - // - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: WARNING! SPLIT! The split store " - << "is still empty.\n" << logofs_flush; - #endif - - break; - } - - // - // Splits already aborted can't be in the - // split store. - // - - #if defined(TEST) || defined(SPLIT) - - if (splitMessage -> getState() == split_aborted) - { - *logofs << "handleSplit: PANIC! SPLIT! Found an " - << "aborted split in store [" << resource - << "].\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - // - // Check if there are more messages in the - // store that can be aborted or if we have - // exceeded the number of bytes we can send - // for this iteration. - // - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Checking closure " - << "of the inner loop with " << bytes - << " bytes to write and split state [" - << DumpState(splitMessage -> getState()) - << "].\n" << logofs_flush; - #endif - - if ((splitMessage -> getMode() == split_sync && - splitMessage -> getState() == split_added) || - (bytes <= 0 && splitMessage -> - getState() != split_loaded)) - { - break; - } - - // - // If the split was loaded at the remote - // side abort it immediately. - // - - if (splitMessage -> getState() == split_loaded) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Sending more data " - << "for store [" << resource << "] with " - << "a split to be aborted.\n" - << logofs_flush; - #endif - - if (handleSplitSend(encodeBuffer, resource, splits, bytes) < 0) - { - return -1; - } - } - else if (bytes > 0) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Sending more data " - << "for store [" << resource << "] with " - << bytes << " bytes to send.\n" - << logofs_flush; - #endif - - if (handleSplitSend(encodeBuffer, resource, splits, bytes) < 0) - { - return -1; - } - } - - // - // Check if the split store was deleted. - // - - splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore == NULL) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Exiting from the " - << "inner loop with split store [" << resource - << "] destroyed.\n" << logofs_flush; - #endif - - break; - } - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Completed handling splits " - << "for store [" << resource << "] with " << bytes - << " bytes still to send.\n" << logofs_flush; - #endif - - // - // Check if there is still a split to - // send for the store just processed. - // - - handleSplitPending(resource); - } - } - - #if defined(TEST) || defined(SPLIT) - - if (splits == 0) - { - #ifdef PANIC - *logofs << "handleSplit: PANIC! Function called but " - << "no split message was sent.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - - *logofs << "handleSplit: SPLIT! Sent " << splits - << " splits and " << total - bytes << " bytes for FD#" << fd_ - << " with " << clientStore_ -> getSplitTotalStorageSize() - << " bytes and [" << clientStore_ -> getSplitTotalSize() - << "] splits remaining.\n" << logofs_flush; - - *logofs << "handleSplit: SPLIT! The pending split flag is " - << splitState_.pending << " with " << clientStore_ -> - getSplitTotalSize() << " splits in the split stores.\n" - << logofs_flush; - - clientStore_ -> dumpSplitStores(); - - #endif - - return 1; -} - -int ClientChannel::handleSplitSend(EncodeBuffer &encodeBuffer, int resource, - int &splits, int &bytes) -{ - #if defined(TEST) || defined(SPLIT) - - SplitStore *splitStore = clientStore_ -> getSplitStore(resource); - - Split *splitMessage = splitStore -> getFirstSplit(); - - if (splitStore -> getResource() != resource || - splitMessage -> getResource() != resource) - { - #ifdef PANIC - *logofs << "handleSplitSend: PANIC! The resource doesn't " - << "match the split store.\n" << logofs_flush; - #endif - - HandleCleanup(); - } - - *logofs << "handleSplitSend: SPLIT! Sending message " - << "OPCODE#" << (unsigned) opcodeStore_ -> splitData - << " for resource " << splitMessage -> getResource() - << " with request " << splitMessage -> getRequest() - << " position " << splitMessage -> getPosition() - << " and " << bytes << " bytes to write.\n" - << logofs_flush; - #endif - - // - // Use a special opcode to signal the other - // side this is part of a split and not a - // new message. - // - - encodeBuffer.encodeOpcodeValue(opcodeStore_ -> splitData, - clientCache_ -> opcodeCache); - - encodeBuffer.encodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - int result = clientStore_ -> getSplitStore(resource) -> - send(encodeBuffer, bytes); - - if (result < 0) - { - #ifdef PANIC - *logofs << "handleSplit: PANIC! Error sending splits for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Error sending splits for FD#" - << fd_ << ".\n"; - - return -1; - } - - // - // Get the bits written and update the - // statistics for this special opcode. - // - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(SPLIT)|| defined(OPCODES) - *logofs << "handleSplitSend: SPLIT! Handled request OPCODE#" - << (unsigned int) opcodeStore_ -> splitData << " (" - << DumpOpcode(opcodeStore_ -> splitData) << ")" << " for FD#" - << fd_ << " sequence none. 0 bytes in, " << bits << " bits (" - << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; - #endif - - statistics -> addRequestBits(opcodeStore_ -> splitData, 0, bits); - - bytes -= bits >> 3; - - splits++; - - if (result == 1) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitSend: SPLIT! Split at the head " - << "of the list was completely transferred.\n" - << logofs_flush; - #endif - - // - // The split at the head of the list was - // completely transferred. - // - - handleRestart(sequence_deferred, resource); - } - #if defined(TEST) || defined(SPLIT) - else - { - *logofs << "handleSplitSend: SPLIT! More data to send " - << "for the split at the head of the list.\n" - << logofs_flush; - } - #endif - - return result; -} - -int ClientChannel::handleSplitChecksum(EncodeBuffer &encodeBuffer, T_checksum checksum) -{ - // - // Send the checksum only if the loading - // or the saving of the message to the - // persistent image cache is enabled. - // - - if ((control -> ImageCacheEnableLoad == 1 || - control -> ImageCacheEnableSave == 1) && - (enableLoad_ == 1 || enableSave_ == 1)) - { - encodeBuffer.encodeBoolValue(1); - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - encodeBuffer.encodeValue((unsigned int) checksum[i], 8); - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitChecksum: SPLIT! Sent checksum " - << "[" << DumpChecksum(checksum) << "].\n" - << logofs_flush; - #endif - - return 1; - } - else - { - encodeBuffer.encodeBoolValue(0); - - return 0; - } -} - -void ClientChannel::handleSplitPending() -{ - #if defined(TEST) || defined(SPLIT) - - int previous = splitState_.pending; - - #endif - - if (clientStore_ -> getSplitTotalSize() == 0) - { - splitState_.pending = 0; - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitPending: SPLIT! Set the pending " - << "split flag to " << splitState_.pending - << " with split stores empty.\n" - << logofs_flush; - #endif - } - else - { - // - // Loop through the stores to find if - // there is any split that has become - // ready. - // - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitPending: WARNING! SPLIT! Looping to " - << "find if there is any split pending.\n" - << logofs_flush; - #endif - - splitState_.pending = 0; - - T_list &splitList = splitResources_.getList(); - - for (T_list::iterator j = splitList.begin(); - j != splitList.end(); j++) - { - int resource = *j; - - SplitStore *splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore != NULL) - { - #if defined(TEST) || defined(SPLIT) - - clientStore_ -> dumpSplitStore(resource); - - #endif - - Split *splitMessage = splitStore -> getFirstSplit(); - - if (splitMessage != NULL && canSendSplit(splitMessage) == 1) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitPending: SPLIT! Found a pending " - << "split in store [" << resource << "].\n" - << logofs_flush; - #endif - - splitState_.pending = 1; - - #if defined(TEST) || defined(SPLIT) - - if (splitMessage -> getState() == split_loaded) - { - *logofs << "handleSplitPending: PANIC! SPLIT! Found a " - << "loaded split in store [" << resource - << "].\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - break; - } - } - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitPending: SPLIT! Set the pending " - << "split flag to " << splitState_.pending - << " with " << clientStore_ -> getSplitTotalSize() - << " splits in the split stores.\n" - << logofs_flush; - #endif - } - - #if defined(TEST) || defined(SPLIT) - - if (splitState_.pending != previous) - { - *logofs << "handleSplitPending: SPLIT! Pending state " - << "changed from " << previous << " to " - << splitState_.pending << ".\n" - << logofs_flush; - } - - #endif -} - -int ClientChannel::handleSplitEvent(EncodeBuffer &encodeBuffer, Split *splitMessage) -{ - SplitStore *splitStore; - - int resource = splitMessage -> getResource(); - - #if defined(TEST) || defined(INFO) - - splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore == NULL) - { - #ifdef PANIC - *logofs << "handleSplitEvent: PANIC! The split store can't " - << "be NULL handling abort splits.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - else if (splitMessage -> getState() != split_loaded) - { - *logofs << "handleSplitEvent: PANIC! Can't find the split " - << "to be aborted.\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - // - // Send any split that it is possible to - // abort until the store is either empty - // or the next split can't be aborted. - // - - if (proxy -> handleAsyncSwitch(fd_) < 0) - { - return -1; - } - - while ((splitStore = clientStore_ -> - getSplitStore(resource)) != NULL && - (splitMessage = splitStore -> getFirstSplit()) != NULL && - splitMessage -> getState() == split_loaded) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Aborting split with " - << "checksum [" << DumpChecksum(splitMessage -> - getChecksum()) << "] for resource " << resource - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - int any = 0; - - if (handleSplitSend(encodeBuffer, resource, any, any) < 0) - { - return -1; - } - } - - #if defined(TEST) || defined(SPLIT) - - if ((splitStore = clientStore_ -> - getSplitStore(resource)) == NULL) - { - *logofs << "handleSplitEvent: SPLIT! The split store [" - << resource << "] has been destroyed.\n" - << logofs_flush; - } - else if ((splitMessage = splitStore -> - getFirstSplit()) == NULL) - { - *logofs << "handleSplitEvent: SPLIT! The split store [" - << resource << "] is empty.\n" - << logofs_flush; - } - else if (splitMessage -> getState() != split_loaded) - { - *logofs << "handleSplitEvent: SPLIT! The split at the " - << "head of store [" << resource << "] doesn't " - << "need to be aborted.\n" << logofs_flush; - } - - #endif - - return 1; -} - -int ClientChannel::handleSplitEvent(DecodeBuffer &decodeBuffer) -{ - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Handling abort " - << "split messages for FD#" << fd_ << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - // Since ProtoStep7 (#issue 108) - - // - // Decode the information about the - // message to be updated. - // - - unsigned char resource; - - decodeBuffer.decodeCachedValue(resource, 8, - serverCache_ -> resourceCache); - - unsigned int loaded; - - decodeBuffer.decodeBoolValue(loaded); - - unsigned char request; - unsigned int size; - - if (loaded == 1) - { - decodeBuffer.decodeOpcodeValue(request, serverCache_ -> abortOpcodeCache); - - decodeBuffer.decodeValue(size, 32, 14); - } - else - { - request = 0; - size = 0; - } - - unsigned int value; - - md5_byte_t checksum[MD5_LENGTH]; - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - decodeBuffer.decodeValue(value, 8); - - checksum[i] = (unsigned char) value; - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Checking split " - << "with checksum [" << DumpChecksum(checksum) - << "] loaded " << loaded << " request " << (unsigned int) - request << " compressed size " << size << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - Split *splitMessage = handleSplitFind(checksum, resource); - - if (splitMessage != NULL) - { - if (loaded == 1) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Marked split with " - << "checksum [" << DumpChecksum(checksum) << "] " - << "as [loaded] at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - splitMessage -> setState(split_loaded); - - #if defined(TEST) || defined(SPLIT) - - if (splitMessage -> compressedSize() != (int) size) - { - *logofs << "handleSplitEvent: WARNING! SPLIT! Updating " - << "compressed data size from " << splitMessage -> - compressedSize() << " to " << size << ".\n" - << logofs_flush; - } - - #endif - - splitMessage -> compressedSize(size); - - // - // The splits to be aborted are checked by the split - // store at the time we are going to send a new chunk - // of split data. The splits must be strictly handled - // in the same order as they were added to the split - // store and the split we want to abort here may be - // not at the head of the list. - // - - if (splitMessage == clientStore_ -> - getSplitStore(resource) -> getFirstSplit()) - { - // - // We don't need to flush this packet immediately. - // The abort can be sent at any time to the remote - // proxy. What's important is that we restart the - // agent resource as soon as possible. - // - - #if defined(TEST) || defined(SPLIT) - - T_timestamp startTs = getTimestamp(); - - *logofs << "handleSplitEvent: SPLIT! Encoding abort " - << "split events for FD#" << fd_ << " with " - << "resource " << (unsigned) resource << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - if (proxy -> handleAsyncSplit(fd_, splitMessage) < 0) - { - return -1; - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Spent " - << diffTimestamp(startTs, getTimestamp()) << " Ms " - << "handling abort split events for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - // - // Check if we can clear the pending flag. - // - - handleSplitPending(); - } - #if defined(TEST) || defined(SPLIT) - else - { - *logofs << "handleSplitEvent: WARNING! SPLIT! Abort split " - << "event not sent because not at the head " - << "of the list.\n" << logofs_flush; - } - #endif - } - else - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Marked split with " - << "checksum [" << DumpChecksum(checksum) << "] " - << "as [missed] at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - splitMessage -> setState(split_missed); - - // - // Check if we can set the pending flag. - // - - handleSplitPending(resource); - } - } - else - { - // - // The split report came after the split was already - // sent or the split store deleted. If the message - // had been loaded from disk by the remote side, we - // need to update the compressed size in our message - // store or the checksum will not match at the time - // we will try to save the message store on disk. - // - - if (loaded == 1 && size != 0) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: WARNING! SPLIT! Can't find " - << "the split. Updating in the message store.\n" - << logofs_flush; - #endif - - MessageStore *store = clientStore_ -> getRequestStore(request); - - if (store != NULL) - { - store -> updateData(checksum, size); - } - #if defined(TEST) || defined(SPLIT) - else - { - #ifdef PANIC - *logofs << "handleSplitEvent: PANIC! The message store " - << "can't be null.\n" << logofs_flush; - #endif - - HandleCleanup(); - } - #endif - } - #if defined(TEST) || defined(SPLIT) - else - { - *logofs << "handleSplitEvent: WARNING! SPLIT! No need to " - << "update the store with loaded " << loaded - << " and compressed size " << size << ".\n" - << logofs_flush; - } - #endif - } - - return 1; -} - -Split *ClientChannel::handleSplitFind(T_checksum checksum, int resource) -{ - // - // It can be that we handled all the splits, - // restarted the resource and deleted the - // store before the event could even reach - // our side. - // - - SplitStore *splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore != NULL) - { - Split *splitMessage; - - T_splits *splitList = splitStore -> getSplits(); - - for (T_splits::iterator i = splitList -> begin(); - i != splitList -> end(); i++) - { - splitMessage = (*i); - - if (splitMessage -> getChecksum() != NULL) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitFind: SPLIT! Comparing with message [" - << DumpChecksum(splitMessage -> getChecksum()) - << "].\n" << logofs_flush; - #endif - - if (memcmp(checksum, splitMessage -> getChecksum(), MD5_LENGTH) == 0) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitFind: SPLIT! Located split for " - << "checksum [" << DumpChecksum(checksum) << "] " - << "in store [" << splitStore -> getResource() - << "].\n" << logofs_flush; - #endif - - return splitMessage; - } - } - } - } - #if defined(TEST) || defined(SPLIT) - else - { - *logofs << "handleSplitFind: WARNING! SPLIT! The split store " - << "was already deleted.\n" << logofs_flush; - } - #endif - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitFind: WARNING! SPLIT! Can't find the " - << "split for checksum [" << DumpChecksum(checksum) - << "].\n" << logofs_flush; - #endif - - return NULL; -} - -int ClientChannel::handleRestart(T_sequence_mode mode, int resource) -{ - // - // The agent must send a start-split message, followed by the - // X messages that may be optionally split by the proxy. Usu- - // ally, in the middle of a start-split/end-split sequence is - // a single PutImage() or PutPackedImage(), that, in turn, - // can generate multiple partial requests, like a SetUnpack- - // Colormap() and SetUnpackAlpha() followed by the image that - // must be transferred. Multiple requests may be also genera- - // ted because the maximum size of a X request has been exce- - // eded, so that Xlib has divided the single image in multi- - // ple sub-image requests. The agent doesn't need to take care - // of that, except tracking the result of the split operation. - // - // By monitoring the notify events sent by the proxy, the - // agent will have to implement its own strategy to deal with - // its resources (for example its clients). For example: - // - // - It will issue a new image request and suspend a client - // if the image was not entirely sent in the main X oputput - // stream. - // - // - It will choose to commit or discard the messages after - // they are recomposed at the remote side. The set of mes- - // sages that will have to be committed will include all - // messages that were part of the split (the colormap, the - // alpha channel). - // - // - It will restart its own client, in the case it had been - // suspended. - // - // A more useful strategy would be to replace the original im- - // age with a tiny 'placeholder' if a split took place, and - // synchronize the content of the drawable at later time. This - // is generally referred as 'lazy encoding'. - // - // The agent will be able to identify the original split ope- - // ration (the one marked with the start-spit) by the small - // integer number (0-255) referred to as the 'resource' field. - // - // Before the proxy will be able to report the status of the - // split, the agent will have to close the sequence by issueing - // an end-split. The proxy will then report the result of the - // operation, so that the agent will have the option of suspend- - // ing the client or marking the drawable as dirty and take - // care of synchronizing it at later time. - // - // One of the following cases may be encountered: - // - // notify_no_split: All messages were sent in the main out- - // put stream, so that no split actually - // took place. - // - // notify_start_split: One or more messages were split, so, - // at discrection of the agent, the client - // may be suspended until the transferral - // is completed. - // - // notify_commit_split: One of the requests that made up the - // split was recomposed. The agent should - // either commit the given request or tell - // the proxy to discard it. - // - // notify_end_split: The split was duly completed. The agent - // can restart the client. - // - // notify_empty_split: No more split operation are pending. - // The agent can use this information to - // implement specific strategies requiring - // that all messages have been recomposed - // at the remote end, like updating the - // drawables that were not synchronized - // because of the lazy encoding. - // - // By checking the split and commit store we can determine if we - // need to send a new notification event to the agent. There can - // be four different cases: - // - // - If the split store is not null and not empty, we are still - // in the middle of a split. - // - // - If the commit store is not empty, we completely recomposed - // a full message and can send a new commit notify. - // - // - If the split store has become empty, we recomposed all the - // messages added for the given resource, and so will be able - // to restart the resource. - // - // - If no more messages are in the split stores, we can notify - // an empty split event to the agent. - // - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleRestart: SPLIT! Handling [" - << (mode == sequence_immediate ? "immediate" : "deferred") - << "] restart events for resource " << resource << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - SplitStore *splitStore = clientStore_ -> getSplitStore(resource); - - if (mode == sequence_immediate) - { - // - // We have received an end-split request. If the store - // was not deleted already, we mark the last split added - // as the one ending the row for this resource. If the - // commit() function returns 0 it means that the split - // store is either empty or that we did not add any split - // for this resource. This is because when connected to - // an old proxy version we only have a single store for - // all the resources. - // - // It can happen that all the split messages that were - // originally appended to the list were completely sent - // before our client had the chance of ending the split - // sequence. In this case the split store will be empty - // or already deleted and so we will be able to restart - // the resource. - // - - #if defined(TEST) || defined(SPLIT) - - if (splitStore == NULL) - { - *logofs << "handleRestart: WARNING! SPLIT! Split store [" - << resource << "] was already deleted.\n" - << logofs_flush; - } - else - { - clientStore_ -> dumpSplitStore(resource); - } - - #endif - - if (splitStore == NULL || splitStore -> getSize() == 0) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleRestart: SPLIT! Immediate agent split event " - << "TYPE#" << (unsigned) opcodeStore_ -> noSplitNotify - << " [no split] with resource " << resource - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - if (handleNotify(notify_no_split, sequence_immediate, - resource, nothing, nothing) < 0) - { - return -1; - } - } - else - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleRestart: SPLIT! Immediate agent split event " - << "TYPE#" << (unsigned) opcodeStore_ -> startSplitNotify - << " [start split] with resource " << resource - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - if (handleNotify(notify_start_split, sequence_immediate, - resource, nothing, nothing) < 0) - { - return -1; - } - } - } - else - { - // - // We have completely transferred a message - // that was put in the split store. - // - // The id of the resource can be different - // than the index of the store if we are - // connected to an old proxy. - // - - #if defined(TEST) || defined(SPLIT) - - if (splitStore == NULL) - { - #ifdef PANIC - *logofs << "handleRestart: PANIC! The split store can't " - << "be NULL handling deferred restart events.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - else - { - clientStore_ -> dumpSplitStore(resource); - } - - #endif - - CommitStore *commitStore = clientStore_ -> getCommitStore(); - - #if defined(TEST) || defined(SPLIT) - - clientStore_ -> dumpCommitStore(); - - #endif - - // - // Check if there is any commit to notify. - // - - Split *split; - - T_splits *commitList = commitStore -> getSplits(); - - for (T_splits::iterator i = commitList -> begin(); - i != commitList -> end(); i++) - { - split = *i; - - if (split -> getState() != split_notified) - { - #if defined(TEST) || defined(SPLIT) - - if (split -> getResource() != resource) - { - #ifdef PANIC - *logofs << "handleSplitSend: PANIC! The resource doesn't " - << "match the split store.\n" << logofs_flush; - #endif - - HandleCleanup(); - } - - #endif - - int request = split -> getRequest(); - int position = split -> getPosition(); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleRestart: SPLIT! Deferred agent split event " - << "TYPE#" << (unsigned) opcodeStore_ -> commitSplitNotify - << " [commit split] with resource " << resource << " request " - << request << " position " << position << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - if (handleNotify(notify_commit_split, sequence_deferred, - resource, request, position) < 0) - { - return -1; - } - - // - // Don't send the notification again. - // - - split -> setState(split_notified); - } - #if defined(TEST) || defined(SPLIT) - else - { - *logofs << "handleRestart: SPLIT! Split for request " - << split -> getRequest() << " and position " - << split -> getPosition() << " was already " - << "notified.\n" << logofs_flush; - } - #endif - } - - // - // Don't send the end split if we are still - // in the middle of a start-split/end-split - // sequence. We'll send a no-split at the - // time the end-split is received. - // - - if (splitStore -> getSize() == 0 && - splitStore -> getResource() != splitState_.resource) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleRestart: SPLIT! Deferred agent split event " - << "TYPE#" << (unsigned) opcodeStore_ -> endSplitNotify - << " [end split] with resource " << resource << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - if (handleNotify(notify_end_split, sequence_deferred, - resource, nothing, nothing) < 0) - { - return -1; - } - } - #if defined(TEST) || defined(SPLIT) - else if (splitStore -> getSize() == 0 && - splitStore -> getResource() == splitState_.resource) - { - *logofs << "handleRestart: SPLIT! WARNING! The split store " - << "for resource " << resource << " was emptied in the " - << "split sequence at " << strMsTimestamp() << ".\n" - << logofs_flush; - } - #endif - } - - // - // Remove the split store if it's empty. - // - - if (splitStore != NULL && splitStore -> getSize() == 0 && - splitStore -> getResource() != splitState_.resource) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleRestart: SPLIT! Removing the split store [" - << resource << "] at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - handleSplitStoreRemove(&splitResources_, resource); - - if (clientStore_ -> getSplitTotalSize() == 0) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleRestart: SPLIT! Deferred agent split event " - << "TYPE#" << (unsigned) opcodeStore_ -> emptySplitNotify - << " [empty split] for FD#" << fd_ << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - if (handleNotify(notify_empty_split, sequence_deferred, - nothing, nothing, nothing) < 0) - { - return -1; - } - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleRestart: SPLIT! There are " << clientStore_ -> - getSplitTotalSize() << " messages and " << clientStore_ -> - getSplitTotalStorageSize() << " bytes to send in " - << "the split stores.\n" << logofs_flush; - - if ((clientStore_ -> getSplitTotalSize() != 0 && - clientStore_ -> getSplitTotalStorageSize() == 0) || - (clientStore_ -> getSplitTotalSize() == 0 && - clientStore_ -> getSplitTotalStorageSize() != 0)) - { - #ifdef PANIC - *logofs << "handleRestart: PANIC! Inconsistency detected " - << "while handling the split stores.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - - #endif - } - - return 1; -} - -int ClientChannel::handleTaintLameRequest(unsigned char &opcode, const unsigned char *&buffer, - unsigned int &size) -{ - // - // Test the efficiency of the encoding - // without these RENDER requests. - // - - if (opcode == opcodeStore_ -> renderExtension && - (*(buffer + 1) == X_RenderCompositeGlyphs8 || - *(buffer + 1) == X_RenderCompositeGlyphs16 || - *(buffer + 1) == X_RenderCompositeGlyphs32 || - *(buffer + 1) == X_RenderAddGlyphs || - *(buffer + 1) == X_RenderTrapezoids)) - { - #ifdef TEST - *logofs << "handleTaintLameRequest: Tainting request " - << "OPCODE#" << (unsigned int) opcode << " MINOR#" - << (unsigned int) *(buffer + 1) << " for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - opcode = X_NoOperation; - - return 1; - } - - return 0; -} - -int ClientChannel::handleTaintSyncRequest(unsigned char &opcode, const unsigned char *&buffer, - unsigned int &size) -{ - // - // Should short-circuit other common replies - // whose values could be queried only once. - // Examples are X_InterAtom, X_ListExtension - // and X_QueryExtension. - // - - if (taintCounter_ >= control -> TaintThreshold) - { - #ifdef DEBUG - *logofs << "handleTaintSyncRequest: Reset taint counter after " - << taintCounter_ << " replies managed.\n" - << logofs_flush; - #endif - - taintCounter_ = 0; - - return 0; - } - - // - // Check if we are rolling the counter. - // The client sequence number has not - // been incremented yet in the loop. - // - - unsigned int sequence = (clientSequence_ + 1) & 0xffff; - - #ifdef DEBUG - *logofs << "handleTaintSyncRequest: Opcode is " << (unsigned) opcode - << " expected client sequence is " << sequence - << ".\n" << logofs_flush; - #endif - - if (sequence == 0xffff) - { - return 0; - } - - unsigned short t1; - unsigned char t2; - - // - // Check if there is a previous reply - // pending. - // - - if (sequenceQueue_.peek(t1, t2) != 0) - { - #ifdef DEBUG - *logofs << "handleTaintSyncRequest: Skipping taint of reply due to " - << "pending request OPCODE#" << t1 << " with sequence " - << (unsigned int) t2 << ".\n" << logofs_flush; - #endif - - return 0; - } - - #ifdef DEBUG - *logofs << "handleTaintSyncRequest: Suppressing get input focus " - << "request for FD#" << fd_ << " with sequence " - << sequence << ".\n" << logofs_flush; - #endif - - unsigned char *reply = writeBuffer_.addMessage(32); - - *(reply + 0) = X_Reply; - - PutUINT(sequence, reply + 2, bigEndian_); - - PutULONG(0, reply + 4, bigEndian_); - - // - // Set revert-to to none. - // - - *(reply + 1) = 0; - - // - // Set focus to none. - // - - PutULONG(0, reply + 8, bigEndian_); - - // - // Save the sequence number, not incremented - // yet, we used to auto-generate this reply. - // - - lastSequence_ = clientSequence_ + 1; - - #ifdef TEST - *logofs << "handleTaintSyncRequest: Registered " << lastSequence_ - << " as last auto-generated sequence number.\n" - << logofs_flush; - #endif - - // - // Taint the request to a X_NoOperation. - // - - opcode = X_NoOperation; - - // - // We may assume that the client has finished - // drawing and flush immediately, even if this - // seems to perceively affect the performance. - // - // priority_++; - // - - if (handleFlush(flush_if_any) < 0) - { - return -1; - } - - taintCounter_++; - - return 1; -} - -int ClientChannel::handleTaintSyncError(unsigned char opcode) -{ - if (control -> TaintReplies > 0) - { - // - // By enabling short-circuiting of replies - // some window managers can get confused - // by some otherwise innocuous X errors. - // - - if (opcode == X_GrabKey || opcode == X_ReparentWindow || - opcode == X_ConfigureWindow) - { - #if defined(TEST) || defined(OPCODES) - *logofs << "handleTaintSyncError: WARNING! Suppressed error " - << "on OPCODE#" << (unsigned int) opcode << " for FD#" - << fd_ << " sequence " << lastSequence_ << " (real was " - << serverSequence_ << ").\n" << logofs_flush; - #endif - - return 1; - } - } - - return 0; -} - -int ClientChannel::handleNotify(T_notification_type type, T_sequence_mode mode, - int resource, int request, int position) -{ - if (finish_ == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleNotify: Discarding notification on " - << "channel for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - // - // Add a new message to the write buffer. - // - - unsigned char *event = writeBuffer_.addMessage(32); - - // - // Event is ClientMessage, atom and - // window are 0, format is 32. - // - - *(event + 0) = ClientMessage; - - PutULONG(0, event + 4, bigEndian_); - PutULONG(0, event + 8, bigEndian_); - - *(event + 1) = 32; - - // - // If the event follows immediately the request (that is the - // sequence mode is 'immediate') then the sequence number is - // the one of the last request, else it should be the last - // sequence number encoded by peer proxy but, as we are ins- - // erting events in the stream, we must ensure that the se- - // quence we send is not less than the last sequence we have - // auto-generated. - // - - if (mode == sequence_immediate) - { - // - // Save the sequence number we used - // to auto-generate this event. - // - - lastSequence_ = clientSequence_; - - #if defined(TEST) || defined(INFO) - *logofs << "handleNotify: Registered " << lastSequence_ - << " as last auto-generated sequence number.\n" - << logofs_flush; - #endif - } - else - { - if (serverSequence_ > lastSequence_) - { - #ifdef DEBUG - *logofs << "handleNotify: Updating last event's sequence " - << lastSequence_ << " to X server's sequence number " - << serverSequence_ << " for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - lastSequence_ = serverSequence_; - } - #ifdef DEBUG - else if (serverSequence_ < lastSequence_) - { - // - // Use our last auto-generated sequence. - // - - *logofs << "handleNotify: Tainting sequence number " - << serverSequence_ << " to last event's sequence " - << lastSequence_ << " for FD#" << fd_ << ".\n" - << logofs_flush; - } - #endif - } - - PutUINT(lastSequence_, event + 2, bigEndian_); - - // - // Be sure we set to void the fields that - // are not significant for the specific - // notification message. - // - - PutULONG(nothing, event + 16, bigEndian_); - PutULONG(nothing, event + 20, bigEndian_); - PutULONG(nothing, event + 24, bigEndian_); - - switch (type) - { - case notify_no_split: - { - PutULONG(opcodeStore_ -> noSplitNotify, - event + 12, bigEndian_); - - PutULONG(resource, event + 16, bigEndian_); - - break; - } - case notify_start_split: - { - PutULONG(opcodeStore_ -> startSplitNotify, - event + 12, bigEndian_); - - PutULONG(resource, event + 16, bigEndian_); - - break; - } - case notify_commit_split: - { - PutULONG(opcodeStore_ -> commitSplitNotify, - event + 12, bigEndian_); - - PutULONG(resource, event + 16, bigEndian_); - - PutULONG(request, event + 20, bigEndian_); - - PutULONG(position, event + 24, bigEndian_); - - break; - } - case notify_end_split: - { - PutULONG(opcodeStore_ -> endSplitNotify, - event + 12, bigEndian_); - - PutULONG(resource, event + 16, bigEndian_); - - break; - } - case notify_empty_split: - { - PutULONG(opcodeStore_ -> emptySplitNotify, - event + 12, bigEndian_); - break; - } - default: - { - #ifdef PANIC - *logofs << "handleNotify: PANIC! Unrecognized notify " - << "TYPE#" << type << ".\n" - << logofs_flush; - #endif - - return -1; - } - } - - #if defined(TEST) || defined(INFO) || defined (SPLIT) - - *logofs << "handleNotify: Sending " - << (mode == sequence_immediate ? "immediate " : "deferred ") - << "agent notify event TYPE#" << GetULONG(event + 12, bigEndian_) - << logofs_flush; - - if (resource != nothing) - { - *logofs << " with resource " << GetULONG(event + 16, bigEndian_) - << logofs_flush; - - if (request != nothing && position != nothing) - { - *logofs << " request " << GetULONG(event + 20, bigEndian_) - << " position " << GetULONG(event + 24, bigEndian_) - << logofs_flush; - } - } - - *logofs << ".\n" << logofs_flush; - - #endif - - // - // Send the notification now. - // - - if (handleFlush(flush_if_any) < 0) - { - return -1; - } - - return 1; -} - -int ClientChannel::handleCommitSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - // - // Get the data of the request to be - // committed. - // - - unsigned char request = *(buffer + 5); - - MessageStore *store = clientStore_ -> getRequestStore(request); - - if (store == NULL) - { - #ifdef PANIC - *logofs << "handleCommitSplitRequest: PANIC! Can't commit split for " - << "request OPCODE#" << (unsigned int) request - << ". No message store found.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't commit split for request " - << "OPCODE#" << (unsigned int) request - << ". No message store found.\n"; - - return -1; - } - - // - // The position in cache of the message - // to commit. Encode it as difference in - // respect to the last encoded value. - // - - unsigned int position = GetULONG(buffer + 8, bigEndian_); - - unsigned char resource = *(buffer + 1); - unsigned int commit = *(buffer + 4); - - #if defined(TEST) || defined(SPLIT) - - if (commit == 1) - { - *logofs << "handleCommitSplitRequest: SPLIT! Committing request " - << "OPCODE#" << (unsigned) request << " at position " - << position << " for FD#" << fd_ << " with resource " - << (unsigned) resource << ".\n" << logofs_flush; - } - else - { - *logofs << "handleCommitSplitRequest: SPLIT! Discarding request " - << "OPCODE#" << (unsigned) request << " at position " - << position << " for FD#" << fd_ << " with resource " - << (unsigned) resource << ".\n" << logofs_flush; - } - - #endif - - encodeBuffer.encodeOpcodeValue(request, clientCache_ -> opcodeCache); - - int diffCommit = position - splitState_.commit; - - splitState_.commit = position; - - encodeBuffer.encodeValue(diffCommit, 32, 5); - - // - // Send the resource id and the commit - // flag. - // - - encodeBuffer.encodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - encodeBuffer.encodeBoolValue(commit); - - // - // Remove the split from the split queue. - // - - Split *split = handleSplitCommitRemove(request, resource, splitState_.commit); - - if (split == NULL) - { - return -1; - } - - clientStore_ -> getCommitStore() -> update(split); - - // - // Free the split. - // - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleCommitSplitRequest: SPLIT! Freeing up the " - << "committed split.\n" << logofs_flush; - #endif - - delete split; - - return 1; -} - -int ClientChannel::handleAbortSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - unsigned char resource = *(buffer + 1); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Handling abort split " - << "request for FD#"<< fd_ << " and resource " - << (unsigned int) resource << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - SplitStore *splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore == NULL) - { - #ifdef WARNING - *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The split " - << "store [" << (unsigned int) resource << "] " - << "is already empty.\n" << logofs_flush; - #endif - - return 0; - } - - // - // Loop through the messages in the split - // store and discard from the memory cache - // the messages that are still incomplete. - // Then remove the message from the split - // store. - // - - #if defined(TEST) || defined(SPLIT) - - clientStore_ -> dumpSplitStore(resource); - - #endif - - int splits = 0; - - Split *splitMessage; - - for (;;) - { - splitMessage = splitStore -> getFirstSplit(); - - if (splitMessage == NULL) - { - // - // Check if we had created the store - // but no message was added yet. - // - - #ifdef WARNING - - if (splits == 0) - { - *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The " - << "split store [" << (unsigned int) resource - << "] is unexpectedly empty.\n" - << logofs_flush; - } - - #endif - - break; - } - - // - // Splits already aborted can't be in the - // split store. - // - - #if defined(TEST) || defined(SPLIT) - - if (splitMessage -> getState() == split_aborted) - { - *logofs << "handleAbortSplitRequest: PANIC! SPLIT! Found an " - << "aborted split in store [" << (unsigned int) resource - << "].\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - if (splitMessage -> getAction() == IS_HIT) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Removing the " - << "split from the memory cache.\n" - << logofs_flush; - #endif - - splitMessage -> getStore() -> remove(splitMessage -> getPosition(), - use_checksum, discard_data); - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Removing the " - << "split from the split store.\n" - << logofs_flush; - #endif - - splitMessage = splitStore -> pop(); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Freeing up the " - << "aborted split.\n" << logofs_flush; - #endif - - delete splitMessage; - - splits++; - } - - // - // If the start-split/end-split sequence - // was closed, send the notification now, - // else wait for the end-split. - // - - if (resource != splitState_.resource) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Sending the " - << "deferred [end split] event.\n" - << logofs_flush; - #endif - - handleRestart(sequence_deferred, resource); - } - #if defined(TEST) || defined(SPLIT) - else - { - *logofs << "handleAbortSplitRequest: WARNING! SPLIT! Still " - << "waiting for the closure of the split " - << "sequence.\n" << logofs_flush; - } - #endif - - // - // Check if there is any other store - // having splits to send. - // - - handleSplitPending(); - - return (splits > 0); -} - -int ClientChannel::handleFinishSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - unsigned char resource = *(buffer + 1); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleFinishSplitRequest: SPLIT! Handling finish split " - << "request for FD#"<< fd_ << " and resource " - << (unsigned int) resource << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - // - // We need to get the protocol statistics - // for the finish message we are handling - // here because sending a new split will - // reset the bits counter. - // - - int bits = encodeBuffer.diffBits(); - - statistics -> addRequestBits(opcode, size << 3, bits); - - SplitStore *splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore == NULL) - { - #ifdef WARNING - *logofs << "handleFinishSplitRequest: WARNING! SPLIT! The split " - << "store [" << (unsigned int) resource << "] " - << "is already empty.\n" << logofs_flush; - #endif - - return 0; - } - - // - // Send all the split queued for the given - // resource until the split store becomes - // empty. - // - - #if defined(TEST) || defined(SPLIT) - - clientStore_ -> dumpSplitStore(resource); - - #endif - - Split *splitMessage; - - int total = MESSAGE_DATA_LIMIT; - - int bytes = total; - int splits = 0; - - for (;;) - { - splitMessage = splitStore -> getFirstSplit(); - - if (splitMessage == NULL) - { - // - // We have presumably created the store - // after a start split but no message - // was added yet. - // - - #ifdef WARNING - *logofs << "handleFinishSplitRequest: WARNING! SPLIT! The " - << "split store [" << (unsigned int) resource - << "] is unexpectedly empty.\n" - << logofs_flush; - #endif - - break; - } - - // - // Splits already aborted can't be in the - // split store. - // - - #if defined(TEST) || defined(SPLIT) - - if (splitMessage -> getState() == split_aborted) - { - *logofs << "handleFinishSplitRequest: PANIC! SPLIT! Found an " - << "aborted split in store [" << (unsigned int) resource - << "].\n" << logofs_flush; - - HandleCleanup(); - } - - *logofs << "handleFinishSplitRequest: SPLIT! Sending more " - << "data for store [" << (unsigned int) resource - << "].\n" << logofs_flush; - #endif - - if (handleSplitSend(encodeBuffer, resource, splits, bytes) < 0) - { - return -1; - } - - // - // Check if the split store was deleted. - // - - if (clientStore_ -> getSplitStore(resource) == NULL) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleFinishSplitRequest: SPLIT! Exiting " - << "from the finish loop with split store [" - << (unsigned int) resource << "] destroyed.\n" - << logofs_flush; - #endif - - break; - } - } - - // - // Check if there is any other store - // having splits to send. - // - - handleSplitPending(); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleFinishSplitRequest: SPLIT! Sent " << splits - << " splits and " << total - bytes << " bytes for FD#" << fd_ - << " with " << clientStore_ -> getSplitTotalStorageSize() - << " bytes and [" << clientStore_ -> getSplitTotalSize() - << "] splits remaining.\n" << logofs_flush; - #endif - - return (splits > 0); -} - -int ClientChannel::handleConfiguration() -{ - #ifdef TEST - *logofs << "ClientChannel: Setting new buffer parameters.\n" - << logofs_flush; - #endif - - readBuffer_.setSize(control -> ClientInitialReadSize, - control -> ClientMaximumBufferSize); - - writeBuffer_.setSize(control -> TransportXBufferSize, - control -> TransportXBufferThreshold, - control -> TransportMaximumBufferSize); - - transport_ -> setSize(control -> TransportXBufferSize, - control -> TransportXBufferThreshold, - control -> TransportMaximumBufferSize); - - return 1; -} - -int ClientChannel::handleFinish() -{ - #ifdef TEST - *logofs << "ClientChannel: Finishing channel for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - congestion_ = 0; - priority_ = 0; - - finish_ = 1; - - taintCounter_ = 0; - - splitState_.resource = nothing; - splitState_.pending = 0; - splitState_.commit = 0; - splitState_.mode = split_none; - - transport_ -> finish(); - - return 1; -} - -// -// If differential compression is disabled then use the -// most simple encoding but handle the image requests -// and the X_ListExtensions and X_QueryExtension messa- -// ges (needed to detect the opcode of the shape or the -// other extensions) in the usual way. -// - -int ClientChannel::handleFastReadRequest(EncodeBuffer &encodeBuffer, const unsigned char &opcode, - const unsigned char *&buffer, const unsigned int &size) -{ - // - // All the NX requests are handled in the - // main message loop. The X_PutImage can - // be handled here only if the split was - // not requested (since ProtoStep7 #issue 108). - // - - if ((opcode >= X_NXFirstOpcode && opcode <= X_NXLastOpcode) || - (opcode == X_PutImage && splitState_.resource != nothing) || - opcode == X_ListExtensions || - opcode == X_QueryExtension) - { - return 0; - } - - #ifdef DEBUG - *logofs << "handleFastReadRequest: Encoding raw request OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ - << " with size " << size << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeMemory(buffer, size); - - // - // Put request on the fast track - // if it needs a reply. - // - - switch (opcode) - { - case X_GetAtomName: - case X_GetGeometry: - case X_GetInputFocus: - case X_GetModifierMapping: - case X_GetKeyboardMapping: - case X_GetProperty: - case X_GetSelectionOwner: - case X_GrabPointer: - case X_GrabKeyboard: - case X_ListExtensions: - case X_ListFonts: - case X_LookupColor: - case X_AllocNamedColor: - case X_QueryPointer: - case X_GetWindowAttributes: - case X_QueryTree: - case X_QueryBestSize: - case X_QueryColors: - case X_QueryFont: - case X_TranslateCoords: - case X_GetImage: - case X_GetPointerMapping: - case X_GetKeyboardControl: - case X_InternAtom: - case X_AllocColor: - { - sequenceQueue_.push(clientSequence_, opcode); - - priority_++; - - break; - } - default: - { - break; - } - } - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - - *logofs << "handleFastReadRequest: Handled raw request OPCODE#" - << (unsigned int) opcode << " (" << DumpOpcode(opcode) << ")" - << " for FD#" << fd_ << " sequence " << clientSequence_ - << ". " << size << " bytes in, " << bits << " bits (" - << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; - - #endif - - statistics -> addRequestBits(opcode, size << 3, bits); - - if (opcode == opcodeStore_ -> renderExtension) - { - statistics -> addRenderRequestBits(*(buffer + 1), size << 3, bits); - } - - return 1; -} - -int ClientChannel::handleFastWriteReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - if ((opcode >= X_NXFirstOpcode && - opcode <= X_NXLastOpcode) || - opcode == X_ListExtensions || - opcode == X_QueryExtension) - { - return 0; - } - - #ifdef DEBUG - *logofs << "handleFastWriteReply: Decoding raw reply OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - buffer = writeBuffer_.addMessage(8); - - #ifndef __sun - - unsigned int *next = (unsigned int *) decodeBuffer.decodeMemory(8); - - *((unsigned int *) buffer) = *next++; - *((unsigned int *) (buffer + 4)) = *next; - - #else /* #ifndef __sun */ - - memcpy(buffer, decodeBuffer.decodeMemory(8), 8); - - #endif /* #ifndef __sun */ - - size = 32 + (GetULONG(buffer + 4, bigEndian_) << 2); - - writeBuffer_.registerPointer(&buffer); - - if (writeBuffer_.getAvailable() < size - 8 || - (int) size >= control -> TransportFlushBufferSize) - { - #ifdef DEBUG - *logofs << "handleFastWriteReply: Using scratch buffer for OPCODE#" - << (unsigned int) opcode << " with size " << size << " and " - << writeBuffer_.getLength() << " bytes in buffer.\n" - << logofs_flush; - #endif - - writeBuffer_.removeMessage(8); - - buffer = writeBuffer_.addScratchMessage(((unsigned char *) - decodeBuffer.decodeMemory(size - 8)) - 8, size); - } - else - { - writeBuffer_.addMessage(size - 8); - - #ifndef __sun - - if (size == 32) - { - next = (unsigned int *) decodeBuffer.decodeMemory(size - 8); - - for (int i = 8; i < 32; i += sizeof(unsigned int)) - { - *((unsigned int *) (buffer + i)) = *next++; - } - } - else - { - memcpy(buffer + 8, decodeBuffer.decodeMemory(size - 8), size - 8); - } - - #else /* #ifndef __sun */ - - memcpy(buffer + 8, decodeBuffer.decodeMemory(size - 8), size - 8); - - #endif /* #ifndef __sun */ - } - - writeBuffer_.unregisterPointer(); - - // - // We don't need to write our local sequence - // number. Replies are always sent with the - // original X server's sequence number. - // - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleFastWriteReply: Handled raw reply OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ << " with sequence " - << serverSequence_ << ". Output size is " << size << ".\n" - << logofs_flush; - #endif - - #ifdef DEBUG - *logofs << "handleFastWriteReply: Length of sequence queue is " - << sequenceQueue_.length() << ".\n" << logofs_flush; - #endif - - statistics -> addRepliedRequest(opcode); - - handleFlush(flush_if_needed); - - return 1; -} - -int ClientChannel::handleFastWriteEvent(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - #ifdef DEBUG - *logofs << "handleFastWriteEvent: Decoding raw " - << (opcode == X_Error ? "error" : "event") << " OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - size = 32; - - buffer = writeBuffer_.addMessage(size); - - #ifndef __sun - - unsigned int *next = (unsigned int *) decodeBuffer.decodeMemory(size); - - for (int i = 0; i < 32; i += sizeof(unsigned int)) - { - *((unsigned int *) (buffer + i)) = *next++; - } - - #else /* #ifndef __sun */ - - memcpy(buffer, decodeBuffer.decodeMemory(size), size); - - #endif /* #ifndef __sun */ - - // - // Use our local sequence number. - // - - PutUINT(lastSequence_, buffer + 2, bigEndian_); - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleFastWriteEvent: Handled raw " - << (opcode == X_Error ? "error" : "event") << " OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ << " with sequence " - << lastSequence_ << ". Output size is " << size << ".\n" - << logofs_flush; - #endif - - // - // Check if we need to suppress the error. - // - - if (opcode == X_Error && handleTaintSyncError(*(buffer + 10)) > 0) - { - #if defined(TEST) || defined(OPCODES) - *logofs << "handleFastWriteEvent: WARNING! Suppressed error OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ - << " with sequence " << lastSequence_ << ".\n" - << logofs_flush; - #endif - - writeBuffer_.removeMessage(32); - } - - handleFlush(flush_if_needed); - - return 1; -} - -int ClientChannel::handleShmemRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - // - // Will push sequence and set - // priority according to stage. - // - - unsigned int stage = *(buffer + 1); - - #ifdef TEST - *logofs << "handleShmemRequest: Encoding shmem request " - << "OPCODE#" << (unsigned int) opcode << " for FD#" - << fd_ << " with size " << size << " at stage " - << stage << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeValue(stage, 2); - - if (stage == 0) - { - unsigned int enableClient = 0; - unsigned int enableServer = 0; - - if (control -> ShmemClient == 1) - { - enableClient = *(buffer + 4); - } - - if (control -> ShmemServer == 1) - { - enableServer = *(buffer + 5); - } - - encodeBuffer.encodeBoolValue(enableClient); - encodeBuffer.encodeBoolValue(enableServer); - - unsigned int clientSegment = GetULONG(buffer + 8, bigEndian_); - unsigned int serverSegment = GetULONG(buffer + 12, bigEndian_); - - encodeBuffer.encodeValue(clientSegment, 29, 9); - encodeBuffer.encodeValue(serverSegment, 29, 9); - - #ifdef TEST - *logofs << "handleShmemRequest: Enable client is " - << enableClient << " enable server is " << enableServer - << " client segment is " << (void *) clientSegment - << " server segment is " << (void *) serverSegment - << ".\n" << logofs_flush; - #endif - - #ifdef TEST - *logofs << "handleShmemRequest: Size of the shared memory " - << "segment will be " << control -> ShmemServerSize - << ".\n" << logofs_flush; - #endif - } - - if (stage != 1) - { - sequenceQueue_.push(clientSequence_, opcodeStore_ -> - getShmemParameters); - - priority_++; - } - - return 1; -} - -int ClientChannel::handleShmemReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - #ifdef TEST - *logofs << "handleShmemReply: Received shmem parameters " - << "reply OPCODE#" << (unsigned int) opcode - << ".\n" << logofs_flush; - #endif - - size = 32; - buffer = writeBuffer_.addMessage(size); - - unsigned int stage; - - decodeBuffer.decodeValue(stage, 2); - - *(buffer + 1) = stage; - - if (stage == 2) - { - unsigned int clientEnabled; - unsigned int serverEnabled; - - decodeBuffer.decodeBoolValue(clientEnabled); - decodeBuffer.decodeBoolValue(serverEnabled); - - // - // Client support is not implemented - // and not useful. It is here only - // for compatibility. - // - - clientEnabled = 0; - - *(buffer + 8) = clientEnabled; - *(buffer + 9) = serverEnabled; - - PutULONG(0, buffer + 12, bigEndian_); - - if (serverEnabled == 1) - { - #ifdef TEST - *logofs << "handleShmemReply: Enabled shared memory " - << "support in X server with segment size " - << control -> ShmemServerSize << ".\n" - << logofs_flush; - #endif - - PutULONG(control -> ShmemServerSize, buffer + 16, bigEndian_); - } - else - { - PutULONG(0, buffer + 16, bigEndian_); - } - } - else - { - *(buffer + 8) = 0; - *(buffer + 9) = 0; - - PutULONG(0, buffer + 12, bigEndian_); - PutULONG(0, buffer + 16, bigEndian_); - } - - return 1; -} - -int ClientChannel::handleFontRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - #ifdef TEST - *logofs << "handleFontRequest: Encoding font request " - << "OPCODE#" << (unsigned int) opcode << " for FD#" - << fd_ << " with size " << size << ".\n" - << logofs_flush; - #endif - - sequenceQueue_.push(clientSequence_, opcodeStore_ -> - getFontParameters); - - return 1; -} - -int ClientChannel::handleFontReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - #ifdef TEST - *logofs << "handleFontReply: Received font operation " - << "reply OPCODE#" << (unsigned int) opcode - << ".\n" << logofs_flush; - #endif - - unsigned int length; - - decodeBuffer.decodeValue(length, 8); - - size = 32 + RoundUp4(length + 1); - buffer = writeBuffer_.addMessage(size); - - unsigned char *next = buffer + 32; - - *next++ = length; - - decodeBuffer.decodeTextData(next, length); - - #ifdef TEST - - *logofs << "handleFontReply: Received tunneled font server " - << "path '"; - - for (unsigned int i = 0; i < length; i++) - { - *logofs << *(buffer + 32 + 1 + i); - } - - *logofs << "' for FD#" << fd_ << ".\n" << logofs_flush; - - #endif - - if (fontPort_ == -1) - { - // - // The local side is not going to forward - // the font server connections. - // - - #ifdef TEST - *logofs << "handleFontReply: WARNING! Returning an empty " - << "font server path.\n" << logofs_flush; - #endif - - writeBuffer_.removeMessage(size); - - size = 36; - buffer = writeBuffer_.addMessage(size); - - // - // Set the length of the returned - // path to 0. - // - - *(buffer + 32) = 0; - } - #ifdef TEST - else - { - *logofs << "handleFontReply: Returning the received " - << "font server path.\n" << logofs_flush; - } - #endif - - return 1; -} - -int ClientChannel::handleCacheRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - #ifdef TEST - *logofs << "handleCacheRequest: Handling cache request " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - enableCache_ = *(buffer + 4); - enableSplit_ = *(buffer + 5); - enableSave_ = *(buffer + 6); - enableLoad_ = *(buffer + 7); - - #ifdef TEST - *logofs << "handleCacheRequest: Set cache parameters to " - << " cache " << enableCache_ << " split " << enableSplit_ - << " save " << enableSave_ << " load " << enableLoad_ - << ".\n" << logofs_flush; - #endif - - // - // Encode all the parameters as a - // single unsigned int so we can - // use an int cache. - // - - unsigned int mask = enableSave_ << 8 | enableLoad_; - - encodeBuffer.encodeCachedValue(mask, 32, clientCache_ -> - setCacheParametersCache); - return 0; -} - -int ClientChannel::handleStartSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - #if defined(TEST) || defined(SPLIT) - *logofs << "handleStartSplitRequest: SPLIT! Handling start split " - << "request for FD#"<< fd_ << ".\n" << logofs_flush; - #endif - - if (splitState_.resource != nothing) - { - #ifdef PANIC - *logofs << "handleStartSplitRequest: PANIC! SPLIT! Split requested " - << "for resource id " << (unsigned int) *(buffer + 1) - << " while handling resource " << splitState_.resource - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Split requested for " - << "resource id " << (unsigned int) *(buffer + 1) - << " while handling resource " << splitState_.resource - << ".\n"; - - return -1; - } - else if (fd_ != firstClient_) - { - // - // It can be that an auxiliary channel is the - // first to connect, then comes the agent that - // is actually using the NX opcodes. - // - - #ifdef WARNING - *logofs << "handleStartSplitRequest: WARNING SPLIT! Split requested " - << "on FD#" << fd_ << " while expecting FD#" << firstClient_ - << ".\n" << logofs_flush; - #endif - - firstClient_ = fd_; - } - - // - // Set the agent's resource for which we are - // going to split the request. - // - - splitState_.resource = *(buffer + 1); - - #if defined(TEST) || defined(SPLIT) - - *logofs << "handleStartSplitRequest: SPLIT! Registered id " - << splitState_.resource << " as resource " - << "waiting for a split.\n" << logofs_flush; - - if (clientStore_ -> getSplitStore(splitState_.resource) != NULL) - { - *logofs << "handleStartSplitRequest: WARNING! SPLIT! A split " - << "store for resource id " << splitState_.resource - << " already exists.\n" << logofs_flush; - - clientStore_ -> dumpSplitStore(splitState_.resource); - } - - #endif - - // - // Send the selected resource to the remote. - // - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeCachedValue(splitState_.resource, 8, - clientCache_ -> resourceCache); - - splitState_.mode = (T_split_mode) *(buffer + 4); - - if (splitState_.mode != NXSplitModeAsync && - splitState_.mode != NXSplitModeSync) - { - splitState_.mode = (T_split_mode) control -> SplitMode; - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleStartSplitRequest: SPLIT! Set split " - << "mode to '" << splitState_.mode << "' with " - << "provided value '" << (unsigned) *(buffer + 4) - << "'.\n" << logofs_flush; - #endif - } - - #if defined(TEST) || defined(SPLIT) - - if (splitState_.mode == NXSplitModeAsync) - { - *logofs << "handleStartSplitRequest: SPLIT! Selected split " - << "mode is [split_async].\n" << logofs_flush; - } - else if (splitState_.mode == NXSplitModeSync) - { - *logofs << "handleStartSplitRequest: SPLIT! Selected split " - << "mode is [split_sync].\n" << logofs_flush; - } - - clientStore_ -> dumpSplitStores(); - - #endif - - return 1; -} - -int ClientChannel::handleEndSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - #if defined(TEST) || defined(SPLIT) - *logofs << "handleEndSplitRequest: SPLIT! Handling end split " - << "request for FD#"<< fd_ << ".\n" << logofs_flush; - #endif - - // - // Verify that the agent resource matches. - // - - if (splitState_.resource == nothing) - { - #ifdef PANIC - *logofs << "handleEndSplitRequest: PANIC! SPLIT! Received an end of " - << "split for resource id " << (unsigned int) *(buffer + 1) - << " without a previous start.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Received an end of split " - << "for resource id " << (unsigned int) *(buffer + 1) - << " without a previous start.\n"; - - return -1; - } - else if (splitState_.resource != *(buffer + 1)) - { - #ifdef PANIC - *logofs << "handleEndSplitRequest: PANIC! SPLIT! Invalid resource id " - << (unsigned int) *(buffer + 1) << " received while " - << "waiting for resource id " << splitState_.resource - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid resource id " - << (unsigned int) *(buffer + 1) << " received while " - << "waiting for resource id " << splitState_.resource - << ".\n"; - - return -1; - } - - // - // Send the selected resource to the remote. - // - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeCachedValue(splitState_.resource, 8, - clientCache_ -> resourceCache); - - // - // Send the split notification events - // to the agent. - // - - handleRestart(sequence_immediate, splitState_.resource); - - // - // Check if we still have splits to send. - // - - handleSplitPending(); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleEndSplitRequest: SPLIT! Reset id " - << splitState_.resource << " as resource " - << "selected for splits.\n" << logofs_flush; - #endif - - splitState_.resource = nothing; - splitState_.mode = split_none; - - #if defined(TEST) || defined(SPLIT) - - clientStore_ -> dumpSplitStores(); - - #endif - - return 1; -} - -void ClientChannel::handleDecodeCharInfo(DecodeBuffer &decodeBuffer, unsigned char *nextDest) -{ - unsigned int value; - - decodeBuffer.decodeCachedValue(value, 32, - *serverCache_ -> queryFontCharInfoCache[0], 6); - - PutUINT(value & 0xffff, nextDest, bigEndian_); - PutUINT(value >> 16, nextDest + 10, bigEndian_); - - nextDest += 2; - - for (unsigned int i = 1; i < 5; i++) - { - unsigned int value; - - decodeBuffer.decodeCachedValue(value, 16, - *serverCache_ -> queryFontCharInfoCache[i], 6); - - PutUINT(value, nextDest, bigEndian_); - - nextDest += 2; - } -} - -int ClientChannel::setBigEndian(int flag) -{ - bigEndian_ = flag; - - return 1; -} - -int ClientChannel::setReferences() -{ - #ifdef TEST - *logofs << "ClientChannel: Initializing the static " - << "members for the client channels.\n" - << logofs_flush; - #endif - - #ifdef REFERENCES - - references_ = 0; - - #endif - - return 1; -} diff --git a/nxcomp/ClientChannel.h b/nxcomp/ClientChannel.h deleted file mode 100644 index ae92648d5..000000000 --- a/nxcomp/ClientChannel.h +++ /dev/null @@ -1,434 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ClientChannel_H -#define ClientChannel_H - -#include "List.h" -#include "Channel.h" - -#include "SequenceQueue.h" - -#include "ClientReadBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// If defined, the client channel will -// have the chance of suppressing more -// opcodes for test purposes. -// - -#undef LAME - -// -// Define this to log a line when a -// channel is created or destroyed. -// - -#undef REFERENCES - -// -// This class implements the X client -// side compression of the protocol. -// - -class ClientChannel : public Channel -{ - public: - - ClientChannel(Transport *transport, StaticCompressor *compressor); - - virtual ~ClientChannel(); - - virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, - unsigned int length); - - virtual int handleWrite(const unsigned char *message, unsigned int length); - - virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, - T_store_action action, int position, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, - T_store_action action, int position, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) - { - return 0; - } - - virtual int handleSplit(EncodeBuffer &encodeBuffer); - - virtual int handleSplit(DecodeBuffer &decodeBuffer) - { - return 0; - } - - virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split); - - virtual int handleSplitEvent(DecodeBuffer &decodeBuffer); - - virtual int handleMotion(EncodeBuffer &encodeBuffer) - { - return 0; - } - - virtual int handleCompletion(EncodeBuffer &encodeBuffer) - { - return 0; - } - - virtual int handleConfiguration(); - - virtual int handleFinish(); - - virtual int handleAsyncEvents() - { - return 0; - } - - virtual int needSplit() const - { - #if defined(TEST) || defined(SPLIT) - *logofs << "needSplit: SPLIT! Returning pending split " - << "flag " << splitState_.pending << " with " - << clientStore_ -> getSplitTotalSize() - << " splits in the split stores.\n" - << logofs_flush; - #endif - - return splitState_.pending; - } - - virtual int needMotion() const - { - return 0; - } - - virtual T_channel_type getType() const - { - return channel_x11; - } - - int setBigEndian(int flag); - - // - // Initialize the static members. - // - - static int setReferences(); - - private: - - int handleFastReadRequest(EncodeBuffer &encodeBuffer, const unsigned char &opcode, - const unsigned char *&buffer, const unsigned int &size); - - int handleFastWriteReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - int handleFastWriteEvent(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - // - // Intercept the request before the opcode - // is encoded. - // - - int handleTaintRequest(unsigned char &opcode, const unsigned char *&buffer, - unsigned int &size) - { - if (control -> TaintReplies > 0 && - opcode == X_GetInputFocus) - { - return handleTaintSyncRequest(opcode, buffer, size); - } - - #ifdef LAME - - return handleTaintLameRequest(opcode, buffer, size); - - #endif - - return 0; - } - - int handleTaintLameRequest(unsigned char &opcode, const unsigned char *&buffer, - unsigned int &size); - - int handleTaintSyncRequest(unsigned char &opcode, const unsigned char *&buffer, - unsigned int &size); - - int handleTaintSyncError(unsigned char opcode); - - // - // How to handle sequence counter - // in notification event. - // - - enum T_sequence_mode - { - sequence_immediate, - sequence_deferred - }; - - // - // Send split notifications to the - // agent. - // - - int handleRestart(T_sequence_mode mode, int resource); - - int handleNotify(T_notification_type type, T_sequence_mode mode, - int resource, int request, int position); - - // - // Other utility functions used in - // handling of the image streaming. - // - - int mustSplitMessage(int resource) - { - return (clientStore_ -> getSplitStore(resource) -> - getSize() != 0); - } - - int canSplitMessage(T_split_mode mode, unsigned int size) - { - return ((int) size >= control -> SplitDataThreshold && - (clientStore_ -> getSplitTotalStorageSize() < control -> - SplitTotalStorageSize && clientStore_ -> - getSplitTotalSize() < control -> SplitTotalSize)); - } - - int canSendSplit(Split *split) - { - return (split -> getMode() != split_sync || - split -> getState() == split_missed || - split -> getState() == split_loaded); - } - - int handleSplitSend(EncodeBuffer &encodeBuffer, int resource, - int &total, int &bytes); - - Split *handleSplitFind(T_checksum checksum, int resource); - - int handleSplitChecksum(EncodeBuffer &encodeBuffer, T_checksum checksum); - - void handleSplitPending(int resource) - { - if (splitState_.pending == 0) - { - if (clientStore_ -> getSplitStore(resource) != NULL && - clientStore_ -> getSplitStore(resource) -> - getFirstSplit() != NULL) - { - splitState_.pending = canSendSplit(clientStore_ -> - getSplitStore(resource) -> getFirstSplit()); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitPending: SPLIT! Set the pending " - << "split flag to " << splitState_.pending - << " with " << clientStore_ -> getSplitTotalSize() - << " splits in the split stores.\n" - << logofs_flush; - #endif - } - } - } - - // - // Scan all the split stores to find - // if there is any split to send. - // - - void handleSplitPending(); - - // - // Handle the MIT-SHM initialization - // messages exchanged with the remote - // proxy. - // - - int handleShmemRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - int handleShmemReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - // - // Query the port used to tunnel - // the font server connections. - // - - int handleFontRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - int handleFontReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - // - // Let the agent set the cache - // policy for image requests. - // - - int handleCacheRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - // - // Encode the start and end split - // requests. - // - - int handleStartSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - int handleEndSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - // - // Empty a split store and send the - // restart event. - // - - int handleAbortSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - // - // Force the proxy to finalize all - // the pending split operations and - // restart a resource. - // - - int handleFinishSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - // - // Tell the remote peer to send the - // split requests to the X server. - // - - int handleCommitSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - // - // Other utilities. - // - - void handleDecodeCharInfo(DecodeBuffer &, unsigned char *); - - // - // Own read buffer. It is able to identify - // full messages read from the X descriptor. - // - - ClientReadBuffer readBuffer_; - - // - // Sequence number of last request coming - // from the X client or the X server. - // - - unsigned int clientSequence_; - unsigned int serverSequence_; - - // - // Last sequence number known by client. It can - // be the real sequence generated by server or - // the one of the last auto-generated event. - // - - unsigned int lastSequence_; - - // - // Used to identify replies based on sequence - // number of original request. - // - - SequenceQueue sequenceQueue_; - - // - // This is used to test the synchronous flush - // in the proxy. - // - - int lastRequest_; - - // - // Current resource id selected as target and - // other information related to the image split. - // The pending and abort flags are set when we - // want the proxy to give us a chance to send - // more split data. We also save the position - // of the last commit operation performed by - // channel so we can differentially encode the - // position of next message to commit. - // - - typedef struct - { - int resource; - int pending; - int commit; - T_split_mode mode; - - } T_split_state; - - T_split_state splitState_; - - // - // List of agent resources. - // - - List splitResources_; - - // - // How many sync requests we - // have tainted so far. - // - - int taintCounter_; - - private: - - // - // Keep track of object - // creation and deletion. - // - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -#endif /* ClientChannel_H */ diff --git a/nxcomp/ClientProxy.cpp b/nxcomp/ClientProxy.cpp deleted file mode 100644 index 3df45331a..000000000 --- a/nxcomp/ClientProxy.cpp +++ /dev/null @@ -1,549 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Socket.h" -#include "Agent.h" - -#include "ClientProxy.h" - -#include "ClientChannel.h" -#include "GenericChannel.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Log the operations related to sending -// and receiving the control tokens. -// - -#undef TOKEN - -ClientProxy::ClientProxy(int proxyFd) : Proxy(proxyFd) -{ - fontServerPort_ = NULL; - - #ifdef DEBUG - *logofs << "ClientProxy: Created new object at " << this - << ".\n" << logofs_flush; - #endif -} - -ClientProxy::~ClientProxy() -{ - delete [] fontServerPort_; - - #ifdef DEBUG - *logofs << "ClientProxy: Deleted object at " << this - << ".\n" << logofs_flush; - #endif -} - -void ClientProxy::handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, - sockaddr * xServerAddr, unsigned int xServerAddrLength) -{ - #ifdef DEBUG - *logofs << "ClientProxy: No display configuration to set.\n" - << logofs_flush; - #endif -} - -void ClientProxy::handlePortConfiguration(ChannelEndPoint &cupsServerPort, - ChannelEndPoint &smbServerPort, - ChannelEndPoint &mediaServerPort, - ChannelEndPoint &httpServerPort, - const char *fontServerPort) -{ - delete [] fontServerPort_; - - fontServerPort_ = new char[strlen(fontServerPort) + 1]; - - strcpy(fontServerPort_, fontServerPort); - - #ifdef DEBUG - *logofs << "ClientProxy: Set port configuration to font '" - << fontServerPort_ << "'.\n" - << logofs_flush; - #endif -} - -int ClientProxy::handleNewConnection(T_channel_type type, int clientFd) -{ - switch (type) - { - case channel_x11: - { - return handleNewXConnection(clientFd); - } - case channel_cups: - { - return handleNewGenericConnection(clientFd, channel_cups, "CUPS"); - } - case channel_smb: - { - return handleNewGenericConnection(clientFd, channel_smb, "SMB"); - } - case channel_media: - { - return handleNewGenericConnection(clientFd, channel_media, "media"); - } - case channel_http: - { - return handleNewGenericConnection(clientFd, channel_http, "HTTP"); - } - case channel_slave: - { - return handleNewSlaveConnection(clientFd); - } - default: - { - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Unsupported channel with type '" - << getTypeName(type) << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unsupported channel with type '" - << getTypeName(type) << "'.\n"; - - return -1; - } - } -} - -int ClientProxy::handleNewConnectionFromProxy(T_channel_type type, int channelId) -{ - switch (type) - { - case channel_font: - { - int port = atoi(fontServerPort_); - - if (port > 0) - { - // - // Connect on the TCP port number. - // - - return handleNewGenericConnectionFromProxyTCP(channelId, channel_font, "localhost", - port, "font"); - } - else - { - // - // Connect to the Unix path. - // - - return handleNewGenericConnectionFromProxyUnix(channelId, channel_font, - fontServerPort_, "font"); - } - } - case channel_slave: - { - return handleNewSlaveConnectionFromProxy(channelId); - } - default: - { - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Unsupported channel with type '" - << getTypeName(type) << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unsupported channel with type '" - << getTypeName(type) << "'.\n"; - - return -1; - } - } -} - -int ClientProxy::handleNewAgentConnection(Agent *agent) -{ - int clientFd = agent -> getLocalFd(); - - int channelId = allocateChannelMap(clientFd); - - if (channelId == -1) - { - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Maximum number of available " - << "channels exceeded.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Maximum number of available " - << "channels exceeded.\n"; - - return -1; - } - - transports_[channelId] = agent -> getTransport(); - - agent_ = channelId; - - return handleNewXConnection(clientFd); -} - -int ClientProxy::handleNewXConnection(int clientFd) -{ - int channelId = getChannel(clientFd); - - // - // Check if the channel has been - // already mapped. - // - - if (channelId == -1) - { - channelId = allocateChannelMap(clientFd); - - if (channelId == -1) - { - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Maximum number of available " - << "channels exceeded.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Maximum number of available " - << "channels exceeded.\n"; - - return -1; - } - } - - #ifdef TEST - *logofs << "ClientProxy: X client descriptor FD#" << clientFd - << " mapped to channel ID#" << channelId << ".\n" - << logofs_flush; - #endif - - // - // Turn queuing off for path proxy-to-X-client. - // - - if (control -> OptionClientNoDelay == 1) - { - SetNoDelay(clientFd, control -> OptionClientNoDelay); - } - - // - // If requested, set the size of the TCP send - // and receive buffers. - // - - if (control -> OptionClientSendBuffer != -1) - { - SetSendBuffer(clientFd, control -> OptionClientSendBuffer); - } - - if (control -> OptionClientReceiveBuffer != -1) - { - SetReceiveBuffer(clientFd, control -> OptionClientReceiveBuffer); - } - - if (allocateTransport(clientFd, channelId) < 0) - { - return -1; - } - - // - // Starting from protocol level 3 client and server - // caches are created in proxy and shared between all - // channels. If remote proxy has older protocol level - // pointers are NULL and channels must create their - // own instances. - // - - channels_[channelId] = new ClientChannel(transports_[channelId], compressor_); - - if (channels_[channelId] == NULL) - { - deallocateTransport(channelId); - - return -1; - } - - increaseChannels(channelId); - - // - // Propagate channel stores and caches to the new - // channel. - // - - channels_[channelId] -> setOpcodes(opcodeStore_); - - channels_[channelId] -> setStores(clientStore_, serverStore_); - - channels_[channelId] -> setCaches(clientCache_, serverCache_); - - int port = atoi(fontServerPort_); - - if (port > 0 || *fontServerPort_ != '\0') - { - channels_[channelId] -> setPorts(1); - } - - if (handleControl(code_new_x_connection, channelId) < 0) - { - return -1; - } - - // - // Let channel configure itself according - // to control parameters. - // - - channels_[channelId] -> handleConfiguration(); - - return 1; -} - -int ClientProxy::handleNewXConnectionFromProxy(int channelId) -{ - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Can't create a new X channel " - << "with ID#" << channelId << " at this side.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't create a new X channel " - << "with ID#" << channelId << " at this side.\n"; - - return -1; -} - -int ClientProxy::handleLoad(T_load_type type) -{ - int channelCount = getChannels(channel_x11); - - if ((channelCount == 0 && type == load_if_first) || - (channelCount > 0 && type == load_if_any)) - { - #ifdef TEST - *logofs << "ClientProxy: Going to load content of client store.\n" - << logofs_flush; - #endif - - int result = handleLoadStores(); - - if (result == 1) - { - if (handleControl(code_load_request) < 0) - { - return -1; - } - - priority_ = 1; - } - else if (result < 0) - { - #ifdef WARNING - *logofs << "ClientProxy: WARNING! Failed to load content " - << "of persistent cache.\n" << logofs_flush; - #endif - - // - // Don't abort the proxy connection in the case - // of a corrupted cache. By not sending the load - // message to the remote peer, both sides will - // start encoding messages using empty stores. - // This behaviour is compatible with old proxy - // versions. - // - - if (channelCount == 0 && type == load_if_first) - { - if (handleResetStores() < 0) - { - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Failed to reset message stores.\n" - << logofs_flush; - #endif - - return -1; - } - } - else - { - return -1; - } - } - } - else - { - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Can't load the stores with " - << channelCount << " remaining channels.\n" - << logofs_flush; - #endif - - return -1; - } - - return 1; -} - -int ClientProxy::handleSave() -{ - // - // If no more X channels are remaining - // then save content of message stores. - // - - int channelCount = getChannels(channel_x11); - - if (channelCount == 0) - { - int result = handleSaveStores(); - - if (result == 1) - { - if (handleControl(code_save_request) < 0) - { - return -1; - } - - priority_ = 1; - - return 1; - } - else if (result < 0) - { - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Failed to save stores " - << "to persistent cache.\n" << logofs_flush; - #endif - - return -1; - } - } - else - { - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Can't save the stores with " - << channelCount << " remaining channels.\n" - << logofs_flush; - #endif - - return -1; - } - - return 1; -} - -int ClientProxy::handleAsyncEvents() -{ - if (canRead() == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: WARNING! Reading while writing " - << "with data available on the proxy link.\n" - << logofs_flush; - #endif - - if (handleRead() < 0) - { - return -1; - } - - return 1; - } - - return 0; -} - -int ClientProxy::handleLoadFromProxy() -{ - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Invalid load control message " - << "received in proxy.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid load control message " - << "received in proxy.\n"; - - return -1; -} - -int ClientProxy::handleSaveFromProxy() -{ - #ifdef PANIC - *logofs << "ClientProxy: PANIC! Invalid save control message " - << "received in proxy.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid save control message " - << "received in proxy.\n"; - - return -1; -} - -int ClientProxy::handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient) const -{ - if (clientStore_ -> saveRequestStores(cachefs, md5StateStream, md5StateClient, - use_checksum, discard_data) < 0) - { - return -1; - } - else if (serverStore_ -> saveReplyStores(cachefs, md5StateStream, md5StateClient, - discard_checksum, use_data) < 0) - { - return -1; - } - else if (serverStore_ -> saveEventStores(cachefs, md5StateStream, md5StateClient, - discard_checksum, use_data) < 0) - { - return -1; - } - - return 1; -} - -int ClientProxy::handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const -{ - if (clientStore_ -> loadRequestStores(cachefs, md5StateStream, - use_checksum, discard_data) < 0) - { - return -1; - } - else if (serverStore_ -> loadReplyStores(cachefs, md5StateStream, - discard_checksum, use_data) < 0) - { - return -1; - } - else if (serverStore_ -> loadEventStores(cachefs, md5StateStream, - discard_checksum, use_data) < 0) - { - return -1; - } - - return 1; -} - diff --git a/nxcomp/ClientProxy.h b/nxcomp/ClientProxy.h deleted file mode 100644 index b89785b1a..000000000 --- a/nxcomp/ClientProxy.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ClientProxy_H -#define ClientProxy_H - -#include "Proxy.h" - -// -// Set the verbosity level. -// - -#undef TEST -#undef DEBUG - -class ClientProxy : public Proxy -{ - public: - - ClientProxy(int proxyFD); - - virtual ~ClientProxy(); - - virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, - sockaddr *xServerAddr, unsigned int xServerAddrLength); - - virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort, - ChannelEndPoint &smbServerPort, - ChannelEndPoint &mediaServerPort, - ChannelEndPoint &httpServerPort, - const char *fontServerPort); - - protected: - - // - // Create a new channel. - // - - virtual int handleNewConnection(T_channel_type type, int clientFd); - - virtual int handleNewConnectionFromProxy(T_channel_type type, int channelId); - - virtual int handleNewAgentConnection(Agent *agent); - - virtual int handleNewXConnection(int clientFd); - - virtual int handleNewXConnectionFromProxy(int channelId); - - // - // Implement persistence according - // to our proxy mode. - // - - virtual int handleLoad(T_load_type type); - virtual int handleSave(); - - virtual int handleAsyncEvents(); - - virtual int handleLoadFromProxy(); - virtual int handleSaveFromProxy(); - - virtual int handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient) const; - - virtual int handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const; - - // - // Utility function used to realize - // a new connection. - // - - protected: - - virtual int checkLocalChannelMap(int channelId) - { - // Since ProtoStep7 (#issue 108) - return ((channelId & control -> ChannelMask) != 0); - } - - // - // Ports where to forward extended services' - // TCP connections. - // - - private: - - char *fontServerPort_; -}; - - -#endif /* ClientProxy_H */ diff --git a/nxcomp/ClientReadBuffer.cpp b/nxcomp/ClientReadBuffer.cpp deleted file mode 100644 index 37502038f..000000000 --- a/nxcomp/ClientReadBuffer.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ClientReadBuffer.h" - -#include "ClientChannel.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -unsigned int ClientReadBuffer::suggestedLength(unsigned int pendingLength) -{ - // - // Even if the pending data is not - // enough to make a complete message, - // resize the buffer to accommodate - // it all. - // - - unsigned int readLength = pendingLength; - - if (pendingLength < remaining_) - { - readLength = remaining_; - } - - return readLength; -} - -int ClientReadBuffer::locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength) -{ - unsigned int size = end - start; - - #ifdef TEST - *logofs << "ClientReadBuffer: Locating message for FD#" - << transport_ -> fd() << " with " << size - << " bytes.\n" << logofs_flush; - #endif - - if (firstMessage_) - { - if (size < 12) - { - remaining_ = 12 - size; - - #ifdef TEST - *logofs << "ClientReadBuffer: No message was located " - << "with remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - if (*start == 0x42) - { - bigEndian_ = 1; - } - else - { - bigEndian_ = 0; - } - - channel_ -> setBigEndian(bigEndian_); - - dataLength = 12 + RoundUp4(GetUINT(start + 6, bigEndian_)) + - RoundUp4(GetUINT(start + 8, bigEndian_)); - - // - // Send the data immediately if this is unlikely - // to be a X connection attempt. - // - - if (dataLength > 4096) - { - #ifdef WARNING - *logofs << "ClientReadBuffer: WARNING! Flushing suspicious X " - << "connection with first request of " << dataLength - << " bytes.\n" << logofs_flush; - #endif - - dataLength = size; - } - } - else - { - if (size < 4) - { - remaining_ = 4 - size; - - #ifdef TEST - *logofs << "ClientReadBuffer: No message was located " - << "with remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - dataLength = (GetUINT(start + 2, bigEndian_) << 2); - - if (dataLength < 4) - { - #ifdef TEST - *logofs << "ClientReadBuffer: WARNING! Assuming length 4 " - << "for suspicious message of length " << dataLength - << ".\n" << logofs_flush; - #endif - - dataLength = 4; - } - } - - #ifdef TEST - *logofs << "ClientReadBuffer: Length of the next message is " - << dataLength << ".\n" << logofs_flush; - #endif - - if (size < dataLength) - { - remaining_ = dataLength - size; - - #ifdef TEST - *logofs << "ClientReadBuffer: No message was located " - << "with remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - firstMessage_ = 0; - - controlLength = 0; - trailerLength = 0; - - remaining_ = 0; - - #ifdef TEST - *logofs << "ClientReadBuffer: Located message with " - << "remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 1; -} diff --git a/nxcomp/ClientReadBuffer.h b/nxcomp/ClientReadBuffer.h deleted file mode 100644 index c557417fa..000000000 --- a/nxcomp/ClientReadBuffer.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ClientReadBuffer_H -#define ClientReadBuffer_H - -#include "Control.h" -#include "ReadBuffer.h" - -class ClientChannel; - -class ClientReadBuffer : public ReadBuffer -{ - public: - - ClientReadBuffer(Transport *transport, ClientChannel *channel) - - : ReadBuffer(transport), firstMessage_(1), channel_(channel) - { - } - - virtual ~ClientReadBuffer() - { - } - - protected: - - virtual unsigned int suggestedLength(unsigned int pendingLength); - - virtual int locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength); - - int bigEndian_; - - int firstMessage_; - - ClientChannel *channel_; -}; - -#endif /* ClientReadBuffer_H */ diff --git a/nxcomp/ClientStore.cpp b/nxcomp/ClientStore.cpp deleted file mode 100644 index e1ba3f4a7..000000000 --- a/nxcomp/ClientStore.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ClientStore.h" - -// -// Cached request classes. -// - -#include "ChangeProperty.h" -#include "SendEvent.h" -#include "CreateGC.h" -#include "ChangeGC.h" -#include "CreatePixmap.h" -#include "SetClipRectangles.h" -#include "CopyArea.h" -#include "PolyLine.h" -#include "PolySegment.h" -#include "PolyFillRectangle.h" -#include "PutImage.h" -#include "TranslateCoords.h" -#include "GetImage.h" -#include "ClearArea.h" -#include "ConfigureWindow.h" -#include "ShapeExtension.h" -#include "RenderExtension.h" -#include "PolyText8.h" -#include "PolyText16.h" -#include "ImageText8.h" -#include "ImageText16.h" -#include "PolyPoint.h" -#include "PolyFillArc.h" -#include "PolyArc.h" -#include "FillPoly.h" -#include "InternAtom.h" -#include "GetProperty.h" -#include "SetUnpackGeometry.h" -#include "SetUnpackColormap.h" -#include "SetUnpackAlpha.h" -#include "PutPackedImage.h" -#include "GenericRequest.h" - -// -// Set the verbosity level. -// - -#define WARNING -#define PANIC -#undef TEST - -ClientStore::ClientStore(StaticCompressor *compressor) - - : compressor_(compressor) -{ - if (logofs == NULL) - { - logofs = &cout; - } - - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - requests_[i] = NULL; - } - - requests_[X_ChangeProperty] = new ChangePropertyStore(); - requests_[X_SendEvent] = new SendEventStore(); - requests_[X_CreateGC] = new CreateGCStore(); - requests_[X_SetClipRectangles] = new SetClipRectanglesStore(); - requests_[X_CopyArea] = new CopyAreaStore(); - requests_[X_PolyLine] = new PolyLineStore(); - requests_[X_PolySegment] = new PolySegmentStore(); - requests_[X_PolyFillRectangle] = new PolyFillRectangleStore(); - requests_[X_PutImage] = new PutImageStore(compressor); - requests_[X_TranslateCoords] = new TranslateCoordsStore(); - requests_[X_GetImage] = new GetImageStore(); - requests_[X_ClearArea] = new ClearAreaStore(); - requests_[X_ConfigureWindow] = new ConfigureWindowStore(); - requests_[X_PolyText8] = new PolyText8Store(); - requests_[X_PolyText16] = new PolyText16Store(); - requests_[X_ImageText8] = new ImageText8Store(); - requests_[X_ImageText16] = new ImageText16Store(); - requests_[X_PolyPoint] = new PolyPointStore(); - requests_[X_PolyFillArc] = new PolyFillArcStore(); - requests_[X_PolyArc] = new PolyArcStore(); - requests_[X_FillPoly] = new FillPolyStore(); - requests_[X_InternAtom] = new InternAtomStore(); - requests_[X_GetProperty] = new GetPropertyStore(); - - requests_[X_NXInternalShapeExtension] = new ShapeExtensionStore(compressor); - requests_[X_NXInternalGenericRequest] = new GenericRequestStore(compressor); - requests_[X_NXInternalRenderExtension] = new RenderExtensionStore(compressor); - requests_[X_NXSetUnpackGeometry] = new SetUnpackGeometryStore(compressor); - requests_[X_NXPutPackedImage] = new PutPackedImageStore(compressor); - - // Since ProtoStep7 (#issue 108) - requests_[X_ChangeGC] = new ChangeGCStore(); - requests_[X_CreatePixmap] = new CreatePixmapStore(); - requests_[X_NXSetUnpackColormap] = new SetUnpackColormapStore(compressor); - requests_[X_NXSetUnpackAlpha] = new SetUnpackAlphaStore(compressor); - - for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++) - { - splits_[i] = NULL; - } - - commits_ = new CommitStore(compressor); -} - -ClientStore::~ClientStore() -{ - if (logofs == NULL) - { - logofs = &cout; - } - - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - delete requests_[i]; - } - - for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++) - { - delete splits_[i]; - } - - delete commits_; -} - -int ClientStore::saveRequestStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient, T_checksum_action checksumAction, - T_data_action dataAction) const -{ - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - if (requests_[i] != NULL && - requests_[i] -> saveStore(cachefs, md5StateStream, md5StateClient, - checksumAction, dataAction, - storeBigEndian()) < 0) - { - #ifdef WARNING - *logofs << "ClientStore: WARNING! Error saving request store " - << "for OPCODE#" << (unsigned int) i << ".\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Error saving request store " - << "for opcode '" << (unsigned int) i << "'.\n"; - - return -1; - } - } - - return 1; -} - -int ClientStore::loadRequestStores(istream *cachefs, md5_state_t *md5StateStream, - T_checksum_action checksumAction, T_data_action dataAction) const -{ - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - if (requests_[i] != NULL && - requests_[i] -> loadStore(cachefs, md5StateStream, - checksumAction, dataAction, - storeBigEndian()) < 0) - { - #ifdef WARNING - *logofs << "ClientStore: WARNING! Error loading request store " - << "for OPCODE#" << (unsigned int) i << ".\n" - << logofs_flush; - #endif - - return -1; - } - } - - return 1; -} - -void ClientStore::dumpSplitStores() const -{ - for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++) - { - if (splits_[i] != NULL) - { - splits_[i] -> dump(); - } - } - - if ((getSplitTotalSize() != 0 && getSplitTotalStorageSize() == 0) || - (getSplitTotalSize() == 0 && getSplitTotalStorageSize() != 0)) - { - #ifdef PANIC - *logofs << "ClientStore: PANIC! Inconsistency detected " - << "while handling the split stores.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } -} diff --git a/nxcomp/ClientStore.h b/nxcomp/ClientStore.h deleted file mode 100644 index 009d87d9f..000000000 --- a/nxcomp/ClientStore.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ClientStore_H -#define ClientStore_H - -#include "Message.h" -#include "Split.h" - -#include "ChannelStore.h" - -class StaticCompressor; - -class ClientStore : public ChannelStore -{ - public: - - ClientStore(StaticCompressor *compressor); - - virtual ~ClientStore(); - - // - // Get the store based on the index. - // - - MessageStore *getRequestStore(unsigned char opcode) const - { - return requests_[opcode]; - } - - SplitStore *getSplitStore(int resource) const - { - return splits_[resource]; - } - - int getSplitTotalSize() const - { - return SplitStore::getTotalSize(); - } - - int getSplitTotalStorageSize() const - { - return SplitStore::getTotalStorageSize(); - } - - CommitStore *getCommitStore() const - { - return commits_; - } - - int getCommitSize() const - { - return commits_ -> getSize(); - } - - void dumpSplitStore(int resource) const - { - splits_[resource] -> dump(); - } - - void dumpCommitStore() const - { - commits_ -> dump(); - } - - void dumpSplitStores() const; - - SplitStore *createSplitStore(int resource) - { - splits_[resource] = new SplitStore(compressor_, commits_, resource); - - return splits_[resource]; - } - - void destroySplitStore(int resource) - { - delete splits_[resource]; - - splits_[resource] = NULL; - } - - // - // Actually save the message store - // to disk according to proxy mode. - // - - int saveRequestStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient, T_checksum_action checksumAction, - T_data_action dataAction) const; - - int loadRequestStores(istream *cachefs, md5_state_t *md5StateStream, - T_checksum_action checksumAction, T_data_action dataAction) const; - - private: - - // - // A client store contains requests. - // - - MessageStore *requests_[CHANNEL_STORE_OPCODE_LIMIT]; - - // - // Client messages being split. - // - - SplitStore *splits_[CHANNEL_STORE_RESOURCE_LIMIT]; - - // - // Messages having been recomposed. - // - - CommitStore *commits_; - - // - // Passed forward to the other stores. - // - - StaticCompressor *compressor_; -}; - -#endif /* ClientStore_H */ diff --git a/nxcomp/Colormap.cpp b/nxcomp/Colormap.cpp deleted file mode 100644 index 8579b7317..000000000 --- a/nxcomp/Colormap.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Unpack.h" -#include "Colormap.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -int UnpackColormap(unsigned char method, unsigned char *src_data, int src_size, - unsigned char *dst_data, int dst_size) -{ - if (*src_data == 0) - { - if (dst_size != src_size - 1) - { - #ifdef TEST - *logofs << "UnpackColormap: PANIC! Invalid destination size " - << dst_size << " with source " << src_size - << ".\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef TEST - *logofs << "UnpackColormap: Expanding " << src_size - 1 - << " bytes of plain colormap data.\n" << logofs_flush; - #endif - - memcpy(dst_data, src_data + 1, src_size - 1); - - return 1; - } - - unsigned int check_size = dst_size; - - int result = ZDecompress(&unpackStream, dst_data, &check_size, - src_data + 1, src_size - 1); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "UnpackColormap: PANIC! Failure decompressing colormap data. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decompressing colormap data. " - << "Error is '" << zError(result) << "'.\n"; - - return -1; - } - else if (check_size != (unsigned int) dst_size) - { - #ifdef PANIC - *logofs << "UnpackColormap: PANIC! Size mismatch in colormap data. " - << "Resulting size is " << check_size << " with " - << "expected size " << dst_size << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Size mismatch in colormap data. " - << "Resulting size is " << check_size << " with " - << "expected size " << dst_size << ".\n"; - - return -1; - } - - #ifdef TEST - *logofs << "UnpackColormap: Decompressed " << src_size - 1 - << " bytes to " << dst_size << " bytes of colormap data.\n" - << logofs_flush; - #endif - - return 1; -} diff --git a/nxcomp/Colormap.h b/nxcomp/Colormap.h deleted file mode 100644 index a96d003fa..000000000 --- a/nxcomp/Colormap.h +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Colormap_H -#define Colormap_H - -int UnpackColormap(unsigned char method, unsigned char *src_data, int src_size, - unsigned char *dst_data, int dst_size); - -#endif /* Colormap_H */ diff --git a/nxcomp/ConfigureWindow.cpp b/nxcomp/ConfigureWindow.cpp deleted file mode 100644 index 7b0794269..000000000 --- a/nxcomp/ConfigureWindow.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ConfigureWindow.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int ConfigureWindowStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message; - - // - // Here is the fingerprint. - // - - configureWindow -> window = GetULONG(buffer + 4, bigEndian); - - configureWindow -> value_mask = GetUINT(buffer + 8, bigEndian); - - // - // To increase effectiveness of the caching algorithm - // we remove the unused bytes carried in the data part. - // - - if ((int) size > dataOffset) - { - #ifdef DEBUG - *logofs << name() << ": Removing unused bytes from the data payload.\n" << logofs_flush; - #endif - - configureWindow -> value_mask &= (1 << 7) - 1; - - unsigned int mask = 0x1; - unsigned char *source = (unsigned char *) buffer + CONFIGUREWINDOW_DATA_OFFSET; - unsigned long value = 0; - - for (unsigned int i = 0; i < 7; i++) - { - if (configureWindow -> value_mask & mask) - { - value = GetULONG(source, bigEndian); - - value &= (1 << CONFIGUREWINDOW_FIELD_WIDTH[i]) - 1; - - PutULONG(value, source, bigEndian); - - source += 4; - } - mask <<= 1; - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ConfigureWindowStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(configureWindow -> window, buffer + 4, bigEndian); - - PutUINT(configureWindow -> value_mask, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void ConfigureWindowStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message; - - *logofs << "ConfigureWindow: window " << configureWindow -> window - << ", value_mask " << configureWindow -> value_mask - << ", size " << configureWindow -> size_ << ".\n"; - - #endif -} - -void ConfigureWindowStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 4, 4); - md5_append(md5_state_, buffer + 8, 2); -} diff --git a/nxcomp/ConfigureWindow.h b/nxcomp/ConfigureWindow.h deleted file mode 100644 index e02c2aae1..000000000 --- a/nxcomp/ConfigureWindow.h +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ConfigureWindow_H -#define ConfigureWindow_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define CONFIGUREWINDOW_ENABLE_CACHE 1 -#define CONFIGUREWINDOW_ENABLE_DATA 0 -#define CONFIGUREWINDOW_ENABLE_SPLIT 0 -#define CONFIGUREWINDOW_ENABLE_COMPRESS 0 - -#define CONFIGUREWINDOW_DATA_LIMIT 32 -#define CONFIGUREWINDOW_DATA_OFFSET 12 - -#define CONFIGUREWINDOW_CACHE_SLOTS 3000 -#define CONFIGUREWINDOW_CACHE_THRESHOLD 5 -#define CONFIGUREWINDOW_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class ConfigureWindowMessage : public Message -{ - friend class ConfigureWindowStore; - - public: - - ConfigureWindowMessage() - { - } - - ~ConfigureWindowMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int window; - unsigned short value_mask; -}; - -class ConfigureWindowStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - ConfigureWindowStore() : MessageStore() - { - enableCache = CONFIGUREWINDOW_ENABLE_CACHE; - enableData = CONFIGUREWINDOW_ENABLE_DATA; - enableSplit = CONFIGUREWINDOW_ENABLE_SPLIT; - enableCompress = CONFIGUREWINDOW_ENABLE_COMPRESS; - - dataLimit = CONFIGUREWINDOW_DATA_LIMIT; - dataOffset = CONFIGUREWINDOW_DATA_OFFSET; - - cacheSlots = CONFIGUREWINDOW_CACHE_SLOTS; - cacheThreshold = CONFIGUREWINDOW_CACHE_THRESHOLD; - cacheLowerThreshold = CONFIGUREWINDOW_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~ConfigureWindowStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "ConfigureWindow"; - } - - virtual unsigned char opcode() const - { - return X_ConfigureWindow; - } - - virtual unsigned int storage() const - { - return sizeof(ConfigureWindowMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new ConfigureWindowMessage(); - } - - virtual Message *create(const Message &message) const - { - return new ConfigureWindowMessage((const ConfigureWindowMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (ConfigureWindowMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* ConfigureWindow_H */ diff --git a/nxcomp/Control.cpp b/nxcomp/Control.cpp deleted file mode 100644 index 4469a9bf5..000000000 --- a/nxcomp/Control.cpp +++ /dev/null @@ -1,818 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "NX.h" -#include "NXpack.h" - -#include "Control.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Flush immediately on prioritized messages. -// - -#define FLUSH_PRIORITY 0 - -// -// Maximum number of bytes sent for each token. -// - -#define TOKEN_SIZE 1536 - -// -// Maximum number of tokens that can be spent -// by the client proxy before having to block -// waiting for a token reply. -// - -#define TOKEN_LIMIT 24 - -// -// By default assume the proxy is running as a -// standalone program. -// - -#define LINK_ENCRYPTED 0 - -// -// Maximum number of pids the proxy will record -// and kill at shutdown. -// - -#define KILL_LIMIT 16 - -// -// Allocate on the NX client side channels whose -// ids are a multiple of 8 (starting from 0). All -// the other ids can be used to allocate channels -// at the NX server side (X client side). -// - -#define CHANNEL_MASK 0x07 - -// -// Kill session if control parameters cannot be -// negotiated before this timeout. -// - -#define INIT_TIMEOUT 60000 - -// -// Enter the congestion state if the remote does -// not reply to a ping within the given amount -// of time. -// - -#define PING_TIMEOUT 5000 - -// -// Only send one motion event any N milliseconds. -// - -#define MOTION_TIMEOUT 0 - - -// -// Force an update of the congestion counter if -// the proxy is idle for this time. -// - -#define IDLE_TIMEOUT 50 - -// -// Close X connection if can't write before this -// timeout. -// - -#define CHANNEL_TIMEOUT 10000 - -// -// Warn user (or close proxy connection) if don't -// receive any data before this timeout. -// - -#define PROXY_TIMEOUT 120000 - -// -// How many milliseconds to wait for the shared -// memory completion event to become available. -// - -#define SHMEM_TIMEOUT 200 -// -// Before closing down the proxy, wait for the -// given amount of miliseconds to let all the -// running applications to close down their -// connections. -// -// A null timeout will cause the proxy to wait -// indefinitely, until the watchdog process is -// killed. This is usually the way the proxy is -// started by the NX server. If on the other -// hand a timeout is given and there no channel -// is remaining, the proxy will be closed down -// using a small timeout, presently of 500 ms. -// - -#define CLEANUP_TIMEOUT 3000 - -// -// Wait this amount of milliseconds after any -// iteration of the house-keeping process. -// - -#define KEEPER_TIMEOUT 60000 - -// -// In case of timeout, select can return control -// to program earlier or later of this amount of -// ms. Consider this when calculating if timeout -// is elapsed. -// - -#define LATENCY_TIMEOUT 1 - -// -// Control memory allocation in transport -// and other classes. -// - -#define TRANSPORT_X_BUFFER_SIZE 131072 -#define TRANSPORT_PROXY_BUFFER_SIZE 65536 -#define TRANSPORT_GENERIC_BUFFER_SIZE 16384 - -#define TRANSPORT_X_BUFFER_THRESHOLD 262144 -#define TRANSPORT_PROXY_BUFFER_THRESHOLD 131072 -#define TRANSPORT_GENERIC_BUFFER_THRESHOLD 32768 - -// -// Never allow buffers to exceed this limit. -// - -#define TRANSPORT_MAXIMUM_BUFFER_SIZE 393216 - -// -// Immediately flush the accumulated data to -// the X server if the write buffer exceeds -// this size. -// - -#define TRANSPORT_FLUSH_BUFFER_SIZE 16384 - -// -// Defaults used for socket options. -// - -#define OPTION_PROXY_KEEP_ALIVE 0 -#define OPTION_PROXY_LOW_DELAY 1 -#define OPTION_PROXY_CLIENT_NO_DELAY 1 -#define OPTION_PROXY_SERVER_NO_DELAY 1 -#define OPTION_CLIENT_NO_DELAY 1 -#define OPTION_SERVER_NO_DELAY 1 - -#define OPTION_PROXY_RECEIVE_BUFFER -1 -#define OPTION_CLIENT_RECEIVE_BUFFER -1 -#define OPTION_SERVER_RECEIVE_BUFFER -1 - -#define OPTION_PROXY_SEND_BUFFER -1 -#define OPTION_CLIENT_SEND_BUFFER -1 -#define OPTION_SERVER_SEND_BUFFER -1 - -#define OPTION_PROXY_RETRY_CONNECT 30 -#define OPTION_PROXY_RETRY_ACCEPT 3 -#define OPTION_SERVER_RETRY_CONNECT 3 - -// -// Defaults used for cache persistence. -// - -#define PERSISTENT_CACHE_THRESHOLD 102400 - -#define PERSISTENT_CACHE_ENABLE_LOAD 1 -#define PERSISTENT_CACHE_ENABLE_SAVE 1 - -#define PERSISTENT_CACHE_CHECK_ON_SHUTDOWN 0 - -#define PERSISTENT_CACHE_LOAD_PACKED 1 -#define PERSISTENT_CACHE_LOAD_RENDER 1 - -#define PERSISTENT_CACHE_DISK_LIMIT 33554432 - -// -// Defaults used for image cache. -// - -#define IMAGE_CACHE_ENABLE_LOAD 0 -#define IMAGE_CACHE_ENABLE_SAVE 0 - -#define IMAGE_CACHE_DISK_LIMIT 33554432 - -// -// Suggested defaults for read length parameters -// used by read buffer classes. -// - -#define CLIENT_INITIAL_READ_SIZE 8192 -#define CLIENT_MAXIMUM_BUFFER_SIZE 262144 - -#define SERVER_INITIAL_READ_SIZE 8192 -#define SERVER_MAXIMUM_BUFFER_SIZE 65536 - -#define PROXY_INITIAL_READ_SIZE 65536 -#define PROXY_MAXIMUM_BUFFER_SIZE 262144 + 1024 - -#define GENERIC_INITIAL_READ_SIZE 8192 -#define GENERIC_MAXIMUM_BUFFER_SIZE 8192 - -// -// Calculate bitrate in given time frames. -// Values are in milliseconds. -// - -#define SHORT_BITRATE_TIME_FRAME 5000 -#define LONG_BITRATE_TIME_FRAME 30000 - -// -// Bandwidth control. A value of 0 means no -// limit. Values are stored internally in -// bytes per second. -// - -#define CLIENT_BITRATE_LIMIT 0 -#define SERVER_BITRATE_LIMIT 0 - -// -// Default values for cache control. We limit -// the maximum size of a request to 262144 but -// we need to consider the replies, whose size -// may be up to 4MB. -// - -#define MINIMUM_MESSAGE_SIZE 4 -#define MAXIMUM_MESSAGE_SIZE 4194304 -#define MAXIMUM_REQUEST_SIZE 262144 - -#define CLIENT_TOTAL_STORAGE_SIZE 8388608 -#define SERVER_TOTAL_STORAGE_SIZE 8388608 - -#define STORE_TIME_LIMIT 3600 - -#define STORE_HITS_LOAD_BONUS 10 -#define STORE_HITS_ADD_BONUS 20 -#define STORE_HITS_LIMIT 100 - -#define STORE_HITS_TOUCH 1 -#define STORE_HITS_UNTOUCH 2 - -// -// Default parameters for message splitting. -// - -#define SPLIT_MODE 1 -#define SPLIT_TIMEOUT 50 -#define SPLIT_TOTAL_SIZE 128 -#define SPLIT_TOTAL_STORAGE_SIZE 1048576 -#define SPLIT_DATA_THRESHOLD 65536 -#define SPLIT_DATA_PACKET_LIMIT 24576 - -// -// Agent related parameters. -// - -#define PACK_METHOD 63 -#define PACK_QUALITY 9 -#define HIDE_RENDER 0 -#define TAINT_REPLIES 1 -#define TAINT_THRESHOLD 8 - -// -// In current version only X server support is -// implemented. Note that use of shared memory -// is negotiated according to options provided -// by the user. -// - -#define SHMEM_CLIENT 0 -#define SHMEM_SERVER 1 - -// -// Default size of shared memory segments used -// in MIT-SHM support. -// - -#define SHMEM_CLIENT_SIZE 0 -#define SHMEM_SERVER_SIZE 2097152 - -// -// What do we do at the end of session? If this -// flag is set, we launch a new client letting -// the user run a new NX session. -// - -#define ENABLE_RESTART_ON_SHUTDOWN 0 - -// -// Do we produce a core dump on fatal errors? -// - -#define ENABLE_CORE_DUMP_ON_ABORT 0 - -// -// Reopen the log file if it exceeds this size. -// - -#define FILE_SIZE_LIMIT 60000000 - -// -// Check periodically if we need to truncate the -// log file. By default check every minute. -// - -#define FILE_SIZE_CHECK_TIMEOUT 60000 - -// -// Protocol version compatibility values -// - -const int Control::NX_MIN_PROTO_STEP = 10; -const int Control::NX_MAX_PROTO_STEP = 10; -const char* const Control::NXPROXY_COMPATIBILITY_VERSION = "3.5.0"; - -// -// Set defaults for control. They should be what -// you get in case of 'local' connection. -// - -Control::Control() -{ - ProxyMode = proxy_undefined; - ProxyStage = stage_undefined; - SessionMode = session_undefined; - FlushPolicy = policy_undefined; - LinkMode = link_undefined; - - LinkEncrypted = LINK_ENCRYPTED; - FlushPriority = FLUSH_PRIORITY; - - TokenSize = TOKEN_SIZE; - TokenLimit = TOKEN_LIMIT; - - ChannelMask = CHANNEL_MASK; - - InitTimeout = INIT_TIMEOUT; - PingTimeout = PING_TIMEOUT; - MotionTimeout = MOTION_TIMEOUT; - IdleTimeout = IDLE_TIMEOUT; - - ChannelTimeout = CHANNEL_TIMEOUT; - ProxyTimeout = PROXY_TIMEOUT; - ShmemTimeout = SHMEM_TIMEOUT; - - CleanupTimeout = CLEANUP_TIMEOUT; - KeeperTimeout = KEEPER_TIMEOUT; - LatencyTimeout = LATENCY_TIMEOUT; - - FileSizeLimit = FILE_SIZE_LIMIT; - FileSizeCheckTimeout = FILE_SIZE_CHECK_TIMEOUT; - - EnableRestartOnShutdown = ENABLE_RESTART_ON_SHUTDOWN; - - KillDaemonOnShutdownLimit = KILL_LIMIT; - - KillDaemonOnShutdown = new int[KillDaemonOnShutdownLimit]; - - for (int i = 0; i < KILL_LIMIT; i++) - { - KillDaemonOnShutdown[i] = -1; - } - - KillDaemonOnShutdownNumber = 0; - - EnableCoreDumpOnAbort = ENABLE_CORE_DUMP_ON_ABORT; - - // - // Collect statistics by default. - // - - EnableStatistics = 1; - - // - // Memory restrictions if any. - // - - LocalMemoryLevel = -1; - - // - // Compression must be negotiated between proxies. - // - - LocalDeltaCompression = -1; - RemoteDeltaCompression = -1; - - LocalDataCompression = -1; - LocalStreamCompression = -1; - - RemoteDataCompression = -1; - RemoteStreamCompression = -1; - - LocalDataCompressionLevel = -1; - LocalDataCompressionThreshold = -1; - LocalStreamCompressionLevel = -1; - - RemoteDataCompressionLevel = -1; - RemoteStreamCompressionLevel = -1; - - // - // Transport buffers' allocation parameters. - // - - TransportXBufferSize = TRANSPORT_X_BUFFER_SIZE; - TransportProxyBufferSize = TRANSPORT_PROXY_BUFFER_SIZE; - TransportGenericBufferSize = TRANSPORT_GENERIC_BUFFER_SIZE; - - TransportXBufferThreshold = TRANSPORT_X_BUFFER_THRESHOLD; - TransportProxyBufferThreshold = TRANSPORT_PROXY_BUFFER_THRESHOLD; - TransportGenericBufferThreshold = TRANSPORT_GENERIC_BUFFER_THRESHOLD; - - TransportMaximumBufferSize = TRANSPORT_MAXIMUM_BUFFER_SIZE; - - // - // Flush the write buffer if it exceeds - // this size. - // - - TransportFlushBufferSize = TRANSPORT_FLUSH_BUFFER_SIZE; - - // - // Socket options. - // - - OptionProxyKeepAlive = OPTION_PROXY_KEEP_ALIVE; - OptionProxyLowDelay = OPTION_PROXY_LOW_DELAY; - OptionProxyClientNoDelay = OPTION_PROXY_CLIENT_NO_DELAY; - OptionProxyServerNoDelay = OPTION_PROXY_SERVER_NO_DELAY; - OptionClientNoDelay = OPTION_CLIENT_NO_DELAY; - OptionServerNoDelay = OPTION_SERVER_NO_DELAY; - - OptionProxyReceiveBuffer = OPTION_PROXY_RECEIVE_BUFFER; - OptionClientReceiveBuffer = OPTION_CLIENT_RECEIVE_BUFFER; - OptionServerReceiveBuffer = OPTION_SERVER_RECEIVE_BUFFER; - - OptionProxySendBuffer = OPTION_PROXY_SEND_BUFFER; - OptionClientSendBuffer = OPTION_CLIENT_SEND_BUFFER; - OptionServerSendBuffer = OPTION_SERVER_SEND_BUFFER; - - OptionProxyRetryAccept = OPTION_PROXY_RETRY_ACCEPT; - OptionProxyRetryConnect = OPTION_PROXY_RETRY_CONNECT; - OptionServerRetryConnect = OPTION_SERVER_RETRY_CONNECT; - - // - // Base NX directories. - // - - HomePath = NULL; - RootPath = NULL; - SystemPath = NULL; - TempPath = NULL; - ClientPath = NULL; - - // - // Set defaults for handling persistent cache. - // - - PersistentCachePath = NULL; - PersistentCacheName = NULL; - - PersistentCacheThreshold = PERSISTENT_CACHE_THRESHOLD; - - PersistentCacheEnableLoad = PERSISTENT_CACHE_ENABLE_LOAD; - PersistentCacheEnableSave = PERSISTENT_CACHE_ENABLE_SAVE; - - PersistentCacheCheckOnShutdown = PERSISTENT_CACHE_CHECK_ON_SHUTDOWN; - - PersistentCacheLoadPacked = PERSISTENT_CACHE_LOAD_PACKED; - PersistentCacheLoadRender = PERSISTENT_CACHE_LOAD_RENDER; - - PersistentCacheDiskLimit = PERSISTENT_CACHE_DISK_LIMIT; - - // - // Set defaults for image cache. - // - - ImageCachePath = NULL; - - ImageCacheEnableLoad = IMAGE_CACHE_ENABLE_LOAD; - ImageCacheEnableSave = IMAGE_CACHE_ENABLE_SAVE; - - ImageCacheDiskLimit = IMAGE_CACHE_DISK_LIMIT; - - // - // Set defaults for the read buffers. - // - - ClientInitialReadSize = CLIENT_INITIAL_READ_SIZE; - ClientMaximumBufferSize = CLIENT_MAXIMUM_BUFFER_SIZE; - - ServerInitialReadSize = SERVER_INITIAL_READ_SIZE; - ServerMaximumBufferSize = SERVER_MAXIMUM_BUFFER_SIZE; - - ProxyInitialReadSize = PROXY_INITIAL_READ_SIZE; - ProxyMaximumBufferSize = PROXY_MAXIMUM_BUFFER_SIZE; - - GenericInitialReadSize = GENERIC_INITIAL_READ_SIZE; - GenericMaximumBufferSize = GENERIC_MAXIMUM_BUFFER_SIZE; - - ShortBitrateTimeFrame = SHORT_BITRATE_TIME_FRAME; - LongBitrateTimeFrame = LONG_BITRATE_TIME_FRAME; - - // - // Bandwidth control. - // - - LocalBitrateLimit = -1; - - ClientBitrateLimit = CLIENT_BITRATE_LIMIT; - ServerBitrateLimit = SERVER_BITRATE_LIMIT; - - // - // Default parameters for message handling. - // - - ClientTotalStorageSize = CLIENT_TOTAL_STORAGE_SIZE; - ServerTotalStorageSize = SERVER_TOTAL_STORAGE_SIZE; - - LocalTotalStorageSize = -1; - RemoteTotalStorageSize = -1; - - StoreTimeLimit = STORE_TIME_LIMIT; - - StoreHitsLoadBonus = STORE_HITS_LOAD_BONUS; - StoreHitsAddBonus = STORE_HITS_ADD_BONUS; - StoreHitsLimit = STORE_HITS_LIMIT; - - StoreHitsTouch = STORE_HITS_TOUCH; - StoreHitsUntouch = STORE_HITS_UNTOUCH; - - MinimumMessageSize = MINIMUM_MESSAGE_SIZE; - MaximumMessageSize = MAXIMUM_MESSAGE_SIZE; - MaximumRequestSize = MAXIMUM_REQUEST_SIZE; - - SplitMode = SPLIT_MODE; - SplitTimeout = SPLIT_TIMEOUT; - SplitTotalSize = SPLIT_TOTAL_SIZE; - SplitTotalStorageSize = SPLIT_TOTAL_STORAGE_SIZE; - SplitDataThreshold = SPLIT_DATA_THRESHOLD; - SplitDataPacketLimit = SPLIT_DATA_PACKET_LIMIT; - - PackMethod = PACK_METHOD; - PackQuality = PACK_QUALITY; - HideRender = HIDE_RENDER; - TaintReplies = TAINT_REPLIES; - TaintThreshold = TAINT_THRESHOLD; - - ShmemClient = SHMEM_CLIENT; - ShmemServer = SHMEM_SERVER; - - ShmemClientSize = SHMEM_CLIENT_SIZE; - ShmemServerSize = SHMEM_SERVER_SIZE; - - // - // Get local version number from compile time - // settings. Version of remote proxy will be - // checked at connection time. - // - - RemoteVersionMajor = -1; - RemoteVersionMinor = -1; - RemoteVersionPatch = -1; - RemoteVersionMaintenancePatch = -1; - - CompatVersionMajor = -1; - CompatVersionMinor = -1; - CompatVersionPatch = -1; - CompatVersionMaintenancePatch = -1; - - LocalVersionMajor = NXMajorVersion(); - LocalVersionMinor = NXMinorVersion(); - LocalVersionPatch = NXPatchVersion(); - LocalVersionMaintenancePatch = NXMaintenancePatchVersion(); - - #ifdef TEST - *logofs << "Control: Major version is " << LocalVersionMajor - << " minor is " << LocalVersionMinor << " patch is " - << LocalVersionPatch << " Maintenance version is " - << LocalVersionMaintenancePatch << ".\n" << logofs_flush; - #endif - - // - // Initialize local implemented methods later - // and negotiate remote methods at connection - // time. - // - - LocalUnpackMethods = NULL; - RemoteUnpackMethods = NULL; - - // - // Set to 1 those methods which are implemented. - // - - setLocalUnpackMethods(); - - // - // Set the protocol version at the - // time the session is negotiated. - // - - protoStep_ = 0; -} - -Control::~Control() -{ - if (KillDaemonOnShutdown != NULL) - { - delete [] KillDaemonOnShutdown; - } - - if (HomePath != NULL) - { - delete [] HomePath; - } - - if (RootPath != NULL) - { - delete [] RootPath; - } - - if (SystemPath != NULL) - { - delete [] SystemPath; - } - - if (TempPath != NULL) - { - delete [] TempPath; - } - - if (ClientPath != NULL) - { - delete [] ClientPath; - } - - if (PersistentCachePath != NULL) - { - delete [] PersistentCachePath; - } - - if (PersistentCacheName != NULL) - { - delete [] PersistentCacheName; - } - - if (LocalUnpackMethods != NULL) - { - delete [] LocalUnpackMethods; - } - - if (RemoteUnpackMethods != NULL) - { - delete [] RemoteUnpackMethods; - } - - if (ImageCachePath != NULL) - { - delete [] ImageCachePath; - } -} - -// -// Set the protocol step based on the -// remote version. -// - -void Control::setProtoStep(int step) -{ - if (isValidProtoStep(step)) - { - protoStep_ = step; - } - else - { - #ifdef PANIC - *logofs << "Control: PANIC! Invalid protocol step " - << "with value " << step << ".\n" - << logofs_flush; - #endif - - HandleCleanup(); - } -} - -int Control::getProtoStep() -{ - if (isValidProtoStep(protoStep_)) - { - return protoStep_; - } - else - { - #ifdef PANIC - *logofs << "Control: PANIC! Can't identify the " - << "protocol step.\n" << logofs_flush; - #endif - - HandleCleanup(); - } -} - -// -// Set here the pack/unpack methods that are -// implemented by this NX proxy. -// - -void Control::setLocalUnpackMethods() -{ - LocalUnpackMethods = new unsigned char[PACK_METHOD_LIMIT]; - RemoteUnpackMethods = new unsigned char[PACK_METHOD_LIMIT]; - - for (int i = 0; i < PACK_METHOD_LIMIT; i++) - { - LocalUnpackMethods[i] = 0; - RemoteUnpackMethods[i] = 0; - } - - LocalUnpackMethods[NO_PACK] = 1; - - LocalUnpackMethods[PACK_MASKED_8_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_64_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_256_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_512_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_4K_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_32K_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_64K_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_256K_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_2M_COLORS] = 1; - LocalUnpackMethods[PACK_MASKED_16M_COLORS] = 1; - - LocalUnpackMethods[PACK_RAW_8_BITS] = 1; - LocalUnpackMethods[PACK_RAW_16_BITS] = 1; - LocalUnpackMethods[PACK_RAW_24_BITS] = 1; - - LocalUnpackMethods[PACK_COLORMAP_256_COLORS] = 1; - - LocalUnpackMethods[PACK_JPEG_8_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_64_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_256_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_512_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_4K_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_32K_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_64K_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_256K_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_2M_COLORS] = 1; - LocalUnpackMethods[PACK_JPEG_16M_COLORS] = 1; - - LocalUnpackMethods[PACK_PNG_8_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_64_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_256_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_512_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_4K_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_32K_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_64K_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_256K_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_2M_COLORS] = 1; - LocalUnpackMethods[PACK_PNG_16M_COLORS] = 1; - - LocalUnpackMethods[PACK_RGB_16M_COLORS] = 1; - LocalUnpackMethods[PACK_RLE_16M_COLORS] = 1; - - LocalUnpackMethods[PACK_ALPHA] = 1; - LocalUnpackMethods[PACK_COLORMAP] = 1; - - LocalUnpackMethods[PACK_BITMAP_16M_COLORS] = 1; -} diff --git a/nxcomp/Control.h b/nxcomp/Control.h deleted file mode 100644 index 764fca2c1..000000000 --- a/nxcomp/Control.h +++ /dev/null @@ -1,764 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Control_H -#define Control_H - -#include "NXpack.h" - -#include "Misc.h" -#include "Types.h" -#include "Timestamp.h" -#include "Statistics.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// This is the mode proxy is running. -// - -typedef enum -{ - proxy_undefined = -1, - proxy_client, - proxy_server, - proxy_last_tag -} -T_proxy_mode; - -// -// Handle advances in the connection -// procedure. -// - -typedef enum -{ - stage_undefined, - stage_initializing, - stage_connecting, - stage_connected, - stage_waiting_forwarder_version, - stage_waiting_forwarder_options, - stage_sending_forwarder_options, - stage_waiting_proxy_version, - stage_waiting_proxy_options, - stage_sending_proxy_options, - stage_waiting_proxy_caches, - stage_sending_proxy_caches, - stage_operational, - stage_terminating, - stage_terminated -} -T_proxy_stage; - -// -// Hint about whether or not the proxy is -// connected to a NX agen. -// - -typedef enum -{ - session_undefined = -1, - session_agent, - session_shadow, - session_proxy, - session_last_tag -} -T_session_mode; - -// -// Set how data will be written to the peer -// socket. -// - -typedef enum -{ - policy_undefined = -1, - policy_immediate, - policy_deferred -} -T_flush_policy; - -// -// Link mode, after negotiation, will be set to -// any of the values defined in the NXproto.h. -// - -#define link_undefined -1; - -// -// This class collects functioning parameters, -// to be configurable at run-time. They are for -// the most part regarding timeouts, transport -// and message stores handling. -// - -class Control -{ - public: - - // - // Does proxy run in client mode or server mode? - // As soon as we'll have gone through parsing of - // the command line options the current mode will - // be propagated to the control class. - // - - T_proxy_mode ProxyMode; - - // - // Goes from initializing to operational. - // - - T_proxy_stage ProxyStage; - - // - // Hint about type of session currently running. - // - - T_session_mode SessionMode; - - // - // Either immediate or defferred flushes. - // - - T_flush_policy FlushPolicy; - - // - // If set, the channels will try to flush the - // encoded data whenever there is a prioritized - // message. Depending on the flush policy, this - // may determine an immediate flush or an event - // being generated telling to the agent that it - // should flush the proxy link. - // - - int FlushPriority; - - // - // Id corresponding to link speed negotiated - // between proxies. - // - - int LinkMode; - - // - // Set if the proxy is connected to a program - // providing the encryption of the point to - // point communication. - // - - int LinkEncrypted; - - // - // Maximum number of bytes sent for each token. - // - - int TokenSize; - - // - // Maximum number of tokens that can be spent - // by the client proxy before having to block - // waiting for a reply. - // - - int TokenLimit; - - // - // Bitmask used to determine the distribution - // of channel ids between the client and server - // proxies. - // - - int ChannelMask; - - // - // Kill session if control parameters cannot - // be negotiated before this timeout. - // - - int InitTimeout; - - // - // Enter the congestion state if the remote does - // not reply to the ping within the given amount - // of time. - // - - int PingTimeout; - - // - // Enqueue motion notify events in server channel. - // - - int MotionTimeout; - - // - // Force an update of the congestion counter if - // the proxy is idle for this time. - // - - int IdleTimeout; - - // - // Close the connection if can't write before - // this timeout. - // - - int ChannelTimeout; - - // - // Close connection if can't write before - // this timeout. - // - - int ProxyTimeout; - - // - // How many milliseconds to wait for the shared - // memory completion event to become available. - // - - int ShmemTimeout; - - // - // Wait for applications to complete at the time - // proxy is shut down. - // - - int CleanupTimeout; - - // - // Wait this amount of milliseconds before any - // iteration of the house-keeping process. - // - - int KeeperTimeout; - - // - // Adjust timeout calculations. - // - - int LatencyTimeout; - - // - // Maximum allowed size of log files. - // - - int FileSizeLimit; - int FileSizeCheckTimeout; - - // - // What do we do at the end of session? If - // this flag is set we launch a new client - // letting the user run a new NX session. - // - - int EnableRestartOnShutdown; - - // - // The client can request the proxy to kill - // a number of processes before exiting. - // - - int *KillDaemonOnShutdown; - int KillDaemonOnShutdownNumber; - int KillDaemonOnShutdownLimit; - - // - // Do we generate a core dump and exit in - // case of program errors? - // - - int EnableCoreDumpOnAbort; - - // - // Is statistic output enabled? - // - - int EnableStatistics; - - // - // Version number of local and remote proxy. - // - - /* - * LocalVersionMaintenancePatch, RemoteVersionMaintenancePatch - * CompatVersionMaintenancePatch - * - * currently not used, for future compatibility checks - */ - int LocalVersionMajor; - int LocalVersionMinor; - int LocalVersionPatch; - int LocalVersionMaintenancePatch; - - int RemoteVersionMajor; - int RemoteVersionMinor; - int RemoteVersionPatch; - int RemoteVersionMaintenancePatch; - - int CompatVersionMajor; - int CompatVersionMinor; - int CompatVersionPatch; - int CompatVersionMaintenancePatch; - - // - // Compatibility version for the proxy - // - - static const char* const NXPROXY_COMPATIBILITY_VERSION; - - // - // Which unpack methods are implemented in proxy? - // - - unsigned char *LocalUnpackMethods; - unsigned char *RemoteUnpackMethods; - - // - // Memory restriction imposed by user. - // - - int LocalMemoryLevel; - - // - // Use or not differential compression - // and caching of X protocol messages. - // - - int LocalDeltaCompression; - int RemoteDeltaCompression; - - // - // Compression of images and replies. - // - - int LocalDataCompression; - int LocalDataCompressionLevel; - - int RemoteDataCompression; - int RemoteDataCompressionLevel; - - // - // Minimum packet size to be compressed. - // - - int LocalDataCompressionThreshold; - - // - // Compress or not data flowing through the proxy - // link. Level should be one of the ZLIB level as - // Z_DEFAULT_COMPRESSION or Z_BEST_COMPRESSION. - // - - int LocalStreamCompression; - int LocalStreamCompressionLevel; - - int RemoteStreamCompression; - int RemoteStreamCompressionLevel; - - // - // Size of read operations in read buffer classes. - // - - int ClientInitialReadSize; - int ClientMaximumBufferSize; - - int ServerInitialReadSize; - int ServerMaximumBufferSize; - - int ProxyInitialReadSize; - int ProxyMaximumBufferSize; - - int GenericInitialReadSize; - int GenericMaximumBufferSize; - - // - // Set initial size and resize policy of - // transport buffers. If maximum size is - // exceeded, print a warning. - // - - int TransportXBufferSize; - int TransportProxyBufferSize; - int TransportGenericBufferSize; - - int TransportXBufferThreshold; - int TransportProxyBufferThreshold; - int TransportGenericBufferThreshold; - - int TransportMaximumBufferSize; - - // - // Flush the data produced for the channel - // connection if it exceeds this size. - // - - int TransportFlushBufferSize; - - // - // Socket options. - // - - int OptionProxyKeepAlive; - int OptionProxyLowDelay; - int OptionProxyClientNoDelay; - int OptionProxyServerNoDelay; - int OptionClientNoDelay; - int OptionServerNoDelay; - - int OptionProxyReceiveBuffer; - int OptionClientReceiveBuffer; - int OptionServerReceiveBuffer; - - int OptionProxySendBuffer; - int OptionClientSendBuffer; - int OptionServerSendBuffer; - - int OptionProxyRetryAccept; - int OptionProxyRetryConnect; - int OptionServerRetryConnect; - - // - // Calculate current bitrate on proxy link - // using these observation periods. Value - // is in milliseconds. - // - - int ShortBitrateTimeFrame; - int LongBitrateTimeFrame; - - // - // Limit the bandwidth usage of the proxy - // link. - // - - int LocalBitrateLimit; - - int ClientBitrateLimit; - int ServerBitrateLimit; - - // - // This is the limit imposed by user on - // total cache size. - // - - int ClientTotalStorageSize; - int ServerTotalStorageSize; - - int LocalTotalStorageSize; - int RemoteTotalStorageSize; - - // - // Discard messages in store older than - // this amount of seconds. - // - - int StoreTimeLimit; - - // - // Any new message in store starts with - // this amount of hits. - // - - int StoreHitsAddBonus; - - // - // Unless it is loaded from persistent - // cache. - // - - int StoreHitsLoadBonus; - - // - // Stop increasing hits at this threshold. - // - - int StoreHitsLimit; - - // - // Give a special weight to messages put or - // taken from cache during startup time. - // - - int StoreHitsStartup; - - // - // Weight of touch and untoch operations. - // - - int StoreHitsTouch; - int StoreHitsUntouch; - - // - // Directives on size of messages to cache. - // - - int MinimumMessageSize; - int MaximumMessageSize; - - // - // Maximum size of a single X request. - // - - int MaximumRequestSize; - - // - // Currently selected streaming mode. - // - - int SplitMode; - - // - // Send new split data any given amount of - // milliseconds. - // - - int SplitTimeout; - - // - // Maximum number of distinct messages and - // maximum size in bytes of the temporary - // storage. - // - - int SplitTotalSize; - int SplitTotalStorageSize; - - // - // Don't split messages smaller that this - // threshold and send no more than the - // given amount of bytes in a single data - // shot when streaming the split messages. - // - - int SplitDataThreshold; - int SplitDataPacketLimit; - - // - // Agent related parameters. These values apply - // to the agent which, at startup, must query - // the user's settings. - // - - int PackMethod; - int PackQuality; - int HideRender; - int TaintReplies; - int TaintThreshold; - - // - // Do we allow shared memory image support in - // client and or server? - // - - int ShmemClient; - int ShmemServer; - - // - // Default size of shared memory segments used - // in MIT-SHM support. - // - - int ShmemClientSize; - int ShmemServerSize; - - // - // The user's home directory. - // - - char *HomePath; - - // - // The ".nx" directory, usually in - // the user's home. - // - - char *RootPath; - - // - // Usually the /usr/NX" directory. - // - - char *SystemPath; - - // - // Usually the "/tmp" directory. - // - - char *TempPath; - - // - // The complete path to the client. - // - - char *ClientPath; - - // - // String containing path of cache - // file selected for load or save. - // - - char *PersistentCachePath; - - // - // Name of selected cache file. - // - - char *PersistentCacheName; - - // - // Minimum size of cache in memory - // to proceed to its storage on disk. - // - - int PersistentCacheThreshold; - - // - // Is persistent cache enabled? - // - - int PersistentCacheEnableLoad; - int PersistentCacheEnableSave; - - // - // This is used just for test because - // it requires that client and server - // reside on the same machine. - // - - int PersistentCacheCheckOnShutdown; - - // - // Load packed image and render extension - // message stores. This currently depends - // on the type of session. - // - - int PersistentCacheLoadPacked; - int PersistentCacheLoadRender; - - // - // Maximum disk consumption of message - // caches on disk. - // - - int PersistentCacheDiskLimit; - - // - // String containing the base path - // of image cache files. - // - - char *ImageCachePath; - - // - // Is image cache enabled? - // - - int ImageCacheEnableLoad; - int ImageCacheEnableSave; - - // - // Maximum disk consumption of image - // caches on disk. - // - - int ImageCacheDiskLimit; - - // - // Only constructor, destructor - // and a few utility functions. - // - - Control(); - - ~Control(); - - // - // Should not leverage control to find channel - // stores' size limits. As most of values in - // control, this info must be moved elsewhere. - // - - int getUpperStorageSize() const - { - return (ClientTotalStorageSize > - ServerTotalStorageSize ? - ClientTotalStorageSize : - ServerTotalStorageSize); - } - - int getLowerStorageSize() const - { - return (ClientTotalStorageSize < - ServerTotalStorageSize ? - ClientTotalStorageSize : - ServerTotalStorageSize); - } - - void setProtoStep(int step); - - int getProtoStep(); - - private: - - // - // Look in Control.cpp. - // - - void setLocalUnpackMethods(); - - // - // Manage the encoding according - // to the protocol version. - // - - int protoStep_; - - // - // Min and max values allowed for protocol step - // depending on protocol version compatibility - // - - static const int NX_MIN_PROTO_STEP; - static const int NX_MAX_PROTO_STEP; - - // - // Check the validity of protocol step - // - - bool isValidProtoStep(int step) - { - return ((step >= NX_MIN_PROTO_STEP) && (step <= NX_MAX_PROTO_STEP)); - } - -}; - -#endif /* Control_H */ diff --git a/nxcomp/CopyArea.cpp b/nxcomp/CopyArea.cpp deleted file mode 100644 index 3bff8d60e..000000000 --- a/nxcomp/CopyArea.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "CopyArea.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -int CopyAreaStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - CopyAreaMessage *copyArea = (CopyAreaMessage *) message; - - // - // Here is the fingerprint. - // - - copyArea -> src_drawable = GetULONG(buffer + 4, bigEndian); - copyArea -> dst_drawable = GetULONG(buffer + 8, bigEndian); - copyArea -> gcontext = GetULONG(buffer + 12, bigEndian); - - copyArea -> src_x = GetUINT(buffer + 16, bigEndian); - copyArea -> src_y = GetUINT(buffer + 18, bigEndian); - copyArea -> dst_x = GetUINT(buffer + 20, bigEndian); - copyArea -> dst_y = GetUINT(buffer + 22, bigEndian); - - copyArea -> width = GetUINT(buffer + 24, bigEndian); - copyArea -> height = GetUINT(buffer + 26, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int CopyAreaStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - CopyAreaMessage *copyArea = (CopyAreaMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(copyArea -> src_drawable, buffer + 4, bigEndian); - PutULONG(copyArea -> dst_drawable, buffer + 8, bigEndian); - PutULONG(copyArea -> gcontext, buffer + 12, bigEndian); - - PutUINT(copyArea -> src_x, buffer + 16, bigEndian); - PutUINT(copyArea -> src_y, buffer + 18, bigEndian); - PutUINT(copyArea -> dst_x, buffer + 20, bigEndian); - PutUINT(copyArea -> dst_y, buffer + 22, bigEndian); - - PutUINT(copyArea -> width, buffer + 24, bigEndian); - PutUINT(copyArea -> height, buffer + 26, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void CopyAreaStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - CopyAreaMessage *copyArea = (CopyAreaMessage *) message; - - *logofs << name() << ": Identity src_drawable " << copyArea -> src_drawable - << ", dst_drawable " << copyArea -> dst_drawable << ", gcontext " << copyArea -> gcontext - << ", src_x " << copyArea -> src_x << ", src_y " << copyArea -> src_y - << ", dst_x " << copyArea -> dst_x << ", dst_y " << copyArea -> dst_y - << ", width " << copyArea -> width << ", height " << copyArea -> height - << ", size " << copyArea -> size_ << ".\n"; - - #endif -} - -void CopyAreaStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 16, 12); -} - -void CopyAreaStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - CopyAreaMessage *copyArea = (CopyAreaMessage *) message; - CopyAreaMessage *cachedCopyArea = (CopyAreaMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << copyArea -> src_drawable - << " as " << "src_drawable" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(copyArea -> src_drawable, clientCache -> drawableCache); - - cachedCopyArea -> src_drawable = copyArea -> src_drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << copyArea -> dst_drawable - << " as " << "dst_drawable" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(copyArea -> dst_drawable, clientCache -> drawableCache); - - cachedCopyArea -> dst_drawable = copyArea -> dst_drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << copyArea -> gcontext - << " as " << "gcontext" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(copyArea -> gcontext, clientCache -> gcCache); - - cachedCopyArea -> gcontext = copyArea -> gcontext; -} - -void CopyAreaStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - CopyAreaMessage *copyArea = (CopyAreaMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - copyArea -> src_drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << copyArea -> src_drawable - << " as " << "src_drawable" << " field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - copyArea -> dst_drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << copyArea -> dst_drawable - << " as " << "dst_drawable" << " field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - copyArea -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << copyArea -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/CopyArea.h b/nxcomp/CopyArea.h deleted file mode 100644 index 6b2617875..000000000 --- a/nxcomp/CopyArea.h +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef CopyArea_H -#define CopyArea_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define COPYAREA_ENABLE_CACHE 1 -#define COPYAREA_ENABLE_DATA 0 -#define COPYAREA_ENABLE_SPLIT 0 -#define COPYAREA_ENABLE_COMPRESS 0 - -#define COPYAREA_DATA_LIMIT 0 -#define COPYAREA_DATA_OFFSET 28 - -#define COPYAREA_CACHE_SLOTS 3000 -#define COPYAREA_CACHE_THRESHOLD 5 -#define COPYAREA_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class CopyAreaMessage : public Message -{ - friend class CopyAreaStore; - - public: - - CopyAreaMessage() - { - } - - ~CopyAreaMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int src_drawable; - unsigned int dst_drawable; - unsigned int gcontext; - unsigned short src_x; - unsigned short src_y; - unsigned short dst_x; - unsigned short dst_y; - unsigned short width; - unsigned short height; -}; - -class CopyAreaStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - CopyAreaStore() : MessageStore() - { - enableCache = COPYAREA_ENABLE_CACHE; - enableData = COPYAREA_ENABLE_DATA; - enableSplit = COPYAREA_ENABLE_SPLIT; - enableCompress = COPYAREA_ENABLE_COMPRESS; - - dataLimit = COPYAREA_DATA_LIMIT; - dataOffset = COPYAREA_DATA_OFFSET; - - cacheSlots = COPYAREA_CACHE_SLOTS; - cacheThreshold = COPYAREA_CACHE_THRESHOLD; - cacheLowerThreshold = COPYAREA_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~CopyAreaStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "CopyArea"; - } - - virtual unsigned char opcode() const - { - return X_CopyArea; - } - - virtual unsigned int storage() const - { - return sizeof(CopyAreaMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new CopyAreaMessage(); - } - - virtual Message *create(const Message &message) const - { - return new CopyAreaMessage((const CopyAreaMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (CopyAreaMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* CopyArea_H */ diff --git a/nxcomp/CreateGC.cpp b/nxcomp/CreateGC.cpp deleted file mode 100644 index 30a2f674e..000000000 --- a/nxcomp/CreateGC.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "CreateGC.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int CreateGCStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - CreateGCMessage *createGC = (CreateGCMessage *) message; - - // - // Here is the fingerprint. - // - - createGC -> gcontext = GetULONG(buffer + 4, bigEndian); - createGC -> drawable = GetULONG(buffer + 8, bigEndian); - createGC -> value_mask = GetULONG(buffer + 12, bigEndian); - - // - // Clear the unused bytes carried in the - // payload to increase the effectiveness - // of the caching algorithm. - // - - if ((int) size > dataOffset) - { - #ifdef DEBUG - *logofs << name() << ": Removing unused bytes from the " - << "data payload.\n" << logofs_flush; - #endif - - createGC -> value_mask &= (1 << 23) - 1; - - unsigned int mask = 0x1; - unsigned char *source = (unsigned char *) buffer + CREATEGC_DATA_OFFSET; - unsigned long value = 0; - - for (unsigned int i = 0; i < 23; i++) - { - if (createGC -> value_mask & mask) - { - value = GetULONG(source, bigEndian); - - value &= (0xffffffff >> (32 - CREATEGC_FIELD_WIDTH[i])); - - PutULONG(value, source, bigEndian); - - source += 4; - } - - mask <<= 1; - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int CreateGCStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - CreateGCMessage *createGC = (CreateGCMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(createGC -> gcontext, buffer + 4, bigEndian); - PutULONG(createGC -> drawable, buffer + 8, bigEndian); - PutULONG(createGC -> value_mask, buffer + 12, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void CreateGCStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - CreateGCMessage *createGC = (CreateGCMessage *) message; - - *logofs << name() << ": Identity gcontext " << createGC -> gcontext << ", drawable " - << createGC -> drawable << ", value_mask " << createGC -> value_mask - << ", size " << createGC -> size_ << ".\n" << logofs_flush; - #endif -} - -void CreateGCStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // This didn't include the drawable - // in previous versions. - // - - md5_append(md5_state_, buffer + 8, 8); -} - -void CreateGCStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - CreateGCMessage *createGC = (CreateGCMessage *) message; - CreateGCMessage *cachedCreateGC = (CreateGCMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - // Since ProtoStep7 (#issue 108) - #ifdef TEST - *logofs << name() << ": Encoding value " << createGC -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeNewXidValue(createGC -> gcontext, clientCache -> lastId, - clientCache -> lastIdCache, clientCache -> gcCache, - clientCache -> freeGCCache); - - cachedCreateGC -> gcontext = createGC -> gcontext; -} - -void CreateGCStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - CreateGCMessage *createGC = (CreateGCMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeNewXidValue(value, clientCache -> lastId, - clientCache -> lastIdCache, clientCache -> gcCache, - clientCache -> freeGCCache); - - createGC -> gcontext = value; - - #ifdef TEST - *logofs << name() << ": Decoded value " << createGC -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/CreateGC.h b/nxcomp/CreateGC.h deleted file mode 100644 index 03e27d685..000000000 --- a/nxcomp/CreateGC.h +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef CreateGC_H -#define CreateGC_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define CREATEGC_ENABLE_CACHE 1 -#define CREATEGC_ENABLE_DATA 0 -#define CREATEGC_ENABLE_SPLIT 0 -#define CREATEGC_ENABLE_COMPRESS 0 - -#define CREATEGC_DATA_LIMIT 144 -#define CREATEGC_DATA_OFFSET 16 - -#define CREATEGC_CACHE_SLOTS 2000 -#define CREATEGC_CACHE_THRESHOLD 2 -#define CREATEGC_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class CreateGCMessage : public Message -{ - friend class CreateGCStore; - - public: - - CreateGCMessage() - { - } - - ~CreateGCMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int gcontext; - unsigned int drawable; - unsigned int value_mask; -}; - -class CreateGCStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - CreateGCStore() : MessageStore() - { - enableCache = CREATEGC_ENABLE_CACHE; - enableData = CREATEGC_ENABLE_DATA; - enableSplit = CREATEGC_ENABLE_SPLIT; - enableCompress = CREATEGC_ENABLE_COMPRESS; - - dataLimit = CREATEGC_DATA_LIMIT; - dataOffset = CREATEGC_DATA_OFFSET; - - cacheSlots = CREATEGC_CACHE_SLOTS; - cacheThreshold = CREATEGC_CACHE_THRESHOLD; - cacheLowerThreshold = CREATEGC_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~CreateGCStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "CreateGC"; - } - - virtual unsigned char opcode() const - { - return X_CreateGC; - } - - virtual unsigned int storage() const - { - return sizeof(CreateGCMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new CreateGCMessage(); - } - - virtual Message *create(const Message &message) const - { - return new CreateGCMessage((const CreateGCMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (CreateGCMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* CreateGC_H */ diff --git a/nxcomp/CreatePixmap.cpp b/nxcomp/CreatePixmap.cpp deleted file mode 100644 index 93ca38fbb..000000000 --- a/nxcomp/CreatePixmap.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "CreatePixmap.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Constructors and destructors. -// - -CreatePixmapStore::CreatePixmapStore() - - : MessageStore() -{ - enableCache = CREATEPIXMAP_ENABLE_CACHE; - enableData = CREATEPIXMAP_ENABLE_DATA; - enableSplit = CREATEPIXMAP_ENABLE_SPLIT; - enableCompress = CREATEPIXMAP_ENABLE_COMPRESS; - - dataLimit = CREATEPIXMAP_DATA_LIMIT; - dataOffset = CREATEPIXMAP_DATA_OFFSET; - - cacheSlots = CREATEPIXMAP_CACHE_SLOTS; - cacheThreshold = CREATEPIXMAP_CACHE_THRESHOLD; - cacheLowerThreshold = CREATEPIXMAP_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -CreatePixmapStore::~CreatePixmapStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int CreatePixmapStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(*(buffer + 1), 8, - clientCache -> depthCache); - - encodeBuffer.encodeNewXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> drawableCache, - clientCache -> freeDrawableCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> windowCache); - - encodeBuffer.encodeCachedValue(GetUINT(buffer + 12, bigEndian), 16, - clientCache -> createPixmapXCache, 8); - - encodeBuffer.encodeCachedValue(GetUINT(buffer + 14, bigEndian), 16, - clientCache -> createPixmapYCache, 8); - - #ifdef TEST - *logofs << name() << ": Encoded message. Size is " - << size << ".\n" << logofs_flush; - #endif - - return 1; -} - -int CreatePixmapStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned char cValue; - unsigned int value; - - size = 16; - - buffer = writeBuffer -> addMessage(size); - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - - *(buffer + 1) = cValue; - - decodeBuffer.decodeNewXidValue(value, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> drawableCache, - clientCache -> freeDrawableCache); - - PutULONG(value, buffer + 4, bigEndian); - - decodeBuffer.decodeXidValue(value, - clientCache -> windowCache); - - PutULONG(value, buffer + 8, bigEndian); - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> createPixmapXCache, 8); - - PutUINT(value, buffer + 12, bigEndian); - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> createPixmapYCache, 8); - - PutUINT(value, buffer + 14, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Size is " - << size << ".\n" << logofs_flush; - #endif - - return 1; -} - -int CreatePixmapStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - CreatePixmapMessage *createPixmap = (CreatePixmapMessage *) message; - - createPixmap -> depth = *(buffer + 1); - - createPixmap -> id = GetULONG(buffer + 4, bigEndian); - createPixmap -> drawable = GetULONG(buffer + 8, bigEndian); - - createPixmap -> width = GetUINT(buffer + 12, bigEndian); - createPixmap -> height = GetUINT(buffer + 14, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Size is " - << createPixmap -> size_ << " identity is " - << createPixmap -> i_size_ << ".\n" - << logofs_flush; - #endif - - return 1; -} - -int CreatePixmapStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - CreatePixmapMessage *createPixmap = (CreatePixmapMessage *) message; - - *(buffer + 1) = createPixmap -> depth; - - PutULONG(createPixmap -> id, buffer + 4, bigEndian); - PutULONG(createPixmap -> drawable, buffer + 8, bigEndian); - - PutUINT(createPixmap -> width, buffer + 12, bigEndian); - PutUINT(createPixmap -> height, buffer + 14, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Size is " - << createPixmap -> size_ << " identity is " - << createPixmap -> i_size_ << ".\n" - << logofs_flush; - #endif - - return 1; -} - -void CreatePixmapStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - #ifdef WARNING - *logofs << name() << ": WARNING! Dump of identity not implemented.\n" - << logofs_flush; - #endif - - #endif -} - -void CreatePixmapStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 8, 8); -} - -void CreatePixmapStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - CreatePixmapMessage *createPixmap = (CreatePixmapMessage *) message; - CreatePixmapMessage *cachedCreatePixmap = (CreatePixmapMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeNewXidValue(createPixmap -> id, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> drawableCache, - clientCache -> freeDrawableCache); - - cachedCreatePixmap -> id = createPixmap -> id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Size is " - << createPixmap -> size_ << " identity is " - << createPixmap -> i_size_ << ".\n" - << logofs_flush; - #endif -} - -void CreatePixmapStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - CreatePixmapMessage *createPixmap = (CreatePixmapMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeNewXidValue(createPixmap -> id, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> drawableCache, - clientCache -> freeDrawableCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Size is " - << createPixmap -> size_ << " identity is " - << createPixmap -> i_size_ << ".\n" - << logofs_flush; - #endif -} diff --git a/nxcomp/CreatePixmap.h b/nxcomp/CreatePixmap.h deleted file mode 100644 index 0a3212dd9..000000000 --- a/nxcomp/CreatePixmap.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef CreatePixmap_H -#define CreatePixmap_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define CREATEPIXMAP_ENABLE_CACHE 1 -#define CREATEPIXMAP_ENABLE_DATA 0 -#define CREATEPIXMAP_ENABLE_SPLIT 0 -#define CREATEPIXMAP_ENABLE_COMPRESS 0 - -#define CREATEPIXMAP_DATA_LIMIT 16 -#define CREATEPIXMAP_DATA_OFFSET 16 - -#define CREATEPIXMAP_CACHE_SLOTS 1000 -#define CREATEPIXMAP_CACHE_THRESHOLD 2 -#define CREATEPIXMAP_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class CreatePixmapMessage : public Message -{ - friend class CreatePixmapStore; - - public: - - CreatePixmapMessage() - { - } - - ~CreatePixmapMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char depth; - - unsigned int id; - unsigned int drawable; - - unsigned short width; - unsigned short height; -}; - -class CreatePixmapStore : public MessageStore -{ - public: - - CreatePixmapStore(); - - virtual ~CreatePixmapStore(); - - virtual const char *name() const - { - return "CreatePixmap"; - } - - virtual unsigned char opcode() const - { - return X_CreatePixmap; - } - - virtual unsigned int storage() const - { - return sizeof(CreatePixmapMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new CreatePixmapMessage(); - } - - virtual Message *create(const Message &message) const - { - return new CreatePixmapMessage((const CreatePixmapMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (CreatePixmapMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* CreatePixmap_H */ diff --git a/nxcomp/DecodeBuffer.cpp b/nxcomp/DecodeBuffer.cpp deleted file mode 100644 index 456dee249..000000000 --- a/nxcomp/DecodeBuffer.cpp +++ /dev/null @@ -1,635 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Control.h" - -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -DecodeBuffer::DecodeBuffer(const unsigned char *data, unsigned int length) - - : buffer_(data), end_(buffer_ + length), nextSrc_(buffer_), srcMask_(0x80) -{ - // Since ProtoStep7 (#issue 108) - end_ = buffer_ + length - DECODE_BUFFER_POSTFIX_SIZE; -} - -int DecodeBuffer::decodeValue(unsigned int &value, unsigned int numBits, - unsigned int blockSize, int endOkay) -{ - #ifdef DUMP - *logofs << "DecodeBuffer: Decoding " << numBits - << " bits value with block " << blockSize - << " and " << (nextSrc_ - buffer_) - << " bytes in buffer.\n" << logofs_flush; - #endif - - unsigned int result = 0; - unsigned int destMask = 0x1; - unsigned int bitsRead = 0; - - if (blockSize == 0) - blockSize = numBits; - - unsigned char nextSrcChar = *nextSrc_; - unsigned int numBlocks = 1; - - do - { - if (numBlocks == 4) - { - blockSize = numBits; - } - - unsigned int bitsToRead = (blockSize > numBits - bitsRead ? - numBits - bitsRead : blockSize); - unsigned int count = 0; - unsigned char lastBit; - - do - { - if (nextSrc_ >= end_) - { - if (!endOkay) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [A] " - << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) - << " end_ = " << (end_ - buffer_) << ".\n" - << logofs_flush; - #endif - - // - // Label "context" is just used to identify - // the routine which detected the problem in - // present source file. - // - - cerr << "Error" << ": Failure decoding data in context [A].\n"; - - HandleAbort(); - } - - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [B] " - << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) - << " end_ = " << (end_ - buffer_) << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [B].\n"; - - HandleAbort(); - } - - lastBit = (nextSrcChar & srcMask_); - - if (lastBit) - result |= destMask; - - srcMask_ >>= 1; - - if (srcMask_ == 0) - { - srcMask_ = 0x80; - nextSrc_++; - nextSrcChar = *nextSrc_; - } - - destMask <<= 1; - } - while (bitsToRead > ++count); - - bitsRead += bitsToRead; - - if (bitsRead < numBits) - { - if (nextSrc_ >= end_) - { - if (!endOkay) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [C] " - << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) - << " end_ = " << (end_ - buffer_) << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [C].\n"; - - HandleAbort(); - } - - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [D] " - << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) - << " end_ = " << (end_ - buffer_) << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [D].\n"; - - HandleAbort(); - } - - unsigned char moreData = (nextSrcChar & srcMask_); - - srcMask_ >>= 1; - - if (srcMask_ == 0) - { - srcMask_ = 0x80; - nextSrc_++; - nextSrcChar = *nextSrc_; - } - - if (!moreData) - { - if (lastBit) - { - do - { - result |= destMask; - destMask <<= 1; - } - while (numBits > ++bitsRead); - } - else - bitsRead = numBits; - } - } - - blockSize >>= 1; - - if (blockSize < 2) - blockSize = 2; - - numBlocks++; - } - while (numBits > bitsRead); - - value = result; - - return 1; -} - -int DecodeBuffer::decodeCachedValue(unsigned int &value, unsigned int numBits, - IntCache &cache, unsigned int blockSize, - int endOkay) -{ - #ifdef DUMP - *logofs << "DecodeBuffer: Decoding " << numBits - << " bits cached value with block " << blockSize - << " and " << (nextSrc_ - buffer_) - << " bytes in buffer.\n" << logofs_flush; - #endif - - if (nextSrc_ >= end_) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [E] " - << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) - << " end_ = " << (end_ - buffer_) << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [E].\n"; - - HandleAbort(); - } - - unsigned int index = 0; - unsigned char nextSrcChar = *nextSrc_; - - while (!(nextSrcChar & srcMask_)) - { - index++; - srcMask_ >>= 1; - if (srcMask_ == 0) - { - srcMask_ = 0x80; - nextSrc_++; - if (nextSrc_ >= end_) - { - if (!endOkay) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [F] " - << "in decodeCachedValue() nextSrc_ = " - << (nextSrc_ - buffer_) << " end_ = " - << (end_ - buffer_) << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [F].\n"; - - HandleAbort(); - } - - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [G] " - << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) - << " end_ = " << (end_ - buffer_) << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [G].\n"; - - HandleAbort(); - } - - nextSrcChar = *nextSrc_; - } - } - - srcMask_ >>= 1; - - if (srcMask_ == 0) - { - srcMask_ = 0x80; - nextSrc_++; - } - - if (index == 2) - { - // Since ProtoStep8 (#issue 108) - blockSize = cache.getBlockSize(blockSize); - - if (decodeValue(value, numBits, blockSize, endOkay)) - { - cache.insert(value, IntMask[numBits]); - - return 1; - } - - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [H] " - << "in decodeCacheValue() with no value found.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [H].\n"; - - HandleAbort(); - } - else - { - if (index > 2) - { - index--; - } - - if (index > cache.getSize()) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [I] " - << "in decodeCachedValue() index = " << index - << " cache size = " << cache.getSize() << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [I].\n"; - - HandleAbort(); - } - - value = cache.get(index); - - return 1; - } -} - -int DecodeBuffer::decodeCachedValue(unsigned char &value, unsigned int numBits, - CharCache &cache, unsigned int blockSize, - int endOkay) -{ - #ifdef DUMP - *logofs << "DecodeBuffer: Decoding " << numBits - << " bits char cached value with block " << blockSize - << " and " << nextSrc_ - buffer_ << " bytes read out of " - << end_ - buffer_ << ".\n" << logofs_flush; - #endif - - if (nextSrc_ >= end_) - { - #ifdef TEST - *logofs << "DecodeBuffer: End of buffer reached in context [J] with " - << nextSrc_ - buffer_ << " bytes read out of " - << end_ - buffer_ << ".\n" << logofs_flush; - #endif - - return 0; - } - - unsigned int index = 0; - unsigned char nextSrcChar = *nextSrc_; - - while (!(nextSrcChar & srcMask_)) - { - index++; - srcMask_ >>= 1; - - if (srcMask_ == 0) - { - srcMask_ = 0x80; - nextSrc_++; - - if (nextSrc_ >= end_) - { - if (!endOkay) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [K] " - << "in decodeCachedValue() nextSrc_ " - << (nextSrc_ - buffer_) << " end_ " << (end_ - buffer_) - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [K].\n"; - - HandleAbort(); - } - - #ifdef TEST - *logofs << "DecodeBuffer: End of buffer reached in context [L] with " - << nextSrc_ - buffer_ << " bytes read out of " - << end_ - buffer_ << ".\n" << logofs_flush; - #endif - - return 0; - } - - nextSrcChar = *nextSrc_; - } - } - - srcMask_ >>= 1; - - if (srcMask_ == 0) - { - srcMask_ = 0x80; - nextSrc_++; - } - - if (index == 2) - { - unsigned int temp; - - if (decodeValue(temp, numBits, blockSize, endOkay)) - { - value = (unsigned char) temp; - - cache.insert(value); - } - else - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [M] " - << "in decodeValue() with index = 2.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [M].\n"; - - HandleAbort(); - } - } - else - { - if (index > 2) - { - index--; - } - - if (index > cache.getSize()) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [N] " - << "in decodeCachedValue() " << "index = " << index - << " cache size = " << cache.getSize() << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [N].\n"; - - HandleAbort(); - } - - value = cache.get(index); - } - - return 1; -} - -// -// Simply returns a pointer to the correct spot in -// the internal buffer. If the caller needs this -// data to last beyond the lifetime of the internal -// buffer, it must copy the data in its own memory. -// - -const unsigned char *DecodeBuffer::decodeMemory(unsigned int numBytes) -{ - #ifdef DUMP - *logofs << "DecodeBuffer: Decoding " << numBytes - << " bytes of memory with " << (nextSrc_ - buffer_) - << " bytes in buffer.\n" << logofs_flush; - #endif - - const unsigned char *result; - - // - // Force ourselves to a byte boundary. - // Is up to application to ensure data - // is word alligned when needed. - // - - if (srcMask_ != 0x80) - { - srcMask_ = 0x80; - nextSrc_++; - } - - result = nextSrc_; - - if (numBytes > DECODE_BUFFER_OVERFLOW_SIZE) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Can't decode a buffer of " - << numBytes << " bytes with limit set to " - << DECODE_BUFFER_OVERFLOW_SIZE << ".\n" - << logofs_flush; - - *logofs << "DecodeBuffer: PANIC! Assuming failure decoding " - << "data in context [O].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Should never decode buffer of size " - << "greater than " << DECODE_BUFFER_OVERFLOW_SIZE - << " bytes.\n"; - - cerr << "Error" << ": Assuming failure decoding data in " - << "context [O].\n"; - - HandleAbort(); - } - else if (end_ - nextSrc_ < (int) numBytes) - { - #ifdef PANIC - *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [P] " - << "in decodeMemory() " << "with length " << numBytes - << " and " << (end_ - nextSrc_) - << " bytes remaining.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failure decoding data in context [P].\n"; - - HandleAbort(); - } - - nextSrc_ += numBytes; - - return result; -} - -void DecodeBuffer::decodeActionValue(unsigned char &value, unsigned short &position, - ActionCache &cache) -{ - unsigned int t; - - decodeCachedValue(t, 15, *(cache.base_[cache.slot_])); - - cache.last_ += t; - cache.last_ &= 0x7fff; - - value = cache.last_ >> 13; - - position = cache.last_ & 0x1fff; - - #ifdef DEBUG - *logofs << "DecodeBuffer: Decoded value " - << (unsigned) value << " and position " - << position << " with base " << cache.slot_ - << ".\n" << logofs_flush; - #endif - - #ifdef DEBUG - *logofs << "DecodeBuffer: Action block prediction is " - << (*(cache.base_[cache.slot_])).getBlockSize(15) - << ".\n" << logofs_flush; - #endif - - cache.slot_ = (cache.last_ & 0xff); -} - -void DecodeBuffer::decodeNewXidValue(unsigned int &value, unsigned int &lastId, - IntCache &lastIdCache, IntCache &cache, - FreeCache &freeCache) -{ - decodeCachedValue(value, 29, lastIdCache); - - lastId += (value + 1); - lastId &= 0x1fffffff; - - value = lastId; - - cache.push(value, 0x1fffffff); - - freeCache.push(value, 0x1fffffff); -} - -void DecodeBuffer::decodeNewXidValue(unsigned int &value, unsigned int &lastId, - IntCache &lastIdCache, XidCache &cache, - FreeCache &freeCache) -{ - decodeCachedValue(value, 29, lastIdCache); - - #ifdef DEBUG - *logofs << "DecodeBuffer: Decoded new Xid difference " - << value << ".\n" << logofs_flush; - #endif - - lastId += (value + 1); - lastId &= 0x1fffffff; - - value = lastId; - - unsigned int t = (value - cache.last_); - - cache.last_ = value; - - #ifdef DEBUG - *logofs << "DecodeBuffer: Decoded new Xid " << value - << " with base " << cache.slot_ << ".\n" - << logofs_flush; - #endif - - cache.slot_ = (value & 0xff); - - cache.base_[cache.slot_] -> push(t, 0x1fffffff); - - freeCache.push(value, 0x1fffffff); -} - -void DecodeBuffer::decodeXidValue(unsigned int &value, XidCache &cache) -{ - unsigned int t; - - decodeCachedValue(t, 29, *(cache.base_[cache.slot_])); - - cache.last_ += t; - cache.last_ &= 0x1fffffff; - - value = cache.last_; - - #ifdef DEBUG - *logofs << "DecodeBuffer: Decoded Xid " << value - << " with base " << cache.slot_ << ".\n" - << logofs_flush; - #endif - - cache.slot_ = (value & 0xff); - - #ifdef DEBUG - *logofs << "DecodeBuffer: Xid block prediction is " - << (*(cache.base_[cache.slot_])).getBlockSize(29) - << ".\n" << logofs_flush; - #endif -} - -void DecodeBuffer::decodeFreeXidValue(unsigned int &value, FreeCache &cache) -{ - decodeCachedValue(value, 29, cache); -} - diff --git a/nxcomp/DecodeBuffer.h b/nxcomp/DecodeBuffer.h deleted file mode 100644 index f5f84c54f..000000000 --- a/nxcomp/DecodeBuffer.h +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef DecodeBuffer_H -#define DecodeBuffer_H - -#include - -#include "IntCache.h" -#include "CharCache.h" -#include "XidCache.h" -#include "FreeCache.h" -#include "OpcodeCache.h" -#include "ActionCache.h" - -#define DECODE_BUFFER_OVERFLOW_SIZE 4194304 - -#define DECODE_BUFFER_POSTFIX_SIZE 1 - -class DecodeBuffer -{ - public: - - DecodeBuffer(const unsigned char *data, unsigned int length); - - ~DecodeBuffer() - { - } - - int decodeValue(unsigned int &value, unsigned int numBits, - unsigned int blockSize = 0, int endOkay = 0); - - int decodeCachedValue(unsigned int &value, unsigned int numBits, - IntCache &cache, unsigned int blockSize = 0, - int endOkay = 0); - - int decodeCachedValue(unsigned char &value, unsigned int numBits, - CharCache &cache, unsigned int blockSize = 0, - int endOkay = 0); - - void decodeDiffCachedValue(unsigned int &value, unsigned int &previous, - unsigned int numBits, IntCache &cache, - unsigned int blockSize = 0) - { - decodeCachedValue(value, numBits, cache, blockSize); - - previous += (value + 1); - previous &= (0xffffffff >> (32 - numBits)); - - value = previous; - } - - void decodeBoolValue(unsigned int &value) - { - decodeValue(value, 1); - } - - int decodeOpcodeValue(unsigned char &value, OpcodeCache &cache, int endOkay = 0) - { - int result = decodeCachedValue(value, 8, cache.base_[cache.slot_], 8, endOkay); - - if (result == 1) - { - cache.slot_ = value; - } - - return result; - } - - void decodeActionValue(unsigned char &value, unsigned short &position, - ActionCache &cache); - - void decodeNewXidValue(unsigned int &value, unsigned int &lastId, - IntCache &lastIdCache, IntCache &cache, - FreeCache &freeCache); - - void decodeNewXidValue(unsigned int &value, unsigned int &lastId, - IntCache &lastIdCache, XidCache &cache, - FreeCache &freeCache); - - void decodeXidValue(unsigned int &value, XidCache &cache); - - void decodeFreeXidValue(unsigned int &value, FreeCache &cache); - - void decodeTextData(unsigned char *buffer, unsigned int numBytes) - { - decodeMemory(buffer, numBytes); - } - - void decodeIntData(unsigned char *buffer, unsigned int numBytes) - { - decodeMemory(buffer, numBytes); - } - - void decodeLongData(unsigned char *buffer, unsigned int numBytes) - { - decodeMemory(buffer, numBytes); - } - - const unsigned char *decodeMemory(unsigned int numBytes); - - void decodeMemory(unsigned char *buffer, unsigned int numBytes) - { - memcpy(buffer, decodeMemory(numBytes), numBytes); - } - - private: - - const unsigned char *buffer_; - const unsigned char *end_; - const unsigned char *nextSrc_; - - unsigned char srcMask_; -}; - -#endif /* DecodeBuffer_H */ diff --git a/nxcomp/EncodeBuffer.cpp b/nxcomp/EncodeBuffer.cpp deleted file mode 100644 index a259aacb2..000000000 --- a/nxcomp/EncodeBuffer.cpp +++ /dev/null @@ -1,619 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Control.h" - -#include "EncodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -#define ADVANCE_DEST \ -\ -if (destShift_ == 0) \ -{ \ - destShift_ = 7; nextDest_++; *nextDest_ = 0; \ -} \ -else \ -{ \ - destShift_--; \ -} - -EncodeBuffer::EncodeBuffer() -{ - size_ = ENCODE_BUFFER_DEFAULT_SIZE; - - buffer_ = new unsigned char[size_ + ENCODE_BUFFER_PREFIX_SIZE + - ENCODE_BUFFER_POSTFIX_SIZE] + ENCODE_BUFFER_PREFIX_SIZE; - end_ = buffer_ + size_; - - nextDest_ = buffer_; - *nextDest_ = 0; - destShift_ = 7; - - lastBits_ = 0; - - initialSize_ = ENCODE_BUFFER_DEFAULT_SIZE; - thresholdSize_ = ENCODE_BUFFER_DEFAULT_SIZE << 1; - maximumSize_ = ENCODE_BUFFER_DEFAULT_SIZE << 4; -} - -EncodeBuffer::~EncodeBuffer() -{ - delete [] (buffer_ - ENCODE_BUFFER_PREFIX_SIZE); -} - -void EncodeBuffer::setSize(unsigned int initialSize, unsigned int thresholdSize, - unsigned int maximumSize) -{ - initialSize_ = initialSize; - thresholdSize_ = thresholdSize; - maximumSize_ = maximumSize; - - #ifdef TEST - *logofs << "EncodeBuffer: Set buffer sizes to " - << initialSize_ << "/" << thresholdSize_ - << "/" << maximumSize_ << ".\n" - << logofs_flush; - #endif -} - -void EncodeBuffer::fullReset() -{ - if (size_ > initialSize_) - { - delete [] (buffer_ - ENCODE_BUFFER_PREFIX_SIZE); - - size_ = initialSize_; - - buffer_ = new unsigned char[size_ + ENCODE_BUFFER_PREFIX_SIZE + - ENCODE_BUFFER_POSTFIX_SIZE] + ENCODE_BUFFER_PREFIX_SIZE; - } - - end_ = buffer_ + size_; - - nextDest_ = buffer_; - *nextDest_ = 0; - destShift_ = 7; - - lastBits_ = 0; -} - -void EncodeBuffer::encodeValue(unsigned int value, unsigned int numBits, - unsigned int blockSize) -{ - #ifdef DUMP - *logofs << "EncodeBuffer: Encoding " << numBits - << " bits value with block " << blockSize - << " and " << (nextDest_ - buffer_) - << " bytes in buffer.\n" << logofs_flush; - #endif - - value &= IntMask[numBits]; - - unsigned int srcMask = 0x1; - unsigned int bitsWritten = 0; - - if (blockSize == 0) - blockSize = numBits; - - if (end_ - nextDest_ < 8) - { - growBuffer(); - } - - unsigned int numBlocks = 1; - - do - { - if (numBlocks == 4) - blockSize = numBits; - - unsigned int bitsToWrite = (blockSize > numBits - bitsWritten ? - numBits - bitsWritten : blockSize); - unsigned int count = 0; - unsigned int lastBit; - - do - { - lastBit = (value & srcMask); - if (lastBit) - *nextDest_ |= (1 << destShift_); - ADVANCE_DEST; - srcMask <<= 1; - } - while (bitsToWrite > ++count); - - bitsWritten += bitsToWrite; - - if (bitsWritten < numBits) - { - unsigned int tmpMask = srcMask; - unsigned int i = bitsWritten; - - if (lastBit) - { - do - { - unsigned int nextBit = (value & tmpMask); - - if (!nextBit) - break; - - tmpMask <<= 1; - } - while (numBits > ++i); - } - else - { - do - { - unsigned int nextBit = (value & tmpMask); - - if (nextBit) - break; - - tmpMask <<= 1; - } - while (numBits > ++i); - } - - if (i < numBits) - *nextDest_ |= (1 << destShift_); - else - bitsWritten = numBits; - - ADVANCE_DEST; - } - blockSize >>= 1; - - if (blockSize < 2) - blockSize = 2; - - numBlocks++; - } - while (numBits > bitsWritten); -} - -void EncodeBuffer::encodeCachedValue(unsigned int value, unsigned int numBits, - IntCache &cache, unsigned int blockSize) -{ - #ifdef DUMP - *logofs << "EncodeBuffer: Encoding " << numBits - << " bits cached value with block " << blockSize - << " and " << (nextDest_ - buffer_) - << " bytes in buffer.\n" << logofs_flush; - #endif - - value &= IntMask[numBits]; - - if (end_ - nextDest_ < 8) - { - growBuffer(); - } - - blockSize = cache.getBlockSize(blockSize); - - unsigned int index; - unsigned int sameDiff; - - #ifdef DUMP - - diffBits(); - - #endif - - if (cache.lookup(value, index, IntMask[numBits], sameDiff)) - { - if (index > 1) - index++; - - while (destShift_ < index) - { - index -= destShift_; - index--; - destShift_ = 7; - nextDest_++; - *nextDest_ = 0; - } - - destShift_ -= index; - *nextDest_ |= (1 << destShift_); - ADVANCE_DEST; - - #ifdef DUMP - *logofs << "EncodeBuffer: Encoded cached int using " - << diffBits() << " bits out of " << numBits - << ".\n" << logofs_flush; - #endif - } - else - { - ADVANCE_DEST; - ADVANCE_DEST; - *nextDest_ |= (1 << destShift_); - ADVANCE_DEST; - - // - // The attempt is very seldom successful. - // Avoid to encode the additional bool. - // - - // Since ProtoStep8 (#issue 108) - #ifdef DUMP - *logofs << "EncodeBuffer: Encoded missed int using " - << diffBits() << " bits out of " << numBits - << ".\n" << logofs_flush; - #endif - - encodeValue(value, numBits, blockSize); - } -} - -void EncodeBuffer::encodeCachedValue(unsigned char value, unsigned int numBits, - CharCache &cache, unsigned int blockSize) -{ - #ifdef DUMP - *logofs << "EncodeBuffer: Encoding " << numBits - << " bits char cached value with block " << blockSize - << " and " << (nextDest_ - buffer_) - << " bytes in buffer.\n" << logofs_flush; - #endif - - value &= IntMask[numBits]; - - if (end_ - nextDest_ < 8) - { - growBuffer(); - } - - unsigned int index; - - #ifdef DUMP - - diffBits(); - - #endif - - if (cache.lookup(value, index)) - { - if (index > 1) - index++; - - while (destShift_ < index) - { - index -= destShift_; - index--; - destShift_ = 7; - nextDest_++; - *nextDest_ = 0; - } - - destShift_ -= index; - *nextDest_ |= (1 << destShift_); - ADVANCE_DEST; - - #ifdef DUMP - *logofs << "EncodeBuffer: Encoded cached char using " - << diffBits() << " bits out of " << numBits - << ".\n" << logofs_flush; - #endif - } - else - { - ADVANCE_DEST; - ADVANCE_DEST; - *nextDest_ |= (1 << destShift_); - ADVANCE_DEST; - - encodeValue(value, numBits, blockSize); - - #ifdef DUMP - *logofs << "EncodeBuffer: Encoded missed char using " - << diffBits() << " bits out of " << numBits - << ".\n" << logofs_flush; - #endif - } -} - -void EncodeBuffer::encodeMemory(const unsigned char *buffer, unsigned int numBytes) -{ - #ifdef DUMP - *logofs << "EncodeBuffer: Encoding " << numBytes - << " bytes of memory with " << (nextDest_ - buffer_) - << " bytes in buffer.\n" << logofs_flush; - #endif - - if (numBytes > ENCODE_BUFFER_OVERFLOW_SIZE) - { - #ifdef PANIC - *logofs << "EncodeBuffer: PANIC! Should never encode buffer " - << "of size greater than " << ENCODE_BUFFER_OVERFLOW_SIZE - << " bytes.\n" << logofs_flush; - - *logofs << "EncodeBuffer: PANIC! Assuming failure encoding data " - << "in context [A].\n" << logofs_flush; - #endif - - // - // Label "context" is just used to identify - // the routine which detected the problem in - // present source file. - // - - cerr << "Error" << ": Should never encode buffer of size " - << "greater than " << ENCODE_BUFFER_OVERFLOW_SIZE - << " bytes.\n"; - - cerr << "Error" << ": Assuming failure encoding data " - << "in context [A].\n" ; - - HandleAbort(); - } - - alignBuffer(); - - if (end_ - nextDest_ < (int) numBytes) - { - growBuffer(numBytes); - } - - memcpy(nextDest_, buffer, numBytes); - - nextDest_ += numBytes; - - if (nextDest_ == end_) - { - growBuffer(); - } - else if (nextDest_ > end_) - { - #ifdef PANIC - *logofs << "EncodeBuffer: PANIC! Assertion failed. Error [B] " - << "in encodeMemory() nextDest_ " << (nextDest_ - buffer) - << " end_ " << (end_ - buffer) << ".\n" - << logofs_flush; - #endif - - // - // Label "context" is just used to identify - // the routine which detected the problem in - // present source file. - // - - cerr << "Error" << ": Failure encoding raw data " - << "in context [B].\n" ; - - HandleAbort(); - } - - *nextDest_ = 0; -} - -unsigned int EncodeBuffer::getLength() const -{ - unsigned int length = nextDest_ - buffer_; - - if (destShift_ != 7) - { - length++; - } - - // Since ProtoStep7 (#issue 108) - if (length > 0) - { - return length + ENCODE_BUFFER_POSTFIX_SIZE; - } - - return length; -} - -unsigned int EncodeBuffer::diffBits() -{ - unsigned int bits = ((nextDest_ - buffer_) << 3); - - bits += (7 - destShift_); - - unsigned int diff = bits - lastBits_; - - lastBits_ = bits; - - return diff; -} - -void EncodeBuffer::growBuffer(unsigned int numBytes) -{ - if (numBytes == 0) - { - numBytes = initialSize_; - } - - unsigned int bytesInBuffer = nextDest_ - buffer_; - - unsigned int newSize = thresholdSize_; - - while (newSize < bytesInBuffer + numBytes) - { - newSize <<= 1; - - if (newSize > maximumSize_) - { - newSize = bytesInBuffer + numBytes + initialSize_; - } - } - - unsigned char *newBuffer; - - newBuffer = new unsigned char[newSize + ENCODE_BUFFER_PREFIX_SIZE + - ENCODE_BUFFER_POSTFIX_SIZE] + ENCODE_BUFFER_PREFIX_SIZE; - - if (newBuffer == NULL) - { - #ifdef PANIC - *logofs << "EncodeBuffer: PANIC! Error in context [C] " - << "growing buffer to accommodate " << numBytes - << " bytes .\n" << logofs_flush; - #endif - - cerr << "Error" << ": Error in context [C] " - << "growing encode buffer to accommodate " - << numBytes << " bytes.\n"; - - HandleAbort(); - } - - #ifdef TEST - if (newSize >= maximumSize_) - { - *logofs << "EncodeBuffer: WARNING! Buffer grown to reach " - << "size of " << newSize << " bytes.\n" - << logofs_flush; - } - #endif - - // - // Prefix should not contain any valid data. - // It is proxy that will fill it with control - // messages and data length at the time a new - // frame is written to socket. - // - - memcpy(newBuffer, buffer_, bytesInBuffer + 1); - - newBuffer[bytesInBuffer + 1] = 0; - - delete [] (buffer_ - ENCODE_BUFFER_PREFIX_SIZE); - - buffer_ = newBuffer; - size_ = newSize; - end_ = buffer_ + size_; - - nextDest_ = buffer_ + bytesInBuffer; -} - -void EncodeBuffer::alignBuffer() -{ - if (destShift_ != 7) - { - destShift_ = 7; - nextDest_++; - - if (nextDest_ >= end_) - { - growBuffer(); - } - - *nextDest_ = 0; - } -} - -void EncodeBuffer::encodeActionValue(unsigned char value, unsigned short position, - ActionCache &cache) -{ - unsigned int v = (value << 13) | position; - - unsigned int t = (v - cache.last_); - - encodeCachedValue(t, 15, *(cache.base_[cache.slot_])); - - cache.last_ = v; - - #ifdef DEBUG - *logofs << "EncodeBuffer: Encoded value " - << (unsigned) value << " and position " - << position << " with base " << cache.slot_ - << ".\n" << logofs_flush; - #endif - - cache.slot_ = (cache.last_ & 0xff); -} - -void EncodeBuffer::encodeNewXidValue(unsigned int value, unsigned int &lastId, - IntCache &lastIdCache, IntCache &cache, - FreeCache &freeCache) -{ - encodeCachedValue((value - 1) - lastId, 29, lastIdCache); - - lastId = value; - - cache.push(value, 0x1fffffff); - - freeCache.push(value, 0x1fffffff); -} - -void EncodeBuffer::encodeNewXidValue(unsigned int value, unsigned int &lastId, - IntCache &lastIdCache, XidCache &cache, - FreeCache &freeCache) -{ - encodeCachedValue((value - 1) - lastId, 29, lastIdCache); - - lastId = value; - - unsigned int t = (value - cache.last_); - - cache.last_ = value; - - #ifdef DEBUG - *logofs << "EncodeBuffer: Encoded new Xid " << value - << " with base " << cache.slot_ << ".\n" - << logofs_flush; - #endif - - cache.slot_ = (value & 0xff); - - cache.base_[cache.slot_] -> push(t, 0x1fffffff); - - freeCache.push(value, IntMask[29]); -} - -void EncodeBuffer::encodeXidValue(unsigned int value, XidCache &cache) -{ - unsigned int t = (value - cache.last_); - - encodeCachedValue(t, 29, *(cache.base_[cache.slot_])); - - cache.last_ = value; - - #ifdef DEBUG - *logofs << "EncodeBuffer: Encoded Xid " << value - << " with base " << cache.slot_ << ".\n" - << logofs_flush; - #endif - - cache.slot_ = (value & 0xff); -} - -void EncodeBuffer::encodeFreeXidValue(unsigned int value, FreeCache &cache) -{ - encodeCachedValue(value, 29, cache); -} diff --git a/nxcomp/EncodeBuffer.h b/nxcomp/EncodeBuffer.h deleted file mode 100644 index 67f6ff093..000000000 --- a/nxcomp/EncodeBuffer.h +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef EncodeBuffer_H -#define EncodeBuffer_H - -#include "IntCache.h" -#include "CharCache.h" -#include "XidCache.h" -#include "FreeCache.h" -#include "OpcodeCache.h" -#include "ActionCache.h" - -#define ENCODE_BUFFER_DEFAULT_SIZE 16384 - -// -// This should match the maximum size of -// a single message added to write buffer -// (see WriteBuffer.h). -// - -#define ENCODE_BUFFER_OVERFLOW_SIZE 4194304 - -// -// Adjust for the control messages and the -// frame length added by the proxy. -// - -#define ENCODE_BUFFER_PREFIX_SIZE 64 - -// -// The encode routines may write one byte -// past the nominal end of the encode buffer. -// This additional byte is included in the -// payload. This is actually a harmless bug. -// - -#define ENCODE_BUFFER_POSTFIX_SIZE 1 - -class EncodeBuffer -{ - public: - - EncodeBuffer(); - - ~EncodeBuffer(); - - void setSize(unsigned int initialSize, unsigned int thresholdSize, - unsigned int maximumSize); - - void encodeValue(unsigned int value, unsigned int numBits, - unsigned int blockSize = 0); - - void encodeCachedValue(unsigned int value, unsigned int numBits, - IntCache &cache, unsigned int blockSize = 0); - - void encodeCachedValue(unsigned char value, unsigned int numBits, - CharCache &cache, unsigned int blockSize = 0); - - void encodeDiffCachedValue(const unsigned int value, unsigned int &previous, - unsigned int numBits, IntCache &cache, - unsigned int blockSize = 0) - { - encodeCachedValue((value - 1) - previous, numBits, cache, blockSize); - - previous = value; - } - - void encodeBoolValue(unsigned int value) - { - encodeValue(value, 1); - } - - void encodeOpcodeValue(unsigned char value, OpcodeCache &cache) - { - encodeCachedValue(value, 8, cache.base_[cache.slot_], 8); - - cache.slot_ = value; - } - - void encodeActionValue(unsigned char value, ActionCache &cache) - { - unsigned short position = 0; - - encodeActionValue(value, position, cache); - } - - void encodeActionValue(unsigned char value, unsigned short position, - ActionCache &cache); - - void encodeNewXidValue(unsigned int value, unsigned int &lastId, - IntCache &lastIdCache, IntCache &cache, - FreeCache &freeCache); - - void encodeNewXidValue(unsigned int value, unsigned int &lastId, - IntCache &lastIdCache, XidCache &cache, - FreeCache &freeCache); - - void encodeXidValue(unsigned int value, XidCache &cache); - - void encodeFreeXidValue(unsigned int value, FreeCache &cache); - - void encodeTextData(const unsigned char *buffer, unsigned int numBytes) - { - encodeMemory(buffer, numBytes); - } - - void encodeIntData(const unsigned char *buffer, unsigned int numBytes) - { - encodeMemory(buffer, numBytes); - } - - void encodeLongData(const unsigned char *buffer, unsigned int numBytes) - { - encodeMemory(buffer, numBytes); - } - - void encodeMemory(const unsigned char *buffer, unsigned int numBytes); - - unsigned char *getData() - { - return buffer_; - } - - unsigned int getLength() const; - - unsigned int getBits() const - { - return ((nextDest_ - buffer_) << 3) + (7 - destShift_); - } - - unsigned int diffBits(); - - void fullReset(); - - private: - - void growBuffer(unsigned int numBytes = 0); - - void alignBuffer(); - - unsigned int size_; - unsigned char *buffer_; - - // - // This points to the first byte - // just beyond end of the buffer. - // - - const unsigned char *end_; - - unsigned char *nextDest_; - unsigned int destShift_; - unsigned int lastBits_; - - unsigned int initialSize_; - unsigned int thresholdSize_; - unsigned int maximumSize_; -}; - -#endif /* EncodeBuffer_H */ diff --git a/nxcomp/FillPoly.cpp b/nxcomp/FillPoly.cpp deleted file mode 100644 index 85fa8fdd1..000000000 --- a/nxcomp/FillPoly.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "FillPoly.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int FillPolyStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - FillPolyMessage *fillPoly = (FillPolyMessage *) message; - - // - // Here is the fingerprint. - // - - fillPoly -> drawable = GetULONG(buffer + 4, bigEndian); - fillPoly -> gcontext = GetULONG(buffer + 8, bigEndian); - - fillPoly -> shape = *(buffer + 12); - fillPoly -> mode = *(buffer + 13); - - // Since ProtoStep8 (#issue 108) - if (size >= (unsigned int) dataOffset) - { - fillPoly -> x_origin = GetUINT(buffer + 16, bigEndian); - fillPoly -> y_origin = GetUINT(buffer + 18, bigEndian); - } - else - { - fillPoly -> x_origin = 0; - fillPoly -> y_origin = 0; - } - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int FillPolyStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - FillPolyMessage *fillPoly = (FillPolyMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(fillPoly -> drawable, buffer + 4, bigEndian); - PutULONG(fillPoly -> gcontext, buffer + 8, bigEndian); - - *(buffer + 12) = fillPoly -> shape; - *(buffer + 13) = fillPoly -> mode; - - // Since ProtoStep8 (#issue 108) - if (size >= (unsigned int) dataOffset) - { - PutUINT(fillPoly -> x_origin, buffer + 16, bigEndian); - PutUINT(fillPoly -> y_origin, buffer + 18, bigEndian); - } - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void FillPolyStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - FillPolyMessage *fillPoly = (FillPolyMessage *) message; - - *logofs << name() << ": Identity drawable " << fillPoly -> drawable - << ", gcontext " << fillPoly -> gcontext << ", shape " - << fillPoly -> shape << ", mode " << fillPoly -> mode - << fillPoly -> size_ << ", x_origin " << fillPoly -> x_origin - << ", y_origin " << fillPoly -> y_origin << ".\n" - << logofs_flush; - #endif -} - -void FillPolyStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Fields shape, mode. - // - - md5_append(md5_state_, buffer + 12, 2); -} - -void FillPolyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - FillPolyMessage *fillPoly = (FillPolyMessage *) message; - FillPolyMessage *cachedFillPoly = (FillPolyMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << fillPoly -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(fillPoly -> drawable, clientCache -> drawableCache); - - cachedFillPoly -> drawable = fillPoly -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << fillPoly -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(fillPoly -> gcontext, clientCache -> gcCache); - - cachedFillPoly -> gcontext = fillPoly -> gcontext; - - // Since ProtoStep8 (#issue 108) - if (fillPoly -> size_ >= dataOffset) - { - #ifdef TEST - *logofs << name() << ": Encoding value " << fillPoly -> x_origin - << " as x_origin field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(fillPoly -> x_origin, 16, - *clientCache -> fillPolyXAbsCache[0], 8); - - cachedFillPoly -> x_origin = fillPoly -> x_origin; - - #ifdef TEST - *logofs << name() << ": Encoding value " << fillPoly -> y_origin - << " as y_origin field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(fillPoly -> y_origin, 16, - *clientCache -> fillPolyYAbsCache[0], 8); - - cachedFillPoly -> y_origin = fillPoly -> y_origin; - } -} - -void FillPolyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - FillPolyMessage *fillPoly = (FillPolyMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(fillPoly -> drawable, clientCache -> drawableCache); - - #ifdef TEST - *logofs << name() << ": Decoded value " << fillPoly -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(fillPoly -> gcontext, clientCache -> gcCache); - - #ifdef TEST - *logofs << name() << ": Decoded value " << fillPoly -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - // Since ProtoStep8 (#issue 108) - if (fillPoly -> size_ >= dataOffset) - { - unsigned int value; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache -> fillPolyXAbsCache[0], 8); - - fillPoly -> x_origin = value; - - #ifdef TEST - *logofs << name() << ": Decoded value " << fillPoly -> x_origin - << " as x_origin field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache -> fillPolyYAbsCache[0], 8); - - fillPoly -> y_origin = value; - - #ifdef TEST - *logofs << name() << ": Decoded value " << fillPoly -> y_origin - << " as y_origin field.\n" << logofs_flush; - #endif - } -} - - diff --git a/nxcomp/FillPoly.h b/nxcomp/FillPoly.h deleted file mode 100644 index 4ceb96c09..000000000 --- a/nxcomp/FillPoly.h +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef FillPoly_H -#define FillPoly_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define FILLPOLY_ENABLE_CACHE 1 -#define FILLPOLY_ENABLE_DATA 0 -#define FILLPOLY_ENABLE_SPLIT 0 -#define FILLPOLY_ENABLE_COMPRESS 0 - -#define FILLPOLY_DATA_LIMIT 512 - -#define FILLPOLY_CACHE_SLOTS 2000 -#define FILLPOLY_CACHE_THRESHOLD 3 -#define FILLPOLY_CACHE_LOWER_THRESHOLD 1 - -#define FILLPOLY_DATA_OFFSET_IF_PROTO_STEP_8 20 - -// -// The message class. -// - -class FillPolyMessage : public Message -{ - friend class FillPolyStore; - - public: - - FillPolyMessage() - { - } - - ~FillPolyMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char shape; - unsigned char mode; - unsigned int drawable; - unsigned int gcontext; - - unsigned short x_origin; - unsigned short y_origin; -}; - -class FillPolyStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - FillPolyStore() : MessageStore() - { - enableCache = FILLPOLY_ENABLE_CACHE; - enableData = FILLPOLY_ENABLE_DATA; - enableSplit = FILLPOLY_ENABLE_SPLIT; - enableCompress = FILLPOLY_ENABLE_COMPRESS; - - dataLimit = FILLPOLY_DATA_LIMIT; - - // Since ProtoStep8 (#issue 108) - dataOffset = FILLPOLY_DATA_OFFSET_IF_PROTO_STEP_8; - - cacheSlots = FILLPOLY_CACHE_SLOTS; - cacheThreshold = FILLPOLY_CACHE_THRESHOLD; - cacheLowerThreshold = FILLPOLY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~FillPolyStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "FillPoly"; - } - - virtual unsigned char opcode() const - { - return X_FillPoly; - } - - virtual unsigned int storage() const - { - return sizeof(FillPolyMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new FillPolyMessage(); - } - - virtual Message *create(const Message &message) const - { - return new FillPolyMessage((const FillPolyMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (FillPolyMessage *) message; - } - - virtual int identitySize(const unsigned char *buffer, unsigned int size) - { - // Since ProtoStep8 (#issue 108) - return (size >= FILLPOLY_DATA_OFFSET_IF_PROTO_STEP_8 ? - FILLPOLY_DATA_OFFSET_IF_PROTO_STEP_8 : size); - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* FillPoly_H */ diff --git a/nxcomp/Fork.cpp b/nxcomp/Fork.cpp deleted file mode 100644 index 0120cb4a6..000000000 --- a/nxcomp/Fork.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include - -#include "Fork.h" -#include "Misc.h" -#include "Timestamp.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Only on Cygwin, retry n times waiting a -// given amount of milliseconds after each -// attempt. -// - -#define RETRY_LIMIT 30 -#define RETRY_TIMEOUT 1000 - -int Fork() -{ - #ifdef __CYGWIN32__ - - int limit = RETRY_LIMIT; - int timeout = RETRY_TIMEOUT; - - #else - - int limit = 1; - int timeout = 0; - - #endif - - int pid = 0; - - for (int i = 0; i < limit; i++) - { - #ifdef TEST - *logofs << "Fork: Trying at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - // - // It could optionally try again only if the - // error code is 11, 'Resource temporarily - // unavailable'. - // - - if ((pid = fork()) >= 0) - { - break; - } - else if (i < limit - 1) - { - #ifdef WARNING - *logofs << "Fork: WARNING! Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'. Retrying...\n" << logofs_flush; - #endif - - usleep(timeout * 1000); - } - } - - #ifdef TEST - - if (pid <= 0) - { - *logofs << "Fork: Returning at " << strMsTimestamp() - << ".\n" << logofs_flush; - } - - #endif - - return pid; -} diff --git a/nxcomp/Fork.h b/nxcomp/Fork.h deleted file mode 100644 index 94238ed90..000000000 --- a/nxcomp/Fork.h +++ /dev/null @@ -1,31 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Try again if the fork() fails, as it can happen -// often on Cygwin. -// - -extern int Fork(); diff --git a/nxcomp/FreeCache.h b/nxcomp/FreeCache.h deleted file mode 100644 index bf5c801e5..000000000 --- a/nxcomp/FreeCache.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef FreeCache_H -#define FreeCache_H - -#include "IntCache.h" - -class FreeCache : public IntCache -{ - public: - - FreeCache(unsigned int size) - - : IntCache(size) - { - } -}; - -#endif /* FreeCache_H */ diff --git a/nxcomp/GenericChannel.cpp b/nxcomp/GenericChannel.cpp deleted file mode 100644 index 6fc049e70..000000000 --- a/nxcomp/GenericChannel.cpp +++ /dev/null @@ -1,491 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include - -#include "GenericChannel.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "StaticCompressor.h" - -#include "Statistics.h" -#include "Proxy.h" - -extern Proxy *proxy; - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Log the important tracepoints related -// to writing packets to the peer proxy. -// - -#undef FLUSH - -// -// Define this to log when a channel -// is created or destroyed. -// - -#undef REFERENCES - -// -// Here are the static members. -// - -#ifdef REFERENCES - -int GenericChannel::references_ = 0; - -#endif - -GenericChannel::GenericChannel(Transport *transport, StaticCompressor *compressor) - - : Channel(transport, compressor), readBuffer_(transport_, this) -{ - #ifdef REFERENCES - *logofs << "GenericChannel: Created new object at " - << this << " for FD#" << fd_ << " out of " - << ++references_ << " allocated channels.\n" - << logofs_flush; - #endif -} - -GenericChannel::~GenericChannel() -{ - #ifdef REFERENCES - *logofs << "GenericChannel: Deleted object at " - << this << " for FD#" << fd_ << " out of " - << --references_ << " allocated channels.\n" - << logofs_flush; - #endif -} - -// -// Beginning of handleRead(). -// - -int GenericChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, - unsigned int length) -{ - #ifdef TEST - *logofs << "handleRead: Called for FD#" << fd_ - << " with " << encodeBuffer.getLength() - << " bytes already encoded.\n" - << logofs_flush; - #endif - - // - // Pointer to located message and - // its size in bytes. - // - - const unsigned char *inputMessage; - unsigned int inputLength; - - // - // Tag message as generic data in compression - // routine. Opcode is not actually transferred - // over the network. - // - - unsigned char inputOpcode = X_NXInternalGenericData; - - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: Trying to read from FD#" - << fd_ << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - int result = readBuffer_.readMessage(); - - #ifdef DEBUG - *logofs << "handleRead: Read result on FD#" << fd_ - << " is " << result << ".\n" - << logofs_flush; - #endif - - if (result < 0) - { - // - // Let the proxy close the channel. - // - - return -1; - } - else if (result == 0) - { - #if defined(TEST) || defined(INFO) - - *logofs << "handleRead: PANIC! No data read from FD#" - << fd_ << " while encoding messages.\n" - << logofs_flush; - - HandleCleanup(); - - #endif - - return 0; - } - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "handleRead: Encoding messages for FD#" << fd_ - << " with " << readBuffer_.getLength() << " bytes " - << "in the buffer.\n" << logofs_flush; - #endif - - // - // Divide the available data in multiple - // messages and encode them one by one. - // - - if (proxy -> handleAsyncSwitch(fd_) < 0) - { - return -1; - } - - while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) - { - encodeBuffer.encodeValue(inputLength, 32, 14); - - if (isCompressed() == 1) - { - unsigned int compressedDataSize = 0; - unsigned char *compressedData = NULL; - - if (handleCompress(encodeBuffer, inputOpcode, 0, - inputMessage, inputLength, compressedData, - compressedDataSize) < 0) - { - return -1; - } - } - else - { - encodeBuffer.encodeMemory(inputMessage, inputLength); - } - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleRead: Handled generic data for FD#" << fd_ - << ". " << inputLength << " bytes in, " << bits << " bits (" - << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; - #endif - - addProtocolBits(inputLength << 3, bits); - - if (isPrioritized() == 1) - { - priority_++; - } - - } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) ... - - // - // All data has been read from the read buffer. - // We still need to mark the end of the encode - // buffer just before sending the frame. This - // allows us to accommodate multiple reads in - // a single frame. - // - - if (priority_ > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: WARNING! Requesting flush " - << "because of " << priority_ << " prioritized " - << "messages for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - if (proxy -> handleAsyncPriority() < 0) - { - return -1; - } - - // - // Reset the priority flag. - // - - priority_ = 0; - } - - // - // Flush if we produced enough data. - // - - if (proxy -> canAsyncFlush() == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: WARNING! Requesting flush " - << "because of enough data or timeout on the " - << "proxy link.\n" << logofs_flush; - #endif - - if (proxy -> handleAsyncFlush() < 0) - { - return -1; - } - } - - #if defined(TEST) || defined(INFO) - - if (transport_ -> pending() != 0 || - readBuffer_.checkMessage() != 0) - { - *logofs << "handleRead: PANIC! Buffer for X descriptor FD#" - << fd_ << " has " << transport_ -> pending() - << " bytes to read.\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - // - // Reset the read buffer. - // - - readBuffer_.fullReset(); - - return 1; -} - -// -// End of handleRead(). -// - -// -// Beginning of handleWrite(). -// - -int GenericChannel::handleWrite(const unsigned char *message, unsigned int length) -{ - #ifdef TEST - *logofs << "handleWrite: Called for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - // - // Create the buffer from which to - // decode messages. - // - - DecodeBuffer decodeBuffer(message, length); - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "handleWrite: Decoding messages for FD#" << fd_ - << " with " << length << " bytes in the buffer.\n" - << logofs_flush; - #endif - - unsigned char *outputMessage; - unsigned int outputLength; - - // - // Tag message as generic data - // in decompression. - // - - unsigned char outputOpcode = X_NXInternalGenericData; - - for (;;) - { - decodeBuffer.decodeValue(outputLength, 32, 14); - - if (outputLength == 0) - { - break; - } - - if (isCompressed() == 1) - { - if (writeBuffer_.getAvailable() < outputLength || - (int) outputLength >= control -> TransportFlushBufferSize) - { - #ifdef DEBUG - *logofs << "handleWrite: Using scratch buffer for " - << "generic data with size " << outputLength << " and " - << writeBuffer_.getLength() << " bytes in buffer.\n" - << logofs_flush; - #endif - - outputMessage = writeBuffer_.addScratchMessage(outputLength); - } - else - { - outputMessage = writeBuffer_.addMessage(outputLength); - } - - const unsigned char *compressedData = NULL; - unsigned int compressedDataSize = 0; - - int decompressed = handleDecompress(decodeBuffer, outputOpcode, 0, - outputMessage, outputLength, compressedData, - compressedDataSize); - if (decompressed < 0) - { - return -1; - } - } - else - { - #ifdef DEBUG - *logofs << "handleWrite: Using scratch buffer for " - << "generic data with size " << outputLength << " and " - << writeBuffer_.getLength() << " bytes in buffer.\n" - << logofs_flush; - #endif - - writeBuffer_.addScratchMessage((unsigned char *) - decodeBuffer.decodeMemory(outputLength), outputLength); - } - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleWrite: Handled generic data for FD#" << fd_ - << ". " << outputLength << " bytes out.\n" - << logofs_flush; - #endif - - handleFlush(flush_if_needed); - } - - // - // Write any remaining data to socket. - // - - if (handleFlush(flush_if_any) < 0) - { - return -1; - } - - return 1; -} - -// -// End of handleWrite(). -// - -// -// Other members. -// - -int GenericChannel::handleCompletion(EncodeBuffer &encodeBuffer) -{ - // - // Add the bits telling to the remote - // that all data in the frame has been - // encoded. - // - - if (encodeBuffer.getLength() > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleCompletion: Writing completion bits with " - << encodeBuffer.getLength() << " bytes encoded " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeValue(0, 32, 14); - - return 1; - } - #if defined(TEST) || defined(INFO) - else - { - *logofs << "handleCompletion: PANIC! No completion to write " - << "for FD#" << fd_ << ".\n" << logofs_flush; - - HandleCleanup(); - } - #endif - - return 0; -} - -int GenericChannel::handleConfiguration() -{ - #ifdef TEST - *logofs << "GenericChannel: Setting new buffer parameters.\n" - << logofs_flush; - #endif - - readBuffer_.setSize(control -> GenericInitialReadSize, - control -> GenericMaximumBufferSize); - - writeBuffer_.setSize(control -> TransportGenericBufferSize, - control -> TransportGenericBufferThreshold, - control -> TransportMaximumBufferSize); - - transport_ -> setSize(control -> TransportGenericBufferSize, - control -> TransportGenericBufferThreshold, - control -> TransportMaximumBufferSize); - - return 1; -} - -int GenericChannel::handleFinish() -{ - #ifdef TEST - *logofs << "GenericChannel: Finishing channel for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - congestion_ = 0; - priority_ = 0; - - finish_ = 1; - - transport_ -> fullReset(); - - return 1; -} - -int GenericChannel::setReferences() -{ - #ifdef TEST - *logofs << "GenericChannel: Initializing the static " - << "members for the generic channels.\n" - << logofs_flush; - #endif - - #ifdef REFERENCES - - references_ = 0; - - #endif - - return 1; -} diff --git a/nxcomp/GenericChannel.h b/nxcomp/GenericChannel.h deleted file mode 100644 index 3df18f444..000000000 --- a/nxcomp/GenericChannel.h +++ /dev/null @@ -1,440 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef GenericChannel_H -#define GenericChannel_H - -#include "Channel.h" - -#include "Statistics.h" - -#include "GenericReadBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#undef TEST -#undef DEBUG - -// -// Define this to log a line when a channel -// is created or destroyed. -// - -#undef REFERENCES - -// -// This class implements the client -// side compression of X protocol. -// - -class GenericChannel : public Channel -{ - public: - - GenericChannel(Transport *transport, StaticCompressor *compressor); - - virtual ~GenericChannel(); - - virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, - unsigned int length); - - virtual int handleWrite(const unsigned char *message, unsigned int length); - - - virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, - T_store_action action, int position, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) - { - return 0; - } - - virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, - T_store_action action, int position, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) - { - return 0; - } - - - virtual int handleSplit(EncodeBuffer &encodeBuffer) - { - return 0; - } - - virtual int handleSplit(DecodeBuffer &decodeBuffer) - { - return 0; - } - - virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split) - { - return 0; - } - - virtual int handleSplitEvent(DecodeBuffer &decodeBuffer) - { - return 0; - } - - virtual int handleMotion(EncodeBuffer &encodeBuffer) - { - return 0; - } - - virtual int handleCompletion(EncodeBuffer &encodeBuffer); - - virtual int handleConfiguration(); - - virtual int handleFinish(); - - virtual int handleAsyncEvents() - { - return 0; - } - - virtual int needSplit() const - { - return 0; - } - - virtual int needMotion() const - { - return 0; - } - - virtual T_channel_type getType() const = 0; - - // - // Initialize the static members. - // - - static int setReferences(); - - protected: - - // - // Generic channels are considered to be - // in congestion state as soon as the - // socket is blocked for write. - // - - virtual int isCongested() - { - return (transport_ -> blocked() == 1); - } - - virtual int isReliable() - { - return 0; - } - - // - // Model generic channels' encoding and - // decoding policy. - // - - virtual int isCompressed() = 0; - - // - // Return true if the channel contains - // time sensitive data. - // - - virtual int isPrioritized() = 0; - - // - // Record the protocol bits for the - // specific service. - // - - virtual void addProtocolBits(unsigned int bitsIn, unsigned int bitsOut) = 0; - - // - // Channel's own read buffer. - // - - GenericReadBuffer readBuffer_; - - private: - - // - // Keep track of object's creation - // and deletion. - // - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -class CupsChannel : public GenericChannel -{ - public: - - CupsChannel(Transport *transport, StaticCompressor *compressor) - - : GenericChannel(transport, compressor) - { - } - - virtual ~CupsChannel() - { - } - - protected: - - virtual T_channel_type getType() const - { - return channel_cups; - } - - virtual int isCompressed() - { - // Since ProtoStep8 (#issue 108) - return 0; - } - - virtual int isPrioritized() - { - return 0; - } - - virtual void addProtocolBits(unsigned int bitsIn, - unsigned int bitsOut) - { - statistics -> addCupsBits(bitsIn, bitsOut); - } -}; - -class SmbChannel : public GenericChannel -{ - public: - - SmbChannel(Transport *transport, StaticCompressor *compressor) - - : GenericChannel(transport, compressor) - { - } - - virtual ~SmbChannel() - { - } - - protected: - - virtual T_channel_type getType() const - { - return channel_smb; - } - - virtual int isCompressed() - { - // Since ProtoStep8 (#issue 108) - return 0; - } - - virtual int isPrioritized() - { - return 0; - } - - virtual void addProtocolBits(unsigned int bitsIn, - unsigned int bitsOut) - { - statistics -> addSmbBits(bitsIn, bitsOut); - } -}; - -class MediaChannel : public GenericChannel -{ - public: - - MediaChannel(Transport *transport, StaticCompressor *compressor) - - : GenericChannel(transport, compressor) - { - } - - virtual ~MediaChannel() - { - } - - protected: - - virtual T_channel_type getType() const - { - return channel_media; - } - - // - // Don't try to compress the media data. - // - - virtual int isCompressed() - { - return 0; - } - - // - // Reduce the latency of media channels - // by setting them as prioritized, even - // if this will take away bandwidth from - // the X channels. - // - - virtual int isPrioritized() - { - return 1; - } - - virtual void addProtocolBits(unsigned int bitsIn, - unsigned int bitsOut) - { - statistics -> addMediaBits(bitsIn, bitsOut); - } -}; - -class HttpChannel : public GenericChannel -{ - public: - - HttpChannel(Transport *transport, StaticCompressor *compressor) - - : GenericChannel(transport, compressor) - { - } - - virtual ~HttpChannel() - { - } - - protected: - - virtual T_channel_type getType() const - { - return channel_http; - } - - virtual int isCompressed() - { - // Since ProtoStep8 (#issue 108) - return 0; - } - - virtual int isPrioritized() - { - return 0; - } - - virtual void addProtocolBits(unsigned int bitsIn, - unsigned int bitsOut) - { - statistics -> addHttpBits(bitsIn, bitsOut); - } -}; - -class FontChannel : public GenericChannel -{ - public: - - FontChannel(Transport *transport, StaticCompressor *compressor) - - : GenericChannel(transport, compressor) - { - } - - virtual ~FontChannel() - { - } - - protected: - - virtual T_channel_type getType() const - { - return channel_font; - } - - virtual int isCompressed() - { - // Since ProtoStep8 (#issue 108) - return 0; - } - - virtual int isPrioritized() - { - return 1; - } - - virtual void addProtocolBits(unsigned int bitsIn, - unsigned int bitsOut) - { - statistics -> addFontBits(bitsIn, bitsOut); - } -}; - -class SlaveChannel : public GenericChannel -{ - public: - - SlaveChannel(Transport *transport, StaticCompressor *compressor) - - : GenericChannel(transport, compressor) - { - } - - virtual ~SlaveChannel() - { - } - - protected: - - virtual T_channel_type getType() const - { - return channel_slave; - } - - virtual int isCompressed() - { - return 0; - } - - virtual int isPrioritized() - { - return 0; - } - - virtual void addProtocolBits(unsigned int bitsIn, - unsigned int bitsOut) - { - statistics -> addSlaveBits(bitsIn, bitsOut); - } -}; - -#endif /* GenericChannel_H */ diff --git a/nxcomp/GenericReadBuffer.cpp b/nxcomp/GenericReadBuffer.cpp deleted file mode 100644 index 337ae2f61..000000000 --- a/nxcomp/GenericReadBuffer.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "GenericReadBuffer.h" - -#include "GenericChannel.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -unsigned int GenericReadBuffer::suggestedLength(unsigned int pendingLength) -{ - // - // Always read the initial read size. - // - - return 0; -} - -int GenericReadBuffer::locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength) -{ - // - // We don't care about the endianess - // in generic channels. - // - - unsigned int size = end - start; - - #ifdef TEST - *logofs << "GenericReadBuffer: Locating message for FD#" - << transport_ -> fd() << " with " << size - << " bytes.\n" << logofs_flush; - #endif - - if (size == 0) - { - remaining_ = 1; - - return 0; - } - - dataLength = size; - - controlLength = 0; - trailerLength = 0; - - remaining_ = 0; - - return 1; -} diff --git a/nxcomp/GenericReadBuffer.h b/nxcomp/GenericReadBuffer.h deleted file mode 100644 index 5ea4d939d..000000000 --- a/nxcomp/GenericReadBuffer.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef GenericReadBuffer_H -#define GenericReadBuffer_H - -#include "ReadBuffer.h" -#include "Control.h" - -class GenericChannel; - -class GenericReadBuffer : public ReadBuffer -{ - public: - - GenericReadBuffer(Transport *transport, GenericChannel *channel) - - : ReadBuffer(transport), channel_(channel) - { - } - - virtual ~GenericReadBuffer() - { - } - - protected: - - virtual unsigned int suggestedLength(unsigned int pendingLength); - - virtual int locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength); - - GenericChannel *channel_; -}; - -#endif /* GenericReadBuffer_H */ diff --git a/nxcomp/GenericReply.cpp b/nxcomp/GenericReply.cpp deleted file mode 100644 index 3d9a0d638..000000000 --- a/nxcomp/GenericReply.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "GenericReply.h" - -#include "ServerCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -GenericReplyStore::GenericReplyStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = GENERICREPLY_ENABLE_CACHE; - enableData = GENERICREPLY_ENABLE_DATA; - enableSplit = GENERICREPLY_ENABLE_SPLIT; - - // Since ProtoStep7 (#issue 108) - enableCompress = GENERICREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = GENERICREPLY_DATA_LIMIT; - dataOffset = GENERICREPLY_DATA_OFFSET; - - cacheSlots = GENERICREPLY_CACHE_SLOTS; - cacheThreshold = GENERICREPLY_CACHE_THRESHOLD; - cacheLowerThreshold = GENERICREPLY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -GenericReplyStore::~GenericReplyStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int GenericReplyStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ServerCache *serverCache = (ServerCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" - << logofs_flush; - #endif - - encodeBuffer.encodeValue(GetULONG(buffer + 4, bigEndian), 32, 15); - - encodeBuffer.encodeCachedValue(*(buffer + 1), 8, - serverCache -> genericReplyCharCache); - - for (unsigned int i = 0; i < 6; i++) - { - encodeBuffer.encodeCachedValue(GetULONG(buffer + i * 4 + 8, bigEndian), 32, - *serverCache -> genericReplyIntCache[i]); - } - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" - << logofs_flush; - #endif - - return 1; -} - -int GenericReplyStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ServerCache *serverCache = (ServerCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" - << logofs_flush; - #endif - - decodeBuffer.decodeValue(size, 32, 15); - - size = 32 + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - decodeBuffer.decodeCachedValue(*(buffer + 1), 8, - serverCache -> genericReplyCharCache); - - unsigned int value; - - for (unsigned int i = 0; i < 6; i++) - { - decodeBuffer.decodeCachedValue(value, 32, - *serverCache -> genericReplyIntCache[i]); - - PutULONG(value, buffer + i * 4 + 8, bigEndian); - } - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" - << logofs_flush; - #endif - - return 1; -} - -int GenericReplyStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GenericReplyMessage *genericReply = (GenericReplyMessage *) message; - - genericReply -> byte_data = *(buffer + 1); - - for (int i = 0; i < 12; i++) - { - genericReply -> short_data[i] = GetUINT(buffer + i * 2 + 8, bigEndian); - } - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int GenericReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GenericReplyMessage *genericReply = (GenericReplyMessage *) message; - - *(buffer + 1) = genericReply -> byte_data; - - for (int i = 0; i < 12; i++) - { - PutUINT(genericReply -> short_data[i], buffer + i * 2 + 8, bigEndian); - } - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void GenericReplyStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - GenericReplyMessage *genericReply = (GenericReplyMessage *) message; - - *logofs << name() << ": Identity byte_data " - << (unsigned) genericReply -> byte_data; - - for (int i = 0; i < 12; i++) - { - *logofs << ", short_data[" << i << "]" - << (unsigned) genericReply -> short_data[i]; - } - - *logofs << ", size " << genericReply -> size_ << ".\n"; - - #endif -} - -void GenericReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} - -void GenericReplyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - // - // Encode the variant part. - // - - GenericReplyMessage *genericReply = (GenericReplyMessage *) message; - GenericReplyMessage *cachedGenericReply = (GenericReplyMessage *) cachedMessage; - - ServerCache *serverCache = (ServerCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " - << (unsigned int) genericReply -> byte_data - << " as byte_data field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(genericReply -> byte_data, 8, - serverCache -> genericReplyCharCache); - - cachedGenericReply -> byte_data = genericReply -> byte_data; - - for (unsigned int i = 0; i < 12; i++) - { - #ifdef TEST - *logofs << name() << ": Encoding value " << genericReply -> short_data[i] - << " as short_data[" << i << "] field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(genericReply -> short_data[i], 16, - *serverCache -> genericReplyIntCache[i]); - - cachedGenericReply -> short_data[i] = genericReply -> short_data[i]; - } -} - -void GenericReplyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - // - // Decode the variant part. - // - - GenericReplyMessage *genericReply = (GenericReplyMessage *) message; - - ServerCache *serverCache = (ServerCache *) channelCache; - - decodeBuffer.decodeCachedValue(genericReply -> byte_data, 8, - serverCache -> genericReplyCharCache); - - #ifdef TEST - *logofs << name() << ": Decoded value " - << (unsigned int) genericReply -> byte_data - << " as byte_data field.\n" << logofs_flush; - #endif - - unsigned int value; - - for (unsigned int i = 0; i < 12; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *serverCache -> genericReplyIntCache[i]); - - genericReply -> short_data[i] = (unsigned short) value; - - #ifdef TEST - *logofs << name() << ": Decoded value " << genericReply -> short_data[i] - << " as short_data[" << i << "] field.\n" << logofs_flush; - #endif - } -} diff --git a/nxcomp/GenericReply.h b/nxcomp/GenericReply.h deleted file mode 100644 index e899b8467..000000000 --- a/nxcomp/GenericReply.h +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef GenericReply_H -#define GenericReply_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define GENERICREPLY_ENABLE_CACHE 1 -#define GENERICREPLY_ENABLE_DATA 1 -#define GENERICREPLY_ENABLE_SPLIT 0 - -#define GENERICREPLY_DATA_LIMIT 1048576 - 32 -#define GENERICREPLY_DATA_OFFSET 32 - -#define GENERICREPLY_CACHE_SLOTS 400 -#define GENERICREPLY_CACHE_THRESHOLD 5 -#define GENERICREPLY_CACHE_LOWER_THRESHOLD 1 - -#define GENERICREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -// -// The message class. -// - -class GenericReplyMessage : public Message -{ - friend class GenericReplyStore; - - public: - - GenericReplyMessage() - { - } - - ~GenericReplyMessage() - { - } - - // - // Put here the fields which constitute the - // 'identity' part of the message. Starting - // from protocol level 3 we use short data - // to increase cache efficiency. - // - - private: - - unsigned char byte_data; - unsigned int int_data[6]; - unsigned short short_data[12]; -}; - -class GenericReplyStore : public MessageStore -{ - public: - - GenericReplyStore(StaticCompressor *compressor); - - virtual ~GenericReplyStore(); - - virtual const char *name() const - { - return "GenericReply"; - } - - virtual unsigned char opcode() const - { - return X_NXInternalGenericReply; - } - - virtual unsigned int storage() const - { - return sizeof(GenericReplyMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new GenericReplyMessage(); - } - - virtual Message *create(const Message &message) const - { - return new GenericReplyMessage((const GenericReplyMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (GenericReplyMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* GenericReply_H */ diff --git a/nxcomp/GenericRequest.cpp b/nxcomp/GenericRequest.cpp deleted file mode 100644 index 5c342fcf7..000000000 --- a/nxcomp/GenericRequest.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "GenericRequest.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -GenericRequestStore::GenericRequestStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = GENERICREQUEST_ENABLE_CACHE; - enableData = GENERICREQUEST_ENABLE_DATA; - enableSplit = GENERICREQUEST_ENABLE_SPLIT; - - // Since ProtoStep7 (#issue 108) - enableCompress = GENERICREQUEST_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = GENERICREQUEST_DATA_LIMIT; - dataOffset = GENERICREQUEST_DATA_OFFSET; - - cacheSlots = GENERICREQUEST_CACHE_SLOTS; - cacheThreshold = GENERICREQUEST_CACHE_THRESHOLD; - cacheLowerThreshold = GENERICREQUEST_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -GenericRequestStore::~GenericRequestStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int GenericRequestStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; - #endif - - encodeBuffer.encodeValue(size >> 2, 16, 10); - - encodeBuffer.encodeCachedValue(*(buffer + 1), 8, - clientCache -> genericRequestOpcodeCache); - - for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) - { - #ifdef DEBUG - *logofs << name() << ": Encoding data[" << i << "] " - << "at position " << i * 2 + 4 << " with value " - << GetUINT(buffer + (i * 2) + 4, bigEndian) - << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(GetUINT(buffer + (i * 2) + 4, bigEndian), 16, - *clientCache -> genericRequestDataCache[i]); - } - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int GenericRequestStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; - #endif - - decodeBuffer.decodeValue(size, 16, 10); - - size <<= 2; - - buffer = writeBuffer -> addMessage(size); - - decodeBuffer.decodeCachedValue(*(buffer + 1), 8, - clientCache -> genericRequestOpcodeCache); - - unsigned int value; - - for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache -> genericRequestDataCache[i]); - - #ifdef DEBUG - *logofs << name() << ": Decoding data[" << i << "] " - << "at position " << i * 2 + 4 << " with value " - << value << ".\n" << logofs_flush; - #endif - - PutUINT(value, buffer + 4 + (i * 2), bigEndian); - } - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int GenericRequestStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; - - genericRequest -> opcode = *(buffer + 1); - - for (unsigned int i = 0; i < 8; i++) - { - if ((i * 2 + 4) < size) - { - genericRequest -> data[i] = GetUINT(buffer + i * 2 + 4, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed data[" << i << "] " - << "with value " << genericRequest -> data[i] - << ".\n" << logofs_flush; - #endif - } - else - { - genericRequest -> data[i] = 0; - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int GenericRequestStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; - - *(buffer + 1) = genericRequest -> opcode; - - for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) - { - #ifdef DEBUG - *logofs << name() << ": Unparsed data[" << i << "] " - << "with value " << genericRequest -> data[i] - << ".\n" << logofs_flush; - #endif - - PutUINT(genericRequest -> data[i], buffer + i * 2 + 4, bigEndian); - } - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void GenericRequestStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; - - *logofs << name() << ": Identity opcode " << (unsigned) genericRequest -> opcode; - - for (int i = 0; i < 8; i++) - { - *logofs << ", data[" << i << "] " << genericRequest -> data[i]; - } - - *logofs << ", size " << genericRequest -> size_ << ".\n" << logofs_flush; - - #endif -} - -void GenericRequestStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // As data offset can be beyond the real end of - // the message, we need to include the message's - // size or we will match any message whose size - // is less or equal to the data offset. - // - - md5_append(md5_state_, buffer + 2, 2); -} - -void GenericRequestStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - // - // Encode the variant part. - // - - GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; - GenericRequestMessage *cachedGenericRequest = (GenericRequestMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Updating value " - << (unsigned) genericRequest -> opcode - << " as opcode field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue((unsigned int) genericRequest -> opcode, 8, - clientCache -> genericRequestOpcodeCache); - - cachedGenericRequest -> opcode = genericRequest -> opcode; - - for (int i = 0; i < 8 && (i * 2 + 4) < genericRequest -> size_; i++) - { - #ifdef TEST - *logofs << name() << ": Updating data[" << i << "] " - << "with value " << genericRequest -> data[i] - << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue((unsigned int) genericRequest -> data[i], 16, - *clientCache -> genericRequestDataCache[i]); - - cachedGenericRequest -> data[i] = genericRequest -> data[i]; - } -} - -void GenericRequestStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(genericRequest -> opcode, 8, - clientCache -> genericRequestOpcodeCache); - - #ifdef TEST - *logofs << name() << ": Updated value " - << (unsigned) genericRequest -> opcode - << " as opcode field.\n" << logofs_flush; - #endif - - unsigned int value; - - for (int i = 0; i < 8 && (i * 2 + 4) < genericRequest -> size_; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache -> genericRequestDataCache[i]); - - genericRequest -> data[i] = (unsigned short) value; - - #ifdef TEST - *logofs << name() << ": Updated data[" << i << "] " - << "with value " << genericRequest -> data[i] - << ".\n" << logofs_flush; - #endif - } -} diff --git a/nxcomp/GenericRequest.h b/nxcomp/GenericRequest.h deleted file mode 100644 index 13ffea718..000000000 --- a/nxcomp/GenericRequest.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef GenericRequest_H -#define GenericRequest_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define GENERICREQUEST_ENABLE_CACHE 1 -#define GENERICREQUEST_ENABLE_DATA 1 -#define GENERICREQUEST_ENABLE_SPLIT 0 - -#define GENERICREQUEST_DATA_LIMIT 262144 - 20 -#define GENERICREQUEST_DATA_OFFSET 20 - -#define GENERICREQUEST_CACHE_SLOTS 400 -#define GENERICREQUEST_CACHE_THRESHOLD 5 -#define GENERICREQUEST_CACHE_LOWER_THRESHOLD 1 - -#define GENERICREQUEST_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -// -// The message class. -// - -class GenericRequestMessage : public Message -{ - friend class GenericRequestStore; - - public: - - GenericRequestMessage() - { - } - - ~GenericRequestMessage() - { - } - - // - // Note that we consider for this message a data offset - // of 4 (or 20 starting from protocol 3). Bytes from 9 - // to 20, if present, are taken as part of identity and - // encoded through an array of int caches. - // - - private: - - unsigned char opcode; - unsigned short data[8]; -}; - -class GenericRequestStore : public MessageStore -{ - public: - - GenericRequestStore(StaticCompressor *compressor); - - virtual ~GenericRequestStore(); - - virtual const char *name() const - { - return "GenericRequest"; - } - - virtual unsigned char opcode() const - { - return X_NXInternalGenericRequest; - } - - virtual unsigned int storage() const - { - return sizeof(GenericRequestMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new GenericRequestMessage(); - } - - virtual Message *create(const Message &message) const - { - return new GenericRequestMessage((const GenericRequestMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (GenericRequestMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* GenericRequest_H */ diff --git a/nxcomp/GetImage.cpp b/nxcomp/GetImage.cpp deleted file mode 100644 index f6481b61c..000000000 --- a/nxcomp/GetImage.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "GetImage.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int GetImageStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GetImageMessage *getImage = (GetImageMessage *) message; - - // - // Here is the fingerprint. - // - - getImage -> format = *(buffer + 1); - - #ifdef TEST - if (getImage -> format != 1 && getImage -> format != 2) - { - *logofs << name() << ": WARNING! Dirty value " << getImage -> format - << " for field format.\n" << logofs_flush; - } - #endif - - getImage -> drawable = GetULONG(buffer + 4, bigEndian); - - getImage -> x = GetUINT(buffer + 8, bigEndian); - getImage -> y = GetUINT(buffer + 10, bigEndian); - getImage -> width = GetUINT(buffer + 12, bigEndian); - getImage -> height = GetUINT(buffer + 14, bigEndian); - - getImage -> plane_mask = GetULONG(buffer + 16, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int GetImageStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GetImageMessage *getImage = (GetImageMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = getImage -> format; - - PutULONG(getImage -> drawable, buffer + 4, bigEndian); - - PutUINT(getImage -> x, buffer + 8, bigEndian); - PutUINT(getImage -> y, buffer + 10, bigEndian); - PutUINT(getImage -> width, buffer + 12, bigEndian); - PutUINT(getImage -> height, buffer + 14, bigEndian); - - PutULONG(getImage -> plane_mask, buffer + 16, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void GetImageStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - GetImageMessage *getImage = (GetImageMessage *) message; - - *logofs << name() << ": Identity format " << (unsigned) getImage -> format - << ", drawable " << getImage -> drawable << ", x " << getImage -> x - << ", y " << getImage -> y << ", width " << getImage -> width - << ", height " << getImage -> height << ", plane_mask " - << getImage -> plane_mask << ", size " << getImage -> size_ - << ".\n" << logofs_flush; - - #endif -} - -void GetImageStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 8, 2); - md5_append(md5_state_, buffer + 10, 2); - md5_append(md5_state_, buffer + 12, 2); - md5_append(md5_state_, buffer + 14, 2); - md5_append(md5_state_, buffer + 16, 4); -} - -void GetImageStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - GetImageMessage *getImage = (GetImageMessage *) message; - GetImageMessage *cachedGetImage = (GetImageMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << getImage -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(getImage -> drawable, clientCache -> drawableCache); - - cachedGetImage -> drawable = getImage -> drawable; -} - -void GetImageStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - GetImageMessage *getImage = (GetImageMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - getImage -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << getImage -> drawable - << " as drawable field.\n" << logofs_flush; - #endif -} - diff --git a/nxcomp/GetImage.h b/nxcomp/GetImage.h deleted file mode 100644 index 1c3558d14..000000000 --- a/nxcomp/GetImage.h +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef GetImage_H -#define GetImage_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define GETIMAGE_ENABLE_CACHE 1 -#define GETIMAGE_ENABLE_DATA 0 -#define GETIMAGE_ENABLE_SPLIT 0 -#define GETIMAGE_ENABLE_COMPRESS 0 - -#define GETIMAGE_DATA_LIMIT 0 -#define GETIMAGE_DATA_OFFSET 20 - -#define GETIMAGE_CACHE_SLOTS 200 -#define GETIMAGE_CACHE_THRESHOLD 1 -#define GETIMAGE_CACHE_LOWER_THRESHOLD 0 - -// -// The message class. -// - -class GetImageMessage : public Message -{ - friend class GetImageStore; - - public: - - GetImageMessage() - { - } - - ~GetImageMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char format; - unsigned int drawable; - unsigned short int x; - unsigned short int y; - unsigned short int width; - unsigned short int height; - unsigned int plane_mask; -}; - -class GetImageStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - GetImageStore() : MessageStore() - { - enableCache = GETIMAGE_ENABLE_CACHE; - enableData = GETIMAGE_ENABLE_DATA; - enableSplit = GETIMAGE_ENABLE_SPLIT; - enableCompress = GETIMAGE_ENABLE_COMPRESS; - - dataLimit = GETIMAGE_DATA_LIMIT; - dataOffset = GETIMAGE_DATA_OFFSET; - - cacheSlots = GETIMAGE_CACHE_SLOTS; - cacheThreshold = GETIMAGE_CACHE_THRESHOLD; - cacheLowerThreshold = GETIMAGE_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~GetImageStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "GetImage"; - } - - virtual unsigned char opcode() const - { - return X_GetImage; - } - - virtual unsigned int storage() const - { - return sizeof(GetImageMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new GetImageMessage(); - } - - virtual Message *create(const Message &message) const - { - return new GetImageMessage((const GetImageMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (GetImageMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* GetImage_H */ diff --git a/nxcomp/GetImageReply.cpp b/nxcomp/GetImageReply.cpp deleted file mode 100644 index 9b99d38e7..000000000 --- a/nxcomp/GetImageReply.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "GetImageReply.h" - -#include "ServerCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -GetImageReplyStore::GetImageReplyStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = GETIMAGEREPLY_ENABLE_CACHE; - enableData = GETIMAGEREPLY_ENABLE_DATA; - enableSplit = GETIMAGEREPLY_ENABLE_SPLIT; - - // Since ProtoStep7 (#issue 108) - enableCompress = GETIMAGEREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = GETIMAGEREPLY_DATA_LIMIT; - dataOffset = GETIMAGEREPLY_DATA_OFFSET; - - cacheSlots = GETIMAGEREPLY_CACHE_SLOTS; - cacheThreshold = GETIMAGEREPLY_CACHE_THRESHOLD; - cacheLowerThreshold = GETIMAGEREPLY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -GetImageReplyStore::~GetImageReplyStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int GetImageReplyStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; - - // - // Here is the fingerprint. - // - - getImageReply -> depth = *(buffer + 1); - - getImageReply -> visual = GetULONG(buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int GetImageReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = getImageReply -> depth; - - PutULONG(getImageReply -> visual, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void GetImageReplyStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; - - *logofs << name() << ": Identity depth " << (unsigned) getImageReply -> depth - << ", visual " << getImageReply -> visual << ", size " - << getImageReply -> size_ << ".\n"; - - #endif -} - -void GetImageReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Field depth. - // - - md5_append(md5_state_, buffer + 1, 1); -} - -void GetImageReplyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - // - // Encode the variant part. - // - - GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; - - ServerCache *serverCache = (ServerCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << getImageReply -> visual - << " as visual field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(getImageReply -> visual, 29, - serverCache -> visualCache); -} - -void GetImageReplyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - // - // Decode the variant part. - // - - GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; - - ServerCache *serverCache = (ServerCache *) channelCache; - - decodeBuffer.decodeCachedValue(getImageReply -> visual, 29, - serverCache -> visualCache); -} diff --git a/nxcomp/GetImageReply.h b/nxcomp/GetImageReply.h deleted file mode 100644 index d4f7c4267..000000000 --- a/nxcomp/GetImageReply.h +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef GetImageReply_H -#define GetImageReply_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define GETIMAGEREPLY_ENABLE_CACHE 1 -#define GETIMAGEREPLY_ENABLE_DATA 1 -#define GETIMAGEREPLY_ENABLE_SPLIT 0 - -#define GETIMAGEREPLY_DATA_LIMIT 1048576 - 32 -#define GETIMAGEREPLY_DATA_OFFSET 32 - -#define GETIMAGEREPLY_CACHE_SLOTS 1000 -#define GETIMAGEREPLY_CACHE_THRESHOLD 20 -#define GETIMAGEREPLY_CACHE_LOWER_THRESHOLD 2 - -#define GETIMAGEREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -// -// The message class. -// - -class GetImageReplyMessage : public Message -{ - friend class GetImageReplyStore; - - public: - - GetImageReplyMessage() - { - } - - ~GetImageReplyMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char depth; - unsigned int visual; -}; - -class GetImageReplyStore : public MessageStore -{ - public: - - GetImageReplyStore(StaticCompressor *compressor); - - virtual ~GetImageReplyStore(); - - virtual const char *name() const - { - return "GetImageReply"; - } - - virtual unsigned char opcode() const - { - return X_GetImage; - } - - virtual unsigned int storage() const - { - return sizeof(GetImageReplyMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new GetImageReplyMessage(); - } - - virtual Message *create(const Message &message) const - { - return new GetImageReplyMessage((const GetImageReplyMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (GetImageReplyMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* GetImageReply_H */ diff --git a/nxcomp/GetProperty.cpp b/nxcomp/GetProperty.cpp deleted file mode 100644 index a79ebd64a..000000000 --- a/nxcomp/GetProperty.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "GetProperty.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int GetPropertyStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GetPropertyMessage *getProperty = (GetPropertyMessage *) message; - - // - // Here is the fingerprint. - // - - getProperty -> property_delete = *(buffer + 1); - - getProperty -> window = GetULONG(buffer + 4, bigEndian); - getProperty -> property = GetULONG(buffer + 8, bigEndian); - getProperty -> type = GetULONG(buffer + 12, bigEndian); - getProperty -> long_offset = GetULONG(buffer + 16, bigEndian); - getProperty -> long_length = GetULONG(buffer + 20, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int GetPropertyStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - - GetPropertyMessage *getProperty = (GetPropertyMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = getProperty -> property_delete; - - PutULONG(getProperty -> window, buffer + 4, bigEndian); - PutULONG(getProperty -> property, buffer + 8, bigEndian); - PutULONG(getProperty -> type, buffer + 12, bigEndian); - PutULONG(getProperty -> long_offset, buffer + 16, bigEndian); - PutULONG(getProperty -> long_length, buffer + 20, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void GetPropertyStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - GetPropertyMessage *getProperty = (GetPropertyMessage *) message; - - *logofs << name() << ": Identity property_delete " << (unsigned int) getProperty -> property_delete - << ", window " << getProperty -> window << ", property " << getProperty -> property - << ", type " << getProperty -> type << ", long-offset " << getProperty -> long_offset - << ", long-length " << getProperty -> long_length << ".\n" << logofs_flush; - - #endif -} - -void GetPropertyStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 4, 20); -} diff --git a/nxcomp/GetProperty.h b/nxcomp/GetProperty.h deleted file mode 100644 index 46727280b..000000000 --- a/nxcomp/GetProperty.h +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef GetProperty_H -#define GetProperty_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define GETPROPERTY_ENABLE_CACHE 1 -#define GETPROPERTY_ENABLE_DATA 0 -#define GETPROPERTY_ENABLE_SPLIT 0 -#define GETPROPERTY_ENABLE_COMPRESS 0 - -#define GETPROPERTY_DATA_LIMIT 0 -#define GETPROPERTY_DATA_OFFSET 24 - -#define GETPROPERTY_CACHE_SLOTS 2000 -#define GETPROPERTY_CACHE_THRESHOLD 2 -#define GETPROPERTY_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class GetPropertyMessage : public Message -{ - friend class GetPropertyStore; - - public: - - GetPropertyMessage() - { - } - - ~GetPropertyMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char property_delete; - unsigned long window; - unsigned long property; - unsigned long type; - unsigned long long_offset; - unsigned long long_length; -}; - -class GetPropertyStore : public MessageStore -{ - - // - // Constructors and destructors. - // - - public: - - GetPropertyStore() : MessageStore() - { - enableCache = GETPROPERTY_ENABLE_CACHE; - enableData = GETPROPERTY_ENABLE_DATA; - enableSplit = GETPROPERTY_ENABLE_SPLIT; - enableCompress = GETPROPERTY_ENABLE_COMPRESS; - - dataLimit = GETPROPERTY_DATA_LIMIT; - dataOffset = GETPROPERTY_DATA_OFFSET; - - cacheSlots = GETPROPERTY_CACHE_SLOTS; - cacheThreshold = GETPROPERTY_CACHE_THRESHOLD; - cacheLowerThreshold = GETPROPERTY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~GetPropertyStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "GetProperty"; - } - - virtual unsigned char opcode() const - { - return X_GetProperty; - } - - virtual unsigned int storage() const - { - return sizeof(GetPropertyMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new GetPropertyMessage(); - } - - virtual Message *create(const Message &message) const - { - return new GetPropertyMessage((const GetPropertyMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (GetPropertyMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* GetProperty_H */ diff --git a/nxcomp/GetPropertyReply.cpp b/nxcomp/GetPropertyReply.cpp deleted file mode 100644 index 2d0657a4a..000000000 --- a/nxcomp/GetPropertyReply.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "GetPropertyReply.h" - -#include "ServerCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -GetPropertyReplyStore::GetPropertyReplyStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = GETPROPERTYREPLY_ENABLE_CACHE; - enableData = GETPROPERTYREPLY_ENABLE_DATA; - enableSplit = GETPROPERTYREPLY_ENABLE_SPLIT; - - // Since ProtoStep7 (#issue 108) - enableCompress = GETPROPERTYREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = GETPROPERTYREPLY_DATA_LIMIT; - dataOffset = GETPROPERTYREPLY_DATA_OFFSET; - - cacheSlots = GETPROPERTYREPLY_CACHE_SLOTS; - cacheThreshold = GETPROPERTYREPLY_CACHE_THRESHOLD; - cacheLowerThreshold = GETPROPERTYREPLY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -GetPropertyReplyStore::~GetPropertyReplyStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int GetPropertyReplyStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ServerCache *serverCache = (ServerCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" - << logofs_flush; - #endif - - unsigned char format = (unsigned int) *(buffer + 1); - - encodeBuffer.encodeCachedValue(format, 8, - serverCache -> getPropertyFormatCache); - - unsigned int numBytes = GetULONG(buffer + 16, bigEndian); - - encodeBuffer.encodeValue(numBytes, 32, 9); - - if (format == 16) - { - numBytes <<= 1; - } - else if (format == 32) - { - numBytes <<= 2; - } - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 8, bigEndian), 29, - serverCache -> getPropertyTypeCache, 9); - - encodeBuffer.encodeValue(GetULONG(buffer + 12, bigEndian), 32, 9); - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" - << logofs_flush; - #endif - - return 1; -} - -int GetPropertyReplyStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ServerCache *serverCache = (ServerCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" - << logofs_flush; - #endif - - unsigned char format; - - decodeBuffer.decodeCachedValue(format, 8, - serverCache -> getPropertyFormatCache); - - unsigned int length; - - decodeBuffer.decodeValue(length, 32, 9); - - unsigned int numBytes = length; - - if (format == 16) - { - numBytes <<= 1; - } - else if (format == 32) - { - numBytes <<= 2; - } - - size = 32 + RoundUp4(numBytes); - - buffer = writeBuffer -> addMessage(size); - - *(buffer + 1) = format; - - PutULONG(length, buffer + 16, bigEndian); - - unsigned int value; - - decodeBuffer.decodeCachedValue(value, 29, - serverCache -> getPropertyTypeCache, 9); - - PutULONG(value, buffer + 8, bigEndian); - - decodeBuffer.decodeValue(value, 32, 9); - - PutULONG(value, buffer + 12, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" - << logofs_flush; - #endif - - return 1; -} - -int GetPropertyReplyStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GetPropertyReplyMessage *getPropertyReply = (GetPropertyReplyMessage *) message; - - getPropertyReply -> format = *(buffer + 1); - - getPropertyReply -> type = GetULONG(buffer + 8, bigEndian); - getPropertyReply -> after = GetULONG(buffer + 12, bigEndian); - getPropertyReply -> items = GetULONG(buffer + 16, bigEndian); - - // - // Cleanup the padding bytes. - // - - unsigned int uiLengthInBytes; - unsigned int uiFormat; - - if ((int) size > GETPROPERTYREPLY_DATA_OFFSET) - { - uiLengthInBytes = getPropertyReply -> items; - - uiFormat = *(buffer + 1); - - #ifdef DEBUG - *logofs << name() << ": length " << uiLengthInBytes - << ", format " << uiFormat << ", size " - << size << ".\n" << logofs_flush; - #endif - - if (uiFormat == 16) - { - uiLengthInBytes <<= 1; - } - else if (uiFormat == 32) - { - uiLengthInBytes <<= 2; - } - - unsigned char *end = ((unsigned char *) buffer) + size; - unsigned char *pad = ((unsigned char *) buffer) + GETPROPERTYREPLY_DATA_OFFSET + uiLengthInBytes; - - CleanData((unsigned char *) pad, end - pad); - } - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int GetPropertyReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - GetPropertyReplyMessage *getPropertyReply = (GetPropertyReplyMessage *) message; - - *(buffer + 1) = getPropertyReply -> format; - - PutULONG(getPropertyReply -> type, buffer + 8, bigEndian); - PutULONG(getPropertyReply -> after, buffer + 12, bigEndian); - PutULONG(getPropertyReply -> items, buffer + 16, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void GetPropertyReplyStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - GetPropertyReplyMessage *getPropertyReply = (GetPropertyReplyMessage *) message; - - *logofs << name() << ": Identity format " - << (unsigned) getPropertyReply -> format << ", type " - << getPropertyReply -> type << ", after " << getPropertyReply -> after - << ", items " << getPropertyReply -> items << ", size " - << getPropertyReply -> size_ << ".\n"; - - #endif -} - -void GetPropertyReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Fields format, type, after, items. - // - - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 8, 12); -} - -void GetPropertyReplyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ -} - -void GetPropertyReplyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ -} diff --git a/nxcomp/GetPropertyReply.h b/nxcomp/GetPropertyReply.h deleted file mode 100644 index 01634b408..000000000 --- a/nxcomp/GetPropertyReply.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef GetPropertyReply_H -#define GetPropertyReply_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define GETPROPERTYREPLY_ENABLE_CACHE 1 -#define GETPROPERTYREPLY_ENABLE_DATA 1 -#define GETPROPERTYREPLY_ENABLE_SPLIT 0 - -#define GETPROPERTYREPLY_DATA_LIMIT 1048576 - 32 -#define GETPROPERTYREPLY_DATA_OFFSET 32 - -#define GETPROPERTYREPLY_CACHE_SLOTS 400 -#define GETPROPERTYREPLY_CACHE_THRESHOLD 5 -#define GETPROPERTYREPLY_CACHE_LOWER_THRESHOLD 1 - -#define GETPROPERTYREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -// -// The message class. -// - -class GetPropertyReplyMessage : public Message -{ - friend class GetPropertyReplyStore; - - public: - - GetPropertyReplyMessage() - { - } - - ~GetPropertyReplyMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char format; - unsigned int type; - unsigned int after; - unsigned int items; -}; - -class GetPropertyReplyStore : public MessageStore -{ - public: - - GetPropertyReplyStore(StaticCompressor *compressor); - - virtual ~GetPropertyReplyStore(); - - virtual const char *name() const - { - return "GetPropertyReply"; - } - - virtual unsigned char opcode() const - { - return X_GetProperty; - } - - virtual unsigned int storage() const - { - return sizeof(GetPropertyReplyMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new GetPropertyReplyMessage(); - } - - virtual Message *create(const Message &message) const - { - return new GetPropertyReplyMessage((const GetPropertyReplyMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (GetPropertyReplyMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* GetPropertyReply_H */ diff --git a/nxcomp/ImageText16.cpp b/nxcomp/ImageText16.cpp deleted file mode 100644 index f3315d4ba..000000000 --- a/nxcomp/ImageText16.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ImageText16.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int ImageText16Store::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ImageText16Message *imageText16 = (ImageText16Message *) message; - - // - // Here is the fingerprint. - // - - imageText16 -> len = *(buffer + 1); - - imageText16 -> drawable = GetULONG(buffer + 4, bigEndian); - imageText16 -> gcontext = GetULONG(buffer + 8, bigEndian); - - imageText16 -> x = GetUINT(buffer + 12, bigEndian); - imageText16 -> y = GetUINT(buffer + 14, bigEndian); - - if ((int) size > dataOffset) - { - int pad = (size - dataOffset) - (imageText16 -> len * 2); - - if (pad > 0) - { - CleanData((unsigned char *) buffer + size - pad, pad); - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ImageText16Store::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ImageText16Message *imageText16 = (ImageText16Message *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = imageText16 -> len; - - PutULONG(imageText16 -> drawable, buffer + 4, bigEndian); - PutULONG(imageText16 -> gcontext, buffer + 8, bigEndian); - - PutUINT(imageText16 -> x, buffer + 12, bigEndian); - PutUINT(imageText16 -> y, buffer + 14, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void ImageText16Store::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - ImageText16Message *imageText16 = (ImageText16Message *) message; - - *logofs << name() << ": Identity len " << (unsigned int) imageText16 -> len - << " drawable " << imageText16 -> drawable << ", gcontext " - << imageText16 -> gcontext << ", x " << imageText16 -> x << ", y " - << imageText16 -> y << ", size " << imageText16 -> size_ << ".\n"; - - #endif -} - -void ImageText16Store::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); -} - -void ImageText16Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - ImageText16Message *imageText16 = (ImageText16Message *) message; - ImageText16Message *cachedImageText16 = (ImageText16Message *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << imageText16 -> drawable - << " as " << "drawable" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(imageText16 -> drawable, clientCache -> drawableCache); - - cachedImageText16 -> drawable = imageText16 -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << imageText16 -> gcontext - << " as " << "gcontext" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(imageText16 -> gcontext, clientCache -> gcCache); - - cachedImageText16 -> gcontext = imageText16 -> gcontext; - - #ifdef TEST - *logofs << name() << ": Encoding value " << imageText16 -> x - << " as " << "x" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_x = imageText16 -> x - cachedImageText16 -> x; - - encodeBuffer.encodeCachedValue(diff_x, 16, - clientCache -> imageTextCacheX); - - cachedImageText16 -> x = imageText16 -> x; - - #ifdef TEST - *logofs << name() << ": Encoding value " << imageText16 -> y - << " as " << "y" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_y = imageText16 -> y - cachedImageText16 -> y; - - encodeBuffer.encodeCachedValue(diff_y, 16, - clientCache -> imageTextCacheY); - - cachedImageText16 -> y = imageText16 -> y; -} - -void ImageText16Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - ImageText16Message *imageText16 = (ImageText16Message *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - imageText16 -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << imageText16 -> drawable - << " as " << "drawable" << " field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - imageText16 -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << imageText16 -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> imageTextCacheX); - - imageText16 -> x += value; - imageText16 -> x &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << imageText16 -> x - << " as x field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> imageTextCacheY); - - imageText16 -> y += value; - imageText16 -> y &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << imageText16 -> y - << " as y field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/ImageText16.h b/nxcomp/ImageText16.h deleted file mode 100644 index 98462ab35..000000000 --- a/nxcomp/ImageText16.h +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ImageText16_H -#define ImageText16_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define IMAGETEXT16_ENABLE_CACHE 1 -#define IMAGETEXT16_ENABLE_DATA 0 -#define IMAGETEXT16_ENABLE_SPLIT 0 -#define IMAGETEXT16_ENABLE_COMPRESS 0 - -#define IMAGETEXT16_DATA_LIMIT 512 -#define IMAGETEXT16_DATA_OFFSET 16 - -#define IMAGETEXT16_CACHE_SLOTS 3000 -#define IMAGETEXT16_CACHE_THRESHOLD 5 -#define IMAGETEXT16_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class ImageText16Message : public Message -{ - friend class ImageText16Store; - - public: - - ImageText16Message() - { - } - - ~ImageText16Message() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char len; - - unsigned int drawable; - unsigned int gcontext; - - unsigned short x; - unsigned short y; -}; - -class ImageText16Store : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - ImageText16Store() : MessageStore() - { - enableCache = IMAGETEXT16_ENABLE_CACHE; - enableData = IMAGETEXT16_ENABLE_DATA; - enableSplit = IMAGETEXT16_ENABLE_SPLIT; - enableCompress = IMAGETEXT16_ENABLE_COMPRESS; - - dataLimit = IMAGETEXT16_DATA_LIMIT; - dataOffset = IMAGETEXT16_DATA_OFFSET; - - cacheSlots = IMAGETEXT16_CACHE_SLOTS; - cacheThreshold = IMAGETEXT16_CACHE_THRESHOLD; - cacheLowerThreshold = IMAGETEXT16_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~ImageText16Store() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "ImageText16"; - } - - virtual unsigned char opcode() const - { - return X_ImageText16; - } - - virtual unsigned int storage() const - { - return sizeof(ImageText16Message); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new ImageText16Message(); - } - - virtual Message *create(const Message &message) const - { - return new ImageText16Message((const ImageText16Message &) message); - } - - virtual void destroy(Message *message) const - { - delete (ImageText16Message *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* ImageText16_H */ diff --git a/nxcomp/ImageText8.cpp b/nxcomp/ImageText8.cpp deleted file mode 100644 index b0d6ac44e..000000000 --- a/nxcomp/ImageText8.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ImageText8.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int ImageText8Store::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ImageText8Message *imageText8 = (ImageText8Message *) message; - - // - // Here is the fingerprint. - // - - imageText8 -> len = *(buffer + 1); - - imageText8 -> drawable = GetULONG(buffer + 4, bigEndian); - imageText8 -> gcontext = GetULONG(buffer + 8, bigEndian); - - imageText8 -> x = GetUINT(buffer + 12, bigEndian); - imageText8 -> y = GetUINT(buffer + 14, bigEndian); - - if ((int) size > dataOffset) - { - int pad = (size - dataOffset) - imageText8 -> len; - - if (pad > 0) - { - CleanData((unsigned char *) buffer + size - pad, pad); - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ImageText8Store::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ImageText8Message *imageText8 = (ImageText8Message *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = imageText8 -> len; - - PutULONG(imageText8 -> drawable, buffer + 4, bigEndian); - PutULONG(imageText8 -> gcontext, buffer + 8, bigEndian); - - PutUINT(imageText8 -> x, buffer + 12, bigEndian); - PutUINT(imageText8 -> y, buffer + 14, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void ImageText8Store::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - ImageText8Message *imageText8 = (ImageText8Message *) message; - - *logofs << name() << ": Identity len " << (unsigned int) imageText8 -> len - << " drawable " << imageText8 -> drawable << ", gcontext " - << imageText8 -> gcontext << ", x " << imageText8 -> x << ", y " - << imageText8 -> y << ", size " << imageText8 -> size_ << ".\n"; - - #endif -} - -void ImageText8Store::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); -} - -void ImageText8Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - ImageText8Message *imageText8 = (ImageText8Message *) message; - ImageText8Message *cachedImageText8 = (ImageText8Message *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << imageText8 -> drawable - << " as " << "drawable" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(imageText8 -> drawable, clientCache -> drawableCache); - - cachedImageText8 -> drawable = imageText8 -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << imageText8 -> gcontext - << " as " << "gcontext" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(imageText8 -> gcontext, clientCache -> gcCache); - - cachedImageText8 -> gcontext = imageText8 -> gcontext; - - #ifdef TEST - *logofs << name() << ": Encoding value " << imageText8 -> x - << " as " << "x" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_x = imageText8 -> x - cachedImageText8 -> x; - - encodeBuffer.encodeCachedValue(diff_x, 16, - clientCache -> imageTextCacheX); - - cachedImageText8 -> x = imageText8 -> x; - - #ifdef TEST - *logofs << name() << ": Encoding value " << imageText8 -> y - << " as " << "y" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_y = imageText8 -> y - cachedImageText8 -> y; - - encodeBuffer.encodeCachedValue(diff_y, 16, - clientCache -> imageTextCacheY); - - cachedImageText8 -> y = imageText8 -> y; -} - -void ImageText8Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - ImageText8Message *imageText8 = (ImageText8Message *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - imageText8 -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << imageText8 -> drawable - << " as " << "drawable" << " field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - imageText8 -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << imageText8 -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> imageTextCacheX); - - imageText8 -> x += value; - imageText8 -> x &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << imageText8 -> x - << " as x field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> imageTextCacheY); - - imageText8 -> y += value; - imageText8 -> y &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << imageText8 -> y - << " as y field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/ImageText8.h b/nxcomp/ImageText8.h deleted file mode 100644 index aa9ccb5d9..000000000 --- a/nxcomp/ImageText8.h +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ImageText8_H -#define ImageText8_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define IMAGETEXT8_ENABLE_CACHE 1 -#define IMAGETEXT8_ENABLE_DATA 0 -#define IMAGETEXT8_ENABLE_SPLIT 0 -#define IMAGETEXT8_ENABLE_COMPRESS 0 - -#define IMAGETEXT8_DATA_LIMIT 256 -#define IMAGETEXT8_DATA_OFFSET 16 - -#define IMAGETEXT8_CACHE_SLOTS 3000 -#define IMAGETEXT8_CACHE_THRESHOLD 5 -#define IMAGETEXT8_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class ImageText8Message : public Message -{ - friend class ImageText8Store; - - public: - - ImageText8Message() - { - } - - ~ImageText8Message() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char len; - - unsigned int drawable; - unsigned int gcontext; - - unsigned short x; - unsigned short y; -}; - -class ImageText8Store : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - ImageText8Store() : MessageStore() - { - enableCache = IMAGETEXT8_ENABLE_CACHE; - enableData = IMAGETEXT8_ENABLE_DATA; - enableSplit = IMAGETEXT8_ENABLE_SPLIT; - enableCompress = IMAGETEXT8_ENABLE_COMPRESS; - - dataLimit = IMAGETEXT8_DATA_LIMIT; - dataOffset = IMAGETEXT8_DATA_OFFSET; - - cacheSlots = IMAGETEXT8_CACHE_SLOTS; - cacheThreshold = IMAGETEXT8_CACHE_THRESHOLD; - cacheLowerThreshold = IMAGETEXT8_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~ImageText8Store() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "ImageText8"; - } - - virtual unsigned char opcode() const - { - return X_ImageText8; - } - - virtual unsigned int storage() const - { - return sizeof(ImageText8Message); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new ImageText8Message(); - } - - virtual Message *create(const Message &message) const - { - return new ImageText8Message((const ImageText8Message &) message); - } - - virtual void destroy(Message *message) const - { - delete (ImageText8Message *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* ImageText8_H */ diff --git a/nxcomp/IntCache.cpp b/nxcomp/IntCache.cpp deleted file mode 100644 index 362412182..000000000 --- a/nxcomp/IntCache.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include - -#include "Misc.h" -#include "IntCache.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -IntCache::IntCache(unsigned int size) - - : size_(size), length_(0), buffer_(new unsigned int[size]), - lastDiff_(0), lastValueInserted_(0), predictedBlockSize_(0) -{ -} - -int IntCache::lookup(unsigned int &value, unsigned int &index, - unsigned int mask, unsigned int &sameDiff) -{ - for (unsigned int i = 0; i < length_; i++) - { - if (value == buffer_[i]) - { - index = i; - if (i) - { - unsigned int target = (i >> 1); - do - { - buffer_[i] = buffer_[i - 1]; - i--; - } - while (i > target); - buffer_[target] = value; - } - return 1; - } - } - unsigned int insertionPoint; - if (2 >= length_) - insertionPoint = length_; - else - insertionPoint = 2; - unsigned int start; - if (length_ >= size_) - start = size_ - 1; - else - { - start = length_; - length_++; - } - for (unsigned int k = start; k > insertionPoint; k--) - buffer_[k] = buffer_[k - 1]; - buffer_[insertionPoint] = value; - unsigned int diff = value - lastValueInserted_; - - lastValueInserted_ = (value & mask); - value = (diff & mask); - sameDiff = (value == lastDiff_); - if (!sameDiff) - { - lastDiff_ = value; - - unsigned int lastChangeIndex = 0; - unsigned int lastBitIsOne = (lastDiff_ & 0x1); - unsigned int j = 1; - for (unsigned int nextMask = 0x2; nextMask & mask; nextMask <<= 1) - { - unsigned int nextBitIsOne = (lastDiff_ & nextMask); - if (nextBitIsOne) - { - if (!lastBitIsOne) - { - lastChangeIndex = j; - lastBitIsOne = nextBitIsOne; - } - } - else - { - if (lastBitIsOne) - { - lastChangeIndex = j; - lastBitIsOne = nextBitIsOne; - } - } - j++; - } - predictedBlockSize_ = lastChangeIndex + 1; - if (predictedBlockSize_ < 2) - predictedBlockSize_ = 2; - } - return 0; -} - -void IntCache::insert(unsigned int &value, unsigned int mask) -{ - unsigned int insertionPoint; - if (2 >= length_) - insertionPoint = length_; - else - insertionPoint = 2; - unsigned int start; - if (length_ >= size_) - start = size_ - 1; - else - { - start = length_; - length_++; - } - for (unsigned int k = start; k > insertionPoint; k--) - buffer_[k] = buffer_[k - 1]; - if (lastDiff_ != value) - { - lastDiff_ = value; - unsigned int lastChangeIndex = 0; - unsigned int lastBitIsOne = (lastDiff_ & 0x1); - unsigned int j = 1; - for (unsigned int nextMask = 0x2; nextMask & mask; nextMask <<= 1) - { - unsigned int nextBitIsOne = (lastDiff_ & nextMask); - if (nextBitIsOne) - { - if (!lastBitIsOne) - { - lastChangeIndex = j; - lastBitIsOne = nextBitIsOne; - } - } - else - { - if (lastBitIsOne) - { - lastChangeIndex = j; - lastBitIsOne = nextBitIsOne; - } - } - j++; - } - predictedBlockSize_ = lastChangeIndex + 1; - if (predictedBlockSize_ < 2) - predictedBlockSize_ = 2; - } - lastValueInserted_ += value; - lastValueInserted_ &= mask; - buffer_[insertionPoint] = lastValueInserted_; - value = lastValueInserted_; -} - -void IntCache::push(unsigned int &value, unsigned int mask) -{ - // - // Using a memmove() appears to be slower. - // - // memmove((char *) &buffer_[1], (char *) &buffer_[0], - // sizeof(unsigned int) * (size_ - 1)); - // - // if (length_ < size_) - // { - // length_++; - // } - // - - unsigned int start; - - if (length_ >= size_) - { - start = size_ - 1; - } - else - { - start = length_; - - length_++; - } - - for (unsigned int k = start; k > 0; k--) - { - buffer_[k] = buffer_[k - 1]; - } - - value &= mask; - - buffer_[0] = value; -} - -void IntCache::dump() -{ - #ifdef DUMP - - *logofs << "IntCache: Dumping content of cache at " - << (void *) this << ":\n" << logofs_flush; - - for (unsigned int i = 0; i < length_; i++) - { - *logofs << "IntCache: [" << i << "][" << buffer_[i] << "]\n"; - } - - #endif -} diff --git a/nxcomp/IntCache.h b/nxcomp/IntCache.h deleted file mode 100644 index 69c522325..000000000 --- a/nxcomp/IntCache.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef IntCache_H -#define IntCache_H - -class IntCache -{ - public: - - IntCache(unsigned int size); - - ~IntCache() - { - delete [] buffer_; - } - - unsigned int getSize() const - { - return length_; - } - - int lookup(unsigned int &value, unsigned int &index, - unsigned int mask, unsigned int &sameDiff); - - // - // This can be inlined as it is only - // called by decodeCachedValue(). - // - - unsigned int get(unsigned int index) - { - unsigned int result = buffer_[index]; - - if (index != 0) - { - // - // Using a memmove() appears to be slower. - // - // unsigned int target = index >> 1; - // - // memmove((char *) &buffer_[target + 1], (char *) &buffer_[target], - // sizeof(unsigned int) * (index - target)); - // - // buffer_[target] = result; - // - - unsigned int i = index; - - unsigned int target = (i >> 1); - - do - { - buffer_[i] = buffer_[i - 1]; - - i--; - } - while (i > target); - - buffer_[target] = result; - } - - return result; - } - - void insert(unsigned int &value, unsigned int mask); - - void push(unsigned int &value, unsigned int mask); - - void dump(); - - unsigned int getLastDiff(unsigned int mask) const - { - return lastDiff_; - } - - unsigned int getBlockSize(unsigned int bits) const - { - if (bits > 0) - { - return (predictedBlockSize_ < bits ? predictedBlockSize_ : bits); - } - - return predictedBlockSize_; - } - - private: - - unsigned int size_; - unsigned int length_; - unsigned int *buffer_; - unsigned int lastDiff_; - unsigned int lastValueInserted_; - unsigned int predictedBlockSize_; -}; - -#endif /* IntCache_H */ diff --git a/nxcomp/InternAtom.cpp b/nxcomp/InternAtom.cpp deleted file mode 100644 index 760d72222..000000000 --- a/nxcomp/InternAtom.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "InternAtom.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int InternAtomStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - InternAtomMessage *internAtom = (InternAtomMessage *) message; - - // - // Here is the fingerprint. - // - - internAtom -> only_if_exists = *(buffer + 1); - internAtom -> name_length = GetUINT(buffer + 4, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - // - // Clean up padding bytes. - // - - if ((int) size > dataOffset) - { - unsigned char *end = ((unsigned char *) buffer) + size; - - for (unsigned char *pad = ((unsigned char *) buffer) + 8 + - internAtom -> name_length; pad < end; pad++) - { - *pad = 0; - } - } - - return 1; -} - -int InternAtomStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - InternAtomMessage *internAtom = (InternAtomMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = internAtom -> only_if_exists; - - PutUINT(internAtom -> name_length, buffer + 4, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void InternAtomStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - InternAtomMessage *internAtom = (InternAtomMessage *) message; - - *logofs << name() << ": Identity only_if_exists " - << (unsigned int) internAtom -> only_if_exists - << ", name_length " << internAtom -> name_length - << ", name '"; - - for (int i = 0; i < internAtom -> name_length; i++) - { - *logofs << internAtom -> data_[i]; - } - - *logofs << "'.\n" << logofs_flush; - - #endif -} - -void InternAtomStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 4, 2); -} diff --git a/nxcomp/InternAtom.h b/nxcomp/InternAtom.h deleted file mode 100644 index 6e69eca24..000000000 --- a/nxcomp/InternAtom.h +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef InternAtom_H -#define InternAtom_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define INTERNATOM_ENABLE_CACHE 1 -#define INTERNATOM_ENABLE_DATA 0 -#define INTERNATOM_ENABLE_SPLIT 0 -#define INTERNATOM_ENABLE_COMPRESS 0 - -#define INTERNATOM_DATA_LIMIT 80 -#define INTERNATOM_DATA_OFFSET 8 - -#define INTERNATOM_CACHE_SLOTS 2000 -#define INTERNATOM_CACHE_THRESHOLD 2 -#define INTERNATOM_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class InternAtomMessage : public Message -{ - friend class InternAtomStore; - - public: - - InternAtomMessage() - { - } - - ~InternAtomMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char only_if_exists; - unsigned short name_length; -}; - -class InternAtomStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - InternAtomStore() : MessageStore() - { - enableCache = INTERNATOM_ENABLE_CACHE; - enableData = INTERNATOM_ENABLE_DATA; - enableSplit = INTERNATOM_ENABLE_SPLIT; - enableCompress = INTERNATOM_ENABLE_COMPRESS; - - dataLimit = INTERNATOM_DATA_LIMIT; - dataOffset = INTERNATOM_DATA_OFFSET; - - cacheSlots = INTERNATOM_CACHE_SLOTS; - cacheThreshold = INTERNATOM_CACHE_THRESHOLD; - cacheLowerThreshold = INTERNATOM_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~InternAtomStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "InternAtom"; - } - - virtual unsigned char opcode() const - { - return X_InternAtom; - } - - virtual unsigned int storage() const - { - return sizeof(InternAtomMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new InternAtomMessage(); - } - - virtual Message *create(const Message &message) const - { - return new InternAtomMessage((const InternAtomMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (InternAtomMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* InternAtom_H */ diff --git a/nxcomp/Jpeg.cpp b/nxcomp/Jpeg.cpp deleted file mode 100644 index 54fa71d21..000000000 --- a/nxcomp/Jpeg.cpp +++ /dev/null @@ -1,886 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include - -#ifdef ANDROID -#include -#endif -#include -#include -#include - -#ifdef __cplusplus - -extern "C" -{ - #include - #include -} - -#else - -#include -#include - -#endif - -#include "Misc.h" -#include "Jpeg.h" -#include "Unpack.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#define RGB24_TO_PIXEL(bpp,r,g,b) \ - ((((CARD##bpp)(r) & 0xff) * srcRedMax + 127) / 255 \ - << srcRedShift | \ - (((CARD##bpp)(g) & 0xff) * srcGreenMax + 127) / 255 \ - << srcGreenShift | \ - (((CARD##bpp)(b) & 0xff) * srcBlueMax + 127) / 255 \ - << srcBlueShift) - -#define RGB24_TO_PIXEL32(r,g,b) \ - (((CARD32)(r) & 0xff) << srcRedShift | \ - ((CARD32)(g) & 0xff) << srcGreenShift | \ - ((CARD32)(b) & 0xff) << srcBlueShift) - -// -// Functions from Unpack.cpp -// - -extern int Unpack32To32(const T_colormask *colormask, const unsigned int *data, - unsigned int *out, unsigned int *end); - -extern int Unpack24To24(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -extern int Unpack16To16(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -// -// Local functions used for the jpeg decompression. -// - -static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData, int compressedLen); -static void JpegInitSource(j_decompress_ptr cinfo); -static void JpegTermSource(j_decompress_ptr cinfo); -static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes); - -static boolean JpegFillInputBuffer(j_decompress_ptr cinfo); - -static int DecompressJpeg16(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder); - -static int DecompressJpeg24(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder); - -static int DecompressJpeg32(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder); - -void UnpackJpegErrorHandler(j_common_ptr cinfo); - -// -// Colormap stuff. -// - -CARD16 srcRedMax, srcGreenMax, srcBlueMax; -CARD8 srcRedShift, srcGreenShift, srcBlueShift; - -// -// Error handler. -// - -static bool jpegError; - -jmp_buf UnpackJpegContext; - -void UnpackJpegErrorHandler(j_common_ptr cinfo) -{ - #ifdef PANIC - *logofs << "UnpackJpegErrorHandler: PANIC! Detected error in JPEG decompression.\n" - << logofs_flush; - - *logofs << "UnpackJpegErrorHandler: PANIC! Trying to revert to the previous context.\n" - << logofs_flush; - #endif - - jpegError = 1; - - longjmp(UnpackJpegContext, 1); -} - -// -// Attributes used for the jpeg decompression. -// - -static struct jpeg_source_mgr jpegSrcManager; -static JOCTET *jpegBufferPtr; -static size_t jpegBufferLen; - -static char *tmpBuf; -static int tmpBufSize = 0; - -int UnpackJpeg(T_geometry *geometry, unsigned char method, unsigned char *srcData, - int srcSize, int dstBpp, int dstWidth, int dstHeight, - unsigned char *dstData, int dstSize) -{ - int byteOrder = geometry -> image_byte_order; - - // - // Check if data is coming from a failed unsplit. - // - - if (srcSize < 2 || (srcData[0] == SPLIT_PATTERN && - srcData[1] == SPLIT_PATTERN)) - { - #ifdef WARNING - *logofs << "UnpackJpeg: WARNING! Skipping unpack of dummy data.\n" - << logofs_flush; - #endif - - return -1; - } - - #ifdef DEBUG - *logofs << "UnpackJpeg: Decompression. Source size " - << srcSize << " bits per plane " << dstBpp - << ".\n" << logofs_flush; - #endif - - srcRedShift = ffs(geometry -> red_mask) - 1; - srcGreenShift = ffs(geometry -> green_mask) - 1; - srcBlueShift = ffs(geometry -> blue_mask) - 1; - - #ifdef DEBUG - *logofs << "UnpackJpeg: Red shift " << (int) srcRedShift - << " green shift " << (int) srcGreenShift << " blue shift " - << (int) srcBlueShift << ".\n" << logofs_flush; - #endif - - srcRedMax = geometry -> red_mask >> srcRedShift; - srcGreenMax = geometry -> green_mask >> srcGreenShift; - srcBlueMax = geometry -> blue_mask >> srcBlueShift; - - #ifdef DEBUG - *logofs << "UnpackJpeg: Red mask " << (void *) geometry -> red_mask - << " green mask " << (void *) geometry -> green_mask - << " blue mask " << (void *) geometry -> blue_mask - << ".\n" << logofs_flush; - #endif - - #ifdef DEBUG - *logofs << "UnpackJpeg: Red max " << srcRedMax << " green max " - << srcGreenMax << " blue max " << srcBlueMax - << ".\n" << logofs_flush; - #endif - - // - // Make enough space in the temporary - // buffer to have one complete row of - // the image with 3 bytes for a pixel. - // - - tmpBufSize = dstWidth * 3; - tmpBuf = new char[tmpBufSize]; - - if (tmpBuf == NULL) - { - #ifdef PANIC - *logofs << "UnpackJpeg: PANIC! Cannot allocate " - << dstWidth * 3 << " bytes for Jpeg " - << "decompressed data.\n" << logofs_flush; - #endif - - delete [] tmpBuf; - - return -1; - } - - int result = 1; - - switch(dstBpp) - { - case 8: - { - // - // Simply move the data from srcData to dstData - // taking into consideration the correct padding. - // - - int row; - - unsigned char * dstBuff = dstData; - unsigned char * srcBuff = srcData; - - for (row = 0; row < dstHeight; row++) - { - memcpy(dstBuff, srcBuff, dstWidth); - - dstBuff += RoundUp4(dstWidth); - srcBuff += dstWidth; - } - - break; - } - case 16: - { - result = DecompressJpeg16(srcData, srcSize, dstWidth, - dstHeight, dstData, byteOrder); - break; - } - case 24: - { - result = DecompressJpeg24(srcData, srcSize, dstWidth, - dstHeight, dstData, byteOrder); - break; - } - case 32: - { - result = DecompressJpeg32(srcData, srcSize, dstWidth, - dstHeight, dstData, byteOrder); - break; - } - default: - { - #ifdef PANIC - *logofs << "UnpackJpeg: PANIC! Failed to decode Jpeg image. " - << " Unsupported Bpp value " << dstBpp - << " for the Jpeg compression" - << ".\n" << logofs_flush; - #endif - - delete [] tmpBuf; - - result = -1; - } - } - - #ifdef DEBUG - *logofs << "UnpackJpeg: Decompression finished with result " - << result << ".\n" << logofs_flush; - #endif - - if (result == -1) - { - delete [] tmpBuf; - - #ifdef PANIC - *logofs << "UnpackJpeg: PANIC! Failed to decode Jpeg image using " - << dstBpp << " Bpp destination.\n" << logofs_flush; - #endif - - return result; - } - - // - // Apply the correction for the brightness. - // - - int maskMethod; - - switch(method) - { - case PACK_JPEG_8_COLORS: - { - maskMethod = MASK_8_COLORS; - - break; - } - case PACK_JPEG_64_COLORS: - { - maskMethod = MASK_64_COLORS; - - break; - } - case PACK_JPEG_256_COLORS: - { - maskMethod = MASK_256_COLORS; - - break; - } - case PACK_JPEG_512_COLORS: - { - maskMethod = MASK_512_COLORS; - - break; - } - case PACK_JPEG_4K_COLORS: - { - maskMethod = MASK_4K_COLORS; - - break; - } - case PACK_JPEG_32K_COLORS: - { - maskMethod = MASK_32K_COLORS; - - break; - } - case PACK_JPEG_64K_COLORS: - { - maskMethod = MASK_64K_COLORS; - - break; - } - case PACK_JPEG_256K_COLORS: - { - maskMethod = MASK_256K_COLORS; - - break; - } - case PACK_JPEG_2M_COLORS: - { - maskMethod = MASK_2M_COLORS; - - break; - } - case PACK_JPEG_16M_COLORS: - { - maskMethod = MASK_16M_COLORS; - - break; - } - default: - { - delete [] tmpBuf; - - return -1; - } - } - - const T_colormask *colorMask = MethodColorMask(maskMethod); - - unsigned char *dstBuff = dstData; - - switch (dstBpp) - { - case 16: - { - Unpack16To16(colorMask, dstBuff, dstBuff, dstBuff + dstSize); - - break; - } - case 24: - { - break; - } - case 32: - { - Unpack32To32(colorMask, (unsigned int *) dstBuff, (unsigned int *) dstBuff, - (unsigned int *) (dstBuff + dstSize)); - break; - } - default: - { - delete [] tmpBuf; - - return -1; - } - } - - delete [] tmpBuf; - - return 1; -} - -// -// Functions that actually do the Jpeg decompression. -// - -int DecompressJpeg16(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - unsigned char *data; - JSAMPROW rowPointer[1]; - - unsigned int dx = 0; - unsigned int dy = 0; - - #ifdef DEBUG - *logofs << "DecompressJpeg16: Decompressing with length " - << compressedLen << " width " << w << " height " - << h << ".\n" << logofs_flush; - #endif - - jpegError = 0; - - cinfo.err = jpeg_std_error(&jerr); - - jerr.error_exit = UnpackJpegErrorHandler; - - if (setjmp(UnpackJpegContext) == 1) - { - #ifdef TEST - *logofs << "DecompressJpeg16: Out of the long jump with error '" - << jpegError << "'.\n" << logofs_flush; - #endif - - goto AbortDecompressJpeg16; - } - - jpeg_create_decompress(&cinfo); - - if (jpegError) goto AbortDecompressJpeg16; - - JpegSetSrcManager(&cinfo, compressedData, compressedLen); - - jpeg_read_header(&cinfo, TRUE); - - if (jpegError) goto AbortDecompressJpeg16; - - cinfo.out_color_space = JCS_RGB; - - jpeg_start_decompress(&cinfo); - - if (jpegError) goto AbortDecompressJpeg16; - - if (cinfo.output_width != w || - cinfo.output_height != h || - cinfo.output_components != 3) - { - #ifdef PANIC - *logofs << "DecompressJpeg16: PANIC! Wrong JPEG data received.\n" - << logofs_flush; - #endif - - jpeg_destroy_decompress(&cinfo); - - return -1; - } - - // - // PixelPtr points to dstBuf which is - // already padded correctly for the final - // image to put - // - - data = dstBuf; - - rowPointer[0] = (JSAMPROW) tmpBuf; - - unsigned long pixel; - - while (cinfo.output_scanline < cinfo.output_height) - { - jpeg_read_scanlines(&cinfo, rowPointer, 1); - - if (jpegError) goto AbortDecompressJpeg16; - - for (dx = 0; dx < w; dx++) - { - pixel = RGB24_TO_PIXEL(16, tmpBuf[dx * 3], tmpBuf[dx * 3 + 1], - tmpBuf[dx * 3 + 2]); - - // - // Follow the server byte order when arranging data. - // - - if (byteOrder == LSBFirst) - { - data[0] = (unsigned char) (pixel & 0xff); - data[1] = (unsigned char) ((pixel >> 8) & 0xff); - } - else - { - data[1] = (unsigned char) (pixel & 0xff); - data[0] = (unsigned char) ((pixel >> 8) & 0xff); - } - - data += 2; - } - - // - // Move data at the beginning of the - // next line. - // - - data = data + (RoundUp4(w * 2) - w * 2); - - dy++; - } - - AbortDecompressJpeg16: - - if (jpegError == 0) - { - jpeg_finish_decompress(&cinfo); - } - - jpeg_destroy_decompress(&cinfo); - - if (jpegError == 1) - { - #ifdef PANIC - *logofs << "DecompressJpeg16: Failed to decompress JPEG image.\n" - << logofs_flush; - #endif - - return -1; - } - - #ifdef TEST - *logofs << "DecompressJpeg16: Decompression finished with " - << dy << " lines handled.\n" << logofs_flush; - #endif - - return 1; -} - -int DecompressJpeg24(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - CARD8 *pixelPtr = NULL; - JSAMPROW rowPointer[1]; - - unsigned int dx = 0; - unsigned int dy = 0; - - #ifdef TEST - *logofs << "DecompressJpeg24: Decompressing with length " - << compressedLen << " width " << w << " height " - << h << ".\n" << logofs_flush; - #endif - - jpegError = 0; - - cinfo.err = jpeg_std_error(&jerr); - - jerr.error_exit = UnpackJpegErrorHandler; - - if (setjmp(UnpackJpegContext) == 1) - { - #ifdef TEST - *logofs << "DecompressJpeg24: Out of the long jump with error '" - << jpegError << "'.\n" << logofs_flush; - #endif - - goto AbortDecompressJpeg24; - } - - jpeg_create_decompress(&cinfo); - - if (jpegError) goto AbortDecompressJpeg24; - - JpegSetSrcManager(&cinfo, compressedData, compressedLen); - - jpeg_read_header(&cinfo, TRUE); - - if (jpegError) goto AbortDecompressJpeg24; - - cinfo.out_color_space = JCS_RGB; - - jpeg_start_decompress(&cinfo); - - if (jpegError) goto AbortDecompressJpeg24; - - if (cinfo.output_width != w || - cinfo.output_height != h || - cinfo.output_components != 3) - { - #ifdef PANIC - *logofs << "DecompressJpeg24: PANIC! Wrong JPEG data received.\n" - << logofs_flush; - #endif - - jpeg_destroy_decompress(&cinfo); - - return -1; - } - - // - // PixelPtr points to dstBuf which is - // already padded correctly for the final - // image to put. - // - - pixelPtr = (CARD8 *) dstBuf; - - rowPointer[0] = (JSAMPROW) tmpBuf; - - while (cinfo.output_scanline < cinfo.output_height) - { - jpeg_read_scanlines(&cinfo, rowPointer, 1); - - if (jpegError) goto AbortDecompressJpeg24; - - for (dx = 0; dx < w; dx++) - { - // - // Follow the server byte order when arranging data. - // - - if (byteOrder == LSBFirst) - { - pixelPtr[0] = tmpBuf[dx * 3]; - pixelPtr[1] = tmpBuf[dx * 3 + 1]; - pixelPtr[2] = tmpBuf[dx * 3 + 2]; - } - else - { - pixelPtr[2] = tmpBuf[dx * 3]; - pixelPtr[1] = tmpBuf[dx * 3 + 1]; - pixelPtr[0] = tmpBuf[dx * 3 + 2]; - } - - pixelPtr += 3; - } - - // - // Go to the next line. - // - - pixelPtr = (CARD8 *) (((char *) pixelPtr) + (RoundUp4(w * 3) - w * 3)); - - dy++; - } - - AbortDecompressJpeg24: - - if (jpegError == 0) - { - jpeg_finish_decompress(&cinfo); - } - - jpeg_destroy_decompress(&cinfo); - - if (jpegError == 1) - { - #ifdef PANIC - *logofs << "DecompressJpeg24: Failed to decompress JPEG image.\n" - << logofs_flush; - #endif - - return -1; - } - - #ifdef TEST - *logofs << "DecompressJpeg24: Decompression finished with " - << dy << " lines handled.\n" << logofs_flush; - #endif - - return 1; -} - -int DecompressJpeg32(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - unsigned char *data; - JSAMPROW rowPointer[1]; - - unsigned int dx = 0; - unsigned int dy = 0; - - #ifdef TEST - *logofs << "DecompressJpeg32: Decompressing with length " - << compressedLen << " width " << w << " height " - << h << ".\n" << logofs_flush; - #endif - - jpegError = 0; - - cinfo.err = jpeg_std_error(&jerr); - - jerr.error_exit = UnpackJpegErrorHandler; - - if (setjmp(UnpackJpegContext) == 1) - { - #ifdef TEST - *logofs << "DecompressJpeg32: Out of the long jump with error '" - << jpegError << "'.\n" << logofs_flush; - #endif - - goto AbortDecompressJpeg32; - } - - jpeg_create_decompress(&cinfo); - - if (jpegError) goto AbortDecompressJpeg32; - - JpegSetSrcManager(&cinfo, compressedData, compressedLen); - - jpeg_read_header(&cinfo, TRUE); - - if (jpegError) goto AbortDecompressJpeg32; - - cinfo.out_color_space = JCS_RGB; - - jpeg_start_decompress(&cinfo); - - if (jpegError) goto AbortDecompressJpeg32; - - if (cinfo.output_width != w || - cinfo.output_height != h || - cinfo.output_components != 3) - { - #ifdef PANIC - *logofs << "DecompressJpeg32 : PANIC! Wrong JPEG data received.\n" - << logofs_flush; - #endif - - jpeg_destroy_decompress(&cinfo); - - return -1; - } - - // - // PixelPtr points to dstBuf which is - // already padded correctly for the final - // image to put - // - - data = dstBuf; - - rowPointer[0] = (JSAMPROW) tmpBuf; - - unsigned long pixel; - - int i; - - while (cinfo.output_scanline < cinfo.output_height) - { - jpeg_read_scanlines(&cinfo, rowPointer, 1); - - if (jpegError) goto AbortDecompressJpeg32; - - for (dx = 0; dx < w; dx++) - { - pixel = RGB24_TO_PIXEL(32, tmpBuf[dx * 3], tmpBuf[dx * 3 + 1], - tmpBuf[dx * 3 + 2]); - - // - // Follow the server byte order when arranging data. - // - - if (byteOrder == LSBFirst) - { - for (i = 0; i < 4; i++) - { - data[i] = (unsigned char)(pixel & 0xff); - pixel >>= 8; - } - } - else - { - for (i = 3; i >= 0; i--) - { - data[i] = (unsigned char) (pixel & 0xff); - pixel >>= 8; - } - } - - data += 4; - } - - dy++; - } - - AbortDecompressJpeg32: - - if (jpegError == 0) - { - jpeg_finish_decompress(&cinfo); - } - - jpeg_destroy_decompress(&cinfo); - - if (jpegError == 1) - { - #ifdef PANIC - *logofs << "DecompressJpeg32: Failed to decompress JPEG image.\n" - << logofs_flush; - #endif - - return -1; - } - - #ifdef TEST - *logofs << "DecompressJpeg32: Decompression finished with " - << dy << " lines handled.\n" << logofs_flush; - #endif - - return 1; -} - -static void JpegInitSource(j_decompress_ptr cinfo) -{ - jpegError = 0; -} - -static boolean JpegFillInputBuffer(j_decompress_ptr cinfo) -{ - jpegError = 1; - - jpegSrcManager.bytes_in_buffer = jpegBufferLen; - jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr; - - return TRUE; -} - -static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes) -{ - if (num_bytes < 0 || (unsigned long) num_bytes > jpegSrcManager.bytes_in_buffer) - { - jpegError = 1; - - jpegSrcManager.bytes_in_buffer = jpegBufferLen; - jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr; - } - else - { - jpegSrcManager.next_input_byte += (size_t) num_bytes; - jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes; - } -} - -static void JpegTermSource(j_decompress_ptr cinfo) -{ -} - -static void JpegSetSrcManager(j_decompress_ptr cinfo, - CARD8 *compressedData, - int compressedLen) -{ - jpegBufferPtr = (JOCTET *) compressedData; - jpegBufferLen = (size_t) compressedLen; - - jpegSrcManager.init_source = JpegInitSource; - jpegSrcManager.fill_input_buffer = JpegFillInputBuffer; - jpegSrcManager.skip_input_data = JpegSkipInputData; - jpegSrcManager.resync_to_restart = jpeg_resync_to_restart; - jpegSrcManager.term_source = JpegTermSource; - jpegSrcManager.next_input_byte = jpegBufferPtr; - jpegSrcManager.bytes_in_buffer = jpegBufferLen; - - cinfo->src = &jpegSrcManager; -} diff --git a/nxcomp/Jpeg.h b/nxcomp/Jpeg.h deleted file mode 100644 index 58a5bffef..000000000 --- a/nxcomp/Jpeg.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Jpeg_H -#define Jpeg_H - -#include "Misc.h" -#include "Unpack.h" - -int UnpackJpeg(T_geometry *geometry, unsigned char method, unsigned char *srcData, - int srcSize, int dstBpp, int dstWidth, int dstHeight, - unsigned char *dstData, int dstSize); - -#endif /* Jpeg_H */ diff --git a/nxcomp/Keeper.cpp b/nxcomp/Keeper.cpp deleted file mode 100644 index 7e8cd0cd7..000000000 --- a/nxcomp/Keeper.cpp +++ /dev/null @@ -1,608 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include -#include - -#include "Keeper.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Remove the directory if it's empty -// since more than 30 * 24 h. -// - -#define EMPTY_DIR_TIME 2592000 - -// -// Sleep once any ONCE entries. -// - -#define ONCE 2 - -// -// Define this to trace messages while -// they are allocated and deallocated. -// - -#undef REFERENCES - -// -// This is used for reference count. -// - -#ifdef REFERENCES - -int File::references_ = 0; - -#endif - -bool T_older::operator () (File *a, File *b) const -{ - return a -> compare(b); -} - -File::File() -{ - name_ = NULL; - - size_ = 0; - time_ = 0; - - #ifdef REFERENCES - - references_++; - - *logofs << "Keeper: Created new File at " - << this << " out of " << references_ - << " allocated references.\n" - << logofs_flush; - - #endif -} - -// -// TODO: This class can leak industrial amounts of memory. -// I'm 100% sure that the desctructor is called and that -// also the string pointed in the File structure is dele- -// ted. Everything is logged, but still the memory is not -// freed. This is less a problem on Windows, where the me- -// mory occupation remains almost constant. Obviously the -// problem lies in the STL allocators of the GNU libstc++. -// - -File::~File() -{ - #ifdef TEST - *logofs << "Keeper: Deleting name for File at " - << this << ".\n" << logofs_flush; - #endif - - delete [] name_; - - #ifdef REFERENCES - - *logofs << "Keeper: Deleted File at " - << this << " out of " << references_ - << " allocated references.\n" - << logofs_flush; - - references_--; - - #endif -} - -bool File::compare(File *b) const -{ - if (this -> time_ == b -> time_) - { - return (this -> size_ < b -> size_); - } - - return (this -> time_ < b -> time_); -} - -Keeper::Keeper(int caches, int images, const char *root, - int sleep, int parent) -{ - caches_ = caches; - images_ = images; - sleep_ = sleep; - parent_ = parent; - - root_ = new char[strlen(root) + 1]; - - strcpy(root_, root); - - total_ = 0; - signal_ = 0; - - files_ = new T_files; -} - -Keeper::~Keeper() -{ - empty(); - - delete files_; - - delete [] root_; -} - -int Keeper::cleanupCaches() -{ - #ifdef TEST - *logofs << "Keeper: Looking for cache directories in '" - << root_ << "'.\n" << logofs_flush; - #endif - - DIR *rootDir = opendir(root_); - - if (rootDir != NULL) - { - dirent *dirEntry; - - struct stat fileStat; - - int baseSize = strlen(root_); - - int s = 0; - - while (((dirEntry = readdir(rootDir)) != NULL)) - { - if (s++ % ONCE == 0) usleep(sleep_ * 1000); - - if (signal_ != 0) break; - - if (strcmp(dirEntry -> d_name, "cache") == 0 || - strncmp(dirEntry -> d_name, "cache-", 6) == 0) - { - char *dirName = new char[baseSize + strlen(dirEntry -> d_name) + 2]; - - if (dirName == NULL) - { - #ifdef WARNING - *logofs << "Keeper: WARNING! Can't check directory entry '" - << dirEntry -> d_name << "'.\n" << logofs_flush; - #endif - - delete [] dirName; - - continue; - } - - strcpy(dirName, root_); - strcpy(dirName + baseSize, "/"); - strcpy(dirName + baseSize + 1, dirEntry -> d_name); - - #ifdef TEST - *logofs << "Keeper: Checking directory '" << dirName - << "'.\n" << logofs_flush; - #endif - - if (stat(dirName, &fileStat) == 0 && - S_ISDIR(fileStat.st_mode) != 0) - { - // - // Add to repository all the "C-" and - // "S-" files in the given directory. - // - - collect(dirName); - } - - delete [] dirName; - } - } - - closedir(rootDir); - } - else - { - #ifdef WARNING - *logofs << "Keeper: WARNING! Can't open NX root directory '" - << root_ << "'. Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Can't open NX root directory '" - << root_ << "'. Error is " << EGET() << " '" - << ESTR() << "'.\n"; - } - - // - // Remove older files. - // - - cleanup(caches_); - - // - // Empty the repository. - // - - empty(); - - return 1; -} - -int Keeper::cleanupImages() -{ - #ifdef TEST - *logofs << "Keeper: Looking for image directory in '" - << root_ << "'.\n" << logofs_flush; - #endif - - char *imagesPath = new char[strlen(root_) + strlen("/images") + 1]; - - if (imagesPath == NULL) - { - return -1; - } - - strcpy(imagesPath, root_); - strcat(imagesPath, "/images"); - - // - // Check if the cache directory does exist. - // - - struct stat dirStat; - - if (stat(imagesPath, &dirStat) == -1) - { - #ifdef WARNING - *logofs << "Keeper: WARNING! Can't stat NX images cache directory '" - << imagesPath << ". Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Can't stat NX images cache directory '" - << imagesPath << ". Error is " << EGET() << " '" - << ESTR() << "'.\n"; - - delete [] imagesPath; - - return -1; - } - - // - // Check any of the 16 directories in the - // images root path. - // - - char *digitPath = new char[strlen(imagesPath) + 5]; - - strcpy(digitPath, imagesPath); - - for (char digit = 0; digit < 16; digit++) - { - // - // Give up if we received a signal or - // our parent is gone. - // - - if (signal_ != 0) - { - #ifdef TEST - *logofs << "Keeper: Signal detected. Aborting.\n" - << logofs_flush; - #endif - - goto KeeperCleanupImagesAbort; - } - else if (parent_ != getppid() || parent_ == 1) - { - #ifdef WARNING - *logofs << "Keeper: WARNING! Parent process appears " - << "to be dead. Returning.\n" - << logofs_flush; - #endif - - goto KeeperCleanupImagesAbort; - - return 0; - } - - sprintf(digitPath + strlen(imagesPath), "/I-%01X", digit); - - // - // Add to the repository all the files - // in the given directory. - // - - collect(digitPath); - } - - delete [] imagesPath; - delete [] digitPath; - - // - // Remove the oldest files. - // - - cleanup(images_); - - // - // Empty the repository. - // - - empty(); - - return 1; - -KeeperCleanupImagesAbort: - - delete [] imagesPath; - delete [] digitPath; - - empty(); - - return 0; -} - -int Keeper::collect(const char *path) -{ - #ifdef TEST - *logofs << "Keeper: Looking for files in directory '" - << path << "'.\n" << logofs_flush; - #endif - - DIR *cacheDir = opendir(path); - - if (cacheDir != NULL) - { - File *file; - - dirent *dirEntry; - - struct stat fileStat; - - int baseSize = strlen(path); - int fileSize = baseSize + 3 + MD5_LENGTH * 2 + 1; - - int n = 0; - int s = 0; - - while (((dirEntry = readdir(cacheDir)) != NULL)) - { - if (s++ % ONCE == 0) usleep(sleep_ * 1000); - - if (signal_ != 0) break; - - if (strcmp(dirEntry -> d_name, ".") == 0 || - strcmp(dirEntry -> d_name, "..") == 0) - { - continue; - } - - n++; - - if (strlen(dirEntry -> d_name) == (MD5_LENGTH * 2 + 2) && - (strncmp(dirEntry -> d_name, "I-", 2) == 0 || - strncmp(dirEntry -> d_name, "S-", 2) == 0 || - strncmp(dirEntry -> d_name, "C-", 2) == 0)) - { - file = new File(); - - char *fileName = new char[fileSize]; - - if (file == NULL || fileName == NULL) - { - #ifdef WARNING - *logofs << "Keeper: WARNING! Can't add file '" - << dirEntry -> d_name << "' to repository.\n" - << logofs_flush; - #endif - - delete [] fileName; - - delete file; - - continue; - } - - strcpy(fileName, path); - strcpy(fileName + baseSize, "/"); - strcpy(fileName + baseSize + 1, dirEntry -> d_name); - - file -> name_ = fileName; - - #ifdef DEBUG - *logofs << "Keeper: Adding file '" << file -> name_ - << "'.\n" << logofs_flush; - #endif - - if (stat(file -> name_, &fileStat) == -1) - { - #ifdef WARNING - *logofs << "Keeper: WARNING! Can't stat NX file '" - << file -> name_ << ". Error is " << EGET() - << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - delete file; - - continue; - } - - file -> size_ = fileStat.st_size; - file -> time_ = fileStat.st_mtime; - - files_ -> insert(T_files::value_type(file)); - - total_ += file -> size_; - } - } - - closedir(cacheDir); - - if (n == 0) - { - time_t now = time(NULL); - - if (now > 0 && stat(path, &fileStat) == 0) - { - #ifdef TEST - *logofs << "Keeper: Empty NX subdirectory '" << path - << "' unused since " << now - fileStat.st_mtime - << " S.\n" << logofs_flush; - #endif - - if (now - fileStat.st_mtime > EMPTY_DIR_TIME) - { - #ifdef TEST - *logofs << "Keeper: Removing empty NX subdirectory '" - << path << "'.\n" << logofs_flush; - #endif - - rmdir(path); - } - } - } - } - else - { - #ifdef WARNING - *logofs << "Keeper: WARNING! Can't open NX subdirectory '" - << path << ". Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Can't open NX subdirectory '" - << path << ". Error is " << EGET() << " '" << ESTR() - << "'.\n"; - } - - return 1; -} - -int Keeper::cleanup(int threshold) -{ - #ifdef TEST - *logofs << "Keeper: Deleting the oldest files with " - << files_ -> size() << " elements threshold " - << threshold << " and size " << total_ << ".\n" - << logofs_flush; - #endif - - // - // At least some versions of the standard - // library don't allow erasing an element - // while looping. This is not the most ef- - // ficient way to release the objects, but - // it's better than making a copy of the - // container. - // - - while (total_ > threshold && files_ -> size() > 0) - { - T_files::iterator i = files_ -> begin(); - - File *file = *i; - - #ifdef TEST - *logofs << "Keeper: Removing '" << file -> name_ - << "' with time " << file -> time_ << " and size " - << file -> size_ << ".\n" << logofs_flush; - #endif - - unlink(file -> name_); - - total_ -= file -> size_; - - #ifdef DEBUG - *logofs << "Keeper: Going to delete the file at " - << file << " while cleaning up.\n" - << logofs_flush; - #endif - - delete file; - - #ifdef DEBUG - *logofs << "Keeper: Going to erase the element " - << "while cleaning up.\n" - << logofs_flush; - #endif - - files_ -> erase(i); - } - - #ifdef TEST - *logofs << "Keeper: Bytes in repository are " - << total_ << ".\n" << logofs_flush; - #endif - - return 1; -} - -void Keeper::empty() -{ - #ifdef TEST - *logofs << "Keeper: Getting rid of files in repository.\n" - << logofs_flush; - #endif - - while (files_ -> size() > 0) - { - T_files::iterator i = files_ -> begin(); - - File *file = *i; - - #ifdef DEBUG - *logofs << "Keeper: Going to delete the file at " - << file << " while emptying.\n" - << logofs_flush; - #endif - - delete file; - - #ifdef DEBUG - *logofs << "Keeper: Going to erase the element " - << "while emptying.\n" - << logofs_flush; - #endif - - files_ -> erase(i); - } - - total_ = 0; - - #ifdef TEST - *logofs << "Keeper: Bytes in repository are " - << total_ << ".\n" << logofs_flush; - #endif -} diff --git a/nxcomp/Keeper.h b/nxcomp/Keeper.h deleted file mode 100644 index b440beceb..000000000 --- a/nxcomp/Keeper.h +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Keeper_H -#define Keeper_H - -#include "Misc.h" -#include "Types.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Define this to check how many file -// nodes are allocated and deallocated. -// - -#undef REFERENCES - -class Keeper; - -class File -{ - friend class Keeper; - - public: - - File(); - - ~File(); - - // - // Allow sort by time and size. If time - // is the same, keep the bigger element. - // - - bool compare(File *b) const; - - private: - - char *name_; - - int size_; - time_t time_; - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -class Keeper -{ - public: - - Keeper(int caches, int images, const char *root, - int sleep, int parent); - - ~Keeper(); - - // - // Call this just once. - // - - int cleanupCaches(); - - // - // Call this at any given interval. - // - - int cleanupImages(); - - // - // Call this if it's time to exit. - // - - void setSignal(int signal) - { - signal_ = signal; - } - - int getSignal() - { - return signal_; - } - - int getParent() - { - return parent_; - } - - private: - - // - // Get a list of files in directory. - // - - int collect(const char *path); - - // - // Sort the collected files according to - // last modification time and delete the - // older ones until disk size is below - // the threshold. - // - - int cleanup(int threshold); - - // - // Empty the files repository. - // - - void empty(); - - // - // Size in bytes of total allowed - // storage for persistent caches. - // - - int caches_; - - // - // Size in bytes of total allowed - // storage for images cache. - // - - int images_; - - // - // Path of the NX root directory. - // - - char *root_; - - // - // The little delay to be introduced - // before reading a new entry. - // - - int sleep_; - - // - // Total size of files in repository. - // - - int total_; - - // - // The parent process, so we can exit - // if it is gone. - // - - int parent_; - - // - // Set if we need to give up because - // of a signal. - // - - int signal_; - - // - // Repository where to collect files. - // - - T_files *files_; -}; - -#endif /* Keeper_H */ - diff --git a/nxcomp/List.cpp b/nxcomp/List.cpp deleted file mode 100644 index 228f83214..000000000 --- a/nxcomp/List.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "List.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Define this to know how many instances -// are allocated and deallocated. -// - -#undef REFERENCES - -#ifdef REFERENCES - -int List::references_ = 0; - -#endif - -List::List() -{ - #ifdef REFERENCES - - references_++; - - *logofs << "List: Created new List at " - << this << " out of " << references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -List::~List() -{ - #ifdef REFERENCES - - references_--; - - *logofs << "List: Deleted List at " - << this << " out of " << references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -void List::remove(int value) -{ - for (T_list::iterator i = list_.begin(); i != list_.end(); i++) - { - if (*i == value) - { - list_.erase(i); - - return; - } - } - - #ifdef PANIC - *logofs << "List: PANIC! Should not try to remove " - << "an element not found in the list.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Should not try to remove " - << "an element not found in the list.\n"; - - HandleAbort(); -} - -void List::rotate() -{ - if (list_.size() > 1) - { - int value = *(list_.begin()); - - list_.pop_front(); - - list_.push_back(value); - } -} diff --git a/nxcomp/List.h b/nxcomp/List.h deleted file mode 100644 index 31c80f835..000000000 --- a/nxcomp/List.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef List_H -#define List_H - -#include "Misc.h" -#include "Types.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Define this to log when lists are -// allocated and deallocated. -// - -#undef REFERENCES - -class List -{ - public: - - List(); - - ~List(); - - int getSize() - { - return list_.size(); - } - - T_list &getList() - { - return list_; - } - - T_list copyList() - { - return list_; - } - - void add(int value) - { - list_.push_back(value); - } - - void remove(int value); - - void rotate(); - - private: - - // - // The list container. - // - - T_list list_; - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -#endif /* List_H */ diff --git a/nxcomp/ListFontsReply.cpp b/nxcomp/ListFontsReply.cpp deleted file mode 100644 index 827f68a09..000000000 --- a/nxcomp/ListFontsReply.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ListFontsReply.h" - -#include "ServerCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef DUMP -#undef TEST -#undef DEBUG - -ListFontsReplyStore::ListFontsReplyStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = LISTFONTSREPLY_ENABLE_CACHE; - enableData = LISTFONTSREPLY_ENABLE_DATA; - enableSplit = LISTFONTSREPLY_ENABLE_SPLIT; - - // Since ProtoStep7 (#issue 108) - enableCompress = LISTFONTSREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = LISTFONTSREPLY_DATA_LIMIT; - dataOffset = LISTFONTSREPLY_DATA_OFFSET; - - cacheSlots = LISTFONTSREPLY_CACHE_SLOTS; - cacheThreshold = LISTFONTSREPLY_CACHE_THRESHOLD; - cacheLowerThreshold = LISTFONTSREPLY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -ListFontsReplyStore::~ListFontsReplyStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int ListFontsReplyStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ListFontsReplyMessage *listFontsReply = (ListFontsReplyMessage *) message; - - // - // Here is the fingerprint. - // - - listFontsReply -> number_of_names = GetUINT(buffer + 8, bigEndian); - - // - // Clean up padding bytes. - // - - if ((int) size > dataOffset) - { - unsigned int current; - unsigned int length; - unsigned int nstringInNames; - - unsigned char *end = NULL; - unsigned char *pad = NULL; - - #ifdef DUMP - - *logofs << "\n" << logofs_flush; - - *logofs << "Number of STRING8 " << listFontsReply -> number_of_names << ".\n" << logofs_flush; - - *logofs << "Size " << size << ".\n" << logofs_flush; - - DumpHexData(buffer, size); - - *logofs << "\n" << logofs_flush; - - #endif - - length = LISTFONTSREPLY_DATA_OFFSET; - - for (nstringInNames = 0; - nstringInNames < listFontsReply -> number_of_names && - listFontsReply -> number_of_names > 0; - nstringInNames++) - { - // - // Start with offset LISTFONTSREPLY_DATA_OFFSET 32. - // - - current = buffer[length]; - - length += current + 1; - - #ifdef DUMP - *logofs << "\nString number : " << nstringInNames << " Current length : " - << current << "\n" << logofs_flush; - #endif - } - - #ifdef DUMP - *logofs << "\nFinal length " << length << "\n" << logofs_flush; - #endif - - end = ((unsigned char *) buffer) + size; - - for (pad = ((unsigned char *) buffer) + length; pad < end; pad++) - { - *pad = 0; - - #ifdef DUMP - *logofs << "\nPadding ." << "\n" << logofs_flush; - #endif - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ListFontsReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ListFontsReplyMessage *listFontsReply = (ListFontsReplyMessage *) message; - - // - // Fill all the message's fields. - // - - PutUINT(listFontsReply -> number_of_names, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void ListFontsReplyStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - ListFontsReplyMessage *listFontsReply = (ListFontsReplyMessage *) message; - - *logofs << name() << ": Identity number_of_names " - << listFontsReply -> number_of_names << ", size " - << listFontsReply -> size_ << ".\n"; - - #endif -} - -void ListFontsReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Field number_of_names. - // - - md5_append(md5_state_, buffer + 8, 2); -} diff --git a/nxcomp/ListFontsReply.h b/nxcomp/ListFontsReply.h deleted file mode 100644 index c731878e0..000000000 --- a/nxcomp/ListFontsReply.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ListFontsReply_H -#define ListFontsReply_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define LISTFONTSREPLY_ENABLE_CACHE 1 -#define LISTFONTSREPLY_ENABLE_DATA 1 -#define LISTFONTSREPLY_ENABLE_SPLIT 0 - -#define LISTFONTSREPLY_DATA_LIMIT 1048576 - 32 -#define LISTFONTSREPLY_DATA_OFFSET 32 - -#define LISTFONTSREPLY_CACHE_SLOTS 200 -#define LISTFONTSREPLY_CACHE_THRESHOLD 20 -#define LISTFONTSREPLY_CACHE_LOWER_THRESHOLD 5 - -#define LISTFONTSREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -// -// The message class. -// - -class ListFontsReplyMessage : public Message -{ - friend class ListFontsReplyStore; - - public: - - ListFontsReplyMessage() - { - } - - ~ListFontsReplyMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned short int number_of_names; -}; - -class ListFontsReplyStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - ListFontsReplyStore(StaticCompressor *compressor); - - virtual ~ListFontsReplyStore(); - - virtual const char *name() const - { - return "ListFontsReply"; - } - - virtual unsigned char opcode() const - { - return X_ListFonts; - } - - virtual unsigned int storage() const - { - return sizeof(ListFontsReplyMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new ListFontsReplyMessage(); - } - - virtual Message *create(const Message &message) const - { - return new ListFontsReplyMessage((const ListFontsReplyMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (ListFontsReplyMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* ListFontsReply_H */ diff --git a/nxcomp/Loop.cpp b/nxcomp/Loop.cpp deleted file mode 100644 index 4592121de..000000000 --- a/nxcomp/Loop.cpp +++ /dev/null @@ -1,16689 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Misc.h" - -#ifdef __sun -#include -#endif - -// -// MacOSX 10.4 defines socklen_t. This is -// intended to ensure compatibility with -// older versions. -// - -#ifdef __APPLE__ -#include -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3 -typedef int socklen_t; -#endif -#endif - -#ifdef _AIX -#include -#include -#endif - -#ifndef __CYGWIN32__ -#include -#endif - -// -// NX include files. -// - -#include "NX.h" -#include "NXalert.h" - -#include "Misc.h" -#include "Control.h" -#include "Socket.h" -#include "Statistics.h" -#include "Auth.h" -#include "Keeper.h" -#include "Agent.h" - -#include "ClientProxy.h" -#include "ServerProxy.h" - -#include "Message.h" -#include "ChannelEndPoint.h" - -// -// System specific defines. -// - - -// -// HP-UX hides this define. -// - -#if defined(hpux) && !defined(RLIM_INFINITY) - -#define RLIM_INFINITY 0x7fffffff - -#endif - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Enable log output in signal handler. -// This is likely to hang the proxy at -// random, at least on Linux. -// - -#undef UNSAFE - -// -// Let all logs go to the standard error. -// This is useful to interleave the Xlib -// log output with the proxy output in a -// single file. -// - -#undef MIXED - -// -// Define this to check if the client and -// server caches match at shutdown. This -// is a test facility as it requires that -// both proxies are running on the same -// host. -// - -#undef MATCH - -// -// If defined, reduce the size of the log -// file and be sure it never exceeds the -// limit. -// - -#undef QUOTA - -// -// If defined, force very strict limits for -// the proxy tokens and force the proxy to -// enter often in congestion state. -// - -#undef STRICT - -// -// Print a line in the log if the time we -// spent inside the select or handling the -// messages exceeded a given time value. -// - -#undef TIME - -// -// This can be useful when testing the forwarding -// of the SSHD connection by nxssh to the agent. -// The debug output will go to a well known file -// that will be opened also by nxssh when BINDER -// is enabled there. -// - -#undef BINDER - -// -// Define this to override the limits on -// the core dump size. -// - -#define COREDUMPS - -// -// Upper limit of pre-allocated buffers -// for string parameters. -// - -#define DEFAULT_STRING_LENGTH 256 - -// -// Maximum length of remote options data -// passed by peer proxy at startup. -// - -#define DEFAULT_REMOTE_OPTIONS_LENGTH 512 - -// -// Maximum length of NX display string. -// - -#define DEFAULT_DISPLAY_OPTIONS_LENGTH 1024 - -// -// Maximum number of cache file names to -// send to the server side. -// - -#define DEFAULT_REMOTE_CACHE_ENTRIES 100 - -// -// Maximum length of remote options string -// that can be received from the peer proxy. -// - -#define MAXIMUM_REMOTE_OPTIONS_LENGTH 4096 - -// -// Macro is true if we determined our proxy -// mode. -// - -#define WE_SET_PROXY_MODE (control -> ProxyMode != proxy_undefined) - -// -// Macro is true if our side is the one that -// should connect to remote. -// - -#define WE_INITIATE_CONNECTION (connectSocket.enabled()) - -// -// Is true if we must provide our credentials -// to the remote peer. -// - -#define WE_PROVIDE_CREDENTIALS (control -> ProxyMode == proxy_server) - -// -// Is true if we listen for a local forwarder -// that will tunnel the traffic through a SSH -// or HTTP link. -// - -#define WE_LISTEN_FORWARDER (control -> ProxyMode == proxy_server && \ - listenSocket.enabled()) - -// -// You must define FLUSH in Misc.h if -// you want an immediate flush of the -// log output. -// - -ostream *logofs = NULL; - -// -// Other stream destriptors used for -// logging. -// - -ostream *statofs = NULL; -ostream *errofs = NULL; - -// -// Save standard error's rdbuf here -// and restore it when exiting. -// - -static streambuf *errsbuf = NULL; - -// -// Allow faults to be recovered by -// jumping back into the main loop. -// - -jmp_buf context; - -// -// Provide operational parameters. -// - -Control *control = NULL; - -// -// Collect and print statistics. -// - -Statistics *statistics = NULL; - -// -// Keep data for X11 authentication. -// - -Auth *auth = NULL; - -// -// This class makes the hard work. -// - -Proxy *proxy = NULL; - -// -// Used to handle memory-to-memory -// transport to the X agent. -// - -Agent *agent = NULL; - -// -// The image cache house-keeping class. -// - -Keeper *keeper = NULL; - -// -// Callback set by the child process -// to be notified about signals. -// - -int (*handler)(int) = NULL; - -// -// Signal handling functions. -// - -void DisableSignals(); -void EnableSignals(); -void InstallSignals(); - -static void RestoreSignals(); -static void HandleSignal(int signal); - -// -// Signal handling utilities. -// - -static void InstallSignal(int signal, int action); -static void RestoreSignal(int signal); - -static int HandleChildren(); - -int HandleChild(int child); -static int CheckChild(int pid, int status); -static int WaitChild(int child, const char *label, int force); - -int CheckParent(const char *name, const char *type, int parent); - -void RegisterChild(int child); - -static int CheckAbort(); - -// -// Timer handling utilities. -// - -void SetTimer(int timeout); -void ResetTimer(); - -static void HandleTimer(int signal); - -// -// Kill or check a running child. -// - -static int KillProcess(int pid, const char *label, int signal, int wait); -static int CheckProcess(int pid, const char *label); - -// -// Macros used to test the pid of a child. -// - -#define IsFailed(pid) ((pid) < 0) -#define IsRunning(pid) ((pid) > 1) -#define IsNotRunning(pid) ((pid) == 0) -#define IsRestarting(pid) ((pid) == 1) - -#define SetNotRunning(pid) ((pid) = 0) -#define SetRestarting(pid) ((pid) = 1) - -// -// Start or restart the house-keeper process. -// - -static int StartKeeper(); - -// -// Cleanup functions. -// - -void CleanupConnections(); -void CleanupListeners(); -void CleanupSockets(); -void CleanupGlobal(); - -static void CleanupChildren(); -static void CleanupLocal(); -static void CleanupKeeper(); -static void CleanupStreams(); - -// -// Loop forever until the connections -// to the peer proxy is dropped. -// - -static void WaitCleanup(); - -// -// Initialization functions. -// - -static int InitBeforeNegotiation(); -static int SetupProxyConnection(); -static int InitAfterNegotiation(); -static int SetupProxyInstance(); -static int SetupAuthInstance(); -static int SetupAgentInstance(); - -static int SetupTcpSocket(); -static int SetupUnixSocket(); -static int SetupServiceSockets(); -static int SetupDisplaySocket(int &xServerAddrFamily, sockaddr *&xServerAddr, - unsigned int &xServerAddrLength); - -// -// Setup a listening socket and accept -// a new connection. -// - -static int ListenConnection(ChannelEndPoint &endPoint, const char *label); -static int ListenConnectionTCP(const char *host, long port, const char *label); -static int ListenConnectionUnix(const char *path, const char *label); -static int ListenConnectionAny(sockaddr *addr, socklen_t addrlen, const char *label); -static int AcceptConnection(int fd, int domain, const char *label); - -// -// Other convenience functions. -// - -static int PrepareProxyConnectionTCP(char** hostName, long int* portNum, int* timeout, int* proxyFD, int* reason); -static int PrepareProxyConnectionUnix(char** path, int* timeout, int* proxyFD, int* reason); - -static int WaitForRemote(ChannelEndPoint &socketAddress); -static int ConnectToRemote(ChannelEndPoint &socketAddress); - -static int SendProxyOptions(int fd); -static int SendProxyCaches(int fd); -static int ReadProxyVersion(int fd); -static int ReadProxyOptions(int fd); -static int ReadProxyCaches(int fd); -static int ReadForwarderVersion(int fd); -static int ReadForwarderOptions(int fd); - -static int ReadRemoteData(int fd, char *buffer, int size, char stop); -static int WriteLocalData(int fd, const char *buffer, int size); - -static void PrintVersionInfo(); -static void PrintProcessInfo(); -static void PrintConnectionInfo(); -static void PrintUsageInfo(const char *option, const int error); -static void PrintOptionIgnored(const char *type, const char *name, const char *value); - -// -// This is not static to avoid a warning. -// - -void PrintCopyrightInfo(); - -static const char *GetOptions(const char *options); -static const char *GetArg(int &argi, int argc, const char **argv); -static int CheckArg(const char *type, const char *name, const char *value); -static int ParseArg(const char *type, const char *name, const char *value); -static int ValidateArg(const char *type, const char *name, const char *value); -static void SetAndValidateChannelEndPointArg(const char *type, const char *name, const char *value, - ChannelEndPoint &endPoint); -static int LowercaseArg(const char *type, const char *name, char *value); -static int CheckSignal(int signal); - -extern "C" -{ - int ParseCommandLineOptions(int argc, const char **argv); - int ParseEnvironmentOptions(const char *env, int force); - int ParseBindOptions(char **host, int *port); -} - -static int ParseFileOptions(const char *file); -static int ParseRemoteOptions(char *opts); -static int ParseForwarderOptions(char *opts); - -// -// These functions are used to parse literal -// values provided by the user and set the -// control parameters accordingly. -// - -static int ParseLinkOption(const char *opt); -static int ParseBitrateOption(const char *opt); -static int ParseCacheOption(const char *opt); -static int ParseShmemOption(const char *opt); -static int ParseImagesOption(const char *opt); -static int ParsePackOption(const char *opt); - -// -// Set host and port where NX proxy is supposed -// to be listening in case such parameters are -// given on the command line. -// - -static int ParseHostOption(const char *opt, char *host, long &port); - -// -// Translate a font server port specification -// to the corresponding Unix socket path. -// - -static int ParseFontPath(char *path); - -// -// Translate a pack method id in a literal. -// - -static int ParsePackMethod(const int method, const int quality); - -// -// Try to increase the size of the allowed -// core dumps. -// - -static int SetCore(); - -// -// Set the proxy mode to either client or -// server. -// - -static int SetMode(int mode); - -// -// Determine the path of the NX_* directories -// from the environment. -// - -static int SetDirectories(); - -// -// Set the defaults used for the log file and -// statistics. -// - -static int SetLogs(); - -// -// Check if local and remote protocol versions -// are compatible and, eventually, downgrade -// local version to the minimum level that is -// known to work. -// - -static int SetVersion(); - -// -// Setup the listening TCP ports used for the -// additional channels according to user's -// wishes. -// - -static int SetPorts(); - -// -// Set the maximum number of open descriptors. -// - -static int SetDescriptors(); - -// -// Set the path used for choosing the cache. -// It must be selected after determining the -// session type. -// - -static int SetCaches(); - -// -// Initialize, one after the other, all the -// configuration parameters. -// - -static int SetParameters(); - -// -// Set the specific configuration parameter. -// - -static int SetSession(); -static int SetStorage(); -static int SetShmem(); -static int SetPack(); -static int SetImages(); -static int SetLimits(); - -// -// Set up the control parameters based on -// the link speed negotiated between the -// proxies. -// - -static int SetLink(); - -static int SetLinkModem(); -static int SetLinkIsdn(); -static int SetLinkAdsl(); -static int SetLinkWan(); -static int SetLinkLan(); - -// -// Adjust the compression parameters. -// - -static int SetCompression(); - -static int SetCompressionModem(); -static int SetCompressionIsdn(); -static int SetCompressionAdsl(); -static int SetCompressionWan(); -static int SetCompressionLan(); - -// -// Determine the NX paths based on the -// user's parameters or the environment. -// - -char *GetClientPath(); - -static char *GetSystemPath(); -static char *GetHomePath(); -static char *GetTempPath(); -static char *GetRootPath(); -static char *GetCachePath(); -static char *GetImagesPath(); -static char *GetSessionPath(); -static char *GetLastCache(char *list, const char *path); - -static int OpenLogFile(char *name, ostream *&stream); -static int ReopenLogFile(char *name, ostream *&stream, int limit); - -// -// Perform operations on the managed -// descriptors in the main loop. -// - -static void handleCheckSessionInLoop(); -static void handleCheckBitrateInLoop(); - -#if defined(TEST) || defined(INFO) -static void handleCheckSelectInLoop(int &setFDs, fd_set &readSet, - fd_set &writeSet, T_timestamp selectTs); -static void handleCheckResultInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, - fd_set &writeSet, struct timeval &selectTs, - struct timeval &startTs); -static void handleCheckStateInLoop(int &setFDs); -#endif - -static void handleCheckSessionInConnect(); - -static inline void handleSetReadInLoop(fd_set &readSet, int &setFDs, struct timeval &selectTs); -static inline void handleSetWriteInLoop(fd_set &writeSet, int &setFDs, struct timeval &selectTs); -static inline void handleSetListenersInLoop(fd_set &writeSet, int &setFDs); -static inline void handleSetAgentInLoop(int &setFDs, fd_set &readSet, fd_set &writeSet, - struct timeval &selectTs); - -static void handleAlertInLoop(); -static void handleStatisticsInLoop(); - -static inline void handleAgentInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, - fd_set &writeSet, struct timeval &selectTs); -static inline void handleAgentLateInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, - fd_set &writeSet, struct timeval &selectTs); - -static inline void handleReadableInLoop(int &resultFDs, fd_set &readSet); -static inline void handleWritableInLoop(int &resultFDs, fd_set &writeSet); - -static inline void handleRotateInLoop(); -static inline void handleEventsInLoop(); -static inline void handleFlushInLoop(); - -// -// Manage the proxy link during the negotiation -// phase. -// - -static void handleNegotiationInLoop(int &setFDs, fd_set &readSet, - fd_set &writeSet, T_timestamp &selectTs); - -// -// Print the 'terminating' messages in the -// session log. -// - -static inline void handleTerminatingInLoop(); -static inline void handleTerminatedInLoop(); - -// -// Monitor the size of the log file. -// - -static void handleLogReopenInLoop(T_timestamp &logsTs, T_timestamp &nowTs); - -// -// Directory where the NX binaries and libraries reside. -// - -static char systemDir[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Directory used for temporary files. -// - -static char tempDir[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Actually the full path to the client. -// - -static char clientDir[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// User's home directory. -// - -static char homeDir[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Root of directory structure to be created by proxy. -// - -static char rootDir[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Root of statistics and log files to be created by proxy. -// - -static char sessionDir[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Log files for errors and statistics. Error log is -// the place where we print also debug informations. -// Both files are closed, deleted and reopened as -// their size exceed the limit set in control class. -// The session log is not reopened, as it is used by -// the NX client and server to track the advance of -// the session. -// - -static char errorsFileName[DEFAULT_STRING_LENGTH] = { 0 }; -static char statsFileName[DEFAULT_STRING_LENGTH] = { 0 }; -static char sessionFileName[DEFAULT_STRING_LENGTH] = { 0 }; -static char optionsFileName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// String literal representing selected link speed -// parameter. Value is translated in control values -// used by proxies to stay synchronized. -// - -static char linkSpeedName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// String literal representing selected -// cache size. -// - -static char cacheSizeName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// String literal representing selected -// shared memory segment size. -// - -static char shsegSizeName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// String literal of images cache size. -// - -static char imagesSizeName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// String literal for bandwidth limit. -// - -static char bitrateLimitName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// String literal for image packing method. -// - -static char packMethodName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Product name provided by the server or client. -// - -static char productName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Its corresponding value from NXpack.h. -// - -static int packMethod = -1; -static int packQuality = -1; - -// -// String literal for session type. Persistent caches -// are searched in directory whose name matches this -// parameter. -// - -static char sessionType[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Unique id assigned to session. It is used as -// name of directory where all files are placed. -// - -static char sessionId[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Set if we already parsed the options. -// - -static int parsedOptions = 0; -static int parsedCommand = 0; - -// -// Buffer data received from the remote proxy at -// session negotiation. -// - -static char remoteData[MAXIMUM_REMOTE_OPTIONS_LENGTH] = { 0 }; -static int remotePosition = 0; - -// -// Main loop file descriptors. -// - -static int tcpFD = -1; -static int unixFD = -1; -static int cupsFD = -1; -static int auxFD = -1; -static int smbFD = -1; -static int mediaFD = -1; -static int httpFD = -1; -static int fontFD = -1; -static int slaveFD = -1; -static int proxyFD = -1; - -// -// Used for internal communication -// with the X agent. -// - -static int agentFD[2] = { -1, -1 }; - -// -// Flags determining which protocols and -// ports are forwarded. -// - -int useUnixSocket = 1; - -static int useTcpSocket = 1; -static int useCupsSocket = 0; -static int useAuxSocket = 0; -static int useSmbSocket = 0; -static int useMediaSocket = 0; -static int useHttpSocket = 0; -static int useFontSocket = 0; -static int useSlaveSocket = 0; -static int useAgentSocket = 0; - -// -// Set if the launchd service is running -// and its socket must be used as X socket. -// - -static int useLaunchdSocket = 0; - -// -// Set by user if he/she wants to modify -// the default TCP_NODELAY option as set -// in control. -// - -static int useNoDelay = -1; - -// -// Set if user wants to override default -// flush timeout set according to link. -// - -static int usePolicy = -1; - -// -// Set if user wants to hide the RENDER -// extension or wants to short-circuit -// some simple replies at client side. -// - -static int useRender = -1; -static int useTaint = -1; - -// -// Set if the user wants to reduce the -// nominal size of the token messages -// exchanged between the proxies. -// - -static int useStrict = -1; - -// -// Set if the proxy is running as part -// of SSH on the client. -// - -static int useEncryption = -1; - -// -// Name of Unix socket created by the client proxy to -// accept client connections. File must be unlinked -// by cleanup function. -// - -static char unixSocketName[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Other parameters. -// - -static char acceptHost[DEFAULT_STRING_LENGTH] = { 0 }; -static char displayHost[DEFAULT_STRING_LENGTH] = { 0 }; -static char authCookie[DEFAULT_STRING_LENGTH] = { 0 }; - -static int loopbackBind = DEFAULT_LOOPBACK_BIND; -static int proxyPort = DEFAULT_NX_PROXY_PORT; -static int xPort = DEFAULT_NX_X_PORT; - -// -// Used to setup the connection the real -// X display socket. -// - -static int xServerAddrFamily = -1; -static sockaddr *xServerAddr = NULL; -static unsigned int xServerAddrLength = 0; - -// -// The representation of a Unix socket path or -// a bind address, denoting where the local proxy -// will await the peer connection. -// - -static ChannelEndPoint listenSocket; - -// -// The TCP host and port or Unix file socket where -// the remote proxy will be contacted. -// - -static ChannelEndPoint connectSocket; - -// -// Helper channels are disabled by default. -// - -static ChannelEndPoint cupsPort; -static ChannelEndPoint auxPort; -static ChannelEndPoint smbPort; -static ChannelEndPoint mediaPort; -static ChannelEndPoint httpPort; -static ChannelEndPoint slavePort; - -// -// Can be either a port number or a Unix -// socket. -// - -static char fontPort[DEFAULT_STRING_LENGTH] = { 0 }; - -// -// Host and port where the existing proxy -// is running. -// - -static char bindHost[DEFAULT_STRING_LENGTH] = { 0 }; -static int bindPort = -1; - -// -// Pointers to the callback functions and -// parameter set by the agent -// - -static void (*flushCallback)(void *, int) = NULL; -static void *flushParameter = NULL; - -static void (*statisticsCallback)(void *, int) = NULL; -static void *statisticsParameter = NULL; - -// -// State variables shared between the init -// function and the main loop. -// - -T_timestamp initTs; -T_timestamp startTs; -T_timestamp logsTs; -T_timestamp nowTs; - -int diffTs; - -// -// This is set to the main proxy process id. -// - -int lastProxy = 0; - -// -// Set to last dialog process launched by proxy. -// - -int lastDialog = 0; - -// -// Set to watchdog process launched by proxy. -// - -int lastWatchdog = 0; - -// -// Set if a cache house-keeper process is running. -// - -int lastKeeper = 0; - -// -// Let an inner routine register the pid of a slave -// process. -// - -static int lastChild = 0; - -// -// Exit code of the last child process exited. -// - -static int lastStatus = 0; - -// -// Set if shutdown was requested through a signal. -// - -static int lastKill = 0; - -// -// Set if the agent confirmed the destruction of -// the NX transport. -// - -static int lastDestroy = 0; - -// -// This is set to the code and local flag of the -// last requested alert. -// - -static struct -{ - int code; - int local; - -} lastAlert; - -// -// Manage the current signal masks. -// - -static struct -{ - sigset_t saved; - - int blocked; - int installed; - - int enabled[32]; - int forward[32]; - - struct sigaction action[32]; - -} lastMasks; - -// -// Manage the current timer. -// - -static struct -{ - struct sigaction action; - struct itimerval value; - struct timeval start; - struct timeval next; - -} lastTimer; - -// -// This is set to last signal received in handler. -// - -static int lastSignal = 0; - -// -// Set to the last time bytes readable were queried -// by the agent. -// - -static T_timestamp lastReadableTs = nullTimestamp(); - -// -// Here are interfaces declared in NX.h. -// - -int NXTransProxy(int fd, int mode, const char* options) -{ - // - // Let the log temporarily go to the standard - // error. Be also sure we have a jump context, - // in the case any subsequent operation will - // cause a cleanup. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - if (setjmp(context) == 1) - { - #ifdef TEST - *logofs << "NXTransProxy: Out of the long jump with pid '" - << lastProxy << "'.\n" << logofs_flush; - #endif - - return -1; - } - - // - // Check if have already performed a parsing of - // parameters, as in the case we are running as - // a stand-alone process. If needed create the - // parameters repository - // - - if (control == NULL) - { - control = new Control(); - } - - lastProxy = getpid(); - - #ifdef TEST - *logofs << "NXTransProxy: Main process started with pid '" - << lastProxy << "'.\n" << logofs_flush; - #endif - - SetMode(mode); - - if (mode == NX_MODE_CLIENT) - { - if (fd != NX_FD_ANY) - { - #ifdef TEST - - *logofs << "NXTransProxy: Agent descriptor for X client connections is FD#" - << fd << ".\n" << logofs_flush; - - *logofs << "NXTransProxy: Disabling listening on further X client connections.\n" - << logofs_flush; - - #endif - - useTcpSocket = 0; - useUnixSocket = 0; - useAgentSocket = 1; - - agentFD[1] = fd; - } - } - else if (mode == NX_MODE_SERVER) - { - if (fd != NX_FD_ANY) - { - #ifdef TEST - *logofs << "NXTransProxy: PANIC! Agent descriptor for X server connections " - << "not supported yet.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Agent descriptor for X server connections " - << "not supported yet.\n"; - - return -1; - } - } - - const char *env = GetOptions(options); - - if (ParseEnvironmentOptions(env, 0) < 0) - { - cerr << "Error" << ": Parsing of NX transport options failed.\n"; - - return -1; - } - - // - // Set the path of the NX directories. - // - - SetDirectories(); - - // - // Open the log files. - // - - SetLogs(); - - #ifdef TEST - *logofs << "NXTransProxy: Going to run the NX transport loop.\n" - << logofs_flush; - #endif - - WaitCleanup(); - - // - // This function should never return. - // - - exit(0); -} - -void NXTransExit(int code) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - static int recurse; - - if (++recurse > 1) - { - #ifdef TEST - *logofs << "NXTransExit: Aborting process with pid '" - << getpid() << "' due to recursion through " - << "exit.\n" << logofs_flush; - #endif - - abort(); - } - - #ifdef TEST - *logofs << "NXTransExit: Process with pid '" - << getpid() << "' called exit with code '" - << code << "'.\n" << logofs_flush; - #endif - - if (control != NULL) - { - // - // Be sure that there we can detect the - // termination of the watchdog. - // - - EnableSignals(); - - // - // Close the NX transport if it was not - // shut down already. - // - - NXTransDestroy(NX_FD_ANY); - } - - exit(code); -} - -int NXTransParseCommandLine(int argc, const char **argv) -{ - return ParseCommandLineOptions(argc, argv); -} - -int NXTransParseEnvironment(const char *env, int force) -{ - return ParseEnvironmentOptions(env, force); -} - -void NXTransCleanup() -{ - HandleCleanup(); -} - -void NXTransCleanupForReconnect() -{ - HandleCleanupForReconnect(); -} - -// -// Check the parameters for subsequent -// initialization of the NX transport. -// - -int NXTransCreate(int fd, int mode, const char* options) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - // - // Be sure we have a jump context, in the - // case a subsequent operation will cause - // a cleanup. - // - - if (setjmp(context) == 1) - { - return -1; - } - - // - // Create the parameters repository - // - - if (control != NULL) - { - #ifdef PANIC - *logofs << "NXTransCreate: PANIC! The NX transport seems " - << "to be already running.\n" << logofs_flush; - #endif - - cerr << "Error" << ": The NX transport seems " - << "to be already running.\n"; - - return -1; - } - - control = new Control(); - - if (control == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error creating the NX transport.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error creating the NX transport.\n"; - - return -1; - } - - lastProxy = getpid(); - - #ifdef TEST - *logofs << "NXTransCreate: Caller process running with pid '" - << lastProxy << "'.\n" << logofs_flush; - #endif - - // - // Set the local proxy mode an parse the - // display NX options. - // - - SetMode(mode); - - const char *env = GetOptions(options); - - if (ParseEnvironmentOptions(env, 0) < 0) - { - cerr << "Error" << ": Parsing of NX transport options failed.\n"; - - return -1; - } - - // - // Set the path of the NX directories. - // - - SetDirectories(); - - // - // Open the log files. - // - - SetLogs(); - - // - // Use the provided descriptor. - // - - proxyFD = fd; - - #ifdef TEST - *logofs << "NXTransCreate: Called with NX proxy descriptor '" - << proxyFD << "'.\n" << logofs_flush; - #endif - - #ifdef TEST - *logofs << "NXTransCreate: Creation of the NX transport completed.\n" - << logofs_flush; - #endif - - return 1; -} - -// -// Tell the proxy to use the descriptor as the internal -// connection to the X client side NX agent. This will -// have the side effect of disabling listening for add- -// itional X client connections. -// - -int NXTransAgent(int fd[2]) -{ - // - // Be sure we have a jump context, in the - // case a subsequent operation will cause - // a cleanup. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - if (setjmp(context) == 1) - { - return -1; - } - - if (control == NULL) - { - cerr << "Error" << ": Can't set the NX agent without a NX transport.\n"; - - return -1; - } - else if (control -> ProxyMode != proxy_client) - { - #ifdef PANIC - *logofs << "NXTransAgent: Invalid mode while setting the NX agent.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid mode while setting the NX agent.\n\n"; - - return -1; - } - - useTcpSocket = 0; - useUnixSocket = 0; - useAgentSocket = 1; - - agentFD[0] = fd[0]; - agentFD[1] = fd[1]; - - #ifdef TEST - - *logofs << "NXTransAgent: Internal descriptors for agent are FD#" - << agentFD[0] << " and FD#" << agentFD[1] << ".\n" - << logofs_flush; - - *logofs << "NXTransAgent: Disabling listening for further X client " - << "connections.\n" << logofs_flush; - - #endif - - agent = new Agent(agentFD); - - if (agent == NULL || agent -> isValid() != 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error creating the NX memory transport .\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error creating the NX memory transport.\n"; - - HandleCleanup(); - } - - #ifdef TEST - *logofs << "NXTransAgent: Enabling memory-to-memory transport.\n" - << logofs_flush; - #endif - - return 1; -} - -int NXTransClose(int fd) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - /* - * Only handle the proxy connection. The X - * transport will take care of closing its - * end of the socket pair. - */ - - if (control != NULL && ((agent != NULL && - (fd == agentFD[0] || fd == NX_FD_ANY)) || - (fd == proxyFD || fd == NX_FD_ANY))) - { - if (proxy != NULL) - { - #ifdef TEST - *logofs << "NXTransClose: Closing down all the X connections.\n" - << logofs_flush; - #endif - - CleanupConnections(); - } - } - #ifdef TEST - else - { - *logofs << "NXTransClose: The NX transport is not running.\n" - << logofs_flush; - } - #endif - - return 1; -} - -// -// Close down the transport and free the -// allocated NX resources. -// - -int NXTransDestroy(int fd) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - if (control != NULL && ((agent != NULL && - (fd == agentFD[0] || fd == NX_FD_ANY)) || - (fd == proxyFD || fd == NX_FD_ANY))) - { - // - // Shut down the X connections and - // wait the cleanup to complete. - // - - if (proxy != NULL) - { - #ifdef TEST - *logofs << "NXTransDestroy: Closing down all the X connections.\n" - << logofs_flush; - #endif - - CleanupConnections(); - } - - #ifdef TEST - *logofs << "NXTransDestroy: Waiting for the NX transport to terminate.\n" - << logofs_flush; - #endif - - lastDestroy = 1; - - WaitCleanup(); - } - #ifdef TEST - else - { - *logofs << "NXTransDestroy: The NX transport is not running.\n" - << logofs_flush; - } - #endif - - return 1; -} - -// -// Assume that the NX transport is valid -// as long as the control class has not -// been destroyed. -// - -int NXTransRunning(int fd) -{ - return (control != NULL); -} - -int NXTransContinue(struct timeval *selectTs) -{ - if (control != NULL) - { - // - // If no timeout is provided use - // the default. - // - - T_timestamp newTs; - - if (selectTs == NULL) - { - setTimestamp(newTs, control -> PingTimeout); - - selectTs = &newTs; - } - - // - // Use empty masks and only get the - // descriptors set by the proxy. - // - - fd_set readSet; - fd_set writeSet; - - int setFDs; - int errorFDs; - int resultFDs; - - setFDs = 0; - - FD_ZERO(&readSet); - FD_ZERO(&writeSet); - - // - // Run a new loop. If the transport - // is gone avoid sleeping until the - // timeout. - // - - if (NXTransPrepare(&setFDs, &readSet, &writeSet, selectTs) != 0) - { - NXTransSelect(&resultFDs, &errorFDs, &setFDs, &readSet, &writeSet, selectTs); - - NXTransExecute(&resultFDs, &errorFDs, &setFDs, &readSet, &writeSet, selectTs); - } - } - - return (control != NULL); -} - -int NXTransSignal(int signal, int action) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - if (control == NULL) - { - return 0; - } - - if (action == NX_SIGNAL_RAISE) - { - #ifdef TEST - *logofs << "NXTransSignal: Raising signal '" << DumpSignal(signal) - << "' in the proxy handler.\n" << logofs_flush; - #endif - - HandleSignal(signal); - - return 1; - } - else if (signal == NX_SIGNAL_ANY) - { - #ifdef TEST - *logofs << "NXTransSignal: Setting action of all signals to '" - << action << "'.\n" << logofs_flush; - #endif - - for (int i = 0; i < 32; i++) - { - if (CheckSignal(i) == 1) - { - NXTransSignal(i, action); - } - } - - return 1; - } - else if (CheckSignal(signal) == 1) - { - #ifdef TEST - *logofs << "NXTransSignal: Setting action of signal '" - << DumpSignal(signal) << "' to '" << action - << "'.\n" << logofs_flush; - #endif - - if (action == NX_SIGNAL_ENABLE || - action == NX_SIGNAL_FORWARD) - { - InstallSignal(signal, action); - - return 1; - } - else if (action == NX_SIGNAL_DISABLE) - { - RestoreSignal(signal); - - return 1; - } - } - - #ifdef WARNING - *logofs << "NXTransSignal: WARNING! Unable to perform action '" - << action << "' on signal '" << DumpSignal(signal) - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Unable to perform action '" << action - << "' on signal '" << DumpSignal(signal) - << "'.\n"; - - return -1; -} - -int NXTransCongestion(int fd) -{ - if (control != NULL && proxy != NULL) - { - #ifdef DUMP - - int congestion = proxy -> getCongestion(proxyFD); - - *logofs << "NXTransCongestion: Returning " << congestion - << " as current congestion level.\n" << logofs_flush; - - return congestion; - - #endif - - return (proxy -> getCongestion(proxyFD)); - } - - return 0; -} - -int NXTransHandler(int fd, int type, void (*handler)(void *parameter, - int reason), void *parameter) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - switch (type) - { - case NX_HANDLER_FLUSH: - { - flushCallback = handler; - flushParameter = parameter; - - break; - } - case NX_HANDLER_STATISTICS: - { - // - // Reporting of statistics by the agent - // still needs to be implemented. - // - - statisticsCallback = handler; - statisticsParameter = parameter; - - break; - } - default: - { - #ifdef TEST - *logofs << "NXTransHandler: WARNING! Failed to set " - << "the NX callback for event '" << type << "' to '" - << (void *) handler << "' and parameter '" - << parameter << "'.\n" << logofs_flush; - #endif - - return 0; - } - } - - #ifdef TEST - *logofs << "NXTransHandler: Set the NX " - << "callback for event '" << type << "' to '" - << (void *) handler << "' and parameter '" - << parameter << "'.\n" << logofs_flush; - #endif - - return 1; -} - -int NXTransRead(int fd, char *data, int size) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - if (control != NULL && agent != NULL && - fd == agentFD[0]) - { - #ifdef DUMP - *logofs << "NXTransRead: Dequeuing " << size << " bytes " - << "from FD#" << agentFD[0] << ".\n" << logofs_flush; - #endif - - int result = agent -> dequeueData(data, size); - - #ifdef DUMP - - if (result < 0 && EGET() == EAGAIN) - { - *logofs << "NXTransRead: WARNING! Dequeuing from FD#" - << agentFD[0] << " would block.\n" << logofs_flush; - } - else - { - *logofs << "NXTransRead: Dequeued " << result << " bytes " - << "to FD#" << agentFD[0] << ".\n" << logofs_flush; - } - - #endif - - return result; - } - else - { - #ifdef DUMP - *logofs << "NXTransRead: Reading " << size << " bytes " - << "from FD#" << fd << ".\n" << logofs_flush; - #endif - - return read(fd, data, size); - } -} - -int NXTransReadVector(int fd, struct iovec *iovdata, int iovsize) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - if (control != NULL && agent != NULL && - fd == agentFD[0]) - { - #if defined(DUMP) - - if (control -> ProxyStage >= stage_operational && - agent -> localReadable() > 0) - { - *logofs << "NXTransReadVector: WARNING! Agent has data readable.\n" - << logofs_flush; - } - - #endif - - char *base; - - int length; - int result; - - struct iovec *vector = iovdata; - int count = iovsize; - - ESET(0); - - int i = 0; - int total = 0; - - for (; i < count; i++, vector++) - { - length = vector -> iov_len; - base = (char *) vector -> iov_base; - - while (length > 0) - { - #ifdef DUMP - *logofs << "NXTransReadVector: Dequeuing " << length - << " bytes " << "from FD#" << agentFD[0] << ".\n" - << logofs_flush; - #endif - - result = agent -> dequeueData(base, length); - - #ifdef DUMP - - if (result < 0 && EGET() == EAGAIN) - { - *logofs << "NXTransReadVector: WARNING! Dequeuing from FD#" - << agentFD[0] << " would block.\n" << logofs_flush; - } - else - { - *logofs << "NXTransReadVector: Dequeued " << result - << " bytes " << "from FD#" << agentFD[0] << ".\n" - << logofs_flush; - } - - #endif - - if (result < 0 && total == 0) - { - return result; - } - else if (result <= 0) - { - return total; - } - - ESET(0); - - length -= result; - total += result; - base += result; - } - } - - return total; - } - else - { - #ifdef DUMP - *logofs << "NXTransReadVector: Reading vector with " - << iovsize << " elements from FD#" << fd << ".\n" - << logofs_flush; - #endif - - return readv(fd, iovdata, iovsize); - } -} - -int NXTransReadable(int fd, int *readable) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - if (control == NULL || agent == NULL || - fd != agentFD[0]) - { - #ifdef DUMP - - int result = GetBytesReadable(fd, readable); - - if (result == -1) - { - *logofs << "NXTransReadable: Error detected on FD#" - << fd << ".\n" << logofs_flush; - } - else - { - *logofs << "NXTransReadable: Returning " << *readable - << " bytes as readable from FD#" << fd - << ".\n" << logofs_flush; - } - - return result; - - #else - - return GetBytesReadable(fd, readable); - - #endif - } - - int result = agent -> dequeuableData(); - - switch (result) - { - case 0: - { - // - // The client might have enqueued data to our side - // and is now checking for the available events. As - // _XEventsQueued() may omit to call _XSelect(), we - // handle here the new data that is coming from the - // proxy to avoid spinning through this function - // again. - // - - if (proxy != NULL && proxy -> canRead() == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "NXTransReadable: WARNING! Trying to " - << "read to generate new agent data.\n" - << logofs_flush; - #endif - - // - // Set the context as the function - // can cause a cleanup. - // - - if (setjmp(context) == 1) - { - return -1; - } - - if (proxy -> handleRead() < 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "NXTransReadable: Failure reading " - << "messages from proxy FD#" << proxyFD - << ".\n" << logofs_flush; - #endif - - HandleShutdown(); - } - - // - // Call again the routine. By reading - // new control messages from the proxy - // the agent channel may be gone. - // - - return NXTransReadable(fd, readable); - } - - #ifdef DUMP - *logofs << "NXTransReadable: Returning " << 0 - << " bytes as readable from FD#" << fd - << " with result 0.\n" << logofs_flush; - #endif - - *readable = 0; - - return 0; - } - case -1: - { - #ifdef DUMP - *logofs << "NXTransReadable: Returning " << 0 - << " bytes as readable from FD#" << fd - << " with result -1.\n" << logofs_flush; - #endif - - *readable = 0; - - return -1; - } - default: - { - #ifdef DUMP - *logofs << "NXTransReadable: Returning " << result - << " bytes as readable from FD#" << fd - << " with result 0.\n" << logofs_flush; - #endif - - *readable = result; - - return 0; - } - } -} - -int NXTransWrite(int fd, char *data, int size) -{ - // - // Be sure we have a valid log file. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - if (control != NULL && agent != NULL && - fd == agentFD[0]) - { - int result; - - if (proxy != NULL) - { - if (proxy -> canRead(agentFD[1]) == 0) - { - #if defined(DUMP) || defined(TEST) - *logofs << "NXTransWrite: WARNING! Delayed enqueuing to FD#" - << agentFD[0] << " with proxy unable to read.\n" - << logofs_flush; - #endif - - ESET(EAGAIN); - - return -1; - } - - // - // Set the context as the function - // can cause a cleanup. - // - - if (setjmp(context) == 1) - { - return -1; - } - - // - // Don't enqueue the data to the transport - // but let the channel borrow the buffer. - // - - #ifdef DUMP - *logofs << "NXTransWrite: Letting the channel borrow " - << size << " bytes from FD#" << agentFD[0] - << ".\n" << logofs_flush; - #endif - - result = proxy -> handleRead(agentFD[1], data, size); - - if (result == 1) - { - result = size; - } - else - { - if (result == 0) - { - ESET(EAGAIN); - } - else - { - ESET(EPIPE); - } - - result = -1; - } - } - else - { - // - // We don't have a proxy connection, yet. - // Enqueue the data to the agent transport. - // - - #ifdef DUMP - *logofs << "NXTransWrite: Enqueuing " << size << " bytes " - << "to FD#" << agentFD[0] << ".\n" << logofs_flush; - #endif - - result = agent -> enqueueData(data, size); - } - - #ifdef DUMP - - if (result < 0) - { - if (EGET() == EAGAIN) - { - *logofs << "NXTransWrite: WARNING! Enqueuing to FD#" - << agentFD[0] << " would block.\n" - << logofs_flush; - } - else - { - *logofs << "NXTransWrite: WARNING! Error enqueuing to FD#" - << agentFD[0] << ".\n" << logofs_flush; - } - } - else - { - *logofs << "NXTransWrite: Enqueued " << result << " bytes " - << "to FD#" << agentFD[0] << ".\n" << logofs_flush; - } - - #endif - - return result; - } - else - { - #ifdef DUMP - *logofs << "NXTransWrite: Writing " << size << " bytes " - << "to FD#" << fd << ".\n" << logofs_flush; - #endif - - return write(fd, data, size); - } -} - -int NXTransWriteVector(int fd, struct iovec *iovdata, int iovsize) -{ - // - // Be sure we have a valid log file and a - // jump context because we will later call - // functions that can perform a cleanup. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - int result = 0; - - if (control != NULL && agent != NULL && - fd == agentFD[0]) - { - // - // See the comment in NXTransWrite(). - // - - if (proxy != NULL) - { - if (proxy -> canRead(agentFD[1]) == 0) - { - #if defined(DUMP) || defined(TEST) - *logofs << "NXTransWriteVector: WARNING! Delayed enqueuing to FD#" - << agentFD[0] << " with proxy unable to read.\n" - << logofs_flush; - #endif - - ESET(EAGAIN); - - return -1; - } - } - - // - // Set the context as the function - // can cause a cleanup. - // - - if (setjmp(context) == 1) - { - return -1; - } - - char *base; - - int length; - - struct iovec *vector = iovdata; - int count = iovsize; - - ESET(0); - - int i = 0; - int total = 0; - - for (; i < count; i++, vector++) - { - length = vector -> iov_len; - base = (char *) vector -> iov_base; - - while (length > 0) - { - if (proxy != NULL) - { - // - // Don't enqueue the data to the transport - // but let the channel borrow the buffer. - // - - #ifdef DUMP - *logofs << "NXTransWriteVector: Letting the channel borrow " - << length << " bytes from FD#" << agentFD[0] - << ".\n" << logofs_flush; - #endif - - result = proxy -> handleRead(agentFD[1], base, length); - - if (result == 1) - { - result = length; - } - else - { - if (result == 0) - { - ESET(EAGAIN); - } - else - { - ESET(EPIPE); - } - - result = -1; - } - } - else - { - // - // We don't have a proxy connection, yet. - // Enqueue the data to the agent transport. - // - - #ifdef DUMP - *logofs << "NXTransWriteVector: Enqueuing " << length - << " bytes " << "to FD#" << agentFD[0] << ".\n" - << logofs_flush; - #endif - - result = agent -> enqueueData(base, length); - } - - #ifdef DUMP - - if (result < 0) - { - if (EGET() == EAGAIN) - { - *logofs << "NXTransWriteVector: WARNING! Enqueuing to FD#" - << agentFD[0] << " would block.\n" - << logofs_flush; - } - else - { - *logofs << "NXTransWriteVector: WARNING! Error enqueuing to FD#" - << agentFD[0] << ".\n" << logofs_flush; - } - } - else - { - *logofs << "NXTransWriteVector: Enqueued " << result - << " bytes " << "to FD#" << agentFD[0] << ".\n" - << logofs_flush; - } - - #endif - - if (result < 0 && total == 0) - { - return result; - } - else if (result <= 0) - { - return total; - } - - ESET(0); - - length -= result; - total += result; - base += result; - } - } - - return total; - } - else - { - #ifdef DUMP - *logofs << "NXTransWriteVector: Writing vector with " - << iovsize << " elements to FD#" << fd << ".\n" - << logofs_flush; - #endif - - return writev(fd, iovdata, iovsize); - } -} - -int NXTransPolicy(int fd, int type) -{ - if (control != NULL) - { - if (usePolicy == -1) - { - #if defined(TEST) || defined(INFO) - *logofs << "NXTransPolicy: Setting flush policy on " - << "proxy FD#" << proxyFD << " to '" - << DumpPolicy(type == NX_POLICY_DEFERRED ? - policy_deferred : policy_immediate) - << "'.\n" << logofs_flush; - #endif - - control -> FlushPolicy = (type == NX_POLICY_DEFERRED ? - policy_deferred : policy_immediate); - - if (proxy != NULL) - { - proxy -> handleFlush(); - } - - return 1; - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "NXTransPolicy: Ignoring the agent " - << "setting with user policy set to '" - << DumpPolicy(control -> FlushPolicy) - << "'.\n" << logofs_flush; - #endif - - return 0; - } - } - - return 0; -} - -int NXTransFlushable(int fd) -{ - if (proxy == NULL || agent == NULL || - fd != agentFD[0]) - { - #ifdef DUMP - *logofs << "NXTransFlushable: Returning 0 bytes as " - << "flushable for unrecognized FD#" << fd - << ".\n" << logofs_flush; - #endif - - return 0; - } - else - { - #if defined(DUMP) || defined(INFO) - *logofs << "NXTransFlushable: Returning " << proxy -> - getFlushable(proxyFD) << " as bytes flushable on " - << "proxy FD#" << proxyFD << ".\n" - << logofs_flush; - #endif - - return proxy -> getFlushable(proxyFD); - } -} - -int NXTransFlush(int fd) -{ - if (proxy != NULL) - { - #if defined(TEST) || defined(INFO) - *logofs << "NXTransFlush: Requesting an immediate flush of " - << "proxy FD#" << proxyFD << ".\n" - << logofs_flush; - #endif - - return proxy -> handleFlush(); - } - - return 0; -} - -int NXTransChannel(int fd, int channelFd, int type) -{ - if (proxy != NULL) - { - // - // Set the context as the function - // can cause a cleanup. - // - - if (setjmp(context) == 1) - { - return -1; - } - - #if defined(TEST) || defined(INFO) - *logofs << "NXTransChannel: Going to create a new channel " - << "with type '" << type << "' on FD#" << channelFd - << ".\n" << logofs_flush; - #endif - - int result = -1; - - switch (type) - { - case NX_CHANNEL_X11: - { - if (useUnixSocket == 1 || useTcpSocket == 1 || - useAgentSocket == 1 || useAuxSocket == 1) - { - result = proxy -> handleNewConnection(channel_x11, channelFd); - } - - break; - } - case NX_CHANNEL_CUPS: - { - if (useCupsSocket == 1) - { - result = proxy -> handleNewConnection(channel_cups, channelFd); - } - - break; - } - case NX_CHANNEL_SMB: - { - if (useSmbSocket == 1) - { - result = proxy -> handleNewConnection(channel_smb, channelFd); - } - - break; - } - case NX_CHANNEL_MEDIA: - { - if (useMediaSocket == 1) - { - result = proxy -> handleNewConnection(channel_media, channelFd); - } - - break; - } - case NX_CHANNEL_HTTP: - { - if (useHttpSocket == 1) - { - result = proxy -> handleNewConnection(channel_http, channelFd); - } - - break; - } - case NX_CHANNEL_FONT: - { - if (useFontSocket == 1) - { - result = proxy -> handleNewConnection(channel_font, channelFd); - } - - break; - } - case NX_CHANNEL_SLAVE: - { - if (useSlaveSocket == 1) - { - result = proxy -> handleNewConnection(channel_slave, channelFd); - } - - break; - } - default: - { - #ifdef WARNING - *logofs << "NXTransChannel: WARNING! Unrecognized channel " - << "type '" << type << "'.\n" << logofs_flush; - #endif - - break; - } - } - - #ifdef WARNING - - if (result != 1) - { - *logofs << "NXTransChannel: WARNING! Could not create the " - << "new channel with type '" << type << "' on FD#" - << channelFd << ".\n" << logofs_flush; - } - - #endif - - return result; - } - - return 0; -} - -const char *NXTransFile(int type) -{ - char *name = NULL; - - switch (type) - { - case NX_FILE_SESSION: - { - name = sessionFileName; - - break; - } - case NX_FILE_ERRORS: - { - name = errorsFileName; - - break; - } - case NX_FILE_OPTIONS: - { - name = optionsFileName; - - break; - } - case NX_FILE_STATS: - { - name = statsFileName; - - break; - } - } - - if (name != NULL && *name != '\0') - { - return name; - } - - return NULL; -} - -long NXTransTime() -{ - static T_timestamp last = getTimestamp(); - - T_timestamp now = getTimestamp(); - - long diff = diffTimestamp(last, now); - - last = now; - - return diff; -} - -int NXTransAlert(int code, int local) -{ - if (proxy != NULL) - { - #if defined(DUMP) || defined(INFO) - *logofs << "NXTransAlert: Requesting a NX dialog with code " - << code << " and local " << local << ".\n" - << logofs_flush; - #endif - - if (local == 0) - { - // - // Set the context as the function - // can cause a cleanup. - // - - if (setjmp(context) == 1) - { - return -1; - } - - proxy -> handleAlert(code); - } - else - { - // - // Show the alert at the next loop. - // - - HandleAlert(code, local); - } - - return 1; - } - #if defined(DUMP) || defined(INFO) - else - { - if (logofs == NULL) - { - logofs = &cerr; - } - - *logofs << "NXTransAlert: Can't request an alert without " - << "a valid NX transport.\n" << logofs_flush; - } - #endif - - return 0; -} - -// -// Prepare the file sets and the timeout -// for a later execution of the select(). -// - -int NXTransPrepare(int *setFDs, fd_set *readSet, - fd_set *writeSet, struct timeval *selectTs) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - // - // Control is NULL if the NX transport was - // reset or was never created. If control - // is valid then prepare to jump back when - // the transport is destroyed. - // - - if (control == NULL || setjmp(context) == 1) - { - return 0; - } - - #if defined(TEST) || defined(INFO) - *logofs << "\nNXTransPrepare: Going to prepare the NX transport.\n" - << logofs_flush; - #endif - - if (control -> ProxyStage < stage_operational) - { - handleNegotiationInLoop(*setFDs, *readSet, *writeSet, *selectTs); - } - else - { - #if defined(TEST) || defined(INFO) - - if (isTimestamp(*selectTs) == 0) - { - *logofs << "Loop: WARNING! Preparing the select with requested " - << "timeout of " << selectTs -> tv_sec << " S and " - << (double) selectTs -> tv_usec / 1000 << " Ms.\n" - << logofs_flush; - } - else - { - *logofs << "Loop: Preparing the select with requested " - << "timeout of " << selectTs -> tv_sec << " S and " - << (double) selectTs -> tv_usec / 1000 << " Ms.\n" - << logofs_flush; - } - - #endif - - // - // Set descriptors of listening sockets. - // - - handleSetListenersInLoop(*readSet, *setFDs); - - // - // Set descriptors of both proxy and X - // connections. - // - - handleSetReadInLoop(*readSet, *setFDs, *selectTs); - - // - // Find out which file descriptors have - // data to write. - // - - handleSetWriteInLoop(*writeSet, *setFDs, *selectTs); - } - - // - // Prepare the masks for handling the memory- - // to-memory transport. This is required even - // during session negotiation. - // - - if (agent != NULL) - { - handleSetAgentInLoop(*setFDs, *readSet, *writeSet, *selectTs); - } - - // - // Register time spent handling messages. - // - - nowTs = getNewTimestamp(); - - diffTs = diffTimestamp(startTs, nowTs); - - #ifdef TEST - *logofs << "Loop: Mark - 0 - at " << strMsTimestamp() - << " with " << diffTs << " Ms elapsed.\n" - << logofs_flush; - #endif - - // - // TODO: Should add the read time in two - // parts otherwise the limits are checked - // before the counters are updated with - // time spent in the last loop. - // - - if (control -> ProxyStage >= stage_operational) - { - statistics -> addReadTime(diffTs); - } - - startTs = nowTs; - - #ifdef DEBUG - *logofs << "Loop: New timestamp is " << strMsTimestamp(startTs) - << ".\n" << logofs_flush; - #endif - - return 1; -} - -// -// Let's say that we call select() to find out -// if any of the handled descriptors has data, -// but actually things are a bit more complex -// than that. -// - -int NXTransSelect(int *resultFDs, int *errorFDs, int *setFDs, fd_set *readSet, - fd_set *writeSet, struct timeval *selectTs) -{ - #ifdef TIME - - static T_timestamp lastTs; - - #endif - - if (logofs == NULL) - { - logofs = &cerr; - } - - // - // Control is NULL if the NX transport was - // reset or never created. If control is - // valid then prepare for jumping back in - // the case of an error. - // - - if (control == NULL || setjmp(context) == 1) - { - *resultFDs = select(*setFDs, readSet, writeSet, NULL, selectTs); - - *errorFDs = errno; - - return 0; - } - - #if defined(TEST) || defined(INFO) - *logofs << "\nNXTransSelect: Going to select the NX descriptors.\n" - << logofs_flush; - #endif - - #if defined(TEST) || defined(INFO) - - handleCheckSelectInLoop(*setFDs, *readSet, *writeSet, *selectTs); - - #endif - - #ifdef TIME - - diffTs = diffTimestamp(lastTs, getNewTimestamp()); - - if (diffTs > 20) - { - *logofs << "Loop: TIME! Spent " << diffTs - << " Ms handling messages for proxy FD#" - << proxyFD << ".\n" << logofs_flush; - } - - lastTs = getNewTimestamp(); - - #endif - - #if defined(TEST) || defined(INFO) - - if (isTimestamp(*selectTs) == 0) - { - *logofs << "Loop: WARNING! Executing the select with requested " - << "timeout of " << selectTs -> tv_sec << " S and " - << (double) selectTs -> tv_usec / 1000 << " Ms.\n" - << logofs_flush; - } - else if (proxy != NULL && proxy -> getFlushable(proxyFD) > 0) - { - *logofs << "Loop: WARNING! Proxy FD#" << proxyFD - << " has " << proxy -> getFlushable(proxyFD) - << " bytes to write but timeout is " - << selectTs -> tv_sec << " S and " - << selectTs -> tv_usec / 1000 << " Ms.\n" - << logofs_flush; - } - - #endif - - // - // Wait for the selected sockets - // or the timeout. - // - - ESET(0); - - *resultFDs = select(*setFDs, readSet, writeSet, NULL, selectTs); - - *errorFDs = EGET(); - - #ifdef TIME - - diffTs = diffTimestamp(lastTs, getNewTimestamp()); - - if (diffTs > 100) - { - *logofs << "Loop: TIME! Spent " << diffTs - << " Ms waiting for new data for proxy FD#" - << proxyFD << ".\n" << logofs_flush; - } - - lastTs = getNewTimestamp(); - - #endif - - // - // Check the result of the select. - // - - #if defined(TEST) || defined(INFO) - - handleCheckResultInLoop(*resultFDs, *errorFDs, *setFDs, *readSet, *writeSet, *selectTs, startTs); - - #endif - - // - // Get time spent in select. The accouting is done - // in milliseconds. This is a real problem on fast - // machines where each loop is unlikely to take - // more than 500 us, so consider that the results - // can be inaccurate. - // - - nowTs = getNewTimestamp(); - - diffTs = diffTimestamp(startTs, nowTs); - - #ifdef TEST - *logofs << "Loop: Out of select after " << diffTs << " Ms " - << "at " << strMsTimestamp(nowTs) << " with result " - << *resultFDs << ".\n" << logofs_flush; - #endif - - startTs = nowTs; - - #ifdef DEBUG - *logofs << "Loop: New timestamp is " << strMsTimestamp(startTs) - << ".\n" << logofs_flush; - #endif - - if (control -> ProxyStage >= stage_operational) - { - statistics -> addIdleTime(diffTs); - } - - if (*resultFDs < 0) - { - // - // Check if the call was interrupted or if any of the - // managed descriptors has become invalid. This can - // happen to the X11 code, before the descriptor is - // removed from the managed set. - // - - #ifdef __sun - - if (*errorFDs == EINTR || *errorFDs == EBADF || - *errorFDs == EINVAL) - - #else - - if (*errorFDs == EINTR || *errorFDs == EBADF) - - #endif - - { - #ifdef TEST - - if (*errorFDs == EINTR) - { - *logofs << "Loop: Select failed due to EINTR error.\n" - << logofs_flush; - } - else - { - *logofs << "Loop: WARNING! Call to select failed. Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - } - - #endif - } - else - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to select failed. Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Call to select failed. Error is " - << EGET() << " '" << ESTR() << "'.\n"; - - HandleCleanup(); - } - } - - return 1; -} - -// -// Perform the required actions on all -// the descriptors having I/O pending. -// - -int NXTransExecute(int *resultFDs, int *errorFDs, int *setFDs, fd_set *readSet, - fd_set *writeSet, struct timeval *selectTs) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - // - // Control is NULL if the NX transport was - // reset or never created. If control is - // valid then prepare for jumping back in - // the case of an error. - // - - if (control == NULL || setjmp(context) == 1) - { - return 0; - } - - #if defined(TEST) || defined(INFO) - *logofs << "\nNXTransExecute: Going to execute I/O on the NX descriptors.\n" - << logofs_flush; - #endif - - if (control -> ProxyStage >= stage_operational) - { - // - // Check if I/O is possible on the proxy and - // local agent descriptors. - // - - if (agent != NULL) - { - handleAgentInLoop(*resultFDs, *errorFDs, *setFDs, *readSet, *writeSet, *selectTs); - } - - #ifdef TEST - *logofs << "Loop: Mark - 1 - at " << strMsTimestamp() - << " with " << diffTimestamp(startTs, getTimestamp()) - << " Ms elapsed.\n" << logofs_flush; - #endif - - // - // Rotate the channel that will be handled - // first. - // - - handleRotateInLoop(); - - // - // Flush any data on newly writable sockets. - // - - handleWritableInLoop(*resultFDs, *writeSet); - - #ifdef TEST - *logofs << "Loop: Mark - 2 - at " << strMsTimestamp() - << " with " << diffTimestamp(startTs, getTimestamp()) - << " Ms elapsed.\n" << logofs_flush; - #endif - - // - // Check if any socket has become readable. - // - - handleReadableInLoop(*resultFDs, *readSet); - - #ifdef TEST - *logofs << "Loop: Mark - 3 - at " << strMsTimestamp() - << " with " << diffTimestamp(startTs, getTimestamp()) - << " Ms elapsed.\n" << logofs_flush; - #endif - - // - // Handle the scheduled events on channels. - // - // - Restart, if possible, any client that was - // put to sleep. - // - // - Check if there are pointer motion events to - // flush. This applies only to X server side. - // - // - Check if any channel has exited the conges- - // tion state. - // - // - Check if there are images that are currently - // being streamed. - // - - handleEventsInLoop(); - - #ifdef TEST - *logofs << "Loop: Mark - 4 - at " << strMsTimestamp() - << " with " << diffTimestamp(startTs, getTimestamp()) - << " Ms elapsed.\n" << logofs_flush; - #endif - - // - // Check if user sent a signal to produce - // statistics. - // - - handleStatisticsInLoop(); - - // - // We may have flushed the proxy link or - // handled data coming from the remote. - // Post-process the masks and set the - // selected agent descriptors as ready. - // - - if (agent != NULL) - { - handleAgentLateInLoop(*resultFDs, *errorFDs, *setFDs, *readSet, *writeSet, *selectTs); - } - - #ifdef TEST - *logofs << "Loop: Mark - 5 - at " << strMsTimestamp() - << " with " << diffTimestamp(startTs, getTimestamp()) - << " Ms elapsed.\n" << logofs_flush; - #endif - - // - // Check if there is any data to flush. - // Agents should flush the proxy link - // explicitly. - // - - handleFlushInLoop(); - - #ifdef TEST - *logofs << "Loop: Mark - 6 - at " << strMsTimestamp() - << " with " << diffTimestamp(startTs, getTimestamp()) - << " Ms elapsed.\n" << logofs_flush; - #endif - } - - // - // Check if we have an alert to show. - // - - handleAlertInLoop(); - - if (control -> ProxyStage >= stage_operational) - { - // - // Check if it's time to give up. - // - - handleCheckSessionInLoop(); - - // - // Check if local proxy is consuming - // too many resources. - // - - handleCheckBitrateInLoop(); - - // - // Check coherency of internal state. - // - - #if defined(TEST) || defined(INFO) - - handleCheckStateInLoop(*setFDs); - - #endif - - #ifdef TEST - *logofs << "Loop: Mark - 7 - at " << strMsTimestamp() - << " with " << diffTimestamp(startTs, getTimestamp()) - << " Ms elapsed.\n" << logofs_flush; - #endif - } - - // - // Truncate the logs if needed. - // - - handleLogReopenInLoop(logsTs, nowTs); - - return 1; -} - -// -// Initialize the connection parameters and -// prepare for negotiating the link with the -// remote proxy. -// - -int InitBeforeNegotiation() -{ - // - // Disable limits on core dumps. - // - - SetCore(); - - // - // Install the signal handlers. - // - - InstallSignals(); - - // - // Track how much time we spent in initialization. - // - - nowTs = getNewTimestamp(); - - startTs = nowTs; - initTs = nowTs; - - #ifdef TEST - *logofs << "Loop: INIT! Taking mark for initialization at " - << strMsTimestamp(initTs) << ".\n" - << logofs_flush; - #endif - - // - // If not explicitly specified, determine if local - // mode is client or server according to parameters - // provided so far. - // - - if (WE_SET_PROXY_MODE == 0) - { - cerr << "Error" << ": Please specify either the -C or -S option.\n"; - - HandleCleanup(); - } - - // - // Start a watchdog. If initialization cannot - // be completed before timeout, then clean up - // everything and exit. - // - - if (control -> ProxyMode == proxy_client) - { - #ifdef TEST - *logofs << "Loop: Starting watchdog process with timeout of " - << control -> InitTimeout / 1000 << " seconds.\n" - << logofs_flush; - #endif - - lastWatchdog = NXTransWatchdog(control -> InitTimeout); - - if (IsFailed(lastWatchdog)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't start the NX watchdog process.\n" - << logofs_flush; - #endif - - SetNotRunning(lastWatchdog); - } - #ifdef TEST - else - { - *logofs << "Loop: Watchdog started with pid '" - << lastWatchdog << "'.\n" << logofs_flush; - } - #endif - } - - // - // Print preliminary info. - // - - PrintProcessInfo(); - - // - // Set cups, multimedia and other - // auxiliary ports. - // - - SetPorts(); - - // - // Increase the number of maximum open - // file descriptors for this process. - // - - SetDescriptors(); - - // - // Set local endianess. - // - - unsigned int test = 1; - - setHostBigEndian(*((unsigned char *) (&test)) == 0); - - #ifdef TEST - *logofs << "Loop: Local host is " - << (hostBigEndian() ? "big endian" : "little endian") - << ".\n" << logofs_flush; - #endif - - if (control -> ProxyMode == proxy_client) - { - // - // Listen on sockets that mimic an X display to - // which X clients will be able to connect (e.g. - // unix:8 and/or localhost:8). - // - - if (useTcpSocket == 1) - { - SetupTcpSocket(); - } - - if (useUnixSocket == 1) - { - SetupUnixSocket(); - } - } - else - { - // - // Don't listen for X connections. - // - - useUnixSocket = 0; - useTcpSocket = 0; - useAgentSocket = 0; - - // - // Get ready to open the local display. - // - - SetupDisplaySocket(xServerAddrFamily, xServerAddr, xServerAddrLength); - } - - // - // If we are the NX server-side proxy we need to - // complete our initializazion. We will mandate - // our parameters at the time the NX client will - // connect. - // - - if (control -> ProxyMode == proxy_client) - { - SetParameters(); - } - - return 1; -} - -int SetupProxyConnection() -{ - - if (proxyFD == -1) - { - - char *socketUri = NULL; - - // Let's make sure, the default value for listenSocket is properly set. Doing this - // here, because we have to make sure that we call it after the connectSocket - // declaration is really really complete. - - if (listenSocket.disabled() && connectSocket.disabled()) - { - char listenPortValue[20] = { 0 }; - sprintf(listenPortValue, "%ld", (long)(proxyPort + DEFAULT_NX_PROXY_PORT_OFFSET)); - - SetAndValidateChannelEndPointArg("local", "listen", listenPortValue, listenSocket); - } - - #ifdef TEST - connectSocket.getSpec(&socketUri); - *logofs << "Loop: connectSocket is "<< ( connectSocket.enabled() ? "enabled" : "disabled") << ". " - << "The socket URI is '"<< ( socketUri != NULL ? socketUri : "") << "'.\n" << logofs_flush; - listenSocket.getSpec(&socketUri); - *logofs << "Loop: listenSocket is "<< ( listenSocket.enabled() ? "enabled" : "disabled") << ". " - << "The socket URI is '"<< ( socketUri != NULL ? socketUri : "") << "'.\n" << logofs_flush; - free(socketUri); - socketUri = NULL; - #endif - - if (WE_INITIATE_CONNECTION) - { - if (connectSocket.getSpec(&socketUri)) - { - #ifdef TEST - *logofs << "Loop: Going to connect to '" << socketUri - << "'.\n" << logofs_flush; - #endif - free(socketUri); - - proxyFD = ConnectToRemote(connectSocket); - - #ifdef TEST - *logofs << "Loop: Connected to remote proxy on FD#" - << proxyFD << ".\n" << logofs_flush; - #endif - - cerr << "Info" << ": Connected to remote proxy on FD#" - << proxyFD << ".\n"; - } - } - else - { - - if (listenSocket.isTCPSocket() && (listenSocket.getTCPPort() < 0)) - { - listenSocket.setSpec(DEFAULT_NX_PROXY_PORT_OFFSET + proxyPort); - } - - if (listenSocket.getSpec(&socketUri)) - { - #ifdef TEST - *logofs << "Loop: Going to wait for connection at '" - << socketUri << "'.\n" << logofs_flush; - #endif - free(socketUri); - - proxyFD = WaitForRemote(listenSocket); - - #ifdef TEST - if (WE_LISTEN_FORWARDER) - { - *logofs << "Loop: Connected to remote forwarder on FD#" - << proxyFD << ".\n" << logofs_flush; - } - else - { - *logofs << "Loop: Connected to remote proxy on FD#" - << proxyFD << ".\n" << logofs_flush; - } - #endif - - } - } - } - #ifdef TEST - else - { - *logofs << "Loop: Using the inherited connection on FD#" - << proxyFD << ".\n" << logofs_flush; - } - #endif - - // - // Set TCP_NODELAY on proxy descriptor - // to reduce startup time. Option will - // later be disabled if needed. - // - // either listenSocket or connectSocket is used here... - - if(listenSocket.isTCPSocket() || connectSocket.isTCPSocket()) - - SetNoDelay(proxyFD, 1); - - // - // We need non-blocking input since the - // negotiation phase. - // - - SetNonBlocking(proxyFD, 1); - - return 1; -} - -// -// Create the required proxy and channel classes -// and get ready for handling the encoded traffic. -// - -int InitAfterNegotiation() -{ - #ifdef TEST - *logofs << "Loop: Connection with remote proxy completed.\n" - << logofs_flush; - #endif - - cerr << "Info" << ": Connection with remote proxy completed.\n" - << logofs_flush; - - // - // If we are the server proxy we completed - // our initializazion phase according to - // the values provided by the client side. - // - - if (control -> ProxyMode == proxy_server) - { - SetParameters(); - } - - // - // Set up the listeners for the additional - // services. - // - - SetupServiceSockets(); - - // - // Create the proxy class and the statistics - // repository and pass all the configuration - // data we negotiated with the remote peer. - // - - SetupProxyInstance(); - - // - // We completed both parsing of user's parameters - // and handlshaking with remote proxy. Now print - // a brief summary including the most significant - // control values. - // - - PrintConnectionInfo(); - - // - // Cancel the initialization watchdog. - // - - if (IsRunning(lastWatchdog)) - { - KillProcess(lastWatchdog, "watchdog", SIGTERM, 1); - - SetNotRunning(lastWatchdog); - - lastSignal = 0; - } - - // - // Start the house-keeper process. It will - // remove the oldest persistent caches, if - // the amount of storage exceed the limits - // set by the user. - // - - StartKeeper(); - - // - // Set the log size check timestamp. - // - - nowTs = getNewTimestamp(); - - logsTs = nowTs; - - // - // TODO: Due to the way the new NX transport is working, - // the accounting of time spent handling messages must - // be rewritten. In particular, at the moment it only - // shows the time spent encoding and decoding messages - // in the main loop, after executing a select. It doesn't - // take into account the time spent in the NXTrans* calls - // where messages can be encoded and decoded implicitly, - // on demand of the agent. When the agent transport is - // in use, these calls constitute the vast majority of - // the encoding activity. The result is that the number - // of KB encoded per second shown by the proxy statistics - // is actually much lower than the real throughput gene- - // rated by the proxy. - // - - #ifdef TEST - *logofs << "Loop: INIT! Completed initialization at " - << strMsTimestamp(nowTs) << " with " - << diffTimestamp(initTs, nowTs) << " Ms " - << "since the init mark.\n" << logofs_flush; - #endif - - initTs = getNewTimestamp(); - - // - // We can now start handling binary data from - // our peer proxy. - // - - if (agent == NULL) - { - cerr << "Session" << ": Session started at '" - << strTimestamp() << "'.\n"; - } - - return 1; -} - -int SetMode(int mode) -{ - // - // Set the local proxy mode. - // - - if (control -> ProxyMode == proxy_undefined) - { - if (mode == NX_MODE_CLIENT) - { - #ifdef TEST - *logofs << "Loop: INIT! Initializing with mode " - << "NX_MODE_CLIENT at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - control -> ProxyMode = proxy_client; - } - else if (mode == NX_MODE_SERVER) - { - #ifdef TEST - *logofs << "Loop: INIT! Initializing with mode " - << "NX_MODE_SERVER at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - control -> ProxyMode = proxy_server; - } - else - { - cerr << "Error" << ": Please specify either " - << "the -C or -S option.\n"; - - HandleCleanup(); - } - } - - return 1; -} - -int SetupProxyInstance() -{ - if (control -> ProxyMode == proxy_client) - { - proxy = new ClientProxy(proxyFD); - } - else - { - proxy = new ServerProxy(proxyFD); - } - - if (proxy == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error creating the NX proxy.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error creating the NX proxy.\n"; - - HandleCleanup(); - } - - // - // Create the statistics repository. - // - - statistics = new Statistics(proxy); - - if (statistics == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error creating the NX statistics.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error creating the NX statistics.\n"; - - HandleCleanup(); - } - - // - // If user gave us a proxy cookie than create the - // X11 authorization repository and find the real - // cookie to be used for our X display. - // - - SetupAuthInstance(); - - // - // Reset the static members in channels. - // - - proxy -> handleChannelConfiguration(); - - // - // Inform the proxies about the ports where they - // will have to forward the network connections. - // - - proxy -> handleDisplayConfiguration(displayHost, xServerAddrFamily, - xServerAddr, xServerAddrLength); - - proxy -> handlePortConfiguration(cupsPort, smbPort, mediaPort, - httpPort, fontPort); - - // - // We handed over the sockaddr structure we - // created when we set up the display socket - // to the proxy. - // - - xServerAddr = NULL; - - // - // Set socket options on proxy link, then propagate link - // configuration to proxy. This includes translating some - // control parameters in 'local' and 'remote'. Finally - // adjust cache parameters according to pack method and - // session type selected by user. - // - - if (proxy -> handleSocketConfiguration() < 0 || - proxy -> handleLinkConfiguration() < 0 || - proxy -> handleCacheConfiguration() < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error configuring the NX transport.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error configuring the NX transport.\n"; - - HandleCleanup(); - } - - // - // Load the message stores from the persistent - // cache. - // - - proxy -> handleLoad(load_if_first); - - // - // Inform the proxy that from now on it can - // start handling the encoded data. - // - - proxy -> setOperational(); - - // - // Are we going to use an internal IPC connection - // with an agent? In this case create the channel - // by using the socket descriptor provided by the - // caller at the proxy initialization. - // - - SetupAgentInstance(); - - // - // Check if we need to verify the existence of - // a matching client cache at shutdown. - // - - #ifdef MATCH - - control -> PersistentCacheCheckOnShutdown = 1; - - #endif - - // - // Flush any data produced so far. - // - - proxy -> handleFlush(); - - #if defined(TEST) || defined(INFO) - - if (proxy -> getFlushable(proxyFD) > 0) - { - *logofs << "Loop: WARNING! Proxy FD#" << proxyFD << " has data " - << "to flush after setup of the NX transport.\n" - << logofs_flush; - } - - #endif - - return 1; -} - -int SetupAuthInstance() -{ - // - // If user gave us a proxy cookie, then create the - // X11 authorization repository and find the real - // cookie to be used for our X display. - // - - if (control -> ProxyMode == proxy_server) - { - if (authCookie != NULL && *authCookie != '\0') - { - if (useLaunchdSocket == 1) - { - // - // If we are going to retrieve the X11 autho- - // rization through the launchd service, make - // a connection to its socket to trigger the - // X server starting. - // - - sockaddr_un launchdAddrUnix; - - unsigned int launchdAddrLength = sizeof(sockaddr_un); - - int launchdAddrFamily = AF_UNIX; - - launchdAddrUnix.sun_family = AF_UNIX; - - const int launchdAddrNameLength = 108; - - int success = -1; - - strncpy(launchdAddrUnix.sun_path, displayHost, launchdAddrNameLength); - - *(launchdAddrUnix.sun_path + launchdAddrNameLength - 1) = '\0'; - - #ifdef TEST - *logofs << "Loop: Connecting to launchd service " - << "on Unix port '" << displayHost << "'.\n" << logofs_flush; - #endif - - int launchdFd = socket(launchdAddrFamily, SOCK_STREAM, PF_UNSPEC); - - if (launchdFd < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to socket failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - } - else if ((success = connect(launchdFd, (sockaddr *) &launchdAddrUnix, launchdAddrLength)) < 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Connection to launchd service " - << "on Unix port '" << displayHost << "' failed " - << "with error " << EGET() << ", '" << ESTR() << "'.\n" - << logofs_flush; - #endif - } - - if (launchdFd >= 0) - { - close(launchdFd); - } - - // - // The real cookie will not be available - // until the X server starts. Query for the - // cookie in a loop, unless the connection - // to the launchd service failed. - // - - int attempts = (success < 0 ? 1 : 10); - - for (int i = 0; i < attempts; i++) - { - delete auth; - - auth = new Auth(displayHost, authCookie); - - if (auth != NULL && auth -> isFake() == 1) - { - usleep(200000); - - continue; - } - - break; - } - } - else - { - auth = new Auth(displayHost, authCookie); - } - - if (auth == NULL || auth -> isValid() != 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error creating the X authorization.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error creating the X authorization.\n"; - - HandleCleanup(); - } - else if (auth -> isFake() == 1) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Could not retrieve the X server " - << "authentication cookie.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Failed to read data from the X " - << "auth command.\n"; - - cerr << "Warning" << ": Generated a fake cookie for X " - << "authentication.\n"; - } - } - else - { - #ifdef TEST - *logofs << "Loop: No proxy cookie was provided for " - << "authentication.\n" << logofs_flush; - #endif - - cerr << "Info" << ": No proxy cookie was provided for " - << "authentication.\n"; - - #ifdef TEST - *logofs << "Loop: Forwarding the real X authorization " - << "cookie.\n" << logofs_flush; - #endif - - cerr << "Info" << ": Forwarding the real X authorization " - << "cookie.\n"; - } - } - - return 1; -} - -int SetupAgentInstance() -{ - if (control -> ProxyMode == proxy_client && - useAgentSocket == 1) - { - // - // This will temporarily disable signals to safely - // load the cache, then will send a control packet - // to the remote end, telling that cache has to be - // loaded, so it's important that proxy is already - // set in operational state. - // - - int result; - - if (agent != NULL) - { - result = proxy -> handleNewAgentConnection(agent); - } - else - { - result = proxy -> handleNewConnection(channel_x11, agentFD[1]); - } - - if (result < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error creating the NX agent connection.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error creating the NX agent connection.\n"; - - HandleCleanup(); - } - } - - return 1; -} - -int SetupTcpSocket() -{ - // - // Open TCP socket emulating local display. - // - - return ListenConnectionTCP((loopbackBind ? "localhost" : "*"), X_TCP_PORT + proxyPort, "X11"); -} - -int SetupUnixSocket() -{ - // - // Open UNIX domain socket for display. - // - - if (!control->TempPath) { - #ifdef PANIC - *logofs << "Loop: PANIC! Temporal path is null.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Temporal path is null.\n"; - HandleCleanup(); - } - - unsigned int required = snprintf(unixSocketName, DEFAULT_STRING_LENGTH, "%s/.X11-unix", control->TempPath); - if (required < sizeof(unixSocketName)) { - - // No need to execute the following actions conditionally - mkdir(unixSocketName, (0777 | S_ISVTX)); - chmod(unixSocketName, (0777 | S_ISVTX)); - - required = snprintf(unixSocketName, DEFAULT_STRING_LENGTH, "%s/.X11-unix/X%d", control->TempPath, proxyPort); - if (required < sizeof(unixSocketName)) { - - unixFD = ListenConnectionUnix(unixSocketName, "x11"); - if (unixFD >= 0) - chmod(unixSocketName, 0777); - return unixFD; - } - } - - unixSocketName[0] = '\0'; // Just in case! - - #ifdef PANIC - *logofs << "Loop: PANIC! path for unix socket is too long.\n" << logofs_flush; - #endif - - cerr << "Error" << ": path for Unix socket is too long.\n"; - HandleCleanup(); -} - -// -// The following is a dumb copy-paste. The -// nxcompsh library should offer a better -// implementation. -// - -int SetupDisplaySocket(int &xServerAddrFamily, sockaddr *&xServerAddr, - unsigned int &xServerAddrLength) -{ - xServerAddrFamily = AF_INET; - xServerAddr = NULL; - xServerAddrLength = 0; - - char *display; - - if (*displayHost == '\0') - { - // - // Assume DISPLAY as the X server to which - // we will forward the proxied connections. - // This means that NX parameters have been - // passed through other means. - // - - display = getenv("DISPLAY"); - - if (display == NULL || *display == '\0') - { - #ifdef PANIC - *logofs << "Loop: PANIC! Host X server DISPLAY is not set.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Host X server DISPLAY is not set.\n"; - - HandleCleanup(); - } - else if (strncasecmp(display, "nx/nx,", 6) == 0 || - strncasecmp(display, "nx,", 3) == 0 || - strncasecmp(display, "nx/nx:", 6) == 0 || - strncasecmp(display, "nx:", 3) == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! NX transport on host X server '" - << display << "' not supported.\n" << logofs_flush; - #endif - - cerr << "Error" << ": NX transport on host X server '" - << display << "' not supported.\n"; - - cerr << "Error" << ": Please run the local proxy specifying " - << "the host X server to connect to.\n"; - - HandleCleanup(); - } - else if (strlen(display) >= DEFAULT_STRING_LENGTH) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Host X server DISPLAY cannot exceed " - << DEFAULT_STRING_LENGTH << " characters.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Host X server DISPLAY cannot exceed " - << DEFAULT_STRING_LENGTH << " characters.\n"; - - HandleCleanup(); - } - - strcpy(displayHost, display); - } - - display = new char[strlen(displayHost) + 1]; - - if (display == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Out of memory handling DISPLAY variable.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Out of memory handling DISPLAY variable.\n"; - - HandleCleanup(); - } - - strcpy(display, displayHost); - - #ifdef __APPLE__ - - if ((strncasecmp(display, "/tmp/launch", 11) == 0) || (strncasecmp(display, "/private/tmp/com.apple.launchd", 30) == 0)) - { - #ifdef TEST - *logofs << "Loop: Using launchd service on socket '" - << display << "'.\n" << logofs_flush; - #endif - - useLaunchdSocket = 1; - } - - #endif - - char *separator = strrchr(display, ':'); - - if ((separator == NULL) || !isdigit(*(separator + 1))) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid display '" << display << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid display '" << display << "'.\n"; - - HandleCleanup(); - } - - *separator = '\0'; - - xPort = atoi(separator + 1); - - #ifdef TEST - *logofs << "Loop: Using local X display '" << displayHost - << "' with host '" << display << "' and port '" - << xPort << "'.\n" << logofs_flush; - #endif - - #ifdef __APPLE__ - - if (separator == display || strcmp(display, "unix") == 0 || - useLaunchdSocket == 1) - - #else - - if (separator == display || strcmp(display, "unix") == 0) - - #endif - { - // - // UNIX domain port. - // - - #ifdef TEST - *logofs << "Loop: Using real X server on UNIX domain socket.\n" - << logofs_flush; - #endif - - sockaddr_un *xServerAddrUNIX = new sockaddr_un; - - xServerAddrFamily = AF_UNIX; - xServerAddrUNIX -> sun_family = AF_UNIX; - - // - // The scope of this function is to fill either the sockaddr_un - // (when the display is set to the Unix Domain socket) or the - // sockaddr_in structure (when connecting by TCP) only once, so - // that the structure will be later used at the time the server - // proxy will try to forward the connection to the X server. We - // don't need to verify that the socket does exist at the pre- - // sent moment. The method that forwards the connection will - // perform the required checks and will retry, if needed. Anyway - // we need to select the name of the socket, so we check if the - // well-known directory exists and take that as an indication of - // where the socket will be created. - // - - // Try abstract X11 socket first (via a test connect), if that fails - // fall back to Unix domain socket file. - - #ifdef __linux__ - int testSocketFD; - testSocketFD = socket(xServerAddrFamily, SOCK_STREAM, PF_UNSPEC); - - int len = sprintf(unixSocketName + 1, "/tmp/.X11-unix/X%d", xPort); - unixSocketName[0] = '\0'; - - sockaddr_un *xServerAddrABSTRACT = new sockaddr_un; - memset(xServerAddrABSTRACT, 0, xServerAddrLength); - xServerAddrABSTRACT -> sun_family = AF_UNIX; - memcpy(xServerAddrABSTRACT -> sun_path, unixSocketName, len+1); - xServerAddrLength = len +3; - - int ret = connect(testSocketFD, (struct sockaddr *) xServerAddrABSTRACT, xServerAddrLength); - if (ret == 0) { - - cerr << "Info" << ": Using abstract X11 socket in kernel namespace " - << "for accessing DISPLAY=:" << xPort << ".\n"; - - close(testSocketFD); - xServerAddr = (sockaddr *) xServerAddrABSTRACT; - return 1; - - } else { - - cerr << "Info" << ": Falling back to file system X11 socket " - << "for accessing DISPLAY=:" << xPort << ".\n"; - - #endif - - struct stat statInfo; - - char unixSocketDir[DEFAULT_STRING_LENGTH]; - - snprintf(unixSocketDir, DEFAULT_STRING_LENGTH - 1, "%s/.X11-unix", - control -> TempPath); - - #ifdef __APPLE__ - - if (useLaunchdSocket == 1) - { - char *slash = rindex(display, '/'); - - if (slash != NULL) - { - *slash = '\0'; - } - - snprintf(unixSocketDir, DEFAULT_STRING_LENGTH - 1, "%s", display); - } - - #endif - - *(unixSocketDir + DEFAULT_STRING_LENGTH - 1) = '\0'; - - #ifdef TEST - *logofs << "Loop: Assuming X socket in directory '" - << unixSocketDir << "'.\n" << logofs_flush; - #endif - - if (stat(unixSocketDir, &statInfo) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't determine the location of " - << "the X display socket.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't determine the location of " - << "the X display socket.\n"; - - #ifdef PANIC - *logofs << "Loop: PANIC! Error " << EGET() << " '" << ESTR() - << "' checking '" << unixSocketDir << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error " << EGET() << " '" << ESTR() - << "' checking '" << unixSocketDir << "'.\n"; - - HandleCleanup(); - } - - sprintf(unixSocketName, "%s/X%d", unixSocketDir, xPort); - - #ifdef __APPLE__ - - if (useLaunchdSocket == 1) - { - strncpy(unixSocketName, displayHost, DEFAULT_STRING_LENGTH - 1); - } - - #endif - - #ifdef TEST - *logofs << "Loop: Assuming X socket name '" << unixSocketName - << "'.\n" << logofs_flush; - #endif - - strcpy(xServerAddrUNIX -> sun_path, unixSocketName); - - xServerAddr = (sockaddr *) xServerAddrUNIX; - xServerAddrLength = sizeof(sockaddr_un); - - #ifdef __linux__ - - } - #endif - } - else - { - // - // TCP port. - // - - #ifdef TEST - *logofs << "Loop: Using real X server on TCP port.\n" - << logofs_flush; - #endif - - xServerAddrFamily = AF_INET; - - int xServerIPAddr = GetHostAddress(display); - - if (xServerIPAddr == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Unknown display host '" << display - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unknown display host '" << display - << "'.\n"; - - HandleCleanup(); - } - - sockaddr_in *xServerAddrTCP = new sockaddr_in; - - xServerAddrTCP -> sin_family = AF_INET; - xServerAddrTCP -> sin_port = htons(X_TCP_PORT + xPort); - xServerAddrTCP -> sin_addr.s_addr = xServerIPAddr; - - xServerAddr = (sockaddr *) xServerAddrTCP; - xServerAddrLength = sizeof(sockaddr_in); - } - - delete [] display; - - return 1; -} - -int SetupServiceSockets() -{ - if (control -> ProxyMode == proxy_client) - { - if (useCupsSocket) - { - if ((cupsFD = ListenConnection(cupsPort, "CUPS")) < 0) - { - useCupsSocket = 0; - } - } - - if (useAuxSocket) - { - if ((auxFD = ListenConnection(auxPort, "auxiliary X11")) < 0) - { - useAuxSocket = 0; - } - } - - if (useSmbSocket) - { - if ((smbFD = ListenConnection(smbPort, "SMB")) < 0) - { - useSmbSocket = 0; - } - } - - if (useMediaSocket) - { - if ((mediaFD = ListenConnection(mediaPort, "media")) < 0) - { - useMediaSocket = 0; - } - } - - if (useHttpSocket) - { - if ((httpFD = ListenConnection(httpPort, "http")) < 0) - { - useHttpSocket = 0; - } - } - - useFontSocket = 0; - } - else - { - // - // Get ready to listen for the font server connections - // - - if (useFontSocket) - { - // Since ProtoStep7 (#issue 108) - int port = atoi(fontPort); - - if ((fontFD = ListenConnectionTCP("localhost", port, "font")) < 0) - { - useFontSocket = 0; - } - } - - useCupsSocket = 0; - useAuxSocket = 0; - useSmbSocket = 0; - useMediaSocket = 0; - useHttpSocket = 0; - } - - // - // Slave channels can be originated - // by both sides. - // - - if (useSlaveSocket) - { - // Since ProtoStep7 (#issue 108) - if ((slaveFD = ListenConnection(slavePort, "slave")) < 0) - { - useSlaveSocket = 0; - } - } - - return 1; -} - -int ListenConnectionAny(sockaddr *addr, socklen_t addrlen, const char *label) -{ - int newFD = socket(addr->sa_family, SOCK_STREAM, PF_UNSPEC); - - if (newFD == -1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to socket failed for " << label - << " socket. Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to socket failed for " << label - << " socket. Error is " << EGET() << " '" - << ESTR() << "'.\n"; - - goto SetupSocketError; - } - - if (addr->sa_family == AF_INET) - if (SetReuseAddress(newFD) < 0) - { - // SetReuseAddress already warns with an error - goto SetupSocketError; - } - - if (bind(newFD, addr, addrlen) == -1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to bind failed for " << label - << ". Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to bind failed for " << label - << ". Error is " << EGET() - << " '" << ESTR() << "'.\n"; - goto SetupSocketError; - } - - if (listen(newFD, 8) == -1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to listen failed for " << label - << ". Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to listen failed for " << label - << ". Error is " << EGET() - << " '" << ESTR() << "'.\n"; - - goto SetupSocketError; - } - - return newFD; - -SetupSocketError: - - if (newFD != -1) - { - close(newFD); - } - - // - // May optionally return. The session would - // continue without the service. The problem - // with this approach is that it would make - // harder to track problems with allocation - // of ports in clients and server. - // - - HandleCleanup(); - return -1; -} - -int ListenConnectionUnix(const char *path, const char *label) -{ - - sockaddr_un unixAddr; - unixAddr.sun_family = AF_UNIX; -#ifdef UNIX_PATH_MAX - if (strlen(path) >= UNIX_PATH_MAX) -#else - if (strlen(path) >= sizeof(unixAddr.sun_path)) -#endif - { - #ifdef PANIC - *logofs << "Loop: PANIC! Socket path \"" << path << "\" for " - << label << " is too long.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Socket path \"" << path << "\" for " - << label << " is too long.\n"; - - HandleCleanup(); - return -1; - } - - strcpy(unixAddr.sun_path, path); - return ListenConnectionAny((sockaddr *)&unixAddr, sizeof(unixAddr), label); -} - -int ListenConnectionTCP(const char *host, long port, const char *label) -{ - sockaddr_in tcpAddr; - tcpAddr.sin_family = AF_INET; - tcpAddr.sin_port = htons(port); - - if (loopbackBind || - !host || - !strcmp(host, "") || - !strcmp(host, "localhost")) { - tcpAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - } - else if(strcmp(host, "*") == 0) { - tcpAddr.sin_addr.s_addr = htonl(INADDR_ANY); - } - else { - int ip = tcpAddr.sin_addr.s_addr = GetHostAddress(host); - if (ip == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Unknown " << label << " host '" << host - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unknown " << label << " host '" << host - << "'.\n"; - - HandleCleanup(); - return -1; - } - } - - return ListenConnectionAny((sockaddr *)&tcpAddr, sizeof(tcpAddr), label); -} - -int ListenConnection(ChannelEndPoint &endpoint, const char *label) -{ - char *unixPath, *host; - long port; - if (endpoint.getUnixPath(&unixPath)) { - return ListenConnectionUnix(unixPath, label); - } - else if (endpoint.getTCPHostAndPort(&host, &port)) { - return ListenConnectionTCP(host, port, label); - } - return -1; -} - -static int AcceptConnection(int fd, int domain, const char *label) -{ - struct sockaddr newAddr; - - socklen_t addrLen = sizeof(newAddr); - - #ifdef TEST - - if (domain == AF_UNIX) - { - *logofs << "Loop: Going to accept new Unix " << label - << " connection on FD#" << fd << ".\n" - << logofs_flush; - } - else - { - *logofs << "Loop: Going to accept new TCP " << label - << " connection on FD#" << fd << ".\n" - << logofs_flush; - } - - #endif - - int newFD = accept(fd, &newAddr, &addrLen); - - if (newFD < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to accept failed for " - << label << " connection. Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to accept failed for " - << label << " connection. Error is " << EGET() - << " '" << ESTR() << "'.\n"; - } - - return newFD; -} - -void HandleShutdown() -{ - if (proxy -> getShutdown() == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! No shutdown of proxy link " - << "performed by remote proxy.\n" - << logofs_flush; - #endif - - // - // Close the socket before showing the alert. - // It seems that the closure of the socket can - // sometimes take several seconds, even after - // the connection is broken. The result is that - // the dialog can be shown long after the user - // has gone after the failed session. Note that - // disabling the linger timeout does not seem - // to make any difference. - // - - CleanupSockets(); - - cerr << "Error" << ": Connection with remote peer broken.\n"; - - #ifdef TEST - *logofs << "Loop: Bytes received so far are " - << (unsigned long long) statistics -> getBytesIn() - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Please check the state of your " - << "network and retry.\n"; - - handleTerminatingInLoop(); - - if (control -> ProxyMode == proxy_server) - { - #ifdef TEST - *logofs << "Loop: Showing the proxy abort dialog.\n" - << logofs_flush; - #endif - - HandleAlert(ABORT_PROXY_CONNECTION_ALERT, 1); - - handleAlertInLoop(); - } - } - #ifdef TEST - else - { - *logofs << "Loop: Finalized the remote proxy shutdown.\n" - << logofs_flush; - } - #endif - - HandleCleanup(); -} - - -void WaitCleanup() -{ - T_timestamp selectTs; - - while (NXTransRunning(NX_FD_ANY)) - { - setTimestamp(selectTs, control -> PingTimeout); - - NXTransContinue(&selectTs); - } -} - -int KillProcess(int pid, const char *label, int signal, int wait) -{ - if (pid > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Killing the " << label << " process '" - << pid << "' from process with pid '" << getpid() - << "' with signal '" << DumpSignal(signal) - << "'.\n" << logofs_flush; - #endif - - signal = (signal == 0 ? SIGTERM : signal); - - if (kill(pid, signal) < 0 && EGET() != ESRCH) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Couldn't kill the " << label - << " process with pid '" << pid << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Couldn't kill the " << label - << " process with pid '" << pid << "'.\n"; - } - - if (wait == 1) - { - WaitChild(pid, label, 1); - } - - return 1; - } - else - { - #ifdef TEST - *logofs << "Loop: No " << label << " process " - << "to kill with pid '" << pid - << "'.\n" << logofs_flush; - #endif - - return 0; - } -} - -int CheckProcess(int pid, const char *label) -{ - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Checking the " << label << " process '" - << pid << "' from process with pid '" << getpid() - << "'.\n" << logofs_flush; - #endif - - if (kill(pid, SIGCONT) < 0 && EGET() == ESRCH) - { - #ifdef WARNING - *logofs << "Loop: WARNING! The " << label << " process " - << "with pid '" << pid << "' has exited.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": The " << label << " process " - << "with pid '" << pid << "' has exited.\n"; - - return 0; - } - - return 1; -} - -int StartKeeper() -{ - #if defined(TEST) || defined(INFO) - - if (IsRunning(lastKeeper) == 1 || - IsRestarting(lastKeeper) == 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! The house-keeping process is " - << "alreay running with pid '" << lastKeeper - << "'.\n" << logofs_flush; - #endif - - HandleCleanup(); - } - - #endif - - // - // Don't care harvesting the persistent caches if - // the memory cache is not enabled. If the memory - // cache is not enabled neither we produced per- - // sistent caches. The user can still delete any - // persistent cache produced by the previous runs - // by using the client GUI. - // - // TODO: At the moment the user doesn't have a way - // to specify the amount of disk space to use for - // the persistent caches, but only the amount of - // space to use for images. - // - - if (control -> LocalTotalStorageSize > 0) - { - #ifdef TEST - *logofs << "Loop: Starting the house-keeping process with " - << "storage size " << control -> PersistentCacheDiskLimit - << ".\n" << logofs_flush; - #endif - - lastKeeper = NXTransKeeper(control -> PersistentCacheDiskLimit, - 0, control -> RootPath); - - if (IsFailed(lastKeeper)) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Failed to start the NX keeper process.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Failed to start the NX keeper process.\n"; - - SetNotRunning(lastKeeper); - } - #ifdef TEST - else - { - *logofs << "Loop: Keeper started with pid '" - << lastKeeper << "'.\n" << logofs_flush; - } - #endif - } - #ifdef TEST - else - { - *logofs << "Loop: Nothing to do for the keeper process " - << "with persistent cache not enabled.\n" - << logofs_flush; - } - #endif - - return 1; -} - -void HandleCleanupForReconnect() -{ - #ifdef TEST - *logofs << "Loop: Going to clean up system resources for Reconnect " - << "in process '" << getpid() << "'.\n" - << logofs_flush; - #endif - handleTerminatedInLoop(); - DisableSignals(); - if (control) - CleanupChildren(); - CleanupListeners(); - CleanupSockets(); - CleanupKeeper(); - CleanupStreams(); - CleanupLocal(); - CleanupGlobal(); - RestoreSignals(); - ServerCache::lastInitReply.set(0,NULL); - ServerCache::lastKeymap.set(0,NULL); - ServerCache::getKeyboardMappingLastMap.set(0,NULL); -} -void HandleCleanup(int code) -{ - #ifdef TEST - *logofs << "Loop: Going to clean up system resources " - << "in process '" << getpid() << "'.\n" - << logofs_flush; - #endif - - handleTerminatedInLoop(); - - // - // Suspend any signal while cleaning up. - // - - DisableSignals(); - - if (getpid() == lastProxy) - { - // - // Terminate all the children. - // - - CleanupChildren(); - - // - // Close all listeners. - // - - CleanupListeners(); - - // - // Close all sockets. - // - - CleanupSockets(); - - // - // Release the global objects. - // - - CleanupGlobal(); - - // - // Restore the original signal handlers. - // - - RestoreSignals(); - } - - // - // This is our last chance to print a message. If this - // is the process which created the transport we will - // jump back into the loop, letting the caller find out - // that the connection is broken, otherwise we assume - // that this is a child of the proxy and so we will - // safely exit. - // - - #ifdef TEST - - if (getpid() == lastProxy) - { - *logofs << "Loop: Reverting to loop context in process with " - << "pid '" << getpid() << "' at " << strMsTimestamp() - << ".\n" << logofs_flush; - } - else - { - *logofs << "Loop: Exiting from child process with pid '" - << getpid() << "' at " << strMsTimestamp() - << ".\n" << logofs_flush; - } - - #endif - - if (getpid() == lastProxy) - { - // - // Reset all values to their default. - // - - CleanupLocal(); - - CleanupStreams(); - - longjmp(context, 1); - } - else - { - // - // Give a last chance to the process - // to cleanup the ancillary classes. - // - - CleanupKeeper(); - - CleanupStreams(); - - exit(code); - } -} - -void CleanupKeeper() -{ - if (keeper != NULL) - { - #ifdef TEST - *logofs << "Loop: Freeing up keeper in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - delete keeper; - - keeper = NULL; - } -} - -void CleanupStreams() -{ - // - // TODO: The cleanup procedure skips deletion of - // the I/O streams under Windows. This is intended - // to avoid a strange segfault occurring randomly, - // at the time the proxy is being shut down. - // - - #ifndef __CYGWIN32__ - - #ifdef TEST - *logofs << "Loop: Freeing up streams in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - if (logofs != NULL && logofs != &cerr && - *errorsFileName != '\0') - { - *logofs << flush; - - delete logofs; - - // - // Let the log go again to the standard - // error. - // - - logofs = &cerr; - } - - if (statofs != NULL && statofs != &cerr && - *statsFileName != '\0') - { - *statofs << flush; - - delete statofs; - - statofs = NULL; - } - - if (errofs != NULL) - { - *errofs << flush; - - if (errofs == &cerr) - { - errofs = NULL; - } - else if (errsbuf != NULL) - { - cerr.rdbuf(errsbuf); - - errsbuf = NULL; - - delete errofs; - } - - errofs = NULL; - } - - #endif /* #ifndef __CYGWIN32__ */ - - // - // Reset these as they can't be reset - // in CleanupLocal(). - // - - *sessionFileName = '\0'; - *errorsFileName = '\0'; - *optionsFileName = '\0'; - *statsFileName = '\0'; -} - -void CleanupChildren() -{ - // - // Remove any watchdog. - // - - if (IsRunning(lastWatchdog)) - { - KillProcess(lastWatchdog, "watchdog", SIGTERM, 1); - - SetNotRunning(lastWatchdog); - - lastSignal = 0; - } - - // - // Kill the cache house-keeping process. - // - - if (IsRunning(lastKeeper)) - { - KillProcess(lastKeeper, "house-keeping", SIGTERM, 1); - - SetNotRunning(lastKeeper); - } - - // - // Let any running dialog to continue until it is - // closed by the user. In general this is the exp- - // ected behaviour, as for example when we are - // exiting because the link was abrouptedly shut - // down. - // - - if (IsRunning(lastDialog)) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: WARNING! Leaving the dialog process '" - << lastDialog << "' running in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - SetNotRunning(lastDialog); - } - - // - // Give user a chance to start a new session. - // - - if (control -> EnableRestartOnShutdown == 1) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Respawning the NX client " - << "on display '" << displayHost << "'.\n" - << logofs_flush; - #endif - - NXTransClient(displayHost); - } - - for (int i = 0; i < control -> KillDaemonOnShutdownNumber; i++) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Killing the NX daemon with " - << "pid '" << control -> KillDaemonOnShutdown[i] - << "'.\n" << logofs_flush; - #endif - - KillProcess(control -> KillDaemonOnShutdown[i], "daemon", SIGTERM, 0); - } -} - -void CleanupGlobal() -{ - if (proxy != NULL) - { - #ifdef TEST - *logofs << "Loop: Freeing up proxy in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - delete proxy; - - proxy = NULL; - } - - if (agent != NULL) - { - #ifdef TEST - *logofs << "Loop: Freeing up agent in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - delete agent; - - agent = NULL; - } - - if (auth != NULL) - { - #ifdef TEST - *logofs << "Loop: Freeing up auth data in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - delete auth; - - auth = NULL; - } - - if (statistics != NULL) - { - #ifdef TEST - *logofs << "Loop: Freeing up statistics in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - delete statistics; - - statistics = NULL; - } - - if (control != NULL) - { - #ifdef TEST - *logofs << "Loop: Freeing up control in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - delete control; - - control = NULL; - } -} - -void CleanupConnections() -{ - if (proxy -> getChannels(channel_x11) != 0) - { - #ifdef TEST - *logofs << "Loop: Closing any remaining X connections.\n" - << logofs_flush; - #endif - - proxy -> handleCloseAllXConnections(); - - #ifdef TEST - *logofs << "Loop: Closing any remaining listener.\n" - << logofs_flush; - #endif - - proxy -> handleCloseAllListeners(); - } - - proxy -> handleFinish(); -} - -void CleanupListeners() -{ - if (useTcpSocket == 1) - { - if (tcpFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing TCP listener in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(tcpFD); - - tcpFD = -1; - } - - useTcpSocket = 0; - } - - if (useUnixSocket == 1) - { - if (unixFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing UNIX listener in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(unixFD); - - unixFD = -1; - } - - if (*unixSocketName != '\0') - { - #ifdef TEST - *logofs << "Loop: Going to remove the Unix domain socket '" - << unixSocketName << "' in process " << "with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - unlink(unixSocketName); - } - - useUnixSocket = 0; - } - - if (useAgentSocket == 1) - { - // - // There is no listener for the - // agent descriptor. - // - - useAgentSocket = 0; - } - - if (useCupsSocket == 1) - { - if (cupsFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing CUPS listener in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(cupsFD); - - cupsFD = -1; - } - - useCupsSocket = 0; - } - - if (useAuxSocket == 1) - { - if (auxFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing auxiliary X11 listener " - << "in process " << "with pid '" << getpid() - << "'.\n" << logofs_flush; - #endif - - close(auxFD); - - auxFD = -1; - } - - useAuxSocket = 0; - } - - if (useSmbSocket == 1) - { - if (smbFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing SMB listener in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(smbFD); - - smbFD = -1; - } - - useSmbSocket = 0; - } - - if (useMediaSocket == 1) - { - if (mediaFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing multimedia listener in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(mediaFD); - - mediaFD = -1; - } - - useMediaSocket = 0; - } - - if (useHttpSocket == 1) - { - if (httpFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing http listener in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(httpFD); - - httpFD = -1; - } - - useHttpSocket = 0; - } - - if (useFontSocket == 1) - { - if (fontFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing font server listener in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(fontFD); - - fontFD = -1; - } - - useFontSocket = 0; - } - - if (useSlaveSocket == 1) - { - if (slaveFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing slave listener in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(slaveFD); - - slaveFD = -1; - } - - useSlaveSocket = 0; - } -} - -void CleanupSockets() -{ - if (proxyFD != -1) - { - #ifdef TEST - *logofs << "Loop: Closing proxy FD in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(proxyFD); - - proxyFD = -1; - } - - if (agentFD[1] != -1) - { - #ifdef TEST - *logofs << "Loop: Closing agent FD in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - close(agentFD[1]); - - agentFD[0] = -1; - agentFD[1] = -1; - } -} - -void CleanupLocal() -{ - *homeDir = '\0'; - *rootDir = '\0'; - *tempDir = '\0'; - *systemDir = '\0'; - *sessionDir = '\0'; - - *linkSpeedName = '\0'; - *cacheSizeName = '\0'; - *shsegSizeName = '\0'; - *imagesSizeName = '\0'; - *bitrateLimitName = '\0'; - *packMethodName = '\0'; - *productName = '\0'; - - packMethod = -1; - packQuality = -1; - - *sessionType = '\0'; - *sessionId = '\0'; - - parsedOptions = 0; - parsedCommand = 0; - - *remoteData = '\0'; - remotePosition = 0; - - tcpFD = -1; - unixFD = -1; - cupsFD = -1; - auxFD = -1; - smbFD = -1; - mediaFD = -1; - httpFD = -1; - fontFD = -1; - slaveFD = -1; - proxyFD = -1; - - agentFD[0] = -1; - agentFD[1] = -1; - - useUnixSocket = 1; - useTcpSocket = 1; - useCupsSocket = 0; - useAuxSocket = 0; - useSmbSocket = 0; - useMediaSocket = 0; - useHttpSocket = 0; - useFontSocket = 0; - useSlaveSocket = 0; - useAgentSocket = 0; - - useNoDelay = -1; - usePolicy = -1; - useRender = -1; - useTaint = -1; - - *unixSocketName = '\0'; - - *acceptHost = '\0'; - *displayHost = '\0'; - *authCookie = '\0'; - - proxyPort = DEFAULT_NX_PROXY_PORT; - xPort = DEFAULT_NX_X_PORT; - - xServerAddrFamily = -1; - xServerAddrLength = 0; - - delete xServerAddr; - - xServerAddr = NULL; - - listenSocket.disable(); - connectSocket.disable(); - - cupsPort.disable(); - auxPort.disable(); - smbPort.disable(); - mediaPort.disable(); - httpPort.disable(); - slavePort.disable(); - - *fontPort = '\0'; - - *bindHost = '\0'; - bindPort = -1; - - initTs = nullTimestamp(); - startTs = nullTimestamp(); - logsTs = nullTimestamp(); - nowTs = nullTimestamp(); - - diffTs = 0; - - lastProxy = 0; - lastDialog = 0; - lastWatchdog = 0; - lastKeeper = 0; - lastStatus = 0; - lastKill = 0; - lastDestroy = 0; - - lastReadableTs = nullTimestamp(); - - lastAlert.code = 0; - lastAlert.local = 0; - - lastMasks.blocked = 0; - lastMasks.installed = 0; - - memset(&lastMasks.saved, 0, sizeof(sigset_t)); - - for (int i = 0; i < 32; i++) - { - lastMasks.enabled[i] = 0; - lastMasks.forward[i] = 0; - - memset(&lastMasks.action[i], 0, sizeof(struct sigaction)); - } - - lastSignal = 0; - - memset(&lastTimer.action, 0, sizeof(struct sigaction)); - memset(&lastTimer.value, 0, sizeof(struct itimerval)); - - lastTimer.start = nullTimestamp(); - lastTimer.next = nullTimestamp(); -} - -int CheckAbort() -{ - if (lastSignal != 0) - { - #ifdef TEST - *logofs << "Loop: Aborting the procedure due to signal '" - << lastSignal << "', '" << DumpSignal(lastSignal) - << "'.\n" << logofs_flush; - #endif - - cerr << "Info" << ": Aborting the procedure due to signal '" - << lastSignal << "'.\n"; - - lastSignal = 0; - - return 1; - } - - return 0; -} - -void HandleAbort() -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - *logofs << flush; - - handleTerminatingInLoop(); - - if (lastSignal == SIGHUP) - { - lastSignal = 0; - } - - // - // The current default is to just quit the program. - // Code has not been updated to deal with the new - // NX transport loop. - // - - if (control -> EnableCoreDumpOnAbort == 1) - { - if (agent != NULL) - { - cerr << "Session" << ": Terminating session at '" - << strTimestamp() << "'.\n"; - } - - cerr << "Error" << ": Generating a core file to help " - << "the investigations.\n"; - - cerr << "Session" << ": Session terminated at '" - << strTimestamp() << "'.\n"; - - cerr << flush; - - signal(SIGABRT, SIG_DFL); - - raise(SIGABRT); - } - - #ifdef TEST - *logofs << "Loop: Showing the proxy abort dialog.\n" - << logofs_flush; - #endif - - if (control -> ProxyMode == proxy_server) - { - // - // Close the socket before showing the alert. - // It seems that the closure of the socket can - // sometimes take several seconds, even after - // the connection is broken. - // - - CleanupSockets(); - - if (lastKill == 0) - { - HandleAlert(ABORT_PROXY_CONNECTION_ALERT, 1); - } - else - { - HandleAlert(ABORT_PROXY_SHUTDOWN_ALERT, 1); - } - - handleAlertInLoop(); - } - - HandleCleanup(); -} - -void HandleAlert(int code, int local) -{ - if (lastAlert.code == 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Requesting an alert dialog with code " - << code << " and local " << local << ".\n" - << logofs_flush; - #endif - - lastAlert.code = code; - lastAlert.local = local; - } - #if defined(TEST) || defined(INFO) - else - { - *logofs << "Loop: WARNING! Alert dialog already requested " - << "with code " << lastAlert.code << ".\n" - << logofs_flush; - } - #endif - - return; -} - -void FlushCallback(int length) -{ - if (flushCallback != NULL) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Reporting a flush request at " - << strMsTimestamp() << " with " << length - << " bytes written.\n" << logofs_flush; - #endif - - (*flushCallback)(flushParameter, length); - } - #if defined(TEST) || defined(INFO) - else if (control -> ProxyMode == proxy_client) - { - *logofs << "Loop: WARNING! Can't find a flush " - << "callback in process with pid '" << getpid() - << "'.\n" << logofs_flush; - } - #endif -} - -void KeeperCallback() -{ - if (IsRunning(lastKeeper) == 0) - { - // - // Let the house-keeping process take care - // of the persistent image cache. - // - - if (control -> ImageCacheEnableLoad == 1 || - control -> ImageCacheEnableSave == 1) - { - #ifdef TEST - *logofs << "Loop: Starting the house-keeping process with " - << "image storage size " << control -> ImageCacheDiskLimit - << ".\n" << logofs_flush; - #endif - - lastKeeper = NXTransKeeper(0, control -> ImageCacheDiskLimit, - control -> RootPath); - - if (IsFailed(lastKeeper)) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Can't start the NX keeper process.\n" - << logofs_flush; - #endif - - SetNotRunning(lastKeeper); - } - #ifdef TEST - else - { - *logofs << "Loop: Keeper started with pid '" - << lastKeeper << "'.\n" << logofs_flush; - } - #endif - } - #ifdef TEST - else - { - *logofs << "Loop: Nothing to do for the keeper process " - << "with image cache not enabled.\n" - << logofs_flush; - } - #endif - } - #ifdef TEST - else - { - *logofs << "Loop: Nothing to do with the keeper process " - << "already running.\n" << logofs_flush; - } - #endif -} - -void InstallSignals() -{ - #ifdef TEST - *logofs << "Loop: Installing signals in process with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - for (int i = 0; i < 32; i++) - { - if (CheckSignal(i) == 1 && - lastMasks.enabled[i] == 0) - { - InstallSignal(i, NX_SIGNAL_ENABLE); - } - } - - lastMasks.installed = 1; -} - -void RestoreSignals() -{ - #ifdef TEST - *logofs << "Loop: Restoring signals in process with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - if (lastMasks.installed == 1) - { - // - // Need to keep monitoring the children. - // - - for (int i = 0; i < 32; i++) - { - if (lastMasks.enabled[i] == 1) - { - RestoreSignal(i); - } - } - } - - lastMasks.installed = 0; - - if (lastMasks.blocked == 1) - { - EnableSignals(); - } -} - -void DisableSignals() -{ - if (lastMasks.blocked == 0) - { - sigset_t newMask; - - sigemptyset(&newMask); - - // - // Block also the other signals that may be - // installed by the agent, that are those - // signals for which the function returns 2. - // - - for (int i = 0; i < 32; i++) - { - if (CheckSignal(i) > 0) - { - #ifdef DUMP - *logofs << "Loop: Disabling signal " << i << " '" - << DumpSignal(i) << "' in process with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - sigaddset(&newMask, i); - } - } - - sigprocmask(SIG_BLOCK, &newMask, &lastMasks.saved); - - lastMasks.blocked++; - } - #ifdef TEST - else - { - *logofs << "Loop: WARNING! Signals were already blocked in " - << "process with pid '" << getpid() << "'.\n" - << logofs_flush; - } - #endif -} - -void EnableSignals() -{ - if (lastMasks.blocked == 1) - { - #ifdef TEST - *logofs << "Loop: Enabling signals in process with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - sigprocmask(SIG_SETMASK, &lastMasks.saved, NULL); - - lastMasks.blocked = 0; - } - else - { - #ifdef WARNING - *logofs << "Loop: WARNING! Signals were not blocked in " - << "process with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Signals were not blocked in " - << "process with pid '" << getpid() << "'.\n"; - } -} - -void InstallSignal(int signal, int action) -{ - if (lastMasks.enabled[signal] == 1) - { - if (action == NX_SIGNAL_FORWARD) - { - #ifdef TEST - *logofs << "Loop: Forwarding handler for signal " << signal - << " '" << DumpSignal(signal) << "' in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - lastMasks.forward[signal] = 1; - - return; - } - #ifdef TEST - else - { - *logofs << "Loop: Reinstalling handler for signal " << signal - << " '" << DumpSignal(signal) << "' in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - } - #endif - } - #ifdef TEST - else - { - *logofs << "Loop: Installing handler for signal " << signal - << " '" << DumpSignal(signal) << "' in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - } - #endif - - if (signal == SIGALRM && isTimestamp(lastTimer.start)) - { - ResetTimer(); - } - - struct sigaction newAction; - - memset(&newAction, 0, sizeof(newAction)); - - newAction.sa_handler = HandleSignal; - - sigemptyset(&(newAction.sa_mask)); - - if (signal == SIGCHLD) - { - newAction.sa_flags = SA_NOCLDSTOP; - } - else - { - newAction.sa_flags = 0; - } - - sigaction(signal, &newAction, &lastMasks.action[signal]); - - lastMasks.enabled[signal] = 1; - - if (action == NX_SIGNAL_FORWARD) - { - lastMasks.forward[signal] = 1; - } -} - -void RestoreSignal(int signal) -{ - if (lastMasks.enabled[signal] == 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Signal '" << DumpSignal(signal) - << " not installed in process with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Signal '" << DumpSignal(signal) - << " not installed in process with pid '" - << getpid() << "'.\n"; - - return; - } - - #ifdef TEST - *logofs << "Loop: Restoring handler for signal " << signal - << " '" << DumpSignal(signal) << "' in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - if (signal == SIGALRM && isTimestamp(lastTimer.start)) - { - ResetTimer(); - } - - sigaction(signal, &lastMasks.action[signal], NULL); - - lastMasks.enabled[signal] = 0; - lastMasks.forward[signal] = 0; -} - -void HandleSignal(int signal) -{ - if (logofs == NULL) - { - logofs = &cerr; - } - - #if defined(UNSAFE) && (defined(TEST) || defined(INFO)) - - if (lastSignal != 0) - { - *logofs << "Loop: WARNING! Last signal is '" << lastSignal - << "', '" << DumpSignal(signal) << "' and not zero " - << "in process with pid '" << getpid() << "'.\n" - << logofs_flush; - } - - *logofs << "Loop: Signal '" << signal << "', '" - << DumpSignal(signal) << "' received in process " - << "with pid '" << getpid() << "'.\n" << logofs_flush; - - #endif - - if (getpid() != lastProxy && handler != NULL) - { - #if defined(UNSAFE) && (defined(TEST) || defined(INFO)) - *logofs << "Loop: Calling slave handler in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - if ((*handler)(signal) == 0) - { - return; - } - } - - switch (signal) - { - case SIGUSR1: - { - if (proxy != NULL && lastSignal == 0) - { - lastSignal = SIGUSR1; - } - - break; - } - case SIGUSR2: - { - if (proxy != NULL && lastSignal == 0) - { - lastSignal = SIGUSR2; - } - - break; - } - case SIGPIPE: - { - // - // It can happen that SIGPIPE is delivered - // to the proxy even in the case some other - // descriptor is unexpectedly closed. - // - // if (agentFD[1] != -1) - // { - // cerr << "Info" << ": Received signal 'SIGPIPE'. " - // << "Closing agent conection.\n"; - // - // shutdown(agentFD[1], SHUT_RDWR); - // } - // - - break; - } - case SIGALRM: - { - // - // Nothing to do. Just wake up the - // process on blocking operations. - // - - break; - } - case SIGCHLD: - { - // - // Check if any of our children has exited. - // - - if (HandleChildren() != 0) - { - signal = 0; - } - - // - // Don't save this signal or it will override - // any previous signal sent by child before - // exiting. - // - - break; - } - - #ifdef __CYGWIN32__ - - case 12: - { - // - // Nothing to do. This signal is what is delivered - // by the Cygwin library when trying use a shared - // memory function if the daemon is not running. - // - - #ifdef TEST - *logofs << "Loop: WARNING! Received signal '12' in " - << "process with pid '" << getpid() << "'.\n" - << logofs_flush; - - *logofs << "Loop: WARNING! Please check that the " - << "cygserver daemon is running.\n" - << logofs_flush; - #endif - - break; - } - - #endif - - default: - { - // - // Register the signal so we can handle it - // inside the main loop. We will probably - // dispose any resource and exit. - // - - if (getpid() == lastProxy) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Registering end of session request " - << "due to signal '" << signal << "', '" - << DumpSignal(signal) << "'.\n" - << logofs_flush; - #endif - - lastSignal = signal; - } - else - { - // - // This is a child, so exit immediately. - // - - HandleCleanup(); - } - } - } - - if (signal != 0 && lastMasks.forward[signal] == 1) - { - if (lastMasks.action[signal].sa_handler != NULL && - lastMasks.action[signal].sa_handler != HandleSignal) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Forwarding signal '" << signal << "', '" - << DumpSignal(signal) << "' to previous handler.\n" - << logofs_flush; - #endif - - lastMasks.action[signal].sa_handler(signal); - } - #ifdef WARNING - else if (lastMasks.action[signal].sa_handler == NULL) - { - *logofs << "Loop: WARNING! Parent requested to forward " - << "signal '" << signal << "', '" << DumpSignal(signal) - << "' but didn't set a handler.\n" << logofs_flush; - } - #endif - } -} - -int HandleChildren() -{ - // - // Try to waitpid() for each child because the - // call might have return ECHILD and so we may - // have lost any of the processes. - // - - if (IsRunning(lastDialog) && HandleChild(lastDialog) == 1) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Resetting pid of last dialog process " - << "in handler.\n" << logofs_flush; - #endif - - SetNotRunning(lastDialog); - - if (proxy != NULL) - { - proxy -> handleResetAlert(); - } - - return 1; - } - - if (IsRunning(lastWatchdog) && HandleChild(lastWatchdog) == 1) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Watchdog is gone. Setting the last " - << "signal to SIGHUP.\n" << logofs_flush; - #endif - - lastSignal = SIGHUP; - - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Resetting pid of last watchdog process " - << "in handler.\n" << logofs_flush; - #endif - - SetNotRunning(lastWatchdog); - - return 1; - } - - // - // The house-keeping process exits after a - // number of iterations to keep the memory - // pollution low. It is restarted on demand - // by the lower layers, using the callback - // function. - // - - if (IsRunning(lastKeeper) && HandleChild(lastKeeper) == 1) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Resetting pid of last house-keeping " - << "process in handler.\n" << logofs_flush; - #endif - - SetNotRunning(lastKeeper); - - return 1; - } - - // - // The pid will be checked by the code - // that registered the child. - // - - if (IsRunning(lastChild)) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Resetting pid of last child process " - << "in handler.\n" << logofs_flush; - #endif - - SetNotRunning(lastChild); - - return 1; - } - - proxy->checkSlaves(); - - // - // This can actually happen either because we - // reset the pid of the child process as soon - // as we kill it, or because of a child process - // of our parent. - // - - #if defined(UNSAFE) && (defined(TEST) || defined(INFO)) - *logofs << "Loop: Ignoring signal received for the " - << "unregistered child.\n" << logofs_flush; - #endif - - return 0; -} - -int HandleChild(int child) -{ - int pid; - - int status = 0; - int options = WNOHANG | WUNTRACED; - - while ((pid = waitpid(child, &status, options)) && - pid == -1 && EGET() == EINTR); - - return CheckChild(pid, status); -} - -int WaitChild(int child, const char* label, int force) -{ - int pid; - - int status = 0; - int options = WUNTRACED; - - for (;;) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Waiting for the " << label - << " process '" << child << "' to die.\n" - << logofs_flush; - #endif - - pid = waitpid(child, &status, options); - - if (pid == -1 && EGET() == EINTR) - { - if (force == 0) - { - return 0; - } - - #ifdef WARNING - *logofs << "Loop: WARNING! Ignoring signal while " - << "waiting for the " << label << " process '" - << child << "' to die.\n" - << logofs_flush; - #endif - - continue; - } - - break; - } - - return (EGET() == ECHILD ? 1 : CheckChild(pid, status)); -} - -int CheckChild(int pid, int status) -{ - lastStatus = 0; - - if (pid > 0) - { - if (WIFSTOPPED(status)) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Child process '" << pid << "' was stopped " - << "with signal " << (WSTOPSIG(status)) << ".\n" - << logofs_flush; - #endif - - return 0; - } - else - { - if (WIFEXITED(status)) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Child process '" << pid << "' exited " - << "with status '" << (WEXITSTATUS(status)) - << "'.\n" << logofs_flush; - #endif - - lastStatus = WEXITSTATUS(status); - } - else if (WIFSIGNALED(status)) - { - if (CheckSignal(WTERMSIG(status)) != 1) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Child process '" << pid - << "' died because of signal " << (WTERMSIG(status)) - << ", '" << DumpSignal(WTERMSIG(status)) << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Child process '" << pid - << "' died because of signal " << (WTERMSIG(status)) - << ", '" << DumpSignal(WTERMSIG(status)) << "'.\n"; - } - #if defined(UNSAFE) && defined(TEST) - else - { - *logofs << "Loop: Child process '" << pid - << "' died because of signal " << (WTERMSIG(status)) - << ", '" << DumpSignal(WTERMSIG(status)) << "'.\n" - << logofs_flush; - } - #endif - - lastStatus = 1; - } - - return 1; - } - } - else if (pid < 0) - { - if (EGET() != ECHILD) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to waitpid failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to waitpid failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - HandleCleanup(); - } - - // - // This can happen when the waitpid() is - // blocking, as the SIGCHLD is received - // within the call. - // - - #ifdef TEST - *logofs << "Loop: No more children processes running.\n" - << logofs_flush; - #endif - - return 1; - } - - return 0; -} - -void RegisterChild(int child) -{ - #if defined(TEST) || defined(INFO) - - if (IsNotRunning(lastChild)) - { - *logofs << "Loop: Registering child process '" << child - << "' in process with pid '" << getpid() - << "'.\n" << logofs_flush; - } - else - { - *logofs << "Loop: WARNING! Overriding registered child '" - << lastChild << "' with new child '" << child - << "' in process with pid '" << getpid() - << "'.\n" << logofs_flush; - } - - #endif - - lastChild = child; -} - -int CheckParent(const char *name, const char *type, int parent) -{ - if (parent != getppid() || parent == 1) - { - #ifdef WARNING - *logofs << name << ": WARNING! Parent process appears " - << "to be dead. Exiting " << type << ".\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Parent process appears " - << "to be dead. Exiting " << type << ".\n"; - - return 0; - } - - return 1; -} - -void HandleTimer(int signal) -{ - if (signal == SIGALRM) - { - if (isTimestamp(lastTimer.start)) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Timer expired at " << strMsTimestamp() - << " in process with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - if (proxy != NULL) - { - proxy -> handleTimer(); - } - - ResetTimer(); - } - else - { - #ifdef PANIC - *logofs << "Loop: PANIC! Inconsistent timer state " - << " in process with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Inconsistent timer state " - << " in process with pid '" << getpid() << "'.\n"; - } - } - else - { - #ifdef PANIC - *logofs << "Loop: PANIC! Inconsistent signal '" - << signal << "', '" << DumpSignal(signal) - << "' received in process with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Inconsistent signal '" - << signal << "', '" << DumpSignal(signal) - << "' received in process with pid '" - << getpid() << "'.\n"; - } -} - -void SetTimer(int value) -{ - getNewTimestamp(); - - if (isTimestamp(lastTimer.start)) - { - int diffTs = diffTimestamp(lastTimer.start, getTimestamp()); - - if (diffTs > lastTimer.next.tv_usec / 1000 * 2) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Timer missed to expire at " - << strMsTimestamp() << " in process with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Timer missed to expire at " - << strMsTimestamp() << " in process with pid '" - << getpid() << "'.\n"; - - HandleTimer(SIGALRM); - } - else - { - #ifdef TEST - *logofs << "Loop: Timer already running at " - << strMsTimestamp() << " in process with pid '" - << getpid() << "'.\n" << logofs_flush; - #endif - - return; - } - } - - // - // Save the former handler. - // - - struct sigaction action; - - memset(&action, 0, sizeof(action)); - - action.sa_handler = HandleTimer; - - sigemptyset(&action.sa_mask); - - action.sa_flags = 0; - - sigaction(SIGALRM, &action, &lastTimer.action); - - // - // Start the timer. - // - - lastTimer.next = getTimestamp(value); - - struct itimerval timer; - - timer.it_interval = lastTimer.next; - timer.it_value = lastTimer.next; - - #ifdef TEST - *logofs << "Loop: Timer set to " << lastTimer.next.tv_sec - << " S and " << lastTimer.next.tv_usec / 1000 - << " Ms at " << strMsTimestamp() << " in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - if (setitimer(ITIMER_REAL, &timer, &lastTimer.value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to setitimer failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to setitimer failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - lastTimer.next = nullTimestamp(); - - return; - } - - lastTimer.start = getTimestamp(); -} - -void ResetTimer() -{ - if (isTimestamp(lastTimer.start) == 0) - { - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Timer not running in process " - << "with pid '" << getpid() << "'.\n" - << logofs_flush; - #endif - - return; - } - - #if defined(UNSAFE) && defined(TEST) - *logofs << "Loop: Timer reset at " << strMsTimestamp() - << " in process with pid '" << getpid() - << "'.\n" << logofs_flush; - #endif - - // - // Restore the old signal mask and timer. - // - - if (setitimer(ITIMER_REAL, &lastTimer.value, NULL) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to setitimer failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to setitimer failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - } - - if (sigaction(SIGALRM, &lastTimer.action, NULL) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to sigaction failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to sigaction failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - } - - lastTimer.start = lastTimer.next = nullTimestamp(); -} - -// -// Open TCP or UNIX file socket to listen for remote proxy -// and block until remote connects. If successful close -// the listening socket and return FD on which the other -// party is connected. -// - -int WaitForRemote(ChannelEndPoint &socketAddress) -{ - char hostLabel[DEFAULT_STRING_LENGTH] = { 0 }; - char *socketUri = NULL; - - int retryAccept = -1; - - int proxyFD = -1; - int newFD = -1; - - int acceptIPAddr = 0; - - if (socketAddress.isTCPSocket()) - { - - // - // Get IP address of host to be awaited. - // - - if (*acceptHost != '\0') - { - acceptIPAddr = GetHostAddress(acceptHost); - - if (acceptIPAddr == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Cannot accept connections from unknown host '" - << acceptHost << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot accept connections from unknown host '" - << acceptHost << "'.\n"; - - goto WaitForRemoteError; - } - snprintf(hostLabel, sizeof(hostLabel), "'%s'", acceptHost); - } - else - { - strcpy(hostLabel, "any host"); - } - - long bindPort; - if (socketAddress.getTCPHostAndPort(NULL, &bindPort)) - { - socketAddress.setSpec(loopbackBind ? "localhost" : "*", bindPort); - } - else - { - // This should never happen - cerr << "Error" << ": Unable to change bind host\n"; - } - } - else if (socketAddress.isUnixSocket()) - strcpy(hostLabel, "this host"); - else - strcpy(hostLabel, "unknown origin (something went wrong!!!)"); - - - proxyFD = ListenConnection(socketAddress, "NX"); - - socketAddress.getSpec(&socketUri); - #ifdef TEST - *logofs << "Loop: Waiting for connection from " - << hostLabel << " on socket '" << socketUri - << "'.\n" << logofs_flush; - #endif - cerr << "Info" << ": Waiting for connection from " - << hostLabel << " on socket '" << socketUri - << "'.\n"; - free(socketUri); - - // - // How many times to loop waiting for connections - // from the selected host? Each loop wait for at - // most 20 seconds so a default value of 3 gives - // a timeout of 1 minute. - // - // TODO: Handling of timeouts and retry attempts - // must be rewritten. - // - - retryAccept = control -> OptionProxyRetryAccept; - - for (;;) - { - fd_set readSet; - - FD_ZERO(&readSet); - FD_SET(proxyFD, &readSet); - - T_timestamp selectTs; - - selectTs.tv_sec = 20; - selectTs.tv_usec = 0; - - int result = select(proxyFD + 1, &readSet, NULL, NULL, &selectTs); - - getNewTimestamp(); - - if (result == -1) - { - if (EGET() == EINTR) - { - if (CheckAbort() != 0) - { - goto WaitForRemoteError; - } - - continue; - } - - #ifdef PANIC - *logofs << "Loop: PANIC! Call to select failed. Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Call to select failed. Error is " - << EGET() << " '" << ESTR() << "'.\n"; - - goto WaitForRemoteError; - } - else if (result > 0 && FD_ISSET(proxyFD, &readSet)) - { - - sockaddr_in newAddrINET; - - if (socketAddress.isUnixSocket()) - { - socklen_t addrLen = sizeof(sockaddr_un); - newFD = accept(proxyFD, NULL, &addrLen); - } - else if (socketAddress.isTCPSocket()) - { - socklen_t addrLen = sizeof(sockaddr_in); - newFD = accept(proxyFD, (sockaddr *) &newAddrINET, &addrLen); - } - if (newFD == -1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to accept failed. Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Call to accept failed. Error is " - << EGET() << " '" << ESTR() << "'.\n"; - - goto WaitForRemoteError; - } - - if (socketAddress.isUnixSocket()) - { - - char * unixPath = NULL; - socketAddress.getUnixPath(&unixPath); - #ifdef TEST - *logofs << "Loop: Accepted connection from this host on Unix file socket '" - << unixPath << "'.\n" - << logofs_flush; - #endif - - cerr << "Info" << ": Accepted connection from this host on Unix file socket '" - << unixPath << "'.\n"; - free(unixPath); - - break; - } - else if (socketAddress.isTCPSocket()) - { - - char *connectedHost = inet_ntoa(newAddrINET.sin_addr); - - if (*acceptHost == '\0' || (int) newAddrINET.sin_addr.s_addr == acceptIPAddr) - { - - #ifdef TEST - - unsigned int connectedPort = ntohs(newAddrINET.sin_port); - - *logofs << "Loop: Accepted connection from '" << connectedHost - << "' with port '" << connectedPort << "'.\n" - << logofs_flush; - #endif - - cerr << "Info" << ": Accepted connection from '" - << connectedHost << "'.\n"; - - break; - } - else - { - #ifdef PANIC - *logofs << "Loop: WARNING! Refusing connection from '" << connectedHost - << "' on port '" << socketAddress.getTCPPort() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Refusing connection from '" - << connectedHost << "'.\n"; - } - - // - // Not the best way to elude a DOS attack... - // - - sleep(5); - - close(newFD); - - } - - } - - if (--retryAccept == 0) - { - if (socketAddress.isUnixSocket()) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Connection via Unix file socket from this host " - << "could not be established.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Connection via Unix file socket from this host " - << "could not be established.\n"; - } - else if (*acceptHost == '\0') - { - #ifdef PANIC - *logofs << "Loop: PANIC! Connection with remote host " - << "could not be established.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Connection with remote host " - << "could not be established.\n"; - } - else - { - #ifdef PANIC - *logofs << "Loop: PANIC! Connection with remote host '" - << acceptHost << "' could not be established.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Connection with remote host '" - << acceptHost << "' could not be established.\n"; - } - - goto WaitForRemoteError; - } - else - { - handleCheckSessionInConnect(); - } - } - - close(proxyFD); - - return newFD; - -WaitForRemoteError: - - close(proxyFD); - - HandleCleanup(); -} - -int PrepareProxyConnectionTCP(char** hostName, long int* portNum, int* timeout, int* proxyFD, int* reason) -{ - - if (!proxyFD) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Implementation error (PrepareProxyConnectionTCP). " - << "'proxyFD' must not be a NULL pointer.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Implementation error (PrepareProxyConnectionTCP). " - << "'proxyFD' must not be a NULL pointer.\n"; - - return -1; - } - - if (!reason) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Implementation error (PrepareProxyConnectionTCP). " - << "'reason' must not be a NULL pointer.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Implementation error (PrepareProxyConnectionTCP). " - << "'reason' must not be a NULL pointer.\n"; - - return -1; - } - - int remoteIPAddr = GetHostAddress(*hostName); - if (remoteIPAddr == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Unknown remote host '" - << *hostName << "'.\n" << logofs_flush; - #endif - cerr << "Error" << ": Unknown remote host '" - << *hostName << "'.\n"; - - HandleCleanup(); - } - - #ifdef TEST - *logofs << "Loop: Connecting to remote host '" - << *hostName << ":" << *portNum << "'.\n" - << logofs_flush; - #endif - - cerr << "Info" << ": Connecting to remote host '" - << *hostName << ":" << *portNum << "'.\n" - << logofs_flush; - - *proxyFD = -1; - *reason = -1; - - sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(*portNum); - addr.sin_addr.s_addr = remoteIPAddr; - - *proxyFD = socket(AF_INET, SOCK_STREAM, PF_UNSPEC); - *reason = EGET(); - - if (*proxyFD == -1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to socket failed. " - << "Error is " << *reason << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to socket failed. " - << "Error is " << *reason << " '" << ESTR() - << "'.\n"; - return -1; - - } - else if (SetReuseAddress(*proxyFD) < 0) - { - return -1; - } - - // - // Ensure operation is timed out - // if there is a network problem. - // - - if (timeout) - SetTimer(*timeout); - else - SetTimer(20000); - - int result = connect(*proxyFD, (sockaddr *) &addr, sizeof(sockaddr_in)); - - *reason = EGET(); - - ResetTimer(); - - return result; - -} - -int PrepareProxyConnectionUnix(char** path, int* timeout, int* proxyFD, int* reason) -{ - - if (!proxyFD) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Implementation error (PrepareProxyConnectionUnix). " - << "proxyFD must not be a NULL pointer.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Implementation error (PrepareProxyConnectionUnix). " - << "proxyFD must not be a NULL pointer.\n"; - - return -1; - } - - if (!reason) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Implementation error (PrepareProxyConnectionUnix). " - << "'reason' must not be a NULL pointer.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Implementation error (PrepareProxyConnectionUnix). " - << "'reason' must not be a NULL pointer.\n"; - - return -1; - } - - /* FIXME: Add socket file existence and permission checks */ - - *proxyFD = -1; - *reason = -1; - - sockaddr_un addr; - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, *path, 108 - 1); - - *proxyFD = socket(AF_UNIX, SOCK_STREAM, PF_UNSPEC); - *reason = EGET(); - - if (*proxyFD == -1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Call to socket failed. " - << "Error is " << *reason << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to socket failed. " - << "Error is " << *reason << " '" << ESTR() - << "'.\n"; - - return -1; - } - - // - // Ensure operation is timed out - // if there is a network problem. - // - - if (timeout) - SetTimer(*timeout); - else - SetTimer(20000); - - int result = connect(*proxyFD, (sockaddr *) &addr, sizeof(sockaddr_un)); - - *reason = EGET(); - - ResetTimer(); - - return result; -} - -// -// Connect to remote proxy. If successful -// return FD of connection, else return -1. -// - -int ConnectToRemote(ChannelEndPoint &socketAddress) -{ - - // - // How many times we retry to connect to remote - // host / Unix domain socket in case of failure? - // - - int retryConnect = control -> OptionProxyRetryConnect; - - // - // Show an alert after 20 seconds and use the - // same timeout to interrupt the connect. The - // retry timeout is incremental, starting from - // 100 miliseconds up to 1 second. - // - - int alertTimeout = 20000; - int connectTimeout = 20000; - int retryTimeout = 100; - - T_timestamp lastRetry = getNewTimestamp(); - - int result = -1; - int reason = -1; - int proxyFD = -1; - - char *hostName = NULL; - long int portNum = -1; - char *unixPath = NULL; - - for (;;) - { - - #ifdef DEBUG - *logofs << "Loop: Timer set to " << connectTimeout / 1000 - << " S " << "with retry set to " << retryConnect - << " in process with pid '" << getpid() - << "'.\n" << logofs_flush; - #endif - - if (socketAddress.getUnixPath(&unixPath)) - result = PrepareProxyConnectionUnix(&unixPath, &connectTimeout, &proxyFD, &reason); - else if (socketAddress.getTCPHostAndPort(&hostName, &portNum)) - result = PrepareProxyConnectionTCP(&hostName, &portNum, &connectTimeout, &proxyFD, &reason); - - if (result < 0) - { - close(proxyFD); - - if (CheckAbort() != 0) - { - goto ConnectToRemoteError; - } - else if (--retryConnect == 0) - { - ESET(reason); - - if (socketAddress.isUnixSocket()) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Connection to Unix file socket '" - << unixPath << "' failed. Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Connection to Unix file socket '" - << unixPath << "' failed. Error is " - << EGET() << " '" << ESTR() << "'.\n"; - } - else - { - - #ifdef PANIC - *logofs << "Loop: PANIC! Connection to '" << hostName - << ":" << portNum << "' failed. Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Connection to '" << hostName - << ":" << portNum << "' failed. Error is " - << EGET() << " '" << ESTR() << "'.\n"; - } - goto ConnectToRemoteError; - } - else - { - #ifdef TEST - *logofs << "Loop: Sleeping " << retryTimeout - << " ms before retrying.\n" - << logofs_flush; - #endif - - usleep(retryTimeout * 1000); - - retryTimeout <<= 1; - - if (retryTimeout > 1000 * 1000) - { - retryTimeout = 1000 * 1000; - } - } - - // - // Check if it is time to show an alert dialog. - // - - if (diffTimestamp(lastRetry, getNewTimestamp()) >= - (alertTimeout - control -> LatencyTimeout)) - { - if (IsNotRunning(lastDialog)) - { - handleCheckSessionInConnect(); - - // - // Wait for the dialog process to die - // unless a signal is received. - // - - while (IsRunning(lastDialog)) - { - WaitChild(lastDialog, "dialog", 0); - - if (CheckAbort() != 0) - { - // - // The client ignores the TERM signal - // on Windows. - // - - #ifdef __CYGWIN32__ - - KillProcess(lastDialog, "dialog", SIGKILL, 1); - - #else - - KillProcess(lastDialog, "dialog", SIGTERM, 1); - - #endif - - goto ConnectToRemoteError; - } - } - - lastRetry = getTimestamp(); - } - } - #ifdef TEST - { - *logofs << "Loop: Not showing the dialog with " - << (diffTimestamp(lastRetry, getTimestamp()) / 1000) - << " seconds elapsed.\n" << logofs_flush; - } - #endif - - ESET(reason); - - #ifdef TEST - if (unixPath && unixPath[0] != '\0' ) - { - *logofs << "Loop: Connection to Unix socket file '" - << unixPath << "' failed with error '" - << ESTR() << "'. Retrying.\n" - << logofs_flush; - } - else - { - *logofs << "Loop: Connection to '" << hostName - << ":" << portNum << "' failed with error '" - << ESTR() << "'. Retrying.\n" - << logofs_flush; - } - #endif - } - else - { - // - // Connection was successful. - // - - break; - } - } - - return proxyFD; - -ConnectToRemoteError: - - if (proxyFD != -1) - { - close(proxyFD); - } - - HandleCleanup(); -} - -// -// Make a string of options for the remote -// proxy and write it to the descriptor. -// The string includes the local version. -// - -int SendProxyOptions(int fd) -{ - char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; - - // - // Send the "compatibility" version first, then our - // actual version. Old proxies will take the first - // value and ignore the second. - // - - sprintf(options, "NXPROXY-%s-%i.%i.%i", - control -> NXPROXY_COMPATIBILITY_VERSION, - control -> LocalVersionMajor, - control -> LocalVersionMinor, - control -> LocalVersionPatch); - - // - // If you want to send options from proxy - // initiating the connection use something - // like this: - // - // if (WE_PROVIDE_CREDENTIALS) - // { - // sprintf(options + strlen(options), "%s=%s", option, value); - // } - // - // If you want to send options according to - // local proxy mode use something like this: - // - // if (control -> ProxyMode == proxy_client) - // { - // sprintf(options + strlen(options), "%s=%s", option, value); - // } - // - - // - // Send the authorization cookie if any. We assume - // user can choose to not provide any auth cookie - // and allow any connection to be accepted. - // - - if (WE_PROVIDE_CREDENTIALS && *authCookie != '\0') - { - sprintf(options + strlen(options), " cookie=%s,", authCookie); - } - else - { - sprintf(options + strlen(options), " "); - } - - // - // Now link characteristics and compression - // options. Delta compression, as well as - // preferred pack method, are imposed by - // client proxy. - // - - if (control -> ProxyMode == proxy_client) - { - sprintf(options + strlen(options), "link=%s,pack=%s,cache=%s,", - linkSpeedName, packMethodName, cacheSizeName); - - if (*bitrateLimitName != '\0') - { - sprintf(options + strlen(options), "limit=%s,", - bitrateLimitName); - } - - // - // Let the user disable the render extension - // and let the X client proxy know if it can - // short-circuit the X replies. Also pass - // along the session type to ensure that the - // remote proxy gets the right value. - // - - sprintf(options + strlen(options), "render=%d,taint=%d,", - (control -> HideRender == 0), - control -> TaintReplies); - - if (*sessionType != '\0') - { - sprintf(options + strlen(options), "type=%s,", sessionType); - } - else - { - sprintf(options + strlen(options), "type=default,"); - } - - // - // Add the 'strict' option, if needed. - // - - // Since ProtoStep7 (#issue 108) - if (useStrict != -1) - { - sprintf(options + strlen(options), "strict=%d,", useStrict); - } - - // - // Tell the remote the size of the shared - // memory segment. - // - - // Since ProtoStep7 (#issue 108) - if (*shsegSizeName != '\0') - { - sprintf(options + strlen(options), "shseg=%s,", shsegSizeName); - } - - // - // Send image cache parameters. - // - - sprintf(options + strlen(options), "images=%s,", imagesSizeName); - - sprintf(options + strlen(options), "delta=%d,stream=%d,data=%d ", - control -> LocalDeltaCompression, - control -> LocalStreamCompressionLevel, - control -> LocalDataCompressionLevel); - } - else - { - // - // If no special compression level was selected, - // server side will use compression levels set - // by client. - // - - if (control -> LocalStreamCompressionLevel < 0) - { - sprintf(options + strlen(options), "stream=default,"); - } - else - { - sprintf(options + strlen(options), "stream=%d,", - control -> LocalStreamCompressionLevel); - } - - if (control -> LocalDataCompressionLevel < 0) - { - sprintf(options + strlen(options), "data=default "); - } - else - { - sprintf(options + strlen(options), "data=%d ", - control -> LocalDataCompressionLevel); - } - } - - #ifdef TEST - *logofs << "Loop: Sending remote options '" - << options << "'.\n" << logofs_flush; - #endif - - return WriteLocalData(fd, options, strlen(options)); -} - -int ReadProxyVersion(int fd) -{ - #ifdef TEST - *logofs << "Loop: Going to read the remote proxy version " - << "from FD#" << fd << ".\n" << logofs_flush; - #endif - - // - // Read until the first space in string. - // We expect the remote version number. - // - - char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; - - int result = ReadRemoteData(fd, options, sizeof(options), ' '); - - if (result <= 0) - { - if (result < 0) - { - if (control -> ProxyMode == proxy_server) - { - HandleAlert(ABORT_PROXY_NEGOTIATION_ALERT, 1); - } - - handleAlertInLoop(); - } - - return result; - } - - #ifdef TEST - *logofs << "Loop: Received remote version string '" - << options << "' from FD#" << fd << ".\n" - << logofs_flush; - #endif - - if (strncmp(options, "NXPROXY-", strlen("NXPROXY-")) != 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Parse error in remote options string '" - << options << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Parse error in remote options string '" - << options << "'.\n"; - - return -1; - } - - // - // Try to determine if this is a pre-2.0.0 - // version advertising itself as compatible - // with the 1.2.2. - // - - int major = -1; - int minor = -1; - int patch = -1; - - sscanf(options, "NXPROXY-%i.%i.%i-%i.%i.%i", &(control -> RemoteVersionMajor), - &(control -> RemoteVersionMinor), &(control -> RemoteVersionPatch), - &major, &minor, &patch); - - if (control -> RemoteVersionMajor == 1 && - control -> RemoteVersionMinor == 2 && - control -> RemoteVersionPatch == 2 && - major != -1 && minor != -1 && patch != -1) - { - #ifdef TEST - *logofs << "Loop: Read trailing remote version '" << major - << "." << minor << "." << patch << "'.\n" - << logofs_flush; - #endif - - control -> CompatVersionMajor = major; - control -> CompatVersionMinor = minor; - control -> CompatVersionPatch = patch; - - control -> RemoteVersionMajor = major; - control -> RemoteVersionMinor = minor; - control -> RemoteVersionPatch = patch; - } - else - { - // - // We read the remote version at the first - // round. If the second version is missing, - // we will retain the values read before. - // - - sscanf(options, "NXPROXY-%i.%i.%i-%i.%i.%i", &(control -> CompatVersionMajor), - &(control -> CompatVersionMinor), &(control -> CompatVersionPatch), - &(control -> RemoteVersionMajor), &(control -> RemoteVersionMinor), - &(control -> RemoteVersionPatch)); - } - - *logofs << "Loop: Identified remote version '" << control -> RemoteVersionMajor - << "." << control -> RemoteVersionMinor << "." << control -> RemoteVersionPatch - << "'.\n" << logofs_flush; - - *logofs << "Loop: Remote compatibility version '" << control -> CompatVersionMajor - << "." << control -> CompatVersionMinor << "." << control -> CompatVersionPatch - << "'.\n" << logofs_flush; - - *logofs << "Loop: Local version '" << control -> LocalVersionMajor - << "." << control -> LocalVersionMinor << "." << control -> LocalVersionPatch - << "'.\n" << logofs_flush; - - if (SetVersion() < 0) - { - if (control -> ProxyMode == proxy_server) - { - HandleAlert(WRONG_PROXY_VERSION_ALERT, 1); - } - - handleAlertInLoop(); - - return -1; - } - - return 1; -} - -int ReadProxyOptions(int fd) -{ - #ifdef TEST - *logofs << "Loop: Going to read the remote proxy options " - << "from FD#" << fd << ".\n" << logofs_flush; - #endif - - char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; - - int result = ReadRemoteData(fd, options, sizeof(options), ' '); - - if (result <= 0) - { - return result; - } - - #ifdef TEST - *logofs << "Loop: Received remote options string '" - << options << "' from FD#" << fd << ".\n" - << logofs_flush; - #endif - - // - // Get the remote options, delimited by a space character. - // Note that there will be a further initialization phase - // at the time proxies negotiate cache file to restore. - // - - if (ParseRemoteOptions(options) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Couldn't negotiate a valid " - << "session with remote NX proxy.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Couldn't negotiate a valid " - << "session with remote NX proxy.\n"; - - return -1; - } - - return 1; -} - -int SendProxyCaches(int fd) -{ - #ifdef TEST - *logofs << "Loop: Synchronizing local and remote caches.\n" - << logofs_flush; - #endif - - if (control -> ProxyMode == proxy_client) - { - // - // Prepare a list of caches matching this - // session type and send it to the remote. - // - - #ifdef TEST - *logofs << "Loop: Going to send the list of local caches.\n" - << logofs_flush; - #endif - - SetCaches(); - - int entries = DEFAULT_REMOTE_CACHE_ENTRIES; - - const char prefix = 'C'; - - if (control -> LocalDeltaCompression == 0 || - control -> PersistentCacheEnableLoad == 0) - { - #ifdef TEST - *logofs << "Loop: Writing an empty list to FD#" << fd - << ".\n" << logofs_flush; - #endif - - return WriteLocalData(fd, "cachelist=none ", strlen("cachelist=none ")); - } - - int count = 0; - - #ifdef TEST - *logofs << "Loop: Looking for cache files in directory '" - << control -> PersistentCachePath << "'.\n" << logofs_flush; - #endif - - DIR *cacheDir = opendir(control -> PersistentCachePath); - - if (cacheDir != NULL) - { - dirent *dirEntry; - - int prologue = 0; - - while (((dirEntry = readdir(cacheDir)) != NULL) && (count < entries)) - { - if (*dirEntry -> d_name == prefix && - strlen(dirEntry -> d_name) == (MD5_LENGTH * 2 + 2)) - { - if (prologue == 0) - { - WriteLocalData(fd, "cachelist=", strlen("cachelist=")); - - prologue = 1; - } - else - { - WriteLocalData(fd, ",", strlen(",")); - } - - #ifdef TEST - *logofs << "Loop: Writing entry '" << control -> PersistentCachePath - << "/" << dirEntry -> d_name << "' to FD#" << fd - << ".\n" << logofs_flush; - #endif - - // - // Write cache file name to the socket, - // including leading 'C-' or 'S-'. - // - - WriteLocalData(fd, dirEntry -> d_name, MD5_LENGTH * 2 + 2); - - count++; - } - } - - closedir(cacheDir); - } - - if (count == 0) - { - #ifdef TEST - *logofs << "Loop: Writing an empty list to FD#" << fd - << ".\n" << logofs_flush; - #endif - - return WriteLocalData(fd, "cachelist=none ", strlen("cachelist=none ")); - } - else - { - return WriteLocalData(fd, " ", 1); - } - } - else - { - // - // Send back the selected cache name. - // - - #ifdef TEST - *logofs << "Loop: Going to send the selected cache.\n" - << logofs_flush; - #endif - - char buffer[DEFAULT_STRING_LENGTH]; - - if (control -> PersistentCacheName != NULL) - { - #ifdef TEST - *logofs << "Loop: Name of selected cache file is '" - << control -> PersistentCacheName << "'.\n" - << logofs_flush; - #endif - - sprintf(buffer, "cachefile=%s%s ", - *(control -> PersistentCacheName) == 'C' ? "S-" : "C-", - control -> PersistentCacheName + 2); - } - else - { - #ifdef TEST - *logofs << "Loop: No valid cache file was selected.\n" - << logofs_flush; - #endif - - sprintf(buffer, "cachefile=none "); - } - - #ifdef TEST - *logofs << "Loop: Sending string '" << buffer - << "' as selected cache file.\n" - << logofs_flush; - #endif - - return WriteLocalData(fd, buffer, strlen(buffer)); - } -} - -int ReadProxyCaches(int fd) -{ - if (control -> ProxyMode == proxy_client) - { - #ifdef TEST - *logofs << "Loop: Going to receive the selected proxy cache.\n" - << logofs_flush; - #endif - - // - // We will read the name of cache plus the stop character. - // - - char buffer[DEFAULT_STRING_LENGTH]; - - // - // Leave space for a trailing null. - // - - int result = ReadRemoteData(fd, buffer, sizeof("cachefile=") + MD5_LENGTH * 2 + 3, ' '); - - if (result <= 0) - { - return result; - } - - char *cacheName = strstr(buffer, "cachefile="); - - if (cacheName == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid cache file option '" - << buffer << "' provided by remote proxy.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid cache file option '" - << buffer << "' provided by remote proxy.\n"; - - HandleCleanup(); - } - - cacheName += strlen("cachefile="); - - if (control -> PersistentCacheName != NULL) - { - delete [] control -> PersistentCacheName; - } - - control -> PersistentCacheName = NULL; - - if (strncasecmp(cacheName, "none", strlen("none")) == 0) - { - #ifdef TEST - *logofs << "Loop: No cache file selected by remote proxy.\n" - << logofs_flush; - #endif - } - else if (strlen(cacheName) != MD5_LENGTH * 2 + 3 || - *(cacheName + MD5_LENGTH * 2 + 2) != ' ') - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid cache file name '" - << cacheName << "' provided by remote proxy.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid cache file name '" - << cacheName << "' provided by remote proxy.\n"; - - HandleCleanup(); - } - else - { - // - // It is "C-" + 32 + "\0". - // - - control -> PersistentCacheName = new char[MD5_LENGTH * 2 + 3]; - - *(cacheName + MD5_LENGTH * 2 + 2) = '\0'; - - strcpy(control -> PersistentCacheName, cacheName); - - #ifdef TEST - *logofs << "Loop: Cache file '" << control -> PersistentCacheName - << "' selected by remote proxy.\n" << logofs_flush; - #endif - } - } - else - { - #ifdef TEST - *logofs << "Loop: Going to receive the list of remote caches.\n" - << logofs_flush; - #endif - - SetCaches(); - - int size = ((MD5_LENGTH * 2 + 2) + strlen(",")) * DEFAULT_REMOTE_CACHE_ENTRIES + - strlen("cachelist=") + strlen(" ") + 1; - - char *buffer = new char[size]; - - int result = ReadRemoteData(fd, buffer, size - 1, ' '); - - if (result <= 0) - { - delete [] buffer; - - return result; - } - - #ifdef TEST - *logofs << "Loop: Read list of caches from remote side as '" - << buffer << "'.\n" << logofs_flush; - #endif - - // - // Prepare the buffer. What we want is a list - // like "cache1,cache2,cache2" terminated by - // null. - // - - *(buffer + strlen(buffer) - 1) = '\0'; - - if (strncasecmp(buffer, "cachelist=", strlen("cachelist=")) != 0) - { - #ifdef PANIC - *logofs << "Loop: Wrong format for list of cache files " - << "read from FD#" << fd << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Wrong format for list of cache files.\n"; - - delete [] buffer; - - return -1; - } - - control -> PersistentCacheName = GetLastCache(buffer, control -> PersistentCachePath); - - // - // Get rid of list of caches. - // - - delete [] buffer; - } - - return 1; -} - -int ReadForwarderVersion(int fd) -{ - #ifdef TEST - *logofs << "Loop: Going to negotiate the forwarder version.\n" - << logofs_flush; - #endif - - // - // Check if we actually expect the session cookie. - // - - if (*authCookie == '\0') - { - #ifdef TEST - *logofs << "Loop: No authentication cookie required " - << "from FD#" << fd << ".\n" << logofs_flush; - #endif - - return 1; - } - - char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; - - int result = ReadRemoteData(fd, options, sizeof(options), ' '); - - if (result <= 0) - { - return result; - } - - #ifdef TEST - *logofs << "Loop: Received forwarder version string '" << options - << "' from FD#" << fd << ".\n" << logofs_flush; - #endif - - if (strncmp(options, "NXSSH-", strlen("NXSSH-")) != 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Parse error in forwarder options string '" - << options << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Parse error in forwarder options string '" - << options << "'.\n"; - - return -1; - } - - // - // Accept whatever forwarder version. - // - - sscanf(options, "NXSSH-%i.%i.%i", &(control -> RemoteVersionMajor), - &(control -> RemoteVersionMinor), &(control -> RemoteVersionPatch)); - - #ifdef TEST - *logofs << "Loop: Read forwarder version '" << control -> RemoteVersionMajor - << "." << control -> RemoteVersionMinor << "." << control -> RemoteVersionPatch - << "'.\n" << logofs_flush; - #endif - - return 1; -} - -int ReadForwarderOptions(int fd) -{ - // - // Get the forwarder cookie. - // - - if (*authCookie == '\0') - { - #ifdef TEST - *logofs << "Loop: No authentication cookie required " - << "from FD#" << fd << ".\n" << logofs_flush; - #endif - - return 1; - } - - char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; - - int result = ReadRemoteData(fd, options, sizeof(options), ' '); - - if (result <= 0) - { - return result; - } - - #ifdef TEST - *logofs << "Loop: Received forwarder options string '" - << options << "' from FD#" << fd << ".\n" - << logofs_flush; - #endif - - if (ParseForwarderOptions(options) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Couldn't negotiate a valid " - << "cookie with the NX forwarder.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Couldn't negotiate a valid " - << "cookie with the NX forwarder.\n"; - - return -1; - } - - return 1; -} - -int ReadRemoteData(int fd, char *buffer, int size, char stop) -{ - #ifdef TEST - *logofs << "Loop: Going to read remote data from FD#" - << fd << ".\n" << logofs_flush; - #endif - - if (size >= MAXIMUM_REMOTE_OPTIONS_LENGTH) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Maximum remote options buffer " - << "limit exceeded.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Maximum remote options buffer " - << "limit exceeded.\n"; - - HandleCleanup(); - } - - while (remotePosition < (size - 1)) - { - int result = read(fd, remoteData + remotePosition, 1); - - getNewTimestamp(); - - if (result <= 0) - { - if (result == -1) - { - if (EGET() == EAGAIN) - { - #ifdef TEST - *logofs << "Loop: Reading data from FD#" << fd - << " would block.\n" << logofs_flush; - #endif - - return 0; - } - else if (EGET() == EINTR) - { - if (CheckAbort() != 0) - { - return -1; - } - - continue; - } - } - - #ifdef PANIC - *logofs << "Loop: PANIC! The remote NX proxy closed " - << "the connection.\n" << logofs_flush; - #endif - - cerr << "Error" << ": The remote NX proxy closed " - << "the connection.\n"; - - return -1; - } - else if (*(remoteData + remotePosition) == stop) - { - #ifdef TEST - *logofs << "Loop: Read stop character from FD#" - << fd << ".\n" << logofs_flush; - #endif - - remotePosition++; - - // - // Copy the fake terminating null - // in the buffer. - // - - *(remoteData + remotePosition) = '\0'; - - memcpy(buffer, remoteData, remotePosition + 1); - - #ifdef TEST - *logofs << "Loop: Remote string '" << remoteData - << "' read from FD#" << fd << ".\n" - << logofs_flush; - #endif - - int t = remotePosition; - - remotePosition = 0; - - return t; - } - else - { - // - // Make sure string received - // from far end is printable. - // - - if (isgraph(*(remoteData + remotePosition)) == 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Non printable character decimal '" - << (unsigned int) *(remoteData + remotePosition) - << "' received in remote data from FD#" - << fd << ".\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Non printable character decimal '" - << (unsigned int) *(remoteData + remotePosition) - << "' received in remote data from FD#" - << fd << ".\n" << logofs_flush; - - *(remoteData + remotePosition) = ' '; - } - - #ifdef DEBUG - *logofs << "Loop: Read a further character " - << "from FD#" << fd << ".\n" - << logofs_flush; - #endif - - remotePosition++; - } - } - - *(remoteData + remotePosition) = '\0'; - - #ifdef PANIC - *logofs << "Loop: PANIC! Stop character missing " - << "from FD#" << fd << " after " << remotePosition - << " characters read in string '" << remoteData - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Stop character missing " - << "from FD#" << fd << " after " << remotePosition - << " characters read in string '" << remoteData - << "'.\n"; - - memcpy(buffer, remoteData, remotePosition); - - remotePosition = 0; - - return -1; -} - -static int -hexval(char c) { - if ((c >= '0') && (c <= '9')) - return c - '0'; - if ((c >= 'a') && (c <= 'f')) - return c - 'a' + 10; - if ((c >= 'A') && (c <= 'F')) - return c - 'A' + 10; - return -1; -} - -static void -URLDecodeInPlace(char *str) { - if (str) { - char *to = str; - while (str[0]) { - if ((str[0] == '%') && - (hexval(str[1]) >= 0) && - (hexval(str[2]) >= 0)) { - *(to++) = hexval(str[1]) * 16 + hexval(str[2]); - str += 3; - } - else - *(to++) = *(str++); - } - *to = '\0'; - } -} - -int WriteLocalData(int fd, const char *buffer, int size) -{ - int position = 0; - int ret = 0; - fd_set writeSet; - struct timeval selectTs = {30, 0}; - - while (position < size) - { - - // A write to a non-blocking socket may fail with EAGAIN. The problem is - // that cache data is done in several writes, and there's no easy way - // to handle failure without rewriting a significant amount of code. - // - // Bailing out of the outer loop would result in restarting the sending - // of the entire cache list, which would confuse the other side. - - FD_ZERO(&writeSet); - FD_SET(fd, &writeSet); - - ret = select(fd+1, NULL, &writeSet, NULL, &selectTs); - - #ifdef DEBUG - *logofs << "Loop: WriteLocalData: select() returned with a code of " << ret << " and remaining timeout of " - << selectTs.tv_sec << " sec, " << selectTs.tv_usec << "usec\n" << logofs_flush; - #endif - - if ( ret < 0 ) - { - *logofs << "Loop: Error in select() when writing data to FD#" << fd << ": " << strerror(EGET()) << "\n" << logofs_flush; - - if ( EGET() == EINTR ) - continue; - - return -1; - } - else if ( ret == 0 ) - { - *logofs << "Loop: Timeout expired in select() when writing data to FD#" << fd << ": " << strerror(EGET()) << "\n" << logofs_flush; - return -1; - } - - int result = write(fd, buffer + position, size - position); - - getNewTimestamp(); - - if (result <= 0) - { - if (result < 0 && (EGET() == EINTR || EGET() == EAGAIN || EGET() == EWOULDBLOCK)) - { - continue; - } - - #ifdef TEST - *logofs << "Loop: Error writing data to FD#" - << fd << ".\n" << logofs_flush; - #endif - - return -1; - } - - position += result; - } - - return position; -} - -// -// Parse the string passed by calling process in -// the environment. This is not necessarily the -// content of DISPLAY variable, but can be the -// parameters passed when creating the process -// or thread. -// - -int ParseEnvironmentOptions(const char *env, int force) -{ - // - // Be sure log file is valid. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - // - // Be sure we have a parameters repository - // and a context to jump into because this - // can be called before creating the proxy. - // - - if (control == NULL) - { - control = new Control(); - } - - if (setjmp(context) == 1) - { - #ifdef TEST - *logofs << "Loop: Out of the long jump while parsing " - << "the environment options.\n" - << logofs_flush; - #endif - - return -1; - } - - if (force == 0 && parsedOptions == 1) - { - #ifdef TEST - *logofs << "Loop: Skipping a further parse of environment " - << "options string '" << (env != NULL ? env : "") - << "'.\n" << logofs_flush; - #endif - - return 1; - } - - if (env == NULL || *env == '\0') - { - #ifdef TEST - *logofs << "Loop: Nothing to do with empty environment " - << "options string '" << (env != NULL ? env : "") - << "'.\n" << logofs_flush; - #endif - - return 0; - } - - #ifdef TEST - *logofs << "Loop: Going to parse the environment options " - << "string '" << env << "'.\n" - << logofs_flush; - #endif - - parsedOptions = 1; - - // - // Copy the string passed as parameter - // because we need to modify it. - // - - char opts[DEFAULT_DISPLAY_OPTIONS_LENGTH]; - - #ifdef VALGRIND - - memset(opts, '\0', DEFAULT_DISPLAY_OPTIONS_LENGTH); - - #endif - - if (strlen(env) >= DEFAULT_DISPLAY_OPTIONS_LENGTH) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Environment options string '" << env - << "' exceeds length of " << DEFAULT_DISPLAY_OPTIONS_LENGTH - << " characters.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Environment options string '" << env - << "' exceeds length of " << DEFAULT_DISPLAY_OPTIONS_LENGTH - << " characters.\n"; - - return -1; - } - - strcpy(opts, env); - - char *nextOpts = opts; - - // - // Ensure that DISPLAY environment variable - // (roughly) follows the X convention for - // transport notation. - // - - if (strncasecmp(opts, "nx/nx,:", 7) == 0 || - strncasecmp(opts, "nx,:", 4) == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Parse error in options string '" - << opts << "' at 'nx,:'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Parse error in options string '" - << opts << "' at 'nx,:'.\n"; - - return -1; - } - else if (strncasecmp(opts, "nx/nx,", 6) == 0) - { - nextOpts += 6; - } - else if (strncasecmp(opts, "nx,", 3) == 0) - { - nextOpts += 3; - } - else if (strncasecmp(opts, "nx:", 3) == 0) - { - nextOpts += 3; - } - else if (force == 0) - { - #ifdef TEST - *logofs << "Loop: Ignoring host X server display string '" - << opts << "'.\n" << logofs_flush; - #endif - - return 0; - } - - // - // Save here the name of the options file and - // parse it after all the other options. - // - - char fileOptions[DEFAULT_STRING_LENGTH] = { 0 }; - - // - // The options string is intended to be a series - // of name/value tuples in the form name=value - // separated by the ',' character ended by a ':' - // followed by remote NX proxy port. - // - - char *name; - char *value; - - value = strrchr(nextOpts, ':'); - - if (value != NULL) - { - char *check = value + 1; - - if (*check == '\0' || isdigit(*check) == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify NX port in string '" - << value << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify NX port in string '" - << value << "'.\n"; - - return -1; - } - - proxyPort = atoi(check); - - // - // Get rid of the port specification. - // - - *value = '\0'; - } - else if (proxyPort == DEFAULT_NX_PROXY_PORT && force == 0) - { - // - // Complain only if user didn't specify - // the port on the command line. - // - - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify NX port in string '" - << opts << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify NX port in string '" - << opts << "'.\n"; - - return -1; - } - - #ifdef TEST - *logofs << "Loop: Parsing options string '" - << nextOpts << "'.\n" << logofs_flush; - #endif - - // - // Now all the other optional parameters. - // - - name = strtok(nextOpts, "="); - - char connectHost[DEFAULT_STRING_LENGTH] = { 0 }; - long connectPort = -1; - - while (name) - { - value = strtok(NULL, ","); - URLDecodeInPlace(value); - - if (CheckArg("environment", name, value) < 0) - { - return -1; - } - - if (strcasecmp(name, "options") == 0) - { - strncpy(fileOptions, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "display") == 0) - { - strncpy(displayHost, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "link") == 0) - { - - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else if (ParseLinkOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify 'link' option in string '" - << value << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify 'link' option in string '" - << value << "'.\n"; - if (ParseLinkOption("adsl") < 0) - return -1; - } - } - else if (strcasecmp(name, "limit") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else if (ParseBitrateOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify option 'limit' in string '" - << value << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify option 'limit' in string '" - << value << "'.\n"; - - return -1; - } - } - else if (strcasecmp(name, "type") == 0) - { - // - // Type of session, for example "desktop", - // "application", "windows", etc. - // - - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else - { - if (strcasecmp(value, "default") == 0) - { - *sessionType = '\0'; - } - else - { - strncpy(sessionType, value, DEFAULT_STRING_LENGTH - 1); - } - } - } - else if (strcasecmp(name, "listen") == 0) - { - char *socketUri = NULL; - if (connectSocket.getSpec(&socketUri)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't handle 'listen' and 'connect' parameters " - << "at the same time.\n" << logofs_flush; - - *logofs << "Loop: PANIC! Refusing 'listen' parameter with 'connect' being '" - << socketUri << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't handle 'listen' and 'connect' parameters " - << "at the same time.\n"; - - cerr << "Error" << ": Refusing 'listen' parameter with 'connect' being '" - << socketUri << "'.\n"; - - free(socketUri); - return -1; - } - - SetAndValidateChannelEndPointArg("local", name, value, listenSocket); - - } - else if (strcasecmp(name, "loopback") == 0) - { - loopbackBind = ValidateArg("local", name, value); - } - else if (strcasecmp(name, "accept") == 0) - { - char *socketUri = NULL; - if (connectSocket.getSpec(&socketUri)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't handle 'accept' and 'connect' parameters " - << "at the same time.\n" << logofs_flush; - - *logofs << "Loop: PANIC! Refusing 'accept' parameter with 'connect' being '" - << socketUri << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't handle 'accept' and 'connect' parameters " - << "at the same time.\n"; - - cerr << "Error" << ": Refusing 'accept' parameter with 'connect' being '" - << socketUri << "'.\n"; - - free(socketUri); - return -1; - } - - strncpy(acceptHost, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "connect") == 0) - { - if (*acceptHost != '\0') - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't handle 'connect' and 'accept' parameters " - << "at the same time.\n" << logofs_flush; - - *logofs << "Loop: PANIC! Refusing 'connect' parameter with 'accept' being '" - << acceptHost << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't handle 'connect' and 'accept' parameters " - << "at the same time.\n"; - - cerr << "Error" << ": Refusing 'connect' parameter with 'accept' being '" - << acceptHost << "'.\n"; - - return -1; - } - if ((strncmp(value, "tcp:", 4) == 0) || (strncmp(value, "unix:", 5) == 0)) - SetAndValidateChannelEndPointArg("local", name, value, connectSocket); - else - // if the "connect" parameter does not start with "unix:" or "tcp:" assume - // old parameter usage style (providing hostname string only). - strcpy(connectHost, value); - } - else if (strcasecmp(name, "port") == 0) - { - connectPort = ValidateArg("local", name, value); - } - else if (strcasecmp(name, "retry") == 0) - { - control -> OptionProxyRetryConnect = ValidateArg("local", name, value); - control -> OptionServerRetryConnect = ValidateArg("local", name, value); - } - else if (strcasecmp(name, "session") == 0) - { - strncpy(sessionFileName, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "errors") == 0) - { - // - // The old name of the parameter was 'log' - // but the default name for the file is - // 'errors' so it is more logical to use - // the same name. - // - - strncpy(errorsFileName, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "root") == 0) - { - strncpy(rootDir, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "id") == 0) - { - strncpy(sessionId, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "stats") == 0) - { - control -> EnableStatistics = 1; - - strncpy(statsFileName, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "cookie") == 0) - { - LowercaseArg("local", name, value); - - strncpy(authCookie, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "nodelay") == 0) - { - useNoDelay = ValidateArg("local", name, value); - } - else if (strcasecmp(name, "policy") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else - { - usePolicy = ValidateArg("local", name, value); - } - } - else if (strcasecmp(name, "render") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else - { - useRender = ValidateArg("local", name, value); - } - } - else if (strcasecmp(name, "taint") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else - { - useTaint = ValidateArg("local", name, value); - } - } - else if (strcasecmp(name, "delta") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else - { - control -> LocalDeltaCompression = ValidateArg("local", name, value); - } - } - else if (strcasecmp(name, "data") == 0) - { - control -> LocalDataCompressionLevel = ValidateArg("local", name, value); - - if (control -> LocalDataCompressionLevel == 0) - { - control -> LocalDataCompression = 0; - } - else - { - control -> LocalDataCompression = 1; - } - } - else if (strcasecmp(name, "stream") == 0) - { - control -> LocalStreamCompressionLevel = ValidateArg("local", name, value); - - if (control -> LocalStreamCompressionLevel == 0) - { - control -> LocalStreamCompression = 0; - } - else - { - control -> LocalStreamCompression = 1; - } - } - else if (strcasecmp(name, "memory") == 0) - { - control -> LocalMemoryLevel = ValidateArg("local", name, value); - } - else if (strcasecmp(name, "cache") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else if (ParseCacheOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify cache size for string '" - << value << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify cache size for string '" - << value << "'.\n"; - - return -1; - } - } - else if (strcasecmp(name, "images") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else if (ParseImagesOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify images cache size for string '" - << value << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify images cache size for string '" - << value << "'.\n"; - - return -1; - } - } - else if (strcasecmp(name, "shseg") == 0) - { - // - // The 'shmem' option is used by the agent, together - // with 'shpix' literal. We make the 'shseg' option - // specific to the proxy and use it to determine the - // size of the shared memory segment, or otherwise 0, - // if the use of the shared memory extension should - // not be enabled on the real X server. - // - - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else if (ParseShmemOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify size of shared memory " - << "segment in string '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify size of shared memory " - << "segment in string '" << value << "'.\n"; - - return -1; - } - } - else if (strcasecmp(name, "load") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else - { - control -> PersistentCacheEnableLoad = ValidateArg("local", name, value); - - if (control -> PersistentCacheEnableLoad > 0) - { - control -> PersistentCacheEnableLoad = 1; - } - else - { - if (control -> PersistentCacheName != NULL) - { - delete [] control -> PersistentCacheName; - } - - control -> PersistentCacheName = NULL; - - control -> PersistentCacheEnableLoad = 0; - } - } - } - else if (strcasecmp(name, "save") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else - { - control -> PersistentCacheEnableSave = ValidateArg("local", name, value); - - if (control -> PersistentCacheEnableSave > 0) - { - control -> PersistentCacheEnableSave = 1; - } - else - { - if (control -> PersistentCacheName != NULL) - { - delete [] control -> PersistentCacheName; - } - - control -> PersistentCacheName = NULL; - - control -> PersistentCacheEnableSave = 0; - } - } - } - else if (strcasecmp(name, "cups") == 0) - { - SetAndValidateChannelEndPointArg("local", name, value, cupsPort); - } - else if (strcasecmp(name, "sync") == 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! No 'sync' channel in current version. " - << "Assuming 'cups' channel.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": No 'sync' channel in current version. " - << "Assuming 'cups' channel.\n"; - - SetAndValidateChannelEndPointArg("local", name, value, cupsPort); - } - else if (strcasecmp(name, "keybd") == 0 || - strcasecmp(name, "aux") == 0) - { - SetAndValidateChannelEndPointArg("local", name, value, auxPort); - } - else if (strcasecmp(name, "samba") == 0 || - strcasecmp(name, "smb") == 0) - { - SetAndValidateChannelEndPointArg("local", name, value, smbPort); - } - else if (strcasecmp(name, "media") == 0) - { - SetAndValidateChannelEndPointArg("local", name, value, mediaPort); - } - else if (strcasecmp(name, "http") == 0) - { - SetAndValidateChannelEndPointArg("local", name, value, httpPort); - } - else if (strcasecmp(name, "font") == 0) - { - strncpy(fontPort, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "slave") == 0) - { - SetAndValidateChannelEndPointArg("local", name, value, slavePort); - } - else if (strcasecmp(name, "mask") == 0) - { - control -> ChannelMask = ValidateArg("local", name, value); - } - else if (strcasecmp(name, "timeout") == 0) - { - int timeout = ValidateArg("local", name, value); - - if (timeout == 0) - { - #ifdef TEST - *logofs << "Loop: Disabling timeout on broken " - << "proxy connection.\n" << logofs_flush; - #endif - - control -> ProxyTimeout = 0; - } - else - { - control -> ProxyTimeout = timeout * 1000; - } - } - else if (strcasecmp(name, "cleanup") == 0) - { - int cleanup = ValidateArg("local", name, value); - - if (cleanup == 0) - { - #ifdef TEST - *logofs << "Loop: Disabling grace timeout on " - << "proxy shutdown.\n" << logofs_flush; - #endif - - control -> CleanupTimeout = 0; - } - else - { - control -> CleanupTimeout = cleanup * 1000; - } - } - else if (strcasecmp(name, "pack") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else if (ParsePackOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify pack method for string '" - << value << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify pack method for string '" - << value << "'.\n"; - if (ParsePackOption("nopack")<0) - return -1; - } - } - else if (strcasecmp(name, "core") == 0) - { - control -> EnableCoreDumpOnAbort = ValidateArg("local", name, value); - } - else if (strcasecmp(name, "kill") == 0) - { - if (control -> KillDaemonOnShutdownNumber < - control -> KillDaemonOnShutdownLimit) - { - #ifdef TEST - *logofs << "Loop: WARNING! Adding process with pid '" - << ValidateArg("local", name, value) << " to the " - << "daemons to kill at shutdown.\n" - << logofs_flush; - #endif - - control -> KillDaemonOnShutdown[control -> - KillDaemonOnShutdownNumber] = - ValidateArg("local", name, value); - - control -> KillDaemonOnShutdownNumber++; - } - else - { - #ifdef WARNING - *logofs << "Loop: WARNING! Number of daemons to kill " - << "at shutdown exceeded.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Number of daemons to kill " - << "at shutdown exceeded.\n"; - } - } - else if (strcasecmp(name, "strict") == 0) - { - if (control -> ProxyMode == proxy_server) - { - PrintOptionIgnored("local", name, value); - } - else - { - useStrict = ValidateArg("local", name, value); - } - } - else if (strcasecmp(name, "encryption") == 0) - { - useEncryption = ValidateArg("local", name, value); - } - else if (strcasecmp(name, "product") == 0) - { - strncpy(productName, value, DEFAULT_STRING_LENGTH - 1); - } - else if (strcasecmp(name, "rootless") == 0 || - strcasecmp(name, "geometry") == 0 || - strcasecmp(name, "resize") == 0 || - strcasecmp(name, "fullscreen") == 0 || - strcasecmp(name, "keyboard") == 0 || - strcasecmp(name, "clipboard") == 0 || - strcasecmp(name, "streaming") == 0 || - strcasecmp(name, "backingstore") == 0 || - strcasecmp(name, "sleep") == 0 || - strcasecmp(name, "tolerancechecks") == 0) - { - #ifdef DEBUG - *logofs << "Loop: Ignoring agent option '" << name - << "' with value '" << value << "'.\n" - << logofs_flush; - #endif - } - else if (strcasecmp(name, "composite") == 0 || - strcasecmp(name, "shmem") == 0 || - strcasecmp(name, "shpix") == 0 || - strcasecmp(name, "kbtype") == 0 || - strcasecmp(name, "client") == 0 || - strcasecmp(name, "shadow") == 0 || - strcasecmp(name, "shadowuid") == 0 || - strcasecmp(name, "shadowmode") == 0 || - strcasecmp(name, "clients") == 0 || - strcasecmp(name, "xinerama") == 0) - { - #ifdef DEBUG - *logofs << "Loop: Ignoring agent option '" << name - << "' with value '" << value << "'.\n" - << logofs_flush; - #endif - } - else if (strcasecmp(name, "defer") == 0 || - strcasecmp(name, "tile") == 0 || - strcasecmp(name, "menu") == 0 || - strcasecmp(name, "state") == 0 ) - { - #ifdef DEBUG - *logofs << "Loop: Ignoring agent option '" << name - << "' with value '" << value << "'.\n" - << logofs_flush; - #endif - } - else - { - #ifdef WARNING - *logofs << "Loop: WARNING! Ignoring unknown option '" - << name << "' with value '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Ignoring unknown option '" - << name << "' with value '" << value << "'.\n"; - } - - name = strtok(NULL, "="); - - } // End of while (name) ... - - // Assemble the connectSocket channel end point if parameter values have been old-school... - if (connectSocket.disabled() && (connectHost[0] != '\0') && (proxyPort > 0 || connectPort > 0)) - { - if (connectPort < 0) - connectPort = proxyPort + DEFAULT_NX_PROXY_PORT_OFFSET; - - char tcpHostAndPort[DEFAULT_STRING_LENGTH] = { 0 }; - sprintf(tcpHostAndPort, "tcp:%s:%ld", connectHost, connectPort); - SetAndValidateChannelEndPointArg("local", name, tcpHostAndPort, connectSocket); - } - - #ifdef TEST - *logofs << "Loop: Completed parsing of string '" - << env << "'.\n" << logofs_flush; - #endif - - if ((*fileOptions != '\0') && (strncmp(fileOptions, "/dev/", 5) != 0) && (strncmp(fileOptions, "/proc/", 6) != 0) && (strncmp(fileOptions, "/sys/", 5) != 0)) - { - if (strcmp(fileOptions, optionsFileName) != 0) - { - #ifdef TEST - *logofs << "Loop: Reading options from '" << fileOptions - << "'.\n" << logofs_flush; - #endif - - if (ParseFileOptions(fileOptions) < 0) - { - return -1; - } - } - #ifdef WARNING - else - { - *logofs << "Loop: WARNING! Name of the options file " - << "specified multiple times. Not parsing " - << "again.\n" << logofs_flush; - } - #endif - - if (*optionsFileName == '\0') - { - strncpy(optionsFileName, value, DEFAULT_STRING_LENGTH - 1); - - #ifdef TEST - *logofs << "Loop: Assuming name of options file '" - << optionsFileName << "'.\n" - << logofs_flush; - #endif - } - } - - // - // If port where proxy is acting as an X server - // was not specified assume the same port where - // proxy is listening for the remote peer. - // - - if (xPort == DEFAULT_NX_X_PORT) - { - xPort = proxyPort; - } - - return 1; -} - -// -// Parse the command line options passed by user when -// running proxy in stand alone mode. Note that passing -// parameters this way is strongly discouraged. These -// command line switch can change (and they do often). -// Please, use the form "option=value" instead and set -// the DISPLAY environment variable. -// - -int ParseCommandLineOptions(int argc, const char **argv) -{ - // - // Be sure log file is valid. - // - - if (logofs == NULL) - { - logofs = &cerr; - } - - if (setjmp(context) == 1) - { - #ifdef TEST - *logofs << "Loop: Out of the long jump while parsing " - << "the command line options.\n" - << logofs_flush; - #endif - - return -1; - } - - // - // Be sure we have a parameters repository - // - - if (control == NULL) - { - control = new Control(); - } - - if (parsedCommand == 1) - { - #ifdef TEST - *logofs << "Loop: Skipping a further parse of command line options.\n" - << logofs_flush; - #endif - - return 1; - } - - #ifdef TEST - *logofs << "Loop: Going to parse the command line options.\n" - << logofs_flush; - #endif - - parsedCommand = 1; - - // - // Print out arguments. - // - - #ifdef TEST - - *logofs << "Loop: Argc is " << argc << ".\n" << logofs_flush; - - for (int argi = 0; argi < argc; argi++) - { - *logofs << "Loop: Argv[" << argi << "] is " << argv[argi] - << ".\n" << logofs_flush; - } - - #endif - - // - // Shall use getopt here. - // - - for (int argi = 1; argi < argc; argi++) - { - const char *nextArg = argv[argi]; - - if (*nextArg == '-') - { - switch (*(nextArg + 1)) - { - case 'h': - { - PrintUsageInfo(nextArg, 0); - - return -1; - } - case 'C': - { - // - // Start proxy in CLIENT mode. - // - - if (WE_SET_PROXY_MODE == 0) - { - #ifdef TEST - *logofs << "Loop: Setting local proxy mode to proxy_client.\n" - << logofs_flush; - #endif - - control -> ProxyMode = proxy_client; - } - else if (control -> ProxyMode != proxy_client) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't redefine local proxy to " - << "client mode.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't redefine local proxy to " - << "client mode.\n"; - - return -1; - } - - break; - } - case 'S': - { - // - // Start proxy in SERVER mode. - // - - if (WE_SET_PROXY_MODE == 0) - { - #ifdef TEST - *logofs << "Loop: Setting local proxy mode to proxy_server.\n" - << logofs_flush; - #endif - - control -> ProxyMode = proxy_server; - } - else if (control -> ProxyMode != proxy_server) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't redefine local proxy to " - << "server mode.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't redefine local proxy to " - << "server mode.\n"; - - return -1; - } - - break; - } - case 'v': - { - PrintVersionInfo(); - - return -1; - } - default: - { - PrintUsageInfo(nextArg, 1); - - // - // Function GetArg() is not used anymore. - // Add a dummy call to avoid the warning. - // - - if (0) - { - GetArg(argi, argc, argv); - } - - return -1; - } - } - } - else - { - if (nextArg) - { - // - // Try to parse the option as a remote host:port - // specification as in 'localhost:8'. Such a - // parameter can be specified at the end of the - // command line at the connecting side. - // - - char cHost[DEFAULT_STRING_LENGTH] = { '\0' }; - long cPort = 0; - - if (ParseHostOption(nextArg, cHost, cPort) > 0) - { - // - // Assume port is at a proxied display offset. - // - - proxyPort = cPort; - - cPort += DEFAULT_NX_PROXY_PORT_OFFSET; - connectSocket.setSpec(cHost, cPort); - - } - else if (ParseEnvironmentOptions(nextArg, 1) < 0) - { - return -1; - } - } - } - } - - return 1; -} - -// -// Set the variable to the values of host and -// port where this proxy is going to hook to -// an existing proxy. -// - -int ParseBindOptions(char **host, int *port) -{ - if (*bindHost != '\0') - { - *host = bindHost; - *port = bindPort; - - return 1; - } - else - { - return 0; - } -} - -// -// Read options from file and merge with environment. -// - -int ParseFileOptions(const char *file) -{ - char *fileName; - - if (*file != '/' && *file != '.') - { - char *filePath = GetSessionPath(); - - if (filePath == NULL) - { - cerr << "Error" << ": Cannot determine directory for NX option file.\n"; - - HandleCleanup(); - } - - fileName = new char[strlen(filePath) + strlen("/") + - strlen(file) + 1]; - - strcpy(fileName, filePath); - - strcat(fileName, "/"); - strcat(fileName, file); - - delete [] filePath; - } - else - { - fileName = new char[strlen(file) + 1]; - - strcpy(fileName, file); - } - - #ifdef TEST - *logofs << "Loop: Going to read options from file '" - << fileName << "'.\n" << logofs_flush; - #endif - - FILE *filePtr = fopen(fileName, "r"); - - if (filePtr == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't open options file '" << fileName - << "'. Error is " << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't open options file '" << fileName - << "'. Error is " << EGET() << " '" << ESTR() << "'.\n"; - - delete [] fileName; - - return -1; - } - - char options[DEFAULT_DISPLAY_OPTIONS_LENGTH]; - - #ifdef VALGRIND - - memset(options, '\0', DEFAULT_DISPLAY_OPTIONS_LENGTH); - - #endif - - if (fgets(options, DEFAULT_DISPLAY_OPTIONS_LENGTH, filePtr) == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't read options from file '" << fileName - << "'. Error is " << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't read options from file '" << fileName - << "'. Error is " << EGET() << " '" << ESTR() << "'.\n"; - - fclose(filePtr); - - delete [] fileName; - - return -1; - } - - fclose(filePtr); - - // - // Purge the newline and the other non- - // printable characters in the string. - // - - char *next = options; - - while (*next != '\0') - { - if (isprint(*next) == 0) - { - *next = '\0'; - } - - next++; - } - - #ifdef TEST - *logofs << "Loop: Read options '" << options << "' from file '" - << fileName << "'.\n" << logofs_flush; - #endif - - if (ParseEnvironmentOptions(options, 1) < 0) - { - delete [] fileName; - - return -1; - } - - delete [] fileName; - - return 1; -} - -// -// Parse the option string passed from the -// remote proxy at startup. -// - -int ParseRemoteOptions(char *opts) -{ - #ifdef TEST - *logofs << "Loop: Going to parse the remote options " - << "string '" << opts << "'.\n" - << logofs_flush; - #endif - - char *name; - char *value; - - // - // The options string is intended to be a series - // of name/value tuples in the form name=value - // separated by the ',' character. - // - - int hasCookie = 0; - int hasLink = 0; - int hasPack = 0; - int hasCache = 0; - int hasImages = 0; - int hasDelta = 0; - int hasStream = 0; - int hasData = 0; - int hasType = 0; - - // - // Get rid of the terminating space. - // - - if (*(opts + strlen(opts) - 1) == ' ') - { - *(opts + strlen(opts) - 1) = '\0'; - } - - name = strtok(opts, "="); - - while (name) - { - value = strtok(NULL, ","); - - if (CheckArg("remote", name, value) < 0) - { - return -1; - } - - if (strcasecmp(name, "cookie") == 0) - { - if (WE_PROVIDE_CREDENTIALS) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Ignoring remote option 'cookie' " - << "with value '" << value << "' when initiating " - << "connection.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Ignoring remote option 'cookie' " - << "with value '" << value << "' when initiating " - << "connection.\n"; - } - else if (strncasecmp(authCookie, value, strlen(authCookie)) != 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Authentication cookie '" << value - << "' doesn't match '" << authCookie << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Authentication cookie '" << value - << "' doesn't match '" << authCookie << "'.\n"; - - return -1; - } - - hasCookie = 1; - } - else if (strcasecmp(name, "link") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - if (*linkSpeedName != '\0' && strcasecmp(linkSpeedName, value) != 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Overriding option 'link' " - << "with new value '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Overriding option 'link' " - << "with new value '" << value << "'.\n"; - } - - if (ParseLinkOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify remote 'link' " - << "option in string '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify remote 'link' " - << "option in string '" << value << "'.\n"; - - return -1; - } - } - - hasLink = 1; - } - else if (strcasecmp(name, "pack") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - if (*packMethodName != '\0' && strcasecmp(packMethodName, value) != 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Overriding option 'pack' " - << "with remote value '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Overriding option 'pack' " - << "with remote value '" << value << "'.\n"; - } - - if (ParsePackOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid pack option '" - << value << "' requested by remote.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid pack option '" - << value << "' requested by remote.\n"; - - return -1; - } - } - - hasPack = 1; - } - else if (strcasecmp(name, "cache") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - // - // Cache size is sent as a hint of how much memory - // the remote proxy is going to consume. A very low - // powered thin client could choose to refuse the - // connection. - // - - if (ParseCacheOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify remote 'cache' " - << "option in string '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify remote 'cache' " - << "option in string '" << value << "'.\n"; - - return -1; - } - } - - hasCache = 1; - } - else if (strcasecmp(name, "images") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - // - // Images cache size is sent as a hint. - // There is no obbligation for the local - // proxy to use the persistent cache. - // - - if (ParseImagesOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify remote 'images' " - << "option in string '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify remote 'images' " - << "option in string '" << value << "'.\n"; - - return -1; - } - } - - hasImages = 1; - } - else if (strcasecmp(name, "limit") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - if (*bitrateLimitName != '\0' && - strcasecmp(bitrateLimitName, value) != 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Overriding option 'limit' " - << "with new value '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Overriding option 'limit' " - << "with new value '" << value << "'.\n"; - } - - if (ParseBitrateOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify 'limit' " - << "option in string '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify 'limit' " - << "option in string '" << value << "'.\n"; - - return -1; - } - } - - } - else if (strcasecmp(name, "render") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - useRender = ValidateArg("remote", name, value); - } - - } - else if (strcasecmp(name, "taint") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - useTaint = ValidateArg("remote", name, value); - } - - } - else if (strcasecmp(name, "type") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - if (strcasecmp(value, "default") == 0) - { - *sessionType = '\0'; - } - else - { - strncpy(sessionType, value, DEFAULT_STRING_LENGTH - 1); - } - } - - hasType = 1; - } - else if (strcasecmp(name, "strict") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - useStrict = ValidateArg("remote", name, value); - } - - } - else if (strcasecmp(name, "shseg") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else if (ParseShmemOption(value) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't identify size of shared memory " - << "segment in string '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify size of shared memory " - << "segment in string '" << value << "'.\n"; - - return -1; - } - - } - else if (strcasecmp(name, "delta") == 0) - { - if (control -> ProxyMode == proxy_client) - { - PrintOptionIgnored("remote", name, value); - } - else - { - control -> RemoteDeltaCompression = ValidateArg("remote", name, value); - - // - // Follow for delta compression the - // same settings as the client proxy. - // - - control -> LocalDeltaCompression = control -> RemoteDeltaCompression; - } - - hasDelta = 1; - } - else if (strcasecmp(name, "stream") == 0) - { - // - // If remote side didn't choose its own - // stream compression level then assume - // local settings. - // - - if (strcasecmp(value, "default") == 0) - { - // - // This applies only at client side. - // - - control -> RemoteStreamCompression = - control -> LocalStreamCompression; - - control -> RemoteStreamCompressionLevel = - control -> LocalStreamCompressionLevel; - } - else - { - control -> RemoteStreamCompressionLevel = ValidateArg("remote", name, value); - - if (control -> RemoteStreamCompressionLevel > 0) - { - control -> RemoteStreamCompression = 1; - } - else - { - control -> RemoteStreamCompression = 0; - } - - if (control -> LocalStreamCompressionLevel < 0) - { - control -> LocalStreamCompressionLevel = ValidateArg("remote", name, value); - - if (control -> LocalStreamCompressionLevel > 0) - { - control -> LocalStreamCompression = 1; - } - else - { - control -> LocalStreamCompression = 0; - } - } - } - - hasStream = 1; - } - else if (strcasecmp(name, "data") == 0) - { - // - // Apply the same to data compression level. - // - - if (strcasecmp(value, "default") == 0) - { - control -> RemoteDataCompression = - control -> LocalDataCompression; - - control -> RemoteDataCompressionLevel = - control -> LocalDataCompressionLevel; - } - else - { - control -> RemoteDataCompressionLevel = ValidateArg("remote", name, value); - - if (control -> RemoteDataCompressionLevel > 0) - { - control -> RemoteDataCompression = 1; - } - else - { - control -> RemoteDataCompression = 0; - } - - if (control -> LocalDataCompressionLevel < 0) - { - control -> LocalDataCompressionLevel = ValidateArg("remote", name, value); - - if (control -> LocalDataCompressionLevel > 0) - { - control -> LocalDataCompression = 1; - } - else - { - control -> LocalDataCompression = 0; - } - } - } - - hasData = 1; - } - else if (strcasecmp(name, "flush") == 0) - { - // - // This option has no effect in recent - // versions. - // - - #ifdef DEBUG - *logofs << "Loop: Ignoring obsolete remote option '" - << name << "' with value '" << value - << "'.\n" << logofs_flush; - #endif - } - else - { - #ifdef WARNING - *logofs << "Loop: WARNING! Ignoring unknown remote option '" - << name << "' with value '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Ignoring unknown remote option '" - << name << "' with value '" << value << "'.\n"; - } - - name = strtok(NULL, "="); - - } // End of while (name) ... - - // - // If we are client side, we need remote 'stream' - // and 'data' options. If we are server, we need - // all the above plus 'link' and some others. - // - - char missing[DEFAULT_STRING_LENGTH]; - - *missing = '\0'; - - if (control -> ProxyMode == proxy_client) - { - if (hasStream == 0) - { - strcpy(missing, "stream"); - } - else if (hasData == 0) - { - strcpy(missing, "data"); - } - } - else - { - // - // Don't complain if the optional 'flush', - // 'render' and 'taint' options are not - // provided. - // - - if (hasLink == 0) - { - strcpy(missing, "link"); - } - else if (hasCache == 0) - { - strcpy(missing, "cache"); - } - else if (hasPack == 0) - { - strcpy(missing, "pack"); - } - else if (hasDelta == 0) - { - strcpy(missing, "delta"); - } - else if (hasStream == 0) - { - strcpy(missing, "stream"); - } - else if (hasData == 0) - { - strcpy(missing, "data"); - } - else if (hasType == 0) - { - strcpy(missing, "type"); - } - else if (hasImages == 0) - { - strcpy(missing, "images"); - } - } - - if (WE_PROVIDE_CREDENTIALS == 0) - { - // - // Can be that user doesn't have requested to - // check the authorization cookie provided by - // the connecting peer. - // - - if (hasCookie == 0 && *authCookie != '\0') - { - strcpy(missing, "cookie"); - } - } - - if (*missing != '\0') - { - #ifdef PANIC - *logofs << "Loop: PANIC! The remote peer didn't specify the option '" - << missing << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": The remote peer didn't specify the option '" - << missing << "'.\n"; - - return -1; - } - - return 1; -} - -// -// Parse the cookie provided by the NX proxy -// connection forwarder. -// - -int ParseForwarderOptions(char *opts) -{ - #ifdef TEST - *logofs << "Loop: Going to parse the forwarder options " - << "string '" << opts << "'.\n" - << logofs_flush; - #endif - - char *name; - char *value; - - int hasCookie = 0; - - // - // Get rid of the terminating space. - // - - if (*(opts + strlen(opts) - 1) == ' ') - { - *(opts + strlen(opts) - 1) = '\0'; - } - - name = strtok(opts, "="); - - while (name) - { - value = strtok(NULL, ","); - - if (CheckArg("forwarder", name, value) < 0) - { - return -1; - } - - if (strcasecmp(name, "cookie") == 0) - { - if (strncasecmp(authCookie, value, strlen(authCookie)) != 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! The NX forwarder cookie '" << value - << "' doesn't match '" << authCookie << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": The NX forwarder cookie '" << value - << "' doesn't match '" << authCookie << "'.\n"; - - return -1; - } - - hasCookie = 1; - } - else - { - #ifdef WARNING - *logofs << "Loop: WARNING! Ignoring unknown forwarder option '" - << name << "' with value '" << value << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Ignoring unknown forwarder option '" - << name << "' with value '" << value << "'.\n"; - } - - name = strtok(NULL, "="); - - } // End of while (name) ... - - if (hasCookie == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! The NX forwarder didn't provide " - << "the authentication cookie.\n" << logofs_flush; - #endif - - cerr << "Error" << ": The NX forwarder didn't provide " - << "the authentication cookie.\n"; - - return -1; - } - - return 1; -} - -int SetCore() -{ - #ifdef COREDUMPS - - rlimit rlim; - - if (getrlimit(RLIMIT_CORE, &rlim)) - { - #ifdef TEST - *logofs << "Loop: Cannot read RLIMIT_CORE. Error is '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - return -1; - } - - if (rlim.rlim_cur < rlim.rlim_max) - { - rlim.rlim_cur = rlim.rlim_max; - - if (setrlimit(RLIMIT_CORE, &rlim)) - { - #ifdef TEST - *logofs << "Loop: Cannot set RLIMIT_CORE. Error is '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - return -2; - } - } - - #ifdef TEST - *logofs << "Loop: RLIMIT_CORE is "<< rlim.rlim_max - << ".\n" << logofs_flush; - #endif - - #endif // #ifdef COREDUMPS - - return 1; -} - -char *GetLastCache(char *listBuffer, const char *searchPath) -{ - if (listBuffer == NULL || searchPath == NULL || - strncmp(listBuffer, "cachelist=", strlen("cachelist=")) != 0) - { - #ifdef TEST - *logofs << "Loop: Invalid parameters '" << listBuffer << "' and '" - << (searchPath != NULL ? searchPath : "") - << "'. Can't select any cache.\n" << logofs_flush; - #endif - - return NULL; - } - - char *selectedName = new char[MD5_LENGTH * 2 + 3]; - - *selectedName = '\0'; - - const char *localPrefix; - const char *remotePrefix; - - if (control -> ProxyMode == proxy_client) - { - localPrefix = "C-"; - remotePrefix = "S-"; - } - else - { - localPrefix = "S-"; - remotePrefix = "C-"; - } - - // - // Get rid of prefix. - // - - listBuffer += strlen("cachelist="); - - char *fileName; - - fileName = strtok(listBuffer, ","); - - // - // It is "/path/to/file" + "/" + "C-" + 32 + "\0". - // - - char fullPath[strlen(searchPath) + MD5_LENGTH * 2 + 4]; - - time_t selectedTime = 0; - - struct stat fileStat; - - while (fileName) - { - if (strncmp(fileName, "none", strlen("none")) == 0) - { - #ifdef TEST - *logofs << "Loop: No cache files seem to be available.\n" - << logofs_flush; - #endif - - delete [] selectedName; - - return NULL; - } - else if (strlen(fileName) != MD5_LENGTH * 2 + 2 || - strncmp(fileName, remotePrefix, 2) != 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Bad cache file name '" - << fileName << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Bad cache file name '" - << fileName << "'.\n"; - - delete [] selectedName; - - HandleCleanup(); - } - - #ifdef TEST - *logofs << "Loop: Parsing remote cache name '" - << fileName << "'.\n" << logofs_flush; - #endif - - // - // Prefix, received as "S-", becomes - // "C-" and viceversa. - // - - *fileName = *localPrefix; - - strcpy(fullPath, searchPath); - strcat(fullPath, "/"); - strcat(fullPath, fileName); - - if (stat(fullPath, &fileStat) == 0) - { - #ifdef TEST - *logofs << "Loop: Found a matching cache '" - << fullPath << "'.\n" << logofs_flush; - #endif - - if (fileStat.st_mtime >= selectedTime) - { - strcpy(selectedName, fileName); - - selectedTime = fileStat.st_mtime; - } - } - #ifdef TEST - else - { - *logofs << "Loop: Can't get stats of file '" - << fullPath << "'.\n" << logofs_flush; - } - #endif - - fileName = strtok(NULL, ","); - } - - if (*selectedName != '\0') - { - return selectedName; - } - else - { - delete [] selectedName; - - return NULL; - } -} - -char *GetTempPath() -{ - if (*tempDir == '\0') - { - // - // Check the NX_TEMP environment, first, - // then the TEMP variable. - // - - const char *tempEnv = getenv("NX_TEMP"); - - if (tempEnv == NULL || *tempEnv == '\0') - { - #ifdef TEST - *logofs << "Loop: WARNING! No environment for NX_TEMP.\n" - << logofs_flush; - #endif - - tempEnv = getenv("TEMP"); - - if (tempEnv == NULL || *tempEnv == '\0') - { - #ifdef TEST - *logofs << "Loop: WARNING! No environment for TEMP.\n" - << logofs_flush; - #endif - - tempEnv = "/tmp"; - } - } - - if (strlen(tempEnv) > DEFAULT_STRING_LENGTH - 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value for the NX " - << "temporary directory '" << tempEnv - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value for the NX " - << "temporary directory '" << tempEnv - << "'.\n"; - - HandleCleanup(); - } - - strcpy(tempDir, tempEnv); - - #ifdef TEST - *logofs << "Loop: Assuming temporary NX directory '" - << tempDir << "'.\n" << logofs_flush; - #endif - } - - char *tempPath = new char[strlen(tempDir) + 1]; - - if (tempPath == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't allocate memory " - << "for the temp path.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory " - << "for the temp path.\n"; - - HandleCleanup(); - } - - strcpy(tempPath, tempDir); - - return tempPath; -} - -char *GetClientPath() -{ - if (*clientDir == '\0') - { - // - // Check the NX_CLIENT environment. - // - - const char *clientEnv = getenv("NX_CLIENT"); - - if (clientEnv == NULL || *clientEnv == '\0') - { - #ifdef TEST - *logofs << "Loop: WARNING! No environment for NX_CLIENT.\n" - << logofs_flush; - #endif - - // - // Try to guess the location of the client. - // - - clientEnv = "/usr/NX/bin/nxclient"; - - #ifdef __APPLE__ - - clientEnv = "/Applications/NX Client for OSX.app/Contents/MacOS/nxclient"; - - #endif - - #ifdef __CYGWIN32__ - - clientEnv = "C:\\Program Files\\NX Client for Windows\\nxclient"; - - #endif - } - - if (strlen(clientEnv) > DEFAULT_STRING_LENGTH - 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value for the NX " - << "client directory '" << clientEnv - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value for the NX " - << "client directory '" << clientEnv - << "'.\n"; - - HandleCleanup(); - } - - strcpy(clientDir, clientEnv); - - #ifdef TEST - *logofs << "Loop: Assuming NX client location '" - << clientDir << "'.\n" << logofs_flush; - #endif - } - - char *clientPath = new char[strlen(clientDir) + 1]; - - if (clientPath == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't allocate memory " - << "for the client path.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory " - << "for the client path.\n"; - - HandleCleanup(); - } - - strcpy(clientPath, clientDir); - - return clientPath; -} - -char *GetSystemPath() -{ - if (*systemDir == '\0') - { - // - // Check the NX_SYSTEM environment. - // - - const char *systemEnv = getenv("NX_SYSTEM"); - - if (systemEnv == NULL || *systemEnv == '\0') - { - #ifdef TEST - *logofs << "Loop: WARNING! No environment for NX_SYSTEM.\n" - << logofs_flush; - #endif - - systemEnv = "/usr/NX"; - } - - if (strlen(systemEnv) > DEFAULT_STRING_LENGTH - 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value for the NX " - << "system directory '" << systemEnv - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value for the NX " - << "system directory '" << systemEnv - << "'.\n"; - - HandleCleanup(); - } - - strcpy(systemDir, systemEnv); - - #ifdef TEST - *logofs << "Loop: Assuming system NX directory '" - << systemDir << "'.\n" << logofs_flush; - #endif - } - - char *systemPath = new char[strlen(systemDir) + 1]; - - if (systemPath == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't allocate memory " - << "for the system path.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory " - << "for the system path.\n"; - - HandleCleanup(); - } - - strcpy(systemPath, systemDir); - - return systemPath; -} - -char *GetHomePath() -{ - if (*homeDir == '\0') - { - // - // Check the NX_HOME environment. - // - - const char *homeEnv = getenv("NX_HOME"); - - if (homeEnv == NULL || *homeEnv == '\0') - { - #ifdef TEST - *logofs << "Loop: WARNING! No environment for NX_HOME.\n" - << logofs_flush; - #endif - - homeEnv = getenv("HOME"); - - if (homeEnv == NULL || *homeEnv == '\0') - { - #ifdef PANIC - *logofs << "Loop: PANIC! No environment for HOME.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": No environment for HOME.\n"; - - HandleCleanup(); - } - } - - if (strlen(homeEnv) > DEFAULT_STRING_LENGTH - 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value for the NX " - << "home directory '" << homeEnv - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value for the NX " - << "home directory '" << homeEnv - << "'.\n"; - - HandleCleanup(); - } - - strcpy(homeDir, homeEnv); - - #ifdef TEST - *logofs << "Loop: Assuming NX user's home directory '" - << homeDir << "'.\n" << logofs_flush; - #endif - } - - char *homePath = new char[strlen(homeDir) + 1]; - - if (homePath == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't allocate memory " - << "for the home path.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory " - << "for the home path.\n"; - - HandleCleanup(); - } - - strcpy(homePath, homeDir); - - return homePath; -} - -char *GetRootPath() -{ - if (*rootDir == '\0') - { - // - // Check the NX_ROOT environment. - // - - const char *rootEnv = getenv("NX_ROOT"); - - if (rootEnv == NULL || *rootEnv == '\0') - { - #ifdef TEST - *logofs << "Loop: WARNING! No environment for NX_ROOT.\n" - << logofs_flush; - #endif - - // - // We will determine the root NX directory - // based on the NX_HOME or HOME directory - // settings. - // - - const char *homeEnv = GetHomePath(); - - if (strlen(homeEnv) > DEFAULT_STRING_LENGTH - - strlen("/.nx") - 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value for the NX " - << "home directory '" << homeEnv - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value for the NX " - << "home directory '" << homeEnv - << "'.\n"; - - HandleCleanup(); - } - - #ifdef TEST - *logofs << "Loop: Assuming NX root directory in " - << "the user's home '" << homeEnv - << "'.\n" << logofs_flush; - #endif - - strcpy(rootDir, homeEnv); - strcat(rootDir, "/.nx"); - - delete [] homeEnv; - - // - // Create the NX root directory. - // - - struct stat dirStat; - - if ((stat(rootDir, &dirStat) == -1) && (EGET() == ENOENT)) - { - if (mkdir(rootDir, 0700) < 0 && (EGET() != EEXIST)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't create directory '" - << rootDir << ". Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't create directory '" - << rootDir << ". Error is " << EGET() << " '" - << ESTR() << "'.\n"; - - HandleCleanup(); - } - } - } - else - { - if (strlen(rootEnv) > DEFAULT_STRING_LENGTH - 1) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value for the NX " - << "root directory '" << rootEnv - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value for the NX " - << "root directory '" << rootEnv - << "'.\n"; - - HandleCleanup(); - } - - strcpy(rootDir, rootEnv); - } - - #ifdef TEST - *logofs << "Loop: Assuming NX root directory '" - << rootDir << "'.\n" << logofs_flush; - #endif - } - - char *rootPath = new char[strlen(rootDir) + 1]; - - if (rootPath == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't allocate memory " - << "for the root path.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory " - << "for the root path.\n"; - - HandleCleanup(); - } - - strcpy(rootPath, rootDir); - - return rootPath; -} - -char *GetCachePath() -{ - char *rootPath = GetRootPath(); - - char *cachePath; - - if (*sessionType != '\0') - { - cachePath = new char[strlen(rootPath) + strlen("/cache-") + - strlen(sessionType) + 1]; - } - else - { - cachePath = new char[strlen(rootPath) + strlen("/cache") + 1]; - } - - strcpy(cachePath, rootPath); - - if (*sessionType != '\0') - { - strcat(cachePath, "/cache-"); - - strcat(cachePath, sessionType); - } - else - { - strcat(cachePath, "/cache"); - } - - // - // Create the cache directory if needed. - // - - struct stat dirStat; - - if ((stat(cachePath, &dirStat) == -1) && (EGET() == ENOENT)) - { - if (mkdir(cachePath, 0700) < 0 && (EGET() != EEXIST)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't create directory '" << cachePath - << ". Error is " << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't create directory '" << cachePath - << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; - - delete [] rootPath; - delete [] cachePath; - - return NULL; - } - } - - delete [] rootPath; - - return cachePath; -} - -char *GetImagesPath() -{ - char *rootPath = GetRootPath(); - - char *imagesPath = new char[strlen(rootPath) + strlen("/images") + 1]; - - strcpy(imagesPath, rootPath); - - strcat(imagesPath, "/images"); - - // - // Create the cache directory if needed. - // - - struct stat dirStat; - - if ((stat(imagesPath, &dirStat) == -1) && (EGET() == ENOENT)) - { - if (mkdir(imagesPath, 0700) < 0 && (EGET() != EEXIST)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't create directory '" << imagesPath - << ". Error is " << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't create directory '" << imagesPath - << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; - - delete [] rootPath; - delete [] imagesPath; - - return NULL; - } - } - - // - // Create 16 directories in the path to - // hold the images whose name begins with - // the corresponding hexadecimal digit. - // - - char *digitPath = new char[strlen(imagesPath) + 5]; - - strcpy(digitPath, imagesPath); - - // - // Image paths have format "[path][/I-c][\0]", - // where c is the first digit of the checksum. - // - - for (char digit = 0; digit < 16; digit++) - { - sprintf(digitPath + strlen(imagesPath), "/I-%01X", digit); - - if ((stat(digitPath, &dirStat) == -1) && (EGET() == ENOENT)) - { - if (mkdir(digitPath, 0700) < 0 && (EGET() != EEXIST)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't create directory '" << digitPath - << ". Error is " << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't create directory '" << digitPath - << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; - - delete [] rootPath; - delete [] imagesPath; - delete [] digitPath; - - return NULL; - } - } - } - - delete [] rootPath; - delete [] digitPath; - - return imagesPath; -} - -char *GetSessionPath() -{ - if (*sessionDir == '\0') - { - char *rootPath = GetRootPath(); - - strcpy(sessionDir, rootPath); - - if (control -> ProxyMode == proxy_client) - { - strcat(sessionDir, "/C-"); - } - else - { - strcat(sessionDir, "/S-"); - } - - if (*sessionId == '\0') - { - char port[DEFAULT_STRING_LENGTH]; - - sprintf(port, "%d", proxyPort); - - strcpy(sessionId, port); - } - - strcat(sessionDir, sessionId); - - struct stat dirStat; - - if ((stat(sessionDir, &dirStat) == -1) && (EGET() == ENOENT)) - { - if (mkdir(sessionDir, 0700) < 0 && (EGET() != EEXIST)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't create directory '" << sessionDir - << ". Error is " << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't create directory '" << sessionDir - << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; - - delete [] rootPath; - - return NULL; - } - } - - #ifdef TEST - *logofs << "Loop: Root of NX session is '" << sessionDir - << "'.\n" << logofs_flush; - #endif - - delete [] rootPath; - } - - char *sessionPath = new char[strlen(sessionDir) + 1]; - - strcpy(sessionPath, sessionDir); - - return sessionPath; -} - -// -// Identify requested link characteristics -// and set control parameters accordingly. -// - -int ParseLinkOption(const char *opt) -{ - // - // Normalize the user input. - // - - if (strcasecmp(opt, "modem") == 0 || - strcasecmp(opt, "33k") == 0 || - strcasecmp(opt, "56k") == 0) - { - strcpy(linkSpeedName, "MODEM"); - } - else if (strcasecmp(opt, "isdn") == 0 || - strcasecmp(opt, "64k") == 0 || - strcasecmp(opt, "128k") == 0) - { - strcpy(linkSpeedName, "ISDN"); - } - else if (strcasecmp(opt, "adsl") == 0 || - strcasecmp(opt, "256k") == 0 || - strcasecmp(opt, "640k") == 0) - { - strcpy(linkSpeedName, "ADSL"); - } - else if (strcasecmp(opt, "wan") == 0 || - strcasecmp(opt, "1m") == 0 || - strcasecmp(opt, "2m") == 0 || - strcasecmp(opt, "34m") == 0) - { - strcpy(linkSpeedName, "WAN"); - } - else if (strcasecmp(opt, "lan") == 0 || - strcasecmp(opt, "10m") == 0 || - strcasecmp(opt, "100m") == 0 || - strcasecmp(opt, "local") == 0) - { - strcpy(linkSpeedName, "LAN"); - } - - if (strcasecmp(linkSpeedName, "modem") != 0 && - strcasecmp(linkSpeedName, "isdn") != 0 && - strcasecmp(linkSpeedName, "adsl") != 0 && - strcasecmp(linkSpeedName, "wan") != 0 && - strcasecmp(linkSpeedName, "lan") != 0) - { - return -1; - } - - return 1; -} - -int ParsePackOption(const char *opt) -{ - #ifdef DEBUG - *logofs << "Loop: Pack method is " << packMethod - << " quality is " << packQuality << ".\n" - << logofs_flush; - #endif - - #ifdef DEBUG - *logofs << "Loop: Parsing pack method '" << opt - << "'.\n" << logofs_flush; - #endif - - if (strcasecmp(opt, "0") == 0 || - strcasecmp(opt, "none") == 0 || - strcasecmp(opt, "nopack") == 0 || - strcasecmp(opt, "no-pack") == 0) - { - packMethod = PACK_NONE; - } - else if (strcasecmp(opt, "8") == 0) - { - packMethod = PACK_MASKED_8_COLORS; - } - else if (strcasecmp(opt, "64") == 0) - { - packMethod = PACK_MASKED_64_COLORS; - } - else if (strcasecmp(opt, "256") == 0) - { - packMethod = PACK_MASKED_256_COLORS; - } - else if (strcasecmp(opt, "512") == 0) - { - packMethod = PACK_MASKED_512_COLORS; - } - else if (strcasecmp(opt, "4k") == 0) - { - packMethod = PACK_MASKED_4K_COLORS; - } - else if (strcasecmp(opt, "32k") == 0) - { - packMethod = PACK_MASKED_32K_COLORS; - } - else if (strcasecmp(opt, "64k") == 0) - { - packMethod = PACK_MASKED_64K_COLORS; - } - else if (strcasecmp(opt, "256k") == 0) - { - packMethod = PACK_MASKED_256K_COLORS; - } - else if (strcasecmp(opt, "2m") == 0) - { - packMethod = PACK_MASKED_2M_COLORS; - } - else if (strcasecmp(opt, "16m") == 0) - { - packMethod = PACK_MASKED_16M_COLORS; - } - else if (strncasecmp(opt, "8-jpeg", strlen("8-jpeg")) == 0) - { - packMethod = PACK_JPEG_8_COLORS; - } - else if (strncasecmp(opt, "64-jpeg", strlen("64-jpeg")) == 0) - { - packMethod = PACK_JPEG_64_COLORS; - } - else if (strncasecmp(opt, "256-jpeg", strlen("256-jpeg")) == 0) - { - packMethod = PACK_JPEG_256_COLORS; - } - else if (strncasecmp(opt, "512-jpeg", strlen("512-jpeg")) == 0) - { - packMethod = PACK_JPEG_512_COLORS; - } - else if (strncasecmp(opt, "4k-jpeg", strlen("4k-jpeg")) == 0) - { - packMethod = PACK_JPEG_4K_COLORS; - } - else if (strncasecmp(opt, "32k-jpeg", strlen("32k-jpeg")) == 0) - { - packMethod = PACK_JPEG_32K_COLORS; - } - else if (strncasecmp(opt, "64k-jpeg", strlen("64k-jpeg")) == 0) - { - packMethod = PACK_JPEG_64K_COLORS; - } - else if (strncasecmp(opt, "256k-jpeg", strlen("256k-jpeg")) == 0) - { - packMethod = PACK_JPEG_256K_COLORS; - } - else if (strncasecmp(opt, "2m-jpeg", strlen("2m-jpeg")) == 0) - { - packMethod = PACK_JPEG_2M_COLORS; - } - else if (strncasecmp(opt, "16m-jpeg", strlen("16m-jpeg")) == 0) - { - packMethod = PACK_JPEG_16M_COLORS; - } - else if (strncasecmp(opt, "8-png", strlen("8-png")) == 0) - { - packMethod = PACK_PNG_8_COLORS; - } - else if (strncasecmp(opt, "64-png", strlen("64-png")) == 0) - { - packMethod = PACK_PNG_64_COLORS; - } - else if (strncasecmp(opt, "256-png", strlen("256-png")) == 0) - { - packMethod = PACK_PNG_256_COLORS; - } - else if (strncasecmp(opt, "512-png", strlen("512-png")) == 0) - { - packMethod = PACK_PNG_512_COLORS; - } - else if (strncasecmp(opt, "4k-png", strlen("4k-png")) == 0) - { - packMethod = PACK_PNG_4K_COLORS; - } - else if (strncasecmp(opt, "32k-png", strlen("32k-png")) == 0) - { - packMethod = PACK_PNG_32K_COLORS; - } - else if (strncasecmp(opt, "64k-png", strlen("64k-png")) == 0) - { - packMethod = PACK_PNG_64K_COLORS; - } - else if (strncasecmp(opt, "256k-png", strlen("256k-png")) == 0) - { - packMethod = PACK_PNG_256K_COLORS; - } - else if (strncasecmp(opt, "2m-png", strlen("2m-png")) == 0) - { - packMethod = PACK_PNG_2M_COLORS; - } - else if (strncasecmp(opt, "16m-png", strlen("16m-png")) == 0) - { - packMethod = PACK_PNG_16M_COLORS; - } - else if (strncasecmp(opt, "16m-rgb", strlen("16m-rgb")) == 0 || - strncasecmp(opt, "rgb", strlen("rgb")) == 0) - { - packMethod = PACK_RGB_16M_COLORS; - } - else if (strncasecmp(opt, "16m-rle", strlen("16m-rle")) == 0 || - strncasecmp(opt, "rle", strlen("rle")) == 0) - { - packMethod = PACK_RLE_16M_COLORS; - } - else if (strncasecmp(opt, "16m-bitmap", strlen("16m-bitmap")) == 0 || - strncasecmp(opt, "bitmap", strlen("bitmap")) == 0) - { - packMethod = PACK_BITMAP_16M_COLORS; - } - else if (strncasecmp(opt, "lossy", strlen("lossy")) == 0) - { - packMethod = PACK_LOSSY; - } - else if (strncasecmp(opt, "lossless", strlen("lossless")) == 0) - { - packMethod = PACK_LOSSLESS; - } - else if (strncasecmp(opt, "adaptive", strlen("adaptive")) == 0) - { - packMethod = PACK_ADAPTIVE; - } - else - { - return -1; - } - - if (packMethod == PACK_NONE) - { - strcpy(packMethodName, "none"); - } - else - { - strcpy(packMethodName, opt); - } - - if (packMethod == PACK_RGB_16M_COLORS || - packMethod == PACK_RLE_16M_COLORS || - packMethod == PACK_BITMAP_16M_COLORS || - (packMethod >= PACK_JPEG_8_COLORS && - packMethod <= PACK_JPEG_16M_COLORS) || - (packMethod >= PACK_PNG_8_COLORS && - packMethod <= PACK_PNG_16M_COLORS) || - packMethod == PACK_LOSSY || - packMethod == PACK_LOSSLESS || - packMethod == PACK_ADAPTIVE) - { - const char *dash = strrchr(opt, '-'); - - if (dash != NULL && strlen(dash) == 2 && - *(dash + 1) >= '0' && *(dash + 1) <= '9') - { - packQuality = atoi(dash + 1); - - #ifdef DEBUG - *logofs << "Loop: Using pack quality '" - << packQuality << "'.\n" << logofs_flush; - #endif - } - } - else - { - packQuality = 0; - } - - return 1; -} - -int ParsePackMethod(const int method, const int quality) -{ - switch (method) - { - case PACK_NONE: - { - strcpy(packMethodName, "none"); - - break; - } - case PACK_MASKED_8_COLORS: - { - strcpy(packMethodName, "8"); - - break; - } - case PACK_MASKED_64_COLORS: - { - strcpy(packMethodName, "64"); - - break; - } - case PACK_MASKED_256_COLORS: - { - strcpy(packMethodName, "256"); - - break; - } - case PACK_MASKED_512_COLORS: - { - strcpy(packMethodName, "512"); - - break; - } - case PACK_MASKED_4K_COLORS: - { - strcpy(packMethodName, "4k"); - - break; - } - case PACK_MASKED_32K_COLORS: - { - strcpy(packMethodName, "32k"); - - break; - } - case PACK_MASKED_64K_COLORS: - { - strcpy(packMethodName, "64k"); - - break; - } - case PACK_MASKED_256K_COLORS: - { - strcpy(packMethodName, "256k"); - - break; - } - case PACK_MASKED_2M_COLORS: - { - strcpy(packMethodName, "2m"); - - break; - } - case PACK_MASKED_16M_COLORS: - { - strcpy(packMethodName, "16m"); - - break; - } - case PACK_JPEG_8_COLORS: - { - strcpy(packMethodName, "8-jpeg"); - - break; - } - case PACK_JPEG_64_COLORS: - { - strcpy(packMethodName, "64-jpeg"); - - break; - } - case PACK_JPEG_256_COLORS: - { - strcpy(packMethodName, "256-jpeg"); - - break; - } - case PACK_JPEG_512_COLORS: - { - strcpy(packMethodName, "512-jpeg"); - - break; - } - case PACK_JPEG_4K_COLORS: - { - strcpy(packMethodName, "4k-jpeg"); - - break; - } - case PACK_JPEG_32K_COLORS: - { - strcpy(packMethodName, "32k-jpeg"); - - break; - } - case PACK_JPEG_64K_COLORS: - { - strcpy(packMethodName, "64k-jpeg"); - - break; - } - case PACK_JPEG_256K_COLORS: - { - strcpy(packMethodName, "256k-jpeg"); - - break; - } - case PACK_JPEG_2M_COLORS: - { - strcpy(packMethodName, "2m-jpeg"); - - break; - } - case PACK_JPEG_16M_COLORS: - { - strcpy(packMethodName, "16m-jpeg"); - - break; - } - case PACK_PNG_8_COLORS: - { - strcpy(packMethodName, "8-png"); - - break; - } - case PACK_PNG_64_COLORS: - { - strcpy(packMethodName, "64-png"); - - break; - } - case PACK_PNG_256_COLORS: - { - strcpy(packMethodName, "256-png"); - - break; - } - case PACK_PNG_512_COLORS: - { - strcpy(packMethodName, "512-png"); - - break; - } - case PACK_PNG_4K_COLORS: - { - strcpy(packMethodName, "4k-png"); - - break; - } - case PACK_PNG_32K_COLORS: - { - strcpy(packMethodName, "32k-png"); - - break; - } - case PACK_PNG_64K_COLORS: - { - strcpy(packMethodName, "64k-png"); - - break; - } - case PACK_PNG_256K_COLORS: - { - strcpy(packMethodName, "256k-png"); - - break; - } - case PACK_PNG_2M_COLORS: - { - strcpy(packMethodName, "2m-png"); - - break; - } - case PACK_PNG_16M_COLORS: - { - strcpy(packMethodName, "16m-png"); - - break; - } - case PACK_RGB_16M_COLORS: - { - strcpy(packMethodName, "16m-rgb"); - - break; - } - case PACK_RLE_16M_COLORS: - { - strcpy(packMethodName, "16m-rle"); - - break; - } - case PACK_BITMAP_16M_COLORS: - { - strcpy(packMethodName, "16m-bitmap"); - - break; - } - case PACK_LOSSY: - { - strcpy(packMethodName, "lossy"); - - break; - } - case PACK_LOSSLESS: - { - strcpy(packMethodName, "lossless"); - - break; - } - case PACK_ADAPTIVE: - { - strcpy(packMethodName, "adaptive"); - - break; - } - default: - { - return -1; - } - } - - if (quality < 0 || quality > 9) - { - return -1; - } - - if (packMethod == PACK_RGB_16M_COLORS || - packMethod == PACK_RLE_16M_COLORS || - packMethod == PACK_BITMAP_16M_COLORS || - (packMethod >= PACK_JPEG_8_COLORS && - packMethod <= PACK_JPEG_16M_COLORS) || - (packMethod >= PACK_PNG_8_COLORS && - packMethod <= PACK_PNG_16M_COLORS) || - packMethod == PACK_LOSSY || - packMethod == PACK_LOSSLESS || - packMethod == PACK_ADAPTIVE) - { - sprintf(packMethodName + strlen(packMethodName), - "-%d", quality); - } - - packMethod = method; - packQuality = quality; - - control -> PackMethod = packMethod; - control -> PackQuality = packQuality; - - return 1; -} - -int SetDirectories() -{ - // - // Determine the location of the user's NX - // directory and the other relevant paths. - // The functions below will check the pa- - // rameters passed to the program and will - // query the environment, if needed. - // - - control -> HomePath = GetHomePath(); - control -> RootPath = GetRootPath(); - control -> SystemPath = GetSystemPath(); - control -> TempPath = GetTempPath(); - control -> ClientPath = GetClientPath(); - - return 1; -} - -int SetLogs() -{ - // - // So far we used stderr (or stdout under - // WIN32). Now use the files selected by - // the user. - // - - if (*statsFileName == '\0') - { - strcpy(statsFileName, "stats"); - - #ifdef TEST - *logofs << "Loop: Assuming default statistics file '" - << statsFileName << "'.\n" << logofs_flush; - #endif - } - #ifdef TEST - else - { - *logofs << "Loop: Name selected for statistics is '" - << statsFileName << "'.\n" << logofs_flush; - } - #endif - - if (OpenLogFile(statsFileName, statofs) < 0) - { - HandleCleanup(); - } - - #ifndef MIXED - - if (*errorsFileName == '\0') - { - strcpy(errorsFileName, "errors"); - - #ifdef TEST - *logofs << "Loop: Assuming default log file name '" - << errorsFileName << "'.\n" << logofs_flush; - #endif - } - #ifdef TEST - else - { - *logofs << "Loop: Name selected for log file is '" - << errorsFileName << "'.\n" << logofs_flush; - } - #endif - - // - // Share the bebug output with the nxssh binder - // process. The file must be made writable by - // everybody because the nxssh process is run by - // nxserver as the nx user. - // - - #ifdef BINDER - - strcpy(errorsFileName, "/tmp/errors"); - - ostream *tmpfs = new ofstream(errorsFileName, ios::out); - - delete tmpfs; - - chmod(errorsFileName, S_IRUSR | S_IWUSR | S_IRGRP | - S_IWGRP | S_IROTH | S_IWOTH); - - #endif - - if (OpenLogFile(errorsFileName, logofs) < 0) - { - HandleCleanup(); - } - - // - // By default the session log is the standard error - // of the process. It is anyway required to set the - // option when running inside SSH, otherwise the - // output will go to the same file as the SSH log, - // depending where the NX client has redirected the - // output. - // - - if (*sessionFileName != '\0') - { - #ifdef TEST - *logofs << "Loop: Name selected for session file is '" - << sessionFileName << "'.\n" << logofs_flush; - #endif - - if (errofs != NULL) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Unexpected value for stream errofs.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Unexpected value for stream errofs.\n"; - } - - if (errsbuf != NULL) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Unexpected value for buffer errsbuf.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Unexpected value for buffer errsbuf.\n"; - } - - errofs = NULL; - errsbuf = NULL; - - if (OpenLogFile(sessionFileName, errofs) < 0) - { - HandleCleanup(); - } - - // - // Redirect the standard error to the file. - // - - errsbuf = cerr.rdbuf(errofs -> rdbuf()); - } - - #endif - - return 1; -} - -int SetPorts() -{ - // - // Depending on the proxy side, we need to determine on which - // port to listen for the given protocol or to which port we - // will have to forward the connection. Three possibilities - // are given for each supported protocol: - // - // Port <= 0: Disable port forwarding. - // Port == 1: Use the default port. - // Port > 1: Use the specified port. - // - // At the connectiong side the user should always explicitly - // set the ports where the connections will be forwarded. This - // is both for security reasons and because, when running both - // proxies on the same host, there is a concrete possibility - // that, by using the default ports, the connection will be - // forwarded to the same port where the peer proxy is listen- - // ing, causing a loop. - // - - useCupsSocket = 0; - if (cupsPort.enabled()) { - if (control -> ProxyMode == proxy_client) { - cupsPort.setDefaultTCPPort(DEFAULT_NX_CUPS_PORT_OFFSET + proxyPort); - useCupsSocket = 1; - } - else - cupsPort.setDefaultTCPPort(631); - } - -#ifdef TEST - *logofs << "Loop: cups port: " << cupsPort << "\n" - << logofs_flush; -#endif - - useAuxSocket = 0; - if (auxPort.enabled()) { - if (control -> ProxyMode == proxy_client) { - auxPort.setDefaultTCPPort(DEFAULT_NX_AUX_PORT_OFFSET + proxyPort); - useAuxSocket = 1; - } - else { - auxPort.setDefaultTCPPort(1); - - if (auxPort.getTCPPort() != 1) { - -#ifdef WARNING - *logofs << "Loop: WARNING! Overriding auxiliary X11 " - << "port with new value '" << 1 << "'.\n" - << logofs_flush; -#endif - - cerr << "Warning" << ": Overriding auxiliary X11 " - << "port with new value '" << 1 << "'.\n"; - - auxPort.setSpec("1"); - } - } - } - -#ifdef TEST - *logofs << "Loop: aux port: " << auxPort << "\n" - << logofs_flush; -#endif - - useSmbSocket = 0; - if (smbPort.enabled()) { - if (control -> ProxyMode == proxy_client) { - auxPort.setDefaultTCPPort(DEFAULT_NX_SMB_PORT_OFFSET + proxyPort); - useAuxSocket = 1; - } - else - auxPort.setDefaultTCPPort(139); - } - - -#ifdef TEST - *logofs << "Loop: smb port: " << smbPort << "\n" - << logofs_flush; -#endif - - useMediaSocket = 0; - if (mediaPort.enabled()) { - if (control -> ProxyMode == proxy_client) { - mediaPort.setDefaultTCPPort(DEFAULT_NX_MEDIA_PORT_OFFSET + proxyPort); - useMediaSocket = 1; - } - else if (mediaPort.getTCPPort() == 1) { -#ifdef PANIC - *logofs << "Loop: PANIC! No port specified for multimedia connections.\n" - << logofs_flush; -#endif - - cerr << "Error" << ": No port specified for multimedia connections.\n"; - - HandleCleanup(); - } - } - -#ifdef TEST - *logofs << "Loop: Using multimedia port '" << mediaPort - << "'.\n" << logofs_flush; -#endif - - useHttpSocket = 0; - if (httpPort.enabled()) { - if (control -> ProxyMode == proxy_client) { - httpPort.setDefaultTCPPort(DEFAULT_NX_HTTP_PORT_OFFSET + proxyPort); - useHttpSocket = 1; - } - else - httpPort.setDefaultTCPPort(80); - } - -#ifdef TEST - *logofs << "Loop: Using HTTP port '" << httpPort - << "'.\n" << logofs_flush; -#endif - - if (ParseFontPath(fontPort) <= 0) - { - #ifdef TEST - *logofs << "Loop: Disabling font server connections.\n" - << logofs_flush; - #endif - - *fontPort = '\0'; - - useFontSocket = 0; - } - else - { - // - // We don't know yet if the remote proxy supports - // the font server connections. If needed, we will - // disable the font server connections at later - // time. - // - - if (control -> ProxyMode == proxy_server) - { - useFontSocket = 1; - } - else - { - useFontSocket = 0; - } - - #ifdef TEST - *logofs << "Loop: Using font server port '" << fontPort - << "'.\n" << logofs_flush; - #endif - } - - useSlaveSocket = 0; - if (slavePort.enabled()) { - useSlaveSocket = 1; - if (control -> ProxyMode == proxy_client) - slavePort.setDefaultTCPPort(DEFAULT_NX_SLAVE_PORT_CLIENT_OFFSET + proxyPort); - else - slavePort.setDefaultTCPPort(DEFAULT_NX_SLAVE_PORT_SERVER_OFFSET + proxyPort); - } - -#ifdef TEST - *logofs << "Loop: Using slave port '" << slavePort - << "'.\n" << logofs_flush; -#endif - - return 1; -} - -int SetDescriptors() -{ - unsigned int limit = 0; - - #ifdef RLIMIT_NOFILE - - rlimit limits; - - if (getrlimit(RLIMIT_NOFILE, &limits) == 0) - { - if (limits.rlim_max == RLIM_INFINITY) - { - limit = 0; - } - else - { - limit = (unsigned int) limits.rlim_max; - } - } - - #endif - - #ifdef _SC_OPEN_MAX - - if (limit == 0) - { - limit = sysconf(_SC_OPEN_MAX); - } - - #endif - - #ifdef FD_SETSIZE - - if (limit > FD_SETSIZE) - { - limit = FD_SETSIZE; - } - - #endif - - #ifdef RLIMIT_NOFILE - - if (limits.rlim_cur < limit) - { - limits.rlim_cur = limit; - - setrlimit(RLIMIT_NOFILE, &limits); - } - - #endif - - if (limit == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Cannot determine number of available " - << "file descriptors.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot determine number of available " - << "file descriptors.\n"; - - return -1; - } - - return 1; -} - -// -// Find the directory containing the caches -// matching the session type. -// - -int SetCaches() -{ - if ((control -> PersistentCachePath = GetCachePath()) == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error getting or creating the cache path.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error getting or creating the cache path.\n"; - - HandleCleanup(); - } - - #ifdef TEST - *logofs << "Loop: Path of cache files is '" << control -> PersistentCachePath - << "'.\n" << logofs_flush; - #endif - - return 1; -} - -// -// Initialize all configuration parameters. -// - -int SetParameters() -{ - // - // Find out the type of session. - // - - SetSession(); - - // - // Initialize the network and compression - // parameters according to the settings - // suggested by the user. - // - - SetLink(); - - // - // Set compression according to link speed. - // - - SetCompression(); - - // - // Be sure that we have a literal for current - // cache size. Value will reflect control's - // default unless we already parsed a 'cache' - // option. Server side has no control on size - // of cache but is informed at session nego- - // tiation about how much memory is going to - // be used. - // - - SetStorage(); - - // - // Set size of shared memory segments. - // - - SetShmem(); - - // - // Make adjustments to cache based - // on the pack method. - // - - SetPack(); - - // - // Set disk-based image cache. - // - - SetImages(); - - // - // Set CPU and bandwidth limits. - // - - SetLimits(); - - return 1; -} - -// -// According to session literal determine -// the type of traffic that is going to be -// transported. Literals should be better -// standardized in future NX versions. -// - -int SetSession() -{ - if (strncmp(sessionType, "agent", strlen("agent")) == 0 || - strncmp(sessionType, "desktop", strlen("desktop")) == 0 || - strncmp(sessionType, "rootless", strlen("rootless")) == 0 || - strncmp(sessionType, "console", strlen("console")) == 0 || - strncmp(sessionType, "default", strlen("default")) == 0 || - strncmp(sessionType, "gnome", strlen("gnome")) == 0 || - strncmp(sessionType, "kde", strlen("kde")) == 0 || - strncmp(sessionType, "cde", strlen("cde")) == 0 || - strncmp(sessionType, "xdm", strlen("xdm")) == 0) - { - control -> SessionMode = session_agent; - } - else if (strncmp(sessionType, "win", strlen("win")) == 0 || - strncmp(sessionType, "vnc", strlen("vnc")) == 0) - { - control -> SessionMode = session_agent; - } - else if (strncmp(sessionType, "shadow", strlen("shadow")) == 0) - { - control -> SessionMode = session_shadow; - } - else if (strncmp(sessionType, "proxy", strlen("proxy")) == 0 || - strncmp(sessionType, "application", strlen("application")) == 0 || - strncmp(sessionType, "raw", strlen("raw")) == 0) - { - control -> SessionMode = session_proxy; - } - else - { - // - // If the session type is not passed or - // it is not among the recognized strings, - // we assume that the proxy is connected - // to the agent. - // - - // - // Since ProtoStep8 (#issue 108) and also - // with older "unix-" sessions - // - - if (*sessionType != '\0') - { - #ifdef WARNING - *logofs << "Loop: WARNING! Unrecognized session type '" - << sessionType << "'. Assuming agent session.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Unrecognized session type '" - << sessionType << "'. Assuming agent session.\n"; - } - - control -> SessionMode = session_agent; - } - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Assuming session type '" - << DumpSession(control -> SessionMode) << "' with " - << "string '" << sessionType << "'.\n" - << logofs_flush; - #endif - - // - // By default the policy is immediate. Agents - // will set a different policy, if they like. - // Anyway we need to check if the user has - // provided a custom flush policy. - // - - if (usePolicy != -1) - { - if (usePolicy > 0) - { - control -> FlushPolicy = policy_deferred; - } - else - { - control -> FlushPolicy = policy_immediate; - } - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: WARNING! Forcing flush policy to '" - << DumpPolicy(control -> FlushPolicy) - << ".\n" << logofs_flush; - #endif - } - else - { - control -> FlushPolicy = policy_immediate; - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Setting initial flush policy to '" - << DumpPolicy(control -> FlushPolicy) - << "'.\n" << logofs_flush; - #endif - } - - // - // Check if the proxy library is run inside - // another program providing encryption, as - // it is the case of the SSH client. - // - - if (useEncryption != -1) - { - if (useEncryption > 0) - { - control -> LinkEncrypted = 1; - } - else - { - control -> LinkEncrypted = 0; - } - } - - if (control -> LinkEncrypted == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Proxy running as part of an " - << "encrypting client.\n" - << logofs_flush; - #endif - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Assuming proxy running as a " - << "standalone program.\n" - << logofs_flush; - #endif - } - - // - // Check if the system administrator has - // enabled the respawn of the client at - // the end of session. - // - - if (control -> ProxyMode == proxy_server) - { - struct stat fileStat; - - char fileName[DEFAULT_STRING_LENGTH]; - - snprintf(fileName, DEFAULT_STRING_LENGTH - 1, - "%s/share/noexit", control -> SystemPath); - - *(fileName + DEFAULT_STRING_LENGTH - 1) = '\0'; - - if (stat(fileName, &fileStat) == 0) - { - #ifdef TEST - *logofs << "Loop: Enabling respawn of client at session shutdown.\n" - << logofs_flush; - #endif - - control -> EnableRestartOnShutdown = 1; - } - } - - return 1; -} - -int SetStorage() -{ - // - // If differential compression is disabled - // we don't need a cache at all. - // - - if (control -> LocalDeltaCompression == 0) - { - control -> ClientTotalStorageSize = 0; - control -> ServerTotalStorageSize = 0; - } - - // - // Set a a cache size literal. - // - - int size = control -> getUpperStorageSize(); - - if (size / 1024 > 0) - { - sprintf(cacheSizeName, "%dk", size / 1024); - } - else - { - sprintf(cacheSizeName, "%d", size); - } - - if (control -> ProxyMode == proxy_client) - { - control -> LocalTotalStorageSize = - control -> ClientTotalStorageSize; - - control -> RemoteTotalStorageSize = - control -> ServerTotalStorageSize; - } - else - { - control -> LocalTotalStorageSize = - control -> ServerTotalStorageSize; - - control -> RemoteTotalStorageSize = - control -> ClientTotalStorageSize; - } - - #ifdef DEBUG - *logofs << "Loop: Storage size limit is " - << control -> ClientTotalStorageSize - << " at client and " - << control -> ServerTotalStorageSize - << " at server.\n" - << logofs_flush; - #endif - - #ifdef DEBUG - *logofs << "Loop: Storage local limit set to " - << control -> LocalTotalStorageSize - << " remote limit set to " - << control -> RemoteTotalStorageSize - << ".\n" << logofs_flush; - #endif - - // - // Never reserve for split store more than - // half the memory available for messages. - // - - if (size > 0 && control -> - SplitTotalStorageSize > size / 2) - { - #ifdef TEST - *logofs << "Loop: Reducing size of split store to " - << size / 2 << " bytes.\n" - << logofs_flush; - #endif - - control -> SplitTotalStorageSize = size / 2; - } - - // - // Don't load render from persistent - // cache if extension is hidden or - // not supported by agent. - // - - if (control -> HideRender == 1) - { - #ifdef TEST - *logofs << "Loop: Not loading render extension " - << "from persistent cache.\n" - << logofs_flush; - #endif - - control -> PersistentCacheLoadRender = 0; - } - - return 1; -} - -int SetShmem() -{ - // - // If not set, adjust the size of the shared - // memory segment according to size of the - // message cache. - // - - if (*shsegSizeName == '\0') - { - int size = control -> getUpperStorageSize(); - - const int mega = 1048576; - - if (size > 0) - { - if (size <= 1 * mega) - { - size = 0; - } - else if (size <= 2 * mega) - { - size = 524288; - } - else if (size < 4 * mega) - { - size = 1048576; - } - else - { - size = size / 4; - } - - if (size > 4194304) - { - size = 4194304; - } - - control -> ShmemClientSize = size; - control -> ShmemServerSize = size; - } - else - { - // - // The delta compression is disabled. - // Use a default segment size of 2 MB. - // - - control -> ShmemServerSize = 2 * mega; - } - } - - // - // Client side shared memory support is - // not useful and not implemented. - // - - if (control -> ShmemServerSize >= 524288) - { - control -> ShmemServer = 1; - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Set initial shared memory size " - << "to " << control -> ShmemServerSize - << " bytes.\n" << logofs_flush; - #endif - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Disabled use of the shared memory " - << "extension.\n" << logofs_flush; - #endif - - control -> ShmemServer = 0; - } - - // For android, no shared memory available - control -> ShmemServer = 0; - control -> ShmemClientSize = 0; - - return 1; -} - -// -// Adjust the pack method according to the -// type of the session. -// - -int SetPack() -{ - #ifdef TEST - *logofs << "Loop: Setting pack with initial method " - << packMethod << " and quality " << packQuality - << ".\n" << logofs_flush; - #endif - - // - // Check if this is a proxy session and, in - // this case, set the pack method to none. - // Packed images are not supported by plain - // X applications. - // - - if (control -> SessionMode == session_proxy) - { - #ifdef TEST - *logofs << "Loop: WARNING! Disabling pack with proxy session.\n" - << logofs_flush; - #endif - - packMethod = PACK_NONE; - } - - // - // Adjust the internal settings according - // to the newly selected pack method. - // - - ParsePackMethod(packMethod, packQuality); - - // - // Don't load messages from persistent - // cache if packed images are disabled. - // - - if (control -> PackMethod == PACK_NONE) - { - control -> PersistentCacheLoadPacked = 0; - - #ifdef TEST - *logofs << "Loop: Not loading packed images " - << "from persistent cache.\n" - << logofs_flush; - #endif - } - - return 1; -} - -// -// Set the disk-based image cache parameters -// according to the user's wishes. -// - -int SetImages() -{ - // - // Be sure we disable the image cache if we - // are connecting to plain X clients. - // - - if (control -> SessionMode == session_proxy) - { - #ifdef TEST - *logofs << "Loop: Disabling image cache with " - << "session '" << DumpSession(control -> - SessionMode) << "'.\n" << logofs_flush; - #endif - - sprintf(imagesSizeName, "0"); - - control -> ImageCacheEnableLoad = 0; - control -> ImageCacheEnableSave = 0; - - return 1; - } - - int size = control -> ImageCacheDiskLimit; - - if (size / 1024 > 0) - { - sprintf(imagesSizeName, "%dk", size / 1024); - } - else - { - sprintf(imagesSizeName, "%d", size); - } - - if (size > 0) - { - control -> ImageCacheEnableLoad = 1; - control -> ImageCacheEnableSave = 1; - - if (control -> ProxyMode == proxy_server) - { - if ((control -> ImageCachePath = GetImagesPath()) == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error getting or creating image cache path.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error getting or creating image cache path.\n"; - - HandleCleanup(); - } - - #ifdef TEST - *logofs << "Loop: Path of image cache files is '" << control -> ImageCachePath - << "'.\n" << logofs_flush; - #endif - } - } - else - { - #ifdef TEST - *logofs << "Loop: Disabling the persistent image cache.\n" - << logofs_flush; - #endif - - control -> ImageCacheEnableLoad = 0; - control -> ImageCacheEnableSave = 0; - } - - return 1; -} - -int SetVersion() -{ - // - // Normalize the different proxy versions. - // - - int local = (control -> LocalVersionMajor << 24) | - (control -> LocalVersionMinor << 16) | - control -> LocalVersionPatch; - - int remote = (control -> RemoteVersionMajor << 24) | - (control -> RemoteVersionMinor << 16) | - control -> RemoteVersionPatch; - - int major = -1; - int minor = -1; - int patch = -1; - - if (control -> RemoteVersionMajor <= 1) - { - // - // The remote proxy uses a different - // logic to determine the version so - // we default to the compatibility - // version. - // - - major = control -> CompatVersionMajor; - minor = control -> CompatVersionMinor; - patch = control -> CompatVersionPatch; - - #ifdef TEST - *logofs << "Loop: Using compatibility version '" - << major << "." << minor << "." << patch - << "'.\n" << logofs_flush; - #endif - } - else if (control -> LocalVersionMajor > - control -> RemoteVersionMajor) - { - // - // We use a more recent version. Let's - // negotiate the version based on the - // version supported by the remote. - // - - major = control -> RemoteVersionMajor; - minor = control -> RemoteVersionMinor; - patch = control -> RemoteVersionPatch; - - #ifdef TEST - *logofs << "Loop: Using remote version '" - << major << "." << minor << "." << patch - << "'.\n" << logofs_flush; - #endif - } - else - { - // - // We support a major version that is - // equal or older than the remote. We - // assume the smaller version between - // the two, including the minor and - // the patch numbers. - // - - if (local > remote) - { - major = control -> RemoteVersionMajor; - minor = control -> RemoteVersionMinor; - patch = control -> RemoteVersionPatch; - - #ifdef TEST - *logofs << "Loop: Using remote version '" - << major << "." << minor << "." << patch - << "'.\n" << logofs_flush; - #endif - } - else - { - major = control -> LocalVersionMajor; - minor = control -> LocalVersionMinor; - patch = control -> LocalVersionPatch; - - #ifdef TEST - *logofs << "Loop: Using local version '" - << major << "." << minor << "." << patch - << "'.\n" << logofs_flush; - #endif - } - } - - // - // Handle versions from 3.5.0. The protocol - // step 10 is the minimum supported version. - // - - int step = 0; - - if (major == 3) - { - if (minor >= 5) - { - step = 10; - } - } - else if (major > 3) - { - step = 10; - } - - if (step == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Unable to set the protocol step value from " - << "the negotiated protocol version " << major << "." << minor - << "." << patch << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unable to set the protocol step value from " - << "the negotiated protocol version " << major << "." << minor - << "." << patch << ".\n"; - - #ifdef PANIC - *logofs << "Loop: PANIC! Incompatible remote version " - << control -> RemoteVersionMajor << "." << control -> RemoteVersionMinor - << "." << control -> RemoteVersionPatch << " with local version " - << control -> LocalVersionMajor << "." << control -> LocalVersionMinor - << "." << control -> LocalVersionPatch << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Incompatible remote version " - << control -> RemoteVersionMajor << "." << control -> RemoteVersionMinor - << "." << control -> RemoteVersionPatch << " with local version " - << control -> LocalVersionMajor << "." << control -> LocalVersionMinor - << "." << control -> LocalVersionPatch << ".\n"; - - return -1; - } - - #ifdef TEST - *logofs << "Loop: Using NX protocol step " - << step << ".\n" << logofs_flush; - #endif - - control -> setProtoStep(step); - - // - // Ignore the differences in patch version - // and print a warning if the local version - // is different or obsolete compared to - // the remote. - // - - local &= 0xffff0000; - remote &= 0xffff0000; - - if (local != remote) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Connected to remote version " - << control -> RemoteVersionMajor << "." << control -> RemoteVersionMinor - << "." << control -> RemoteVersionPatch << " with local version " - << control -> LocalVersionMajor << "." << control -> LocalVersionMinor - << "." << control -> LocalVersionPatch << ".\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Connected to remote version " - << control -> RemoteVersionMajor << "." << control -> RemoteVersionMinor - << "." << control -> RemoteVersionPatch << " with local version " - << control -> LocalVersionMajor << "." << control -> LocalVersionMinor - << "." << control -> LocalVersionPatch << ".\n" << logofs_flush; - } - - if (local < remote) - { - cerr << "Warning" << ": Consider checking https://github.com/ArcticaProject/nx-libs/releases for updates.\n"; - } - - // - // Now that we are aware of the remote - // version, let's adjust the options to - // be compatible with the remote proxy. - // - - if (control -> ProxyMode == proxy_client) - { - // - // Since ProtoStep8 (#issue 108) - // - // Now it's assumed that the remote is - // able to handle the selected pack - // method - // - - #ifdef TEST - *logofs << __FILE__ << " : " << __LINE__ << " - " - << "step = " << control -> getProtoStep() - << " packMethod = " << packMethod - << " packQuality = " << packQuality - << ".\n" << logofs_flush; - #endif - - // - // Update the pack method name. - // - - ParsePackMethod(packMethod, packQuality); - } - - // - // At the moment the image cache is not used by the - // agent. Proxy versions older than 3.0.0 assumed - // that it was enabled and sent specific bits as part - // of the encoding. Conversely, it is advisable to - // disable the cache right now. By not enabling the - // the image cache, the house-keeping process will - // only take care of cleaning up the "cache-" direc- - // tories. - // - - // - // Considering that compatibility with older versions - // has been set to cover as far as 3.5.0, the cache can - // be disabled at this point without any concern - // - - // Since ProtoStep8 (#issue 108) - #ifdef TEST - *logofs << "Loop: Disabling image cache with protocol " - << "step '" << control -> getProtoStep() - << "'.\n" << logofs_flush; - #endif - - sprintf(imagesSizeName, "0"); - - control -> ImageCacheEnableLoad = 0; - control -> ImageCacheEnableSave = 0; - - return 1; -} - -// -// Identify the requested link settings -// and update the control parameters -// accordingly. -// - -int SetLink() -{ - #ifdef TEST - *logofs << "Loop: Setting link with initial value " - << linkSpeedName << ".\n" << logofs_flush; - #endif - - if (*linkSpeedName == '\0') - { - strcpy(linkSpeedName, "lan"); - } - - #ifdef TEST - *logofs << "Loop: Link speed is " << linkSpeedName - << ".\n" << logofs_flush; - #endif - - if (strcasecmp(linkSpeedName, "modem") == 0) - { - SetLinkModem(); - } - else if (strcasecmp(linkSpeedName, "isdn") == 0) - { - SetLinkIsdn(); - } - else if (strcasecmp(linkSpeedName, "adsl") == 0) - { - SetLinkAdsl(); - } - else if (strcasecmp(linkSpeedName, "wan") == 0) - { - SetLinkWan(); - } - else if (strcasecmp(linkSpeedName, "lan") == 0) - { - SetLinkLan(); - } - else - { - return -1; - } - - // - // Set TCP_NODELAY according to the user's - // wishes. - // - - if (useNoDelay != -1) - { - control -> OptionProxyClientNoDelay = useNoDelay; - control -> OptionProxyServerNoDelay = useNoDelay; - } - - // - // Select the image compression method. - // - - if (packMethod == -1) - { - packMethod = control -> PackMethod; - } - - if (packQuality == -1) - { - packQuality = control -> PackQuality; - } - - if (ParsePackMethod(packMethod, packQuality) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Unrecognized pack method id " - << packMethod << " with quality " << packQuality - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unrecognized pack method id " - << packMethod << " with quality " << packQuality - << ".\n"; - - HandleCleanup(); - } - - // - // Check if the user disabled the ability - // to generate simple replies at the client - // side. - // - - if (control -> SessionMode == session_proxy) - { - if (useTaint != -1) - { - control -> TaintReplies = (useTaint == 1); - } - else - { - #ifdef WARNING - *logofs << "Loop: WARNING! Forcing taint of replies " - << "with a proxy session.\n" - << logofs_flush; - #endif - - control -> TaintReplies = 1; - } - } - else - { - // - // There is no need to taint the - // replies if we have an agent. - // - - control -> TaintReplies = 0; - } - - // - // Be sure that the requests needing a reply - // are flushed immediately. Normal X clients - // use so many replies to make the queuing - // completely useless. - // - - if (control -> SessionMode == session_proxy) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Forcing flush on priority " - << "with a proxy session.\n" - << logofs_flush; - #endif - - control -> FlushPriority = 1; - } - - return 1; -} - -// -// Parameters for MODEM 28.8/33.6/56 Kbps. -// - -int SetLinkModem() -{ - #ifdef TEST - *logofs << "Loop: Setting parameters for MODEM.\n" - << logofs_flush; - #endif - - control -> LinkMode = LINK_TYPE_MODEM; - - control -> TokenSize = 256; - control -> TokenLimit = 24; - - control -> SplitMode = 1; - control -> SplitTotalSize = 128; - control -> SplitTotalStorageSize = 1048576; - - control -> SplitTimeout = 50; - control -> MotionTimeout = 50; - control -> IdleTimeout = 50; - - control -> PackMethod = PACK_ADAPTIVE; - control -> PackQuality = 3; - - return 1; -} - -// -// Parameters for ISDN 64/128 Kbps. -// - -int SetLinkIsdn() -{ - #ifdef TEST - *logofs << "Loop: Setting parameters for ISDN.\n" - << logofs_flush; - #endif - - control -> LinkMode = LINK_TYPE_ISDN; - - control -> TokenSize = 384; - control -> TokenLimit = 24; - - control -> SplitMode = 1; - control -> SplitTotalSize = 128; - control -> SplitTotalStorageSize = 1048576; - - control -> SplitTimeout = 50; - control -> MotionTimeout = 20; - control -> IdleTimeout = 50; - - control -> PackMethod = PACK_ADAPTIVE; - control -> PackQuality = 5; - - return 1; -} - -// -// Parameters for ADSL 256 Kbps. -// - -int SetLinkAdsl() -{ - #ifdef TEST - *logofs << "Loop: Setting parameters for ADSL.\n" - << logofs_flush; - #endif - - control -> LinkMode = LINK_TYPE_ADSL; - - control -> TokenSize = 1536; - control -> TokenLimit = 24; - - control -> SplitMode = 1; - control -> SplitTotalSize = 128; - control -> SplitTotalStorageSize = 1048576; - - control -> SplitTimeout = 50; - control -> MotionTimeout = 10; - control -> IdleTimeout = 50; - - control -> PackMethod = PACK_ADAPTIVE; - control -> PackQuality = 7; - - return 1; -} - -// -// Parameters for XDSL/FDDI/ATM 1/2/34 Mbps WAN. -// - -int SetLinkWan() -{ - #ifdef TEST - *logofs << "Loop: Setting parameters for WAN.\n" - << logofs_flush; - #endif - - control -> LinkMode = LINK_TYPE_WAN; - - control -> TokenSize = 1536; - control -> TokenLimit = 24; - - control -> SplitMode = 1; - control -> SplitTotalSize = 128; - control -> SplitTotalStorageSize = 1048576; - - control -> SplitTimeout = 50; - control -> MotionTimeout = 5; - control -> IdleTimeout = 50; - - control -> PackMethod = PACK_ADAPTIVE; - control -> PackQuality = 9; - - return 1; -} - -// -// Parameters for LAN 10/100 Mbps. -// - -int SetLinkLan() -{ - #ifdef TEST - *logofs << "Loop: Setting parameters for LAN.\n" - << logofs_flush; - #endif - - control -> LinkMode = LINK_TYPE_LAN; - - control -> TokenSize = 1536; - control -> TokenLimit = 24; - - control -> SplitMode = 1; - control -> SplitTotalSize = 128; - control -> SplitTotalStorageSize = 1048576; - - control -> SplitTimeout = 50; - control -> MotionTimeout = 0; - control -> IdleTimeout = 50; - - control -> PackMethod = PACK_ADAPTIVE; - control -> PackQuality = 9; - - return 1; -} - -// -// Identify the requested link type and set -// the control parameters accordingly. -// - -int SetCompression() -{ - if (strcasecmp(linkSpeedName, "modem") == 0) - { - SetCompressionModem(); - } - else if (strcasecmp(linkSpeedName, "isdn") == 0) - { - SetCompressionIsdn(); - } - else if (strcasecmp(linkSpeedName, "adsl") == 0) - { - SetCompressionAdsl(); - } - else if (strcasecmp(linkSpeedName, "wan") == 0) - { - SetCompressionWan(); - } - else if (strcasecmp(linkSpeedName, "lan") == 0) - { - SetCompressionLan(); - } - else - { - return -1; - } - - if (control -> LocalDeltaCompression < 0) - { - control -> LocalDeltaCompression = 1; - } - - // - // If we didn't set remote delta compression - // (as it should always be the case at client - // side) assume value of local side. - // - - if (control -> RemoteDeltaCompression < 0) - { - control -> RemoteDeltaCompression = - control -> LocalDeltaCompression; - } - - // - // If we didn't set remote compression levels - // assume values of local side. - // - - if (control -> RemoteStreamCompression < 0) - { - control -> RemoteStreamCompressionLevel = - control -> LocalStreamCompressionLevel; - - if (control -> RemoteStreamCompressionLevel > 0) - { - control -> RemoteStreamCompression = 1; - } - else - { - control -> RemoteStreamCompression = 0; - } - } - - if (control -> RemoteDataCompression < 0) - { - control -> RemoteDataCompressionLevel = - control -> LocalDataCompressionLevel; - - if (control -> RemoteDataCompressionLevel > 0) - { - control -> RemoteDataCompression = 1; - } - else - { - control -> RemoteDataCompression = 0; - } - } - - return 1; -} - -// -// Compression for MODEM. -// - -int SetCompressionModem() -{ - if (control -> LocalDataCompression < 0) - { - control -> LocalDataCompression = 1; - control -> LocalDataCompressionLevel = 1; - } - - if (control -> LocalDataCompressionThreshold < 0) - { - control -> LocalDataCompressionThreshold = 32; - } - - if (control -> LocalStreamCompression < 0) - { - control -> LocalStreamCompression = 1; - control -> LocalStreamCompressionLevel = 9; - } - - return 1; -} - -// -// Compression for ISDN. -// - -int SetCompressionIsdn() -{ - if (control -> LocalDataCompression < 0) - { - control -> LocalDataCompression = 1; - control -> LocalDataCompressionLevel = 1; - } - - if (control -> LocalDataCompressionThreshold < 0) - { - control -> LocalDataCompressionThreshold = 32; - } - - if (control -> LocalStreamCompression < 0) - { - control -> LocalStreamCompression = 1; - control -> LocalStreamCompressionLevel = 6; - } - - return 1; -} - -// -// Compression for ADSL. -// - -int SetCompressionAdsl() -{ - if (control -> LocalDataCompression < 0) - { - control -> LocalDataCompression = 1; - control -> LocalDataCompressionLevel = 1; - } - - if (control -> LocalDataCompressionThreshold < 0) - { - control -> LocalDataCompressionThreshold = 32; - } - - if (control -> LocalStreamCompression < 0) - { - control -> LocalStreamCompression = 1; - control -> LocalStreamCompressionLevel = 4; - } - - return 1; -} - -// -// Compression for WAN. -// - -int SetCompressionWan() -{ - if (control -> LocalDataCompression < 0) - { - control -> LocalDataCompression = 1; - control -> LocalDataCompressionLevel = 1; - } - - if (control -> LocalDataCompressionThreshold < 0) - { - control -> LocalDataCompressionThreshold = 32; - } - - if (control -> LocalStreamCompression < 0) - { - control -> LocalStreamCompression = 1; - control -> LocalStreamCompressionLevel = 1; - } - - return 1; -} - -// -// Compression for LAN. -// - -int SetCompressionLan() -{ - // - // Disable delta compression if not - // explicitly enabled. - // - - if (control -> LocalDeltaCompression < 0) - { - control -> LocalDeltaCompression = 0; - } - - if (control -> LocalDataCompression < 0) - { - control -> LocalDataCompression = 0; - control -> LocalDataCompressionLevel = 0; - } - - if (control -> LocalDataCompressionThreshold < 0) - { - control -> LocalDataCompressionThreshold = 0; - } - - if (control -> LocalStreamCompression < 0) - { - control -> LocalStreamCompression = 0; - control -> LocalStreamCompressionLevel = 0; - } - - return 1; -} - -int SetLimits() -{ - // - // Check if the user requested strict - // control flow parameters. - // - - if (useStrict == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: LIMIT! Decreasing the token limit " - << "to " << control -> TokenLimit / 2 - << " with option 'strict'.\n" - << logofs_flush; - #endif - - control -> TokenLimit /= 2; - } - - #ifdef STRICT - - control -> TokenLimit = 1; - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: WARNING! LIMIT! Setting the token limit " - << "to " << control -> TokenLimit - << " to simulate the proxy congestion.\n" - << logofs_flush; - #endif - - #endif - - // - // Reduce the size of the log file. - // - - #ifdef QUOTA - - control -> FileSizeLimit = 8388608; - - #endif - - // - // Check the bitrate limits. - // - - if (control -> LocalBitrateLimit == -1) - { - if (control -> ProxyMode == proxy_client) - { - control -> LocalBitrateLimit = - control -> ClientBitrateLimit; - } - else - { - control -> LocalBitrateLimit = - control -> ServerBitrateLimit; - } - } - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: LIMIT! Setting client bitrate limit " - << "to " << control -> ClientBitrateLimit - << " server bitrate limit to " << control -> - ServerBitrateLimit << " with local limit " - << control -> LocalBitrateLimit << ".\n" - << logofs_flush; - #endif - - return 1; -} - -// -// These functions are used to parse literal -// values provided by the user and set the -// control parameters accordingly. -// - -int ParseCacheOption(const char *opt) -{ - int size = ParseArg("", "cache", opt); - - if (size < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value '" - << opt << "' for option 'cache'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value '" - << opt << "' for option 'cache'.\n"; - - return -1; - } - - #ifdef TEST - *logofs << "Loop: Setting size of cache to " - << size << " bytes.\n" << logofs_flush; - #endif - - control -> ClientTotalStorageSize = size; - control -> ServerTotalStorageSize = size; - - strcpy(cacheSizeName, opt); - - if (size == 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Disabling NX delta compression.\n" - << logofs_flush; - #endif - - control -> LocalDeltaCompression = 0; - - #ifdef WARNING - *logofs << "Loop: WARNING! Disabling use of NX persistent cache.\n" - << logofs_flush; - #endif - - control -> PersistentCacheEnableLoad = 0; - control -> PersistentCacheEnableSave = 0; - } - - return 1; -} - -int ParseImagesOption(const char *opt) -{ - int size = ParseArg("", "images", opt); - - if (size < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value '" - << opt << "' for option 'images'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value '" - << opt << "' for option 'images'.\n"; - - return -1; - } - - #ifdef TEST - *logofs << "Loop: Setting size of images cache to " - << size << " bytes.\n" << logofs_flush; - #endif - - control -> ImageCacheDiskLimit = size; - - strcpy(imagesSizeName, opt); - - return 1; -} - -int ParseShmemOption(const char *opt) -{ - int size = ParseArg("", "shseg", opt); - - if (size < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value '" - << opt << "' for option 'shseg'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value '" - << opt << "' for option 'shseg'.\n"; - - return -1; - } - - control -> ShmemClientSize = size; - control -> ShmemServerSize = size; - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Set shared memory size to " - << control -> ShmemServerSize << " bytes.\n" - << logofs_flush; - #endif - - strcpy(shsegSizeName, opt); - - return 1; -} - -int ParseBitrateOption(const char *opt) -{ - int bitrate = ParseArg("", "limit", opt); - - if (bitrate < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid value '" - << opt << "' for option 'limit'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Invalid value '" - << opt << "' for option 'limit'.\n"; - - return -1; - } - - strcpy(bitrateLimitName, opt); - - if (bitrate == 0) - { - #ifdef TEST - *logofs << "Loop: Disabling bitrate limit on proxy link.\n" - << logofs_flush; - #endif - - control -> LocalBitrateLimit = 0; - } - else - { - #ifdef TEST - *logofs << "Loop: Setting bitrate to " << bitrate - << " bits per second.\n" << logofs_flush; - #endif - - // - // Internal representation is in bytes - // per second. - // - - control -> LocalBitrateLimit = bitrate >> 3; - } - - return 1; -} - -int ParseHostOption(const char *opt, char *host, long &port) -{ - #ifdef TEST - *logofs << "Loop: Trying to parse options string '" << opt - << "' as a remote NX host.\n" << logofs_flush; - #endif - - if (opt == NULL || *opt == '\0') - { - #ifdef PANIC - *logofs << "Loop: PANIC! No host parameter provided.\n" - << logofs_flush; - #endif - - return 0; - } - else if (strlen(opt) >= DEFAULT_STRING_LENGTH) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Host parameter exceeds length of " - << DEFAULT_STRING_LENGTH << " characters.\n" - << logofs_flush; - #endif - - return 0; - } - - // - // Look for a host name followed - // by a colon followed by port. - // - - int newPort = port; - - const char *separator = strrchr(opt, ':'); - - if (separator != NULL) - { - const char *check = separator + 1; - - while (*check != '\0' && *check != ',' && - *check != '=' && isdigit(*check) != 0) - { - check++; - } - - newPort = atoi(separator + 1); - - if (newPort < 0 || *check != '\0') - { - #ifdef TEST - *logofs << "Loop: Can't identify remote NX port in string '" - << separator << "'.\n" << logofs_flush; - #endif - - return 0; - } - } - else if (newPort < 0) - { - // - // Complain if port was not passed - // by other means. - // - - #ifdef TEST - *logofs << "Loop: Can't identify remote NX port in string '" - << opt << "'.\n" << logofs_flush; - #endif - - return 0; - } - else - { - separator = opt + strlen(opt); - } - - char newHost[DEFAULT_STRING_LENGTH] = { 0 }; - - strncpy(newHost, opt, strlen(opt) - strlen(separator)); - - *(newHost + strlen(opt) - strlen(separator)) = '\0'; - - const char *check = newHost; - - while (*check != '\0' && *check != ',' && - *check != '=') - { - check++; - } - - if (*check != '\0') - { - #ifdef TEST - *logofs << "Loop: Can't identify remote NX host in string '" - << newHost << "'.\n" << logofs_flush; - #endif - - return 0; - } - else if (*acceptHost != '\0') - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't manage to connect and accept connections " - << "at the same time.\n" << logofs_flush; - - *logofs << "Loop: PANIC! Refusing remote NX host with string '" - << opt << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't manage to connect and accept connections " - << "at the same time.\n"; - - cerr << "Error" << ": Refusing remote NX host with string '" - << opt << "'.\n"; - - return -1; - } - - if (*host != '\0' && strcmp(host, newHost) != 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Overriding remote NX host '" - << host << "' with new value '" << newHost - << "'.\n" << logofs_flush; - #endif - } - - strcpy(host, newHost); - - if (port != -1 && port != newPort) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Overriding remote NX port '" - << port << "' with new value '" << newPort - << "'.\n" << logofs_flush; - #endif - } - - #ifdef TEST - *logofs << "Loop: Parsed options string '" << opt - << "' with host '" << newHost << "' and port '" - << newPort << "'.\n" << logofs_flush; - #endif - - port = newPort; - - return 1; -} - -int ParseFontPath(char *path) -{ - char oldPath[DEFAULT_STRING_LENGTH]; - - strcpy(oldPath, path); - - if (path == NULL || *path == '\0' || strcmp(path, "0") == 0) - { - return 0; - } - - #ifdef TEST - *logofs << "Loop: Parsing font server option '" << path - << "'.\n" << logofs_flush; - #endif - - // - // Convert the value to our default port. - // - - if (strcmp(fontPort, "1") == 0) - { - if (control -> ProxyMode == proxy_server) - { - snprintf(fontPort, DEFAULT_STRING_LENGTH - 1, "%d", - DEFAULT_NX_FONT_PORT_OFFSET + proxyPort); - } - else - { - // - // Let the client use the well-known - // "unix/:7100" font path. - // - - snprintf(fontPort, DEFAULT_STRING_LENGTH - 1, "unix/:7100"); - } - } - - // - // Check if a simple numaric value was given. - // - - if (atoi(path) > 0) - { - #ifdef TEST - *logofs << "Loop: Assuming numeric TCP port '" << atoi(path) - << "' for font server.\n" << logofs_flush; - #endif - - return 1; - } - - // - // Let's assume that a port specification "unix/:7100" - // corresponds to "$TEMP/.font-unix/fs7100" and a port - // "unix/:-1" corresponds to "$TEMP/.font-unix/fs-1". - // - - if (strncmp("unix/:", path, 6) == 0) - { - snprintf(path, DEFAULT_STRING_LENGTH - 1, "%s/.font-unix/fs%s", - control -> TempPath, oldPath + 6); - - *(path + DEFAULT_STRING_LENGTH - 1) = '\0'; - - #ifdef TEST - *logofs << "Loop: Assuming Unix socket '" << path - << "' for font server.\n" << logofs_flush; - #endif - } - else if (strncmp("tcp/:", path, 5) == 0) - { - snprintf(path, DEFAULT_STRING_LENGTH - 1, "%d", atoi(oldPath + 5)); - - *(path + DEFAULT_STRING_LENGTH - 1) = '\0'; - - if (atoi(path) <= 0) - { - goto ParseFontPathError; - } - - #ifdef TEST - *logofs << "Loop: Assuming TCP port '" << atoi(path) - << "' for font server.\n" << logofs_flush; - #endif - } - else - { - // - // Accept an absolute file path as - // a valid Unix socket. - // - - if (*path != '/') - { - goto ParseFontPathError; - } - - #ifdef TEST - *logofs << "Loop: Assuming Unix socket '" << path - << "' for font server.\n" << logofs_flush; - #endif - } - - return 1; - -ParseFontPathError: - - #ifdef TEST - *logofs << "Loop: Unable to determine the font server " - << "port in string '" << path << "'.\n" - << logofs_flush; - #endif - - return -1; -} - -int OpenLogFile(char *name, ostream *&stream) -{ - if (name == NULL || *name == '\0') - { - #ifdef TEST - *logofs << "Loop: WARNING! No name provided for output. Using standard error.\n" - << logofs_flush; - #endif - - if (stream == NULL) - { - stream = &cerr; - } - - return 1; - } - - if (stream == NULL || stream == &cerr) - { - if (*name != '/' && *name != '.') - { - char *filePath = GetSessionPath(); - - if (filePath == NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Cannot determine directory of NX session file.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Cannot determine directory of NX session file.\n"; - - return -1; - } - - if (strlen(filePath) + strlen("/") + - strlen(name) + 1 > DEFAULT_STRING_LENGTH) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Full name of NX file '" << name - << " would exceed length of " << DEFAULT_STRING_LENGTH - << " characters.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Full name of NX file '" << name - << " would exceed length of " << DEFAULT_STRING_LENGTH - << " characters.\n"; - - return -1; - } - - char *file = new char[strlen(filePath) + strlen("/") + - strlen(name) + 1]; - - // - // Transform name in a fully qualified name. - // - - strcpy(file, filePath); - strcat(file, "/"); - strcat(file, name); - - strcpy(name, file); - - delete [] filePath; - delete [] file; - } - - mode_t fileMode = umask(0077); - - for (;;) - { - if ((stream = new ofstream(name, ios::app)) != NULL) - { - break; - } - - usleep(200000); - } - - umask(fileMode); - } - else - { - #ifdef PANIC - *logofs << "Loop: PANIC! Bad stream provided for output.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Bad stream provided for output.\n"; - - return -1; - } - - return 1; -} - -int ReopenLogFile(char *name, ostream *&stream, int limit) -{ - if (*name != '\0' && limit >= 0) - { - struct stat fileStat; - - if (limit > 0) - { - // - // This is used for the log file, if the - // size exceeds the limit. - // - - if (stat(name, &fileStat) != 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Can't get stats of file '" - << name << "'. Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - return 0; - } - else if (fileStat.st_size < (long) limit) - { - return 0; - } - } - - #ifdef TEST - *logofs << "Loop: Deleting file '" << name - << "' with size " << fileStat.st_size - << ".\n" << logofs_flush; - #endif - - // - // Create a new stream over the previous - // file. Trying to delete the file fails - // to work on recent Cygwin installs. - // - - *stream << flush; - - delete stream; - - mode_t fileMode = umask(0077); - - for (;;) - { - if ((stream = new ofstream(name, ios::out)) != NULL) - { - break; - } - - usleep(200000); - } - - umask(fileMode); - - #ifdef TEST - *logofs << "Loop: Reopened file '" << name - << "'.\n" << logofs_flush; - #endif - } - - return 1; -} - -void PrintProcessInfo() -{ - if (agent == NULL) - { - - cerr << endl; - - PrintVersionInfo(); - - cerr << endl; - - cerr << GetCopyrightInfo() - << endl - << GetOtherCopyrightInfo() - << endl - << "See https://github.com/ArcticaProject/nx-libs for more information." << endl << endl; - } - - // - // People get confused by the fact that client - // mode is running on NX server and viceversa. - // Let's adopt an user-friendly naming conven- - // tion here. - // - - cerr << "Info: Proxy running in " - << (control -> ProxyMode == proxy_client ? "client" : "server") - << " mode with pid '" << getpid() << "'.\n"; - - if (agent == NULL) - { - cerr << "Session" << ": Starting session at '" - << strTimestamp() << "'.\n"; - } - - #ifdef TEST - - if (*errorsFileName != '\0') - { - cerr << "Info" << ": Using errors file '" << errorsFileName << "'.\n"; - } - - if (*statsFileName != '\0') - { - cerr << "Info" << ": Using stats file '" << statsFileName << "'.\n"; - } - - #endif -} - -void PrintConnectionInfo() -{ - cerr << "Info" << ": Using " - << linkSpeedName << " link parameters " - << control -> TokenSize - << "/" << control -> TokenLimit - << "/" << control -> FlushPolicy + 1 - << "/" << control -> FlushPriority - << ".\n"; - - if (control -> ProxyMode == proxy_client) - { - cerr << "Info" << ": Using agent parameters " - << control -> PingTimeout - << "/" << control -> MotionTimeout - << "/" << control -> IdleTimeout - << "/" << control -> TaintReplies - << "/" << control -> HideRender - << ".\n"; - } - - if (control -> LocalDeltaCompression == 1) - { - cerr << "Info" << ": Using cache parameters " - << control -> MinimumMessageSize - << "/" << control -> MaximumMessageSize / 1024 << "KB" - << "/" << control -> ClientTotalStorageSize / 1024 << "KB" - << "/" << control -> ServerTotalStorageSize / 1024 << "KB" - << ".\n"; - } - - if (control -> ImageCacheEnableLoad == 1 || - control -> ImageCacheEnableSave == 1) - { - cerr << "Info" << ": Using image streaming parameters " - << control -> SplitTimeout - << "/" << control -> SplitTotalSize - << "/" << control -> SplitTotalStorageSize / 1024 << "KB" - << "/" << control -> SplitDataThreshold - << "/" << control -> SplitDataPacketLimit - << ".\n"; - - cerr << "Info" << ": Using image cache parameters " - << control -> ImageCacheEnableLoad - << "/" << control -> ImageCacheEnableSave - << "/" << control -> ImageCacheDiskLimit / 1024 << "KB" - << ".\n"; - } - - cerr << "Info" << ": Using pack method '" - << packMethodName << "' with session '" - << sessionType << "'.\n"; - - if (*productName != '\0') - { - cerr << "Info" << ": Using product '" << productName - << "'.\n" << logofs_flush; - } - - if (control -> LocalDeltaCompression == 0) - { - cerr << "Info" << ": Not using NX delta compression.\n"; - } - - if (control -> LocalDataCompression == 1 || - control -> RemoteDataCompression == 1) - { - cerr << "Info" << ": Using ZLIB data compression " - << control -> LocalDataCompressionLevel - << "/" << control -> RemoteDataCompressionLevel - << "/" << control -> LocalDataCompressionThreshold - << ".\n"; - } - else - { - cerr << "Info" << ": Not using ZLIB data compression.\n"; - } - - if (control -> LocalStreamCompression == 1 || - control -> RemoteStreamCompression == 1) - { - cerr << "Info" << ": Using ZLIB stream compression " - << control -> LocalStreamCompressionLevel - << "/" << control -> RemoteStreamCompressionLevel - << ".\n"; - } - else - { - cerr << "Info" << ": Not using ZLIB stream compression.\n"; - } - - if (control -> LocalBitrateLimit > 0) - { - cerr << "Info" << ": Using bandwidth limit of " - << bitrateLimitName << " bits per second.\n"; - } - - if (control -> PersistentCacheName != NULL) - { - cerr << "Info" << ": Using cache file '" - << control -> PersistentCachePath << "/" - << control -> PersistentCacheName << "'.\n"; - } - else - { - if (control -> PersistentCacheEnableLoad == 0 || - control -> LocalDeltaCompression == 0) - { - cerr << "Info" << ": Not using a persistent cache.\n"; - } - else - { - cerr << "Info" << ": No suitable cache file found.\n"; - } - } - - if (control -> ProxyMode == proxy_client && - (useUnixSocket > 0 || useTcpSocket > 0 || - useAgentSocket > 0)) - { - cerr << "Info" << ": Listening to X11 connections " - << "on display ':" << xPort << "'.\n"; - } - else if (control -> ProxyMode == proxy_server) - { - cerr << "Info" << ": Forwarding X11 connections " - << "to display '" << displayHost << "'.\n"; - } - - if (control -> ProxyMode == proxy_client && - useCupsSocket > 0 && cupsPort.enabled()) - { - cerr << "Info" << ": Listening to CUPS connections " - << "on port '" << cupsPort << "'.\n"; - } - else if (control -> ProxyMode == proxy_server && - cupsPort.enabled()) - { - cerr << "Info" << ": Forwarding CUPS connections " - << "to port '" << cupsPort << "'.\n"; - } - - if (control -> ProxyMode == proxy_client && - useAuxSocket > 0 && auxPort.enabled()) - { - cerr << "Info" << ": Listening to auxiliary X11 connections " - << "on port '" << auxPort << "'.\n"; - } - else if (control -> ProxyMode == proxy_server && - auxPort.enabled()) - { - cerr << "Info" << ": Forwarding auxiliary X11 connections " - << "to display '" << displayHost << "'.\n"; - } - - if (control -> ProxyMode == proxy_client && - useSmbSocket > 0 && smbPort.enabled()) - { - cerr << "Info" << ": Listening to SMB connections " - << "on port '" << smbPort << "'.\n"; - } - else if (control -> ProxyMode == proxy_server && - smbPort.enabled()) - { - cerr << "Info" << ": Forwarding SMB connections " - << "to port '" << smbPort << "'.\n"; - } - - if (control -> ProxyMode == proxy_client && - useMediaSocket > 0 && mediaPort.enabled()) - { - cerr << "Info" << ": Listening to multimedia connections " - << "on port '" << mediaPort << "'.\n"; - } - else if (control -> ProxyMode == proxy_server && - mediaPort.enabled()) - { - cerr << "Info" << ": Forwarding multimedia connections " - << "to port '" << mediaPort << "'.\n"; - } - - if (control -> ProxyMode == proxy_client && - useHttpSocket > 0 && httpPort.enabled()) - { - cerr << "Info" << ": Listening to HTTP connections " - << "on port '" << httpPort << "'.\n"; - } - else if (control -> ProxyMode == proxy_server && - httpPort.enabled()) - { - cerr << "Info" << ": Forwarding HTTP connections " - << "to port '" << httpPort << "'.\n"; - } - - if (control -> ProxyMode == proxy_server && - useFontSocket > 0 && *fontPort != '\0') - { - cerr << "Info" << ": Listening to font server connections " - << "on port '" << fontPort << "'.\n"; - } - else if (control -> ProxyMode == proxy_client && - *fontPort != '\0') - { - cerr << "Info" << ": Forwarding font server connections " - << "to port '" << fontPort << "'.\n"; - } - - if (useSlaveSocket > 0 && slavePort.enabled()) - { - cerr << "Info" << ": Listening to slave connections " - << "on port '" << slavePort << "'.\n"; - } -} - -void PrintVersionInfo() -{ - cerr << "NXPROXY - " << "Version " - << control -> LocalVersionMajor << "." - << control -> LocalVersionMinor << "." - << control -> LocalVersionPatch << "." - << control -> LocalVersionMaintenancePatch; - - cerr << endl; -} - -void PrintCopyrightInfo() -{ - cerr << endl; - - PrintVersionInfo(); - - cerr << endl; - - cerr << GetCopyrightInfo(); - - // - // Print third party's copyright info. - // - - cerr << endl; - - cerr << GetOtherCopyrightInfo(); - - cerr << endl; -} - -void PrintOptionIgnored(const char *type, const char *name, const char *value) -{ - if (control -> ProxyMode == proxy_server) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Ignoring " << type - << " option '" << name << "' with value '" - << value << "' at " << "NX client side.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Ignoring " << type - << " option '" << name << "' with value '" - << value << "' at " << "NX client side.\n"; - } - else - { - #ifdef WARNING - *logofs << "Loop: WARNING! Ignoring " << type - << " option '" << name << "' with value '" - << value << "' at " << "NX server side.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Ignoring " << type - << " option '" << name << "' with value '" - << value << "' at " << "NX server side.\n"; - } -} - -const char *GetOptions(const char *options) -{ - if (options != NULL) - { - if (strncasecmp(options, "nx/nx,", 6) != 0 && - strncasecmp(options, "nx,", 3) != 0 && - strncasecmp(options, "nx:", 3) != 0) - { - #ifdef TEST - *logofs << "Loop: PANIC! Display options string '" << options - << "' must start with 'nx' or 'nx/nx' prefix.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Display options string '" << options - << "' must start with 'nx' or 'nx/nx' prefix.\n"; - - HandleCleanup(); - } - } - else - { - options = getenv("DISPLAY"); - } - - return options; -} - -const char *GetArg(int &argi, int argc, const char **argv) -{ - // - // Skip "-" and flag character. - // - - const char *arg = argv[argi] + 2; - - if (*arg == 0) - { - if (argi + 1 == argc) - { - return NULL; - } - else - { - argi++; - - return (*argv[argi] == '-' ? NULL : argv[argi]); - } - } - else - { - return (*arg == '-' ? NULL : arg); - } -} - -int CheckArg(const char *type, const char *name, const char *value) -{ - #ifdef TEST - *logofs << "Loop: Parsing " << type << " option '" << name - << "' with value '" << (value ? value : "(null)") - << "'.\n" << logofs_flush; - #endif - - if (value == NULL || strstr(value, "=") != NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error in " << type << " option '" - << name << "'. No value found.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error in " << type << " option '" - << name << "'. No value found.\n"; - - return -1; - } - else if (strstr(name, ",") != NULL) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Parse error at " << type << " option '" - << name << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Parse error at " << type << " option '" - << name << "'.\n"; - - return -1; - } - else if (strlen(value) >= DEFAULT_STRING_LENGTH) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Value '" << value << "' of " - << type << " option '" << name << "' exceeds length of " - << DEFAULT_STRING_LENGTH << " characters.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Value '" << value << "' of " - << type << " option '" << name << "' exceeds length of " - << DEFAULT_STRING_LENGTH << " characters.\n"; - - return -1; - } - - return 1; -} - -int ParseArg(const char *type, const char *name, const char *value) -{ - if (strcasecmp(value, "0") == 0) - { - return 0; - } - - // - // Find the base factor. - // - - double base; - - const char *id = value + strlen(value) - 1; - - if (strcasecmp(id, "g") == 0) - { - base = 1024 * 1024 * 1024; - } - else if (strcasecmp(id, "m") == 0) - { - base = 1024 * 1024; - } - else if (strcasecmp(id, "k") == 0) - { - base = 1024; - } - else if (strcasecmp(id, "b") == 0 || isdigit(*id) == 1) - { - base = 1; - } - else - { - return -1; - } - - char *string = new char[strlen(value)]; - - strncpy(string, value, strlen(value) - 1); - - *(string + (strlen(value) - 1)) = '\0'; - - #ifdef TEST - - *logofs << "Loop: Parsing integer option '" << name - << "' from string '" << string << "' with base set to "; - - switch (tolower(*id)) - { - case 'k': - case 'm': - case 'g': - { - *logofs << (char) toupper(*id); - } - break; - } - - *logofs << ".\n" << logofs_flush; - - #endif - - double result = atof(string) * base; - - if (result < 0 || result > (((unsigned) -1) >> 1)) - { - delete [] string; - - return -1; - } - - delete [] string; - - #ifdef TEST - *logofs << "Loop: Integer option parsed to '" - << (int) result << "'.\n" << logofs_flush; - #endif - - return (int) result; -} - -void SetAndValidateChannelEndPointArg(const char *type, const char *name, const char *value, - ChannelEndPoint &endPoint) { - endPoint.setSpec(value); - if (!endPoint.validateSpec()) { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid " << type - << " option '" << name << "' with value '" - << value << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid " << type - << " option '" << name << "' with value '" - << value << "'.\n"; - - HandleCleanup(); - } -} - - -int ValidateArg(const char *type, const char *name, const char *value) -{ - int number = atoi(value); - - if (number < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Invalid " << type - << " option '" << name << "' with value '" - << value << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid " << type - << " option '" << name << "' with value '" - << value << "'.\n"; - - HandleCleanup(); - } - - return number; -} - -int LowercaseArg(const char *type, const char *name, char *value) -{ - char *next = value; - - while (*next != '\0') - { - *next = tolower(*next); - - next++; - } - - return 1; -} - -int CheckSignal(int signal) -{ - // - // Return 1 if the signal needs to be handled - // by the proxy, 2 if the signal just needs to - // be blocked to avoid interrupting a system - // call. - // - - switch (signal) - { - case SIGCHLD: - case SIGUSR1: - case SIGUSR2: - case SIGHUP: - case SIGINT: - case SIGTERM: - case SIGPIPE: - case SIGALRM: - { - return 1; - } - case SIGVTALRM: - case SIGWINCH: - case SIGIO: - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - { - return 2; - } - default: - { - #ifdef __CYGWIN32__ - - // - // This signal can be raised by the Cygwin - // library. - // - - if (signal == 12) - { - return 1; - } - - #endif - - return 0; - } - } -} - -static void PrintUsageInfo(const char *option, int error) -{ - if (error == 1) - { - cerr << "Error" << ": Invalid command line option '" << option << "'.\n"; - } - - cerr << GetUsageInfo(); - - if (error == 1) - { - cerr << "Error" << ": NX transport initialization failed.\n"; - } -} - -static void handleCheckSessionInLoop() -{ - // - // Check if we completed the shutdown procedure - // and the remote confirmed the shutdown. The - // tear down should be always initiated by the - // agent, but the X server side may unilateral- - // ly shut down the link without our permission. - // - - if (proxy -> getShutdown() > 0) - { - #ifdef TEST - *logofs << "Loop: End of NX transport requested " - << "by remote.\n" << logofs_flush; - #endif - - handleTerminatingInLoop(); - - if (control -> ProxyMode == proxy_server) - { - #ifdef TEST - *logofs << "Loop: Bytes received so far are " - << (unsigned long long) statistics -> getBytesIn() - << ".\n" << logofs_flush; - #endif - - if (statistics -> getBytesIn() < 1024) - { - cerr << "Info" << ": Your session was closed before reaching " - << "a usable state.\n"; - cerr << "Info" << ": This can be due to the local X server " - << "refusing access to the client.\n"; - cerr << "Info" << ": Please check authorization provided " - << "by the remote X application.\n"; - } - } - - #ifdef TEST - *logofs << "Loop: Shutting down the NX transport.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - else if (proxy -> handlePing() < 0) - { - #ifdef TEST - *logofs << "Loop: Failure handling the ping for " - << "proxy FD#" << proxyFD << ".\n" - << logofs_flush; - #endif - - HandleShutdown(); - } - - // - // Check if the watchdog has exited and we didn't - // get the SIGCHLD. This can happen if the parent - // has overridden our signal handlers. - // - - if (IsRunning(lastWatchdog) && CheckProcess(lastWatchdog, "watchdog") == 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Watchdog is gone unnoticed. " - << "Setting the last signal to SIGTERM.\n" - << logofs_flush; - #endif - - lastSignal = SIGTERM; - - #ifdef WARNING - *logofs << "Loop: WARNING! Resetting pid of last " - << "watchdog process.\n" << logofs_flush; - #endif - - SetNotRunning(lastWatchdog); - } - - // - // Let the client proxy find out if the agent's - // channel is gone. This is the normal shutdown - // procedure in the case of an internal connect- - // ion to the agent. - // - - int cleanup = 0; - - if (control -> ProxyMode == proxy_client && - agent != NULL && proxy -> getType(agentFD[1]) == - channel_none && lastKill == 0 && lastDestroy == 1) - { - #ifdef TEST - *logofs << "Loop: End of NX transport requested " - << "by agent.\n" << logofs_flush; - #endif - - #ifdef TEST - *logofs << "Loop: Bytes sent so far are " - << (unsigned long long) statistics -> getBytesOut() - << ".\n" << logofs_flush; - #endif - - if (statistics -> getBytesOut() < 1024) - { - cerr << "Info" << ": Your session has died before reaching " - << "an usable state.\n"; - cerr << "Info" << ": This can be due to the remote X server " - << "refusing access to the client.\n"; - cerr << "Info" << ": Please check the authorization provided " - << "by your X application.\n"; - } - - cleanup = 1; - } - - // - // Check if the user requested the end of the - // session by sending a signal to the proxy. - // All signals are handled in the main loop - // so we need to reset the value to get ready - // for the next iteration. - // - - int signal = 0; - - if (lastSignal != 0) - { - switch (lastSignal) - { - case SIGCHLD: - case SIGUSR1: - case SIGUSR2: - { - break; - } - default: - { - signal = lastSignal; - - cleanup = 1; - - break; - } - } - - lastSignal = 0; - } - - if (cleanup == 1) - { - // - // The first time termination signal is received - // disable all further connections, close down any - // X channel and wait for a second signal. - // - - if (lastKill == 0) - { - // - // Don't print a message if cleanup is - // due to normal termination of agent. - // - - if (signal != 0) - { - #ifdef TEST - *logofs << "Loop: End of NX transport requested by signal '" - << signal << "' '" << DumpSignal(signal) - << "'.\n" << logofs_flush; - #endif - - handleTerminatingInLoop(); - } - - // - // Disable any further connection. - // - - CleanupListeners(); - - // - // Close all the remaining X channels and - // let proxies save their persistent cache - // on disk. - // - - CleanupConnections(); - - // - // We'll need to wait for the X channels - // to be shut down before waiting for the - // cleanup signal. - // - - lastKill = 1; - } - else if (lastKill == 2) - { - #ifdef TEST - *logofs << "Loop: Shutting down the NX transport.\n" - << logofs_flush; - #endif - - proxy -> handleShutdown(); - - HandleCleanup(); - } - } - - if (lastKill == 1 && proxy -> getChannels(channel_x11) == 0) - { - // - // Save the message stores to the - // persistent cache. - // - - proxy -> handleSave(); - - // - // Run a watchdog process so we can finally - // give up at the time the watchdog exits. - // - - if (IsNotRunning(lastWatchdog)) - { - int timeout = control -> CleanupTimeout; - - if (timeout > 0) - { - if (proxy -> getChannels() == 0) - { - timeout = 500; - } - - #ifdef TEST - *logofs << "Loop: Starting watchdog process with timeout " - << "of " << timeout << " Ms.\n" - << logofs_flush; - #endif - } - #ifdef TEST - else - { - *logofs << "Loop: Starting watchdog process without " - << "a timeout.\n" << logofs_flush; - } - #endif - - lastWatchdog = NXTransWatchdog(timeout); - - if (IsFailed(lastWatchdog)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't start the NX watchdog " - << "process in shutdown.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't start the NX watchdog " - << "process in shutdown.\n"; - - HandleCleanup(); - } - #ifdef TEST - else - { - *logofs << "Loop: Watchdog started with pid '" - << lastWatchdog << "'.\n" << logofs_flush; - } - #endif - } - else - { - #ifdef PANIC - *logofs << "Loop: PANIC! Previous watchdog detected " - << "in shutdown with pid '" << lastWatchdog - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Previous watchdog detected " - << "in shutdown with pid '" << lastWatchdog - << "'.\n"; - - HandleCleanup(); - } - - if (control -> CleanupTimeout > 0) - { - #ifdef TEST - *logofs << "Loop: Waiting the cleanup timeout to complete.\n" - << logofs_flush; - #endif - - cerr << "Info" << ": Waiting the cleanup timeout to complete.\n"; - } - else - { - // - // The NX server will kill the watchdog - // process after having shut down the - // service channels. - // - - cerr << "Info" << ": Watchdog running with pid '" << lastWatchdog - << "'.\n"; - - #ifdef TEST - *logofs << "Loop: Waiting the watchdog process to complete.\n" - << logofs_flush; - #endif - - cerr << "Info" << ": Waiting the watchdog process to complete.\n"; - } - - lastKill = 2; - } -} - -static void handleCheckBitrateInLoop() -{ - static long int slept = 0; - - #ifdef TEST - *logofs << "Loop: Bitrate is " << statistics -> getBitrateInShortFrame() - << " B/s and " << statistics -> getBitrateInLongFrame() - << " B/s in " << control -> ShortBitrateTimeFrame / 1000 - << "/" << control -> LongBitrateTimeFrame / 1000 - << " seconds timeframes.\n" << logofs_flush; - #endif - - // - // This can be improved. We may not jump out - // of the select often enough to guarantee - // the necessary accuracy. - // - - if (control -> LocalBitrateLimit > 0) - { - #ifdef TEST - *logofs << "Loop: Calculating bandwidth usage with limit " - << control -> LocalBitrateLimit << ".\n" - << logofs_flush; - #endif - - int reference = (statistics -> getBitrateInLongFrame() + - statistics -> getBitrateInShortFrame()) / 2; - - if (reference > control -> LocalBitrateLimit) - { - double ratio = ((double) reference) / - ((double) control -> LocalBitrateLimit); - - if (ratio > 1.2) - { - ratio = 1.2; - } - - slept += (unsigned int) (pow(50000, ratio) / 1000); - - if (slept > 2000) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Sleeping due to " - << "reference bitrate of " << reference - << " B/s.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Sleeping due to " - << "reference bitrate of " << reference - << " B/s.\n"; - - slept %= 2000; - } - - T_timestamp idleTs = getNewTimestamp(); - - usleep((unsigned int) pow(50000, ratio)); - - int diffTs = diffTimestamp(idleTs, getNewTimestamp()); - - statistics -> addIdleTime(diffTs); - - statistics -> subReadTime(diffTs); - } - } -} - -#if defined(TEST) || defined(INFO) - -static void handleCheckStateInLoop(int &setFDs) -{ - int fdLength; - int fdPending; - int fdSplits; - - for (int j = 0; j < setFDs; j++) - { - if (j != proxyFD) - { - fdPending = proxy -> getPending(j); - - if (fdPending > 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Buffer for descriptor FD#" - << j << " has pending bytes to read.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - - fdLength = proxy -> getLength(j); - - if (fdLength > 0) - { - #ifdef TEST - *logofs << "Loop: WARNING! Buffer for descriptor FD#" - << j << " has " << fdLength << " bytes to write.\n" - << logofs_flush; - #endif - } - } - } - - fdPending = proxy -> getPending(proxyFD); - - if (fdPending > 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Buffer for proxy descriptor FD#" - << proxyFD << " has pending bytes to read.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - - fdLength = proxy -> getFlushable(proxyFD); - - if (fdLength > 0) - { - if (control -> FlushPolicy == policy_immediate && - proxy -> getBlocked(proxyFD) == 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Buffer for proxy descriptor FD#" - << proxyFD << " has " << fdLength << " bytes " - << "to write with policy 'immediate'.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - else - { - #ifdef TEST - *logofs << "Loop: WARNING! Buffer for proxy descriptor FD#" - << proxyFD << " has " << fdLength << " bytes " - << "to write.\n" << logofs_flush; - #endif - } - } - - fdSplits = proxy -> getSplitSize(); - - if (fdSplits > 0) - { - #ifdef WARNING - *logofs << "Loop: WARNING! Proxy descriptor FD#" << proxyFD - << " has " << fdSplits << " splits to send.\n" - << logofs_flush; - #endif - } -} - -static void handleCheckSelectInLoop(int &setFDs, fd_set &readSet, - fd_set &writeSet, T_timestamp selectTs) -{ - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Maximum descriptors is [" - << setFDs << "] at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - int i; - - if (setFDs > 0) - { - i = 0; - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Selected for read are "; - #endif - - for (int j = 0; j < setFDs; j++) - { - if (FD_ISSET(j, &readSet)) - { - #if defined(TEST) || defined(INFO) - *logofs << "[" << j << "]" << logofs_flush; - #endif - - i++; - } - } - - if (i > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << ".\n" << logofs_flush; - #endif - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "[none].\n" << logofs_flush; - #endif - } - - i = 0; - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Selected for write are "; - #endif - - for (int j = 0; j < setFDs; j++) - { - if (FD_ISSET(j, &writeSet)) - { - #if defined(TEST) || defined(INFO) - *logofs << "[" << j << "]" << logofs_flush; - #endif - - i++; - } - } - - if (i > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << ".\n" << logofs_flush; - #endif - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "[none].\n" << logofs_flush; - #endif - } - } - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Select timeout is " - << selectTs.tv_sec << " S and " - << (double) selectTs.tv_usec / 1000 - << " Ms.\n" << logofs_flush; - #endif -} - -static void handleCheckResultInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, - fd_set &writeSet, struct timeval &selectTs, - struct timeval &startTs) -{ - int diffTs = diffTimestamp(startTs, getNewTimestamp()); - - #if defined(TEST) || defined(INFO) - - if (diffTs >= (control -> PingTimeout - - (control -> LatencyTimeout * 4))) - { - *logofs << "Loop: Select result is [" << resultFDs - << "] at " << strMsTimestamp() << " with no " - << "communication within " << diffTs - << " Ms.\n" << logofs_flush; - } - else - { - *logofs << "Loop: Select result is [" << resultFDs - << "] error is [" << errorFDs << "] at " - << strMsTimestamp() << " after " << diffTs - << " Ms.\n" << logofs_flush; - } - - #endif - - int i; - - if (resultFDs > 0) - { - i = 0; - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Selected for read are "; - #endif - - for (int j = 0; j < setFDs; j++) - { - if (FD_ISSET(j, &readSet)) - { - #if defined(TEST) || defined(INFO) - *logofs << "[" << j << "]" << logofs_flush; - #endif - - i++; - } - } - - if (i > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << ".\n" << logofs_flush; - #endif - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "[none].\n" << logofs_flush; - #endif - } - - i = 0; - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Selected for write are "; - #endif - - for (int j = 0; j < setFDs; j++) - { - if (FD_ISSET(j, &writeSet)) - { - #if defined(TEST) || defined(INFO) - *logofs << "[" << j << "]" << logofs_flush; - #endif - - i++; - } - } - - if (i > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << ".\n" << logofs_flush; - #endif - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "[none].\n" << logofs_flush; - #endif - } - } -} - -#endif - -static void handleCheckSessionInConnect() -{ - #ifdef TEST - *logofs << "Loop: Going to check session in connect.\n" - << logofs_flush; - #endif - - if (control -> ProxyMode == proxy_client) - { - HandleAlert(FAILED_PROXY_CONNECTION_CLIENT_ALERT, 1); - } - else if (IsNotRunning(lastDialog)) - { - HandleAlert(FAILED_PROXY_CONNECTION_SERVER_ALERT, 1); - } - - handleAlertInLoop(); -} - -static void handleStatisticsInLoop() -{ - if (lastSignal == 0) - { - return; - } - - int mode = NO_STATS; - - if (control -> EnableStatistics == 1) - { - if (lastSignal == SIGUSR1) - { - // - // Print overall statistics. - // - - mode = TOTAL_STATS; - } - else if (lastSignal == SIGUSR2) - { - // - // Print partial statistics. - // - - mode = PARTIAL_STATS; - } - - if (mode == TOTAL_STATS || mode == PARTIAL_STATS) - { - #ifdef TEST - *logofs << "Loop: Going to request proxy statistics " - << "with signal '" << DumpSignal(lastSignal) - << "'.\n" << logofs_flush; - #endif - - if (proxy != NULL) - { - if (ReopenLogFile(statsFileName, statofs, 0) < 0) - { - HandleCleanup(); - } - - proxy -> handleStatistics(mode, statofs); - } - } - } -} - -static void handleNegotiationInLoop(int &setFDs, fd_set &readSet, - fd_set &writeSet, T_timestamp &selectTs) -{ - int yield = 0; - - while (yield == 0) - { - #ifdef TEST - *logofs << "Loop: Going to run a new negotiation loop " - << "with stage " << control -> ProxyStage - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - switch (control -> ProxyStage) - { - case stage_undefined: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_undefined" << "'.\n" - << logofs_flush; - #endif - - control -> ProxyStage = stage_initializing; - - break; - } - case stage_initializing: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_initializing" << "'.\n" - << logofs_flush; - #endif - - InitBeforeNegotiation(); - - control -> ProxyStage = stage_connecting; - - break; - } - case stage_connecting: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_connecting" << "'.\n" - << logofs_flush; - #endif - - SetupProxyConnection(); - - control -> ProxyStage = stage_connected; - - break; - } - case stage_connected: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_connected" << "'.\n" - << logofs_flush; - #endif - - // - // Server side proxy must always be the one that - // sends its version and options first, so, in - // some way, client side can be the the one that - // has the last word on the matter. - // - - if (control -> ProxyMode == proxy_server) - { - // - // Check if we have been listening for a - // forwarder. In this case it will have to - // authenticate itself. - // - - if (WE_LISTEN_FORWARDER) - { - control -> ProxyStage = stage_waiting_forwarder_version; - - break; - } - - control -> ProxyStage = stage_sending_proxy_options; - } - else - { - // - // The X client side is the side that has to wait - // for the authorization cookie and any remote - // option. - // - - control -> ProxyStage = stage_waiting_proxy_version; - } - - break; - } - case stage_sending_proxy_options: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_sending_proxy_options" << "'.\n" - << logofs_flush; - #endif - - if (SendProxyOptions(proxyFD) < 0) - { - goto handleNegotiationInLoopError; - } - - if (control -> ProxyMode == proxy_server) - { - control -> ProxyStage = stage_waiting_proxy_version; - } - else - { - control -> ProxyStage = stage_sending_proxy_caches; - } - - break; - } - case stage_waiting_forwarder_version: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_waiting_forwarder_version" << "'.\n" - << logofs_flush; - #endif - - int result = ReadForwarderVersion(proxyFD); - - if (result == 0) - { - yield = 1; - } - else if (result == 1) - { - control -> ProxyStage = stage_waiting_forwarder_options; - } - else - { - goto handleNegotiationInLoopError; - } - - break; - } - case stage_waiting_forwarder_options: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_waiting_forwarder_options" << "'.\n" - << logofs_flush; - #endif - - int result = ReadForwarderOptions(proxyFD); - - if (result == 0) - { - yield = 1; - } - else if (result == 1) - { - control -> ProxyStage = stage_sending_proxy_options; - } - else - { - goto handleNegotiationInLoopError; - } - - break; - } - case stage_waiting_proxy_version: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_waiting_proxy_version" << "'.\n" - << logofs_flush; - #endif - - int result = ReadProxyVersion(proxyFD); - - if (result == 0) - { - yield = 1; - } - else if (result == 1) - { - control -> ProxyStage = stage_waiting_proxy_options; - } - else - { - goto handleNegotiationInLoopError; - } - - break; - } - case stage_waiting_proxy_options: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_waiting_proxy_options" << "'.\n" - << logofs_flush; - #endif - - int result = ReadProxyOptions(proxyFD); - - if (result == 0) - { - yield = 1; - } - else if (result == 1) - { - if (control -> ProxyMode == proxy_server) - { - control -> ProxyStage = stage_waiting_proxy_caches; - } - else - { - control -> ProxyStage = stage_sending_proxy_options; - } - } - else - { - goto handleNegotiationInLoopError; - } - - break; - } - case stage_sending_proxy_caches: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_sending_proxy_caches" << "'.\n" - << logofs_flush; - #endif - - if (SendProxyCaches(proxyFD) < 0) - { - goto handleNegotiationInLoopError; - } - - if (control -> ProxyMode == proxy_server) - { - control -> ProxyStage = stage_operational; - } - else - { - control -> ProxyStage = stage_waiting_proxy_caches; - } - - break; - } - case stage_waiting_proxy_caches: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_waiting_proxy_caches" << "'.\n" - << logofs_flush; - #endif - - int result = ReadProxyCaches(proxyFD); - - if (result == 0) - { - yield = 1; - } - else if (result == 1) - { - if (control -> ProxyMode == proxy_server) - { - control -> ProxyStage = stage_sending_proxy_caches; - } - else - { - control -> ProxyStage = stage_operational; - } - } - else - { - goto handleNegotiationInLoopError; - } - - break; - } - case stage_operational: - { - #ifdef TEST - *logofs << "Loop: Handling negotiation with '" - << "stage_operational" << "'.\n" - << logofs_flush; - #endif - - InitAfterNegotiation(); - - yield = 1; - - break; - } - default: - { - #ifdef PANIC - *logofs << "Loop: PANIC! Unmanaged case '" << control -> ProxyStage - << "' while handling negotiation.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unmanaged case '" << control -> ProxyStage - << "' while handling negotiation.\n"; - - HandleCleanup(); - } - } - } - - // - // Check if the user requested the end of - // the session. - // - - if (CheckAbort() != 0) - { - HandleCleanup(); - } - - // - // Select the proxy descriptor so that we - // can proceed negotiating the session. - // - - FD_SET(proxyFD, &readSet); - - if (proxyFD >= setFDs) - { - setFDs = proxyFD + 1; - } - - setMinTimestamp(selectTs, control -> PingTimeout); - - #ifdef TEST - *logofs << "Loop: Selected proxy FD#" << proxyFD << " in negotiation " - << "phase with timeout of " << selectTs.tv_sec << " S and " - << selectTs.tv_usec << " Ms.\n" << logofs_flush; - #endif - - return; - -handleNegotiationInLoopError: - - #ifdef PANIC - *logofs << "Loop: PANIC! Failure negotiating the session in stage '" - << control -> ProxyStage << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failure negotiating the session in stage '" - << control -> ProxyStage << "'.\n"; - - - if (control -> ProxyMode == proxy_server && - control -> ProxyStage == stage_waiting_proxy_version) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Wrong version or invalid session " - << "authentication cookie.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Wrong version or invalid session " - << "authentication cookie.\n"; - } - - handleTerminatingInLoop(); - - HandleCleanup(); -} - -static void handleTerminatingInLoop() -{ - if (getpid() == lastProxy) - { - if (control -> ProxyStage < stage_terminating) - { - if (agent == NULL) - { - cerr << "Session" << ": Terminating session at '" - << strTimestamp() << "'.\n"; - } - - control -> ProxyStage = stage_terminating; - } - } -} - -static void handleTerminatedInLoop() -{ - if (getpid() == lastProxy) - { - if (control -> ProxyStage < stage_terminated) - { - if (agent == NULL) - { - cerr << "Session" << ": Session terminated at '" - << strTimestamp() << "'.\n"; - } - - control -> ProxyStage = stage_terminated; - } - } -} - -static void handleAlertInLoop() -{ - if (lastAlert.code == 0) - { - return; - } - - // - // Since ProtoStep7 (#issue 108) - // - // Now the remote proxy should always - // be able to handle the alert - // - - if (lastAlert.local == 0) - { - if (proxy != NULL) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Requesting a remote alert with code '" - << lastAlert.code << "'.\n" << logofs_flush; - #endif - - if (proxy -> handleAlert(lastAlert.code) < 0) - { - HandleShutdown(); - } - } - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Handling a local alert with code '" - << lastAlert.code << "'.\n" << logofs_flush; - #endif - - if (control -> ProxyMode == proxy_client) - { - // - // If we are at X client side and server - // proxy is not responding, we don't have - // any possibility to interact with user. - // - - if (lastAlert.code != CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT && - lastAlert.code != RESTART_DEAD_PROXY_CONNECTION_CLIENT_ALERT && - lastAlert.code != FAILED_PROXY_CONNECTION_CLIENT_ALERT) - { - // - // Let the server proxy show the dialog. - // - - if (proxy != NULL && - proxy -> handleAlert(lastAlert.code) < 0) - { - HandleShutdown(); - } - } - } - else - { - char caption[DEFAULT_STRING_LENGTH]; - - strcpy(caption, ALERT_CAPTION_PREFIX); - - int length = strlen(sessionId); - - // - // Get rid of the trailing MD5 from session id. - // - - if (length > (MD5_LENGTH * 2 + 1) && - *(sessionId + (length - (MD5_LENGTH * 2 + 1))) == '-') - { - strncat(caption, sessionId, length - (MD5_LENGTH * 2 + 1)); - } - else - { - strcat(caption, sessionId); - } - - // - // Use the display to which we are forwarding - // the remote X connections. - // - - char *display = displayHost; - - int replace = 1; - int local = 1; - - const char *message; - const char *type; - - switch (lastAlert.code) - { - case CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT: - { - message = CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT_STRING; - type = CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT_TYPE; - - break; - } - case CLOSE_DEAD_X_CONNECTION_SERVER_ALERT: - { - message = CLOSE_DEAD_X_CONNECTION_SERVER_ALERT_STRING; - type = CLOSE_DEAD_X_CONNECTION_SERVER_ALERT_TYPE; - - break; - } - case CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT: - { - message = CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT_STRING; - type = CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT_TYPE; - - break; - } - case RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT: - { - message = RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT_STRING; - type = RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT_TYPE; - - break; - } - case CLOSE_UNRESPONSIVE_X_SERVER_ALERT: - { - message = CLOSE_UNRESPONSIVE_X_SERVER_ALERT_STRING; - type = CLOSE_UNRESPONSIVE_X_SERVER_ALERT_TYPE; - - break; - } - case WRONG_PROXY_VERSION_ALERT: - { - message = WRONG_PROXY_VERSION_ALERT_STRING; - type = WRONG_PROXY_VERSION_ALERT_TYPE; - - break; - } - case FAILED_PROXY_CONNECTION_SERVER_ALERT: - { - message = FAILED_PROXY_CONNECTION_SERVER_ALERT_STRING; - type = FAILED_PROXY_CONNECTION_SERVER_ALERT_TYPE; - - break; - } - case MISSING_PROXY_CACHE_ALERT: - { - message = MISSING_PROXY_CACHE_ALERT_STRING; - type = MISSING_PROXY_CACHE_ALERT_TYPE; - - break; - } - case ABORT_PROXY_CONNECTION_ALERT: - { - message = ABORT_PROXY_CONNECTION_ALERT_STRING; - type = ABORT_PROXY_CONNECTION_ALERT_TYPE; - - break; - } - case DISPLACE_MESSAGE_ALERT: - { - message = DISPLACE_MESSAGE_ALERT_STRING; - type = DISPLACE_MESSAGE_ALERT_TYPE; - - break; - } - case GREETING_MESSAGE_ALERT: - { - message = GREETING_MESSAGE_ALERT_STRING; - type = GREETING_MESSAGE_ALERT_TYPE; - - break; - } - case START_RESUME_SESSION_ALERT: - { - message = START_RESUME_SESSION_ALERT_STRING; - type = START_RESUME_SESSION_ALERT_TYPE; - - break; - } - case FAILED_RESUME_DISPLAY_ALERT: - { - message = FAILED_RESUME_DISPLAY_ALERT_STRING; - type = FAILED_RESUME_DISPLAY_ALERT_TYPE; - - break; - } - case FAILED_RESUME_DISPLAY_BROKEN_ALERT: - { - message = FAILED_RESUME_DISPLAY_BROKEN_STRING; - type = FAILED_RESUME_DISPLAY_BROKEN_TYPE; - - break; - } - case FAILED_RESUME_VISUALS_ALERT: - { - message = FAILED_RESUME_VISUALS_ALERT_STRING; - type = FAILED_RESUME_VISUALS_ALERT_TYPE; - - break; - } - case FAILED_RESUME_COLORMAPS_ALERT: - { - message = FAILED_RESUME_COLORMAPS_ALERT_STRING; - type = FAILED_RESUME_COLORMAPS_ALERT_TYPE; - - break; - } - case FAILED_RESUME_PIXMAPS_ALERT: - { - message = FAILED_RESUME_PIXMAPS_ALERT_STRING; - type = FAILED_RESUME_PIXMAPS_ALERT_TYPE; - - break; - } - case FAILED_RESUME_DEPTHS_ALERT: - { - message = FAILED_RESUME_DEPTHS_ALERT_STRING; - type = FAILED_RESUME_DEPTHS_ALERT_TYPE; - - break; - } - case FAILED_RESUME_RENDER_ALERT: - { - message = FAILED_RESUME_RENDER_ALERT_STRING; - type = FAILED_RESUME_RENDER_ALERT_TYPE; - - break; - } - case FAILED_RESUME_FONTS_ALERT: - { - message = FAILED_RESUME_FONTS_ALERT_STRING; - type = FAILED_RESUME_FONTS_ALERT_TYPE; - - break; - } - case INTERNAL_ERROR_ALERT: - { - message = INTERNAL_ERROR_ALERT_STRING; - type = INTERNAL_ERROR_ALERT_TYPE; - - break; - } - case ABORT_PROXY_NEGOTIATION_ALERT: - { - message = ABORT_PROXY_NEGOTIATION_ALERT_STRING; - type = ABORT_PROXY_NEGOTIATION_ALERT_TYPE; - - break; - } - case ABORT_PROXY_SHUTDOWN_ALERT: - { - message = ABORT_PROXY_SHUTDOWN_ALERT_STRING; - type = ABORT_PROXY_SHUTDOWN_ALERT_TYPE; - - break; - } - case FAILED_XDMCP_CONNECTION_ALERT: - { - message = FAILED_XDMCP_CONNECTION_ALERT_STRING; - type = FAILED_XDMCP_CONNECTION_ALERT_TYPE; - - break; - } - default: - { - if (lastAlert.code > LAST_PROTO_STEP_7_ALERT) - { - #ifdef WARNING - *logofs << "Loop: WARNING! An unrecognized alert type '" - << lastAlert.code << "' was requested.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": An unrecognized alert type '" - << lastAlert.code << "' was requested.\n"; - } - #ifdef WARNING - else - { - *logofs << "Loop: WARNING! Ignoring obsolete alert type '" - << lastAlert.code << "'.\n" << logofs_flush; - } - #endif - - message = NULL; - type = NULL; - - replace = 0; - - break; - } - } - - if (replace == 1 && IsRunning(lastDialog)) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Killing the previous dialog with pid '" - << lastDialog << "'.\n" << logofs_flush; - #endif - - // - // The client ignores the TERM signal - // on Windows. - // - - #ifdef __CYGWIN32__ - - KillProcess(lastDialog, "dialog", SIGKILL, 0); - - #else - - KillProcess(lastDialog, "dialog", SIGTERM, 0); - - #endif - - SetNotRunning(lastDialog); - - if (proxy != NULL) - { - proxy -> handleResetAlert(); - } - } - - if (message != NULL && type != NULL) - { - lastDialog = NXTransDialog(caption, message, 0, type, local, display); - - if (IsFailed(lastDialog)) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Can't start the NX dialog process.\n" - << logofs_flush; - #endif - - SetNotRunning(lastDialog); - } - #if defined(TEST) || defined(INFO) - else - { - *logofs << "Loop: Dialog started with pid '" - << lastDialog << "'.\n" << logofs_flush; - } - #endif - } - #if defined(TEST) || defined(INFO) - else - { - *logofs << "Loop: No new dialog required for code '" - << lastAlert.code << "'.\n" << logofs_flush; - } - #endif - } - } - - // - // Reset state. - // - - lastAlert.code = 0; - lastAlert.local = 0; -} - -static inline void handleSetAgentInLoop(int &setFDs, fd_set &readSet, - fd_set &writeSet, struct timeval &selectTs) -{ - #ifdef TEST - *logofs << "Loop: Preparing the masks for the agent descriptors.\n" - << logofs_flush; - #endif - - agent -> saveChannelState(); - - agent -> saveReadMask(&readSet); - agent -> saveWriteMask(&writeSet); - - if (control -> ProxyStage >= stage_operational) - { - if (agent -> remoteCanRead(&readSet) || - agent -> remoteCanWrite(&writeSet) || - agent -> localCanRead() || - agent -> proxyCanRead()) - { - #ifdef TEST - *logofs << "Loop: Setting a null timeout with agent descriptors ready.\n" - << logofs_flush; - #endif - - // - // Force a null timeout so we'll bail out - // of the select immediately. We will ac- - // comodate the result code later. - // - - selectTs.tv_sec = 0; - selectTs.tv_usec = 0; - } - } - - #ifdef TEST - *logofs << "Loop: Clearing the read and write agent descriptors.\n" - << logofs_flush; - #endif - - agent -> clearReadMask(&readSet); - agent -> clearWriteMask(&writeSet); -} - -static inline void handleAgentInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, - fd_set &writeSet, struct timeval &selectTs) -{ - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Setting proxy and local agent descriptors.\n" - << logofs_flush; - #endif - - // - // Check if I/O is possible on the local - // agent or the proxy descriptor. - // - - if (resultFDs >= 0) - { - // - // Save if the proxy can read from the - // the agent descriptor. - // - - agent -> saveChannelState(); - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Values were resultFDs " << resultFDs - << " errorFDs " << errorFDs << " setFDs " - << setFDs << ".\n" << logofs_flush; - #endif - - if (agent -> localCanRead() == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Setting agent descriptor FD#" << agent -> - getLocalFd() << " as ready to read.\n" - << logofs_flush; - #endif - - agent -> setLocalRead(&readSet, &resultFDs); - } - - #if defined(TEST) || defined(INFO) - - if (agent -> proxyCanRead(&readSet) == 0 && - agent -> proxyCanRead() == 1) - { - *logofs << "Loop: WARNING! Can read from proxy FD#" - << proxyFD << " but the descriptor " - << "is not selected.\n" << logofs_flush; - } - - if (agent -> proxyCanRead(&readSet) == 1) - { - *logofs << "Loop: Setting proxy descriptor FD#" << agent -> - getProxyFd() << " as ready to read.\n" - << logofs_flush; - } - - #endif - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Values are now resultFDs " << resultFDs - << " errorFDs " << errorFDs << " setFDs " - << setFDs << ".\n" << logofs_flush; - #endif - } -} - -static inline void handleAgentLateInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, - fd_set &writeSet, struct timeval &selectTs) -{ - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Setting remote agent descriptors.\n" - << logofs_flush; - #endif - - // - // We reset the masks before calling our select. - // We now set the descriptors that are ready but - // only if they were set in the original mask. - // We do this after having executed our loop as - // we may have produced more data and the agent - // descriptors may have become readable or writ- - // able in the meanwhile. - // - - if (resultFDs >= 0) - { - // - // Save if the proxy can read from the - // the agent descriptor. - // - - agent -> saveChannelState(); - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Values were resultFDs " << resultFDs - << " errorFDs " << errorFDs << " setFDs " - << setFDs << ".\n" << logofs_flush; - #endif - - if (agent -> remoteCanRead(agent -> - getSavedReadMask()) == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Setting agent descriptor FD#" << agent -> - getRemoteFd() << " as ready to read.\n" - << logofs_flush; - #endif - - agent -> setRemoteRead(&readSet, &resultFDs); - } - - if (agent -> remoteCanWrite(agent -> - getSavedWriteMask()) == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Setting agent descriptor FD#" << agent -> - getRemoteFd() << " as ready to write.\n" - << logofs_flush; - #endif - - agent -> setRemoteWrite(&writeSet, &resultFDs); - } - - #if defined(TEST) || defined(INFO) - *logofs << "Loop: Values are now resultFDs " << resultFDs - << " errorFDs " << errorFDs << " setFDs " - << setFDs << ".\n" << logofs_flush; - #endif - } -} - -static inline void handleReadableInLoop(int &resultFDs, fd_set &readSet) -{ - if (resultFDs > 0) - { - T_channel_type type = channel_none; - - const char *label = NULL; - int domain = -1; - int fd = -1; - - if (tcpFD != -1 && FD_ISSET(tcpFD, &readSet)) - { - type = channel_x11; - label = "X"; - domain = AF_INET; - fd = tcpFD; - - resultFDs--; - } - - if (unixFD != -1 && FD_ISSET(unixFD, &readSet)) - { - type = channel_x11; - label = "X"; - domain = AF_UNIX; - fd = unixFD; - - resultFDs--; - } - - if (cupsFD != -1 && FD_ISSET(cupsFD, &readSet)) - { - type = channel_cups; - label = "CUPS"; - domain = AF_INET; - fd = cupsFD; - - resultFDs--; - } - - if (auxFD != -1 && FD_ISSET(auxFD, &readSet)) - { - // - // Starting from version 1.5.0 we create real X - // connections for the keyboard channel, so they - // can use the fake authorization cookie. This - // means that there is not such a thing like a - // channel_aux anymore. - // - - type = channel_x11; - label = "auxiliary X11"; - domain = AF_INET; - fd = auxFD; - - resultFDs--; - } - - if (smbFD != -1 && FD_ISSET(smbFD, &readSet)) - { - type = channel_smb; - label = "SMB"; - domain = AF_INET; - fd = smbFD; - - resultFDs--; - } - - if (mediaFD != -1 && FD_ISSET(mediaFD, &readSet)) - { - type = channel_media; - label = "media"; - domain = AF_INET; - fd = mediaFD; - - resultFDs--; - } - - if (httpFD != -1 && FD_ISSET(httpFD, &readSet)) - { - type = channel_http; - label = "HTTP"; - domain = AF_INET; - fd = httpFD; - - resultFDs--; - } - - if (fontFD != -1 && FD_ISSET(fontFD, &readSet)) - { - type = channel_font; - label = "font server"; - domain = AF_INET; - fd = fontFD; - - resultFDs--; - } - - if (slaveFD != -1 && FD_ISSET(slaveFD, &readSet)) - { - type = channel_slave; - label = "slave"; - domain = AF_INET; - fd = slaveFD; - - resultFDs--; - } - - if (type != channel_none) - { - int newFD = AcceptConnection(fd, domain, label); - - if (newFD != -1) - { - if (proxy -> handleNewConnection(type, newFD) < 0) - { - #ifdef PANIC - *logofs << "Loop: PANIC! Error creating new " << label - << " connection.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Error creating new " << label - << " connection.\n"; - - close(newFD); - - // - // Don't kill the proxy in the case of an error. - // - // HandleCleanup(); - // - } - else if (proxy -> getReadable(newFD) > 0) - { - // - // Add the descriptor, so we can try - // to read immediately. - // - - #ifdef TEST - *logofs << "Loop: Trying to read immediately " - << "from descriptor FD#" << newFD - << ".\n" << logofs_flush; - #endif - - FD_SET(newFD, &readSet); - - resultFDs++; - } - #ifdef TEST - else - { - *logofs << "Loop: Nothing to read immediately " - << "from descriptor FD#" << newFD - << ".\n" << logofs_flush; - } - #endif - } - } - } - - #ifdef DEBUG - *logofs << "Loop: Going to check the readable descriptors.\n" - << logofs_flush; - #endif - - if (proxy -> handleRead(resultFDs, readSet) < 0) - { - #ifdef TEST - *logofs << "Loop: Failure reading from descriptors " - << "for proxy FD#" << proxyFD << ".\n" - << logofs_flush; - #endif - - HandleShutdown(); - } -} - -static inline void handleWritableInLoop(int &resultFDs, fd_set &writeSet) -{ - #ifdef DEBUG - *logofs << "Loop: Going to check the writable descriptors.\n" - << logofs_flush; - #endif - - if (resultFDs > 0 && proxy -> handleFlush(resultFDs, writeSet) < 0) - { - #ifdef TEST - *logofs << "Loop: Failure writing to descriptors " - << "for proxy FD#" << proxyFD << ".\n" - << logofs_flush; - #endif - - HandleShutdown(); - } -} - -static inline void handleFlushInLoop() -{ - #ifdef DEBUG - *logofs << "Loop: Going to flush any data to the proxy.\n" - << logofs_flush; - #endif - - if (agent == NULL || control -> - FlushPolicy == policy_immediate) - { - #if defined(TEST) || defined(INFO) - - if (usePolicy == -1 && control -> - ProxyMode == proxy_client) - { - *logofs << "Loop: WARNING! Flushing the proxy link " - << "on behalf of the agent.\n" << logofs_flush; - } - - #endif - - if (proxy -> handleFlush() < 0) - { - #ifdef TEST - *logofs << "Loop: Failure flushing the proxy FD#" - << proxyFD << ".\n" << logofs_flush; - #endif - - HandleShutdown(); - } - } -} - -static inline void handleRotateInLoop() -{ - #ifdef DEBUG - *logofs << "Loop: Going to rotate channels " - << "for proxy FD#" << proxyFD << ".\n" - << logofs_flush; - #endif - - proxy -> handleRotate(); -} - -static inline void handleEventsInLoop() -{ - #ifdef DEBUG - *logofs << "Loop: Going to check channel events " - << "for proxy FD#" << proxyFD << ".\n" - << logofs_flush; - #endif - - if (proxy -> handleEvents() < 0) - { - #ifdef TEST - *logofs << "Loop: Failure handling channel events " - << "for proxy FD#" << proxyFD << ".\n" - << logofs_flush; - #endif - - HandleShutdown(); - } -} - -static void handleLogReopenInLoop(T_timestamp &logsTs, T_timestamp &nowTs) -{ - // - // If need to limit the size of the - // log file, check the size at each - // loop. - // - - #ifndef QUOTA - - if (diffTimestamp(logsTs, nowTs) > control -> FileSizeCheckTimeout) - - #endif - { - #ifdef DEBUG - *logofs << "Loop: Checking size of log file '" - << errorsFileName << "'.\n" << logofs_flush; - #endif - - #ifndef MIXED - - if (ReopenLogFile(errorsFileName, logofs, control -> FileSizeLimit) < 0) - { - HandleShutdown(); - } - - #endif - - // - // Reset to current timestamp. - // - - logsTs = nowTs; - } -} - -static inline void handleSetReadInLoop(fd_set &readSet, int &setFDs, struct timeval &selectTs) -{ - proxy -> setReadDescriptors(&readSet, setFDs, selectTs); -} - -static inline void handleSetWriteInLoop(fd_set &writeSet, int &setFDs, struct timeval &selectTs) -{ - proxy -> setWriteDescriptors(&writeSet, setFDs, selectTs); -} - -static void handleSetListenersInLoop(fd_set &readSet, int &setFDs) -{ - // - // Set descriptors of listening sockets. - // - - if (control -> ProxyMode == proxy_client) - { - if (useTcpSocket == 1) - { - FD_SET(tcpFD, &readSet); - - if (tcpFD >= setFDs) - { - setFDs = tcpFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener tcpFD " << tcpFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } - - if (useUnixSocket == 1) - { - FD_SET(unixFD, &readSet); - - if (unixFD >= setFDs) - { - setFDs = unixFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener unixFD " << unixFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } - - if (useCupsSocket == 1) - { - FD_SET(cupsFD, &readSet); - - if (cupsFD >= setFDs) - { - setFDs = cupsFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener cupsFD " << cupsFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } - - if (useAuxSocket == 1) - { - FD_SET(auxFD, &readSet); - - if (auxFD >= setFDs) - { - setFDs = auxFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener auxFD " << auxFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } - - if (useSmbSocket == 1) - { - FD_SET(smbFD, &readSet); - - if (smbFD >= setFDs) - { - setFDs = smbFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener smbFD " << smbFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } - - if (useMediaSocket == 1) - { - FD_SET(mediaFD, &readSet); - - if (mediaFD >= setFDs) - { - setFDs = mediaFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener mediaFD " << mediaFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } - - if (useHttpSocket == 1) - { - FD_SET(httpFD, &readSet); - - if (httpFD >= setFDs) - { - setFDs = httpFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener httpFD " << httpFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } - } - else - { - if (useFontSocket == 1) - { - FD_SET(fontFD, &readSet); - - if (fontFD >= setFDs) - { - setFDs = fontFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener fontFD " << fontFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } - } - - if (useSlaveSocket == 1) - { - FD_SET(slaveFD, &readSet); - - if (slaveFD >= setFDs) - { - setFDs = slaveFD + 1; - } - - #ifdef DEBUG - *logofs << "Loop: Selected listener slaveFD " << slaveFD - << " with setFDs " << setFDs << ".\n" - << logofs_flush; - #endif - } -} diff --git a/nxcomp/MD5.c b/nxcomp/MD5.c deleted file mode 100644 index e49d3cf58..000000000 --- a/nxcomp/MD5.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "MD5.h" - -#include - -/* - * Try to determine the CPU endianess - * at compile time. - */ - -#if defined(__linux) || defined(__CYGWIN32__) - -#include - -#if (__BYTE_ORDER == __LITTLE_ENDIAN) -#define ARCH_IS_BIG_ENDIAN 0 -#else -#define ARCH_IS_BIG_ENDIAN 1 -#endif - -#endif /* #if defined(__linux) || defined(__CYGWIN32__) */ - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -#else -# define BYTE_ORDER 0 -#endif - -#define T_MASK ((md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - - -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) -{ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } -#endif - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init(md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -{ - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -{ - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} diff --git a/nxcomp/MD5.h b/nxcomp/MD5.h deleted file mode 100644 index 698c995d8..000000000 --- a/nxcomp/MD5.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.h is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); - -/* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* md5_INCLUDED */ diff --git a/nxcomp/Makefile.am b/nxcomp/Makefile.am new file mode 100644 index 000000000..ae5991c3d --- /dev/null +++ b/nxcomp/Makefile.am @@ -0,0 +1,21 @@ +SUBDIRS = src + +pkgconfig_DATA = nxcomp.pc + +MAINTAINERCLEANFILES = \ + $(srcdir)/autom4te.cache/* \ + $(srcdir)/build-aux/* \ + $(srcdir)/Makefile.in \ + $(srcdir)/src/Makefile.in \ + $(srcdir)/aclocal.m4 \ + $(srcdir)/config.h.in \ + $(srcdir)/config.h.in~ \ + $(srcdir)/configure \ + $(srcdir)/m4/libtool.m4 \ + $(srcdir)/m4/lt~obsolete.m4 \ + $(srcdir)/m4/ltoptions.m4 \ + $(srcdir)/m4/ltsugar.m4 \ + $(srcdir)/m4/ltversion.m4 \ + $(NULL) + +DISTCLEANFILES=$(MAINTAINERCLEANFILES) diff --git a/nxcomp/Makefile.in b/nxcomp/Makefile.in deleted file mode 100644 index f18875524..000000000 --- a/nxcomp/Makefile.in +++ /dev/null @@ -1,333 +0,0 @@ -#/**************************************************************************/ -#/* */ -#/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -#/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -#/* Copyright (c) 2014-2016 Ulrich Sibiller */ -#/* Copyright (c) 2014-2016 Mihai Moldovan */ -#/* Copyright (c) 2011-2016 Mike Gabriel */ -#/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -#/* */ -#/* NXCOMP, NX protocol compression and NX extensions to this software */ -#/* are copyright of the aforementioned persons and companies. */ -#/* */ -#/* Redistribution and use of the present software is allowed according */ -#/* to terms specified in the file LICENSE.nxcomp which comes in the */ -#/* source distribution. */ -#/* */ -#/* All rights reserved. */ -#/* */ -#/* NOTE: This software has received contributions from various other */ -#/* contributors, only the core maintainers and supporters are listed as */ -#/* copyright holders. Please contact us, if you feel you should be listed */ -#/* as copyright holder, as well. */ -#/* */ -#/**************************************************************************/ - -# -# Get these values from the configure script. The -# version printed by the program should be derived -# from the CHANGELOG. For example we may use the -# following command: -# -# head -n 3 CHANGELOG | grep 'nxcomp-' | cut -d '-' -f 2-3 -# - -VERSION=@VERSION@ -LIBVERSION=@LIBVERSION@ - -# -# We would really like to enable all warnings, -Wredundant-decls, -# though, gives a warning caused by pthread.h and unistd.h and -# GCC 3.4 was changed in a way that it now complains about some -# of the -W directives we used before (-Wmissing-declarations, -# -Wnested-externs, -Wstrict-prototypes and -Wmissing-prototypes). -# - -CXX = @CXX@ -CXXFLAGS = @CXXFLAGS@ @X_CFLAGS@ @DEFS@ \ - -Wall -Wpointer-arith -CXXINCLUDES = -CXXDEFINES = - -CPPFLAGS = @CPPFLAGS@ - -# -# C programs have their own CFLAGS. -# - -CC = @CC@ -CCFLAGS = @CFLAGS@ @X_CFLAGS@ @DEFS@ \ - -Wall -Wpointer-arith -CCINCLUDES = -CCDEFINES = - -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ - -# -# Other autoconfigured settings, not used at the moment. -# - -srcdir = @srcdir@ -prefix = @prefix@ -datarootdir = @datarootdir@ -datadir = @datadir@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -man1dir = @mandir@/man1 -VPATH = @srcdir@ -libdir = @libdir@ -includedir = @includedir@ -pkgconfigdir = @pkgconfigdir@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_LINK = cp -av -DESTDIR = -RM_FILE = rm -f - -# -# This should be autodetected. -# - -MAKEDEPEND = @MAKEDEPEND@ -DEPENDINCLUDES = -I/usr/include/c++ -I/usr/include/g++ -I/usr/include/g++-3 - -.SUFFIXES: .cpp.c - -.cpp.o: - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CXXINCLUDES) $(CXXDEFINES) $< -.c.o: - $(CC) -c $(CPPFLAGS) $(CCFLAGS) $(CCINCLUDES) $(CCDEFINES) $< - -LIBRARY = Xcomp - -LIBNAME = lib$(LIBRARY) -ifeq ($(shell uname),Darwin) -LIBFULL = lib$(LIBRARY).$(VERSION).dylib -LIBLOAD = lib$(LIBRARY).$(LIBVERSION).dylib -LIBSHARED = lib$(LIBRARY).dylib -COMP_VER = $(shell echo '$(VERSION)' | cut -d '.' -f 1-3) -LIBFLAGS = -install_name $(libdir)/$(LIBLOAD) -compatibility_version $(LIBVERSION) -current_version $(COMP_VER) -else -LIBFULL = lib$(LIBRARY).so.$(VERSION) -LIBLOAD = lib$(LIBRARY).so.$(LIBVERSION) -LIBSHARED = lib$(LIBRARY).so -LIBFLAGS = -endif -LIBARCHIVE = lib$(LIBRARY).a - -LIBCYGSHARED = cyg$(LIBRARY).dll -LIBCYGARCHIVE = lib$(LIBRARY).dll.a - -all: depend @ALL@ - -MSRC = - -CSRC = MD5.c \ - Pack.c \ - Vars.c \ - Version.c - -CXXSRC = Loop.cpp \ - Children.cpp \ - Control.cpp \ - Misc.cpp \ - Socket.cpp \ - Fork.cpp \ - Pipe.cpp \ - List.cpp \ - Keeper.cpp \ - Timestamp.cpp \ - Transport.cpp \ - Statistics.cpp \ - Auth.cpp \ - Agent.cpp \ - Proxy.cpp \ - Channel.cpp \ - Message.cpp \ - Split.cpp \ - ClientProxy.cpp \ - ServerProxy.cpp \ - OpcodeStore.cpp \ - ClientStore.cpp \ - ServerStore.cpp \ - ChannelCache.cpp \ - ClientCache.cpp \ - ServerCache.cpp \ - ClientChannel.cpp \ - ServerChannel.cpp \ - GenericChannel.cpp \ - ChannelEndPoint.cpp \ - ReadBuffer.cpp \ - ProxyReadBuffer.cpp \ - ClientReadBuffer.cpp \ - ServerReadBuffer.cpp \ - GenericReadBuffer.cpp \ - EncodeBuffer.cpp \ - DecodeBuffer.cpp \ - WriteBuffer.cpp \ - SequenceQueue.cpp \ - IntCache.cpp \ - CharCache.cpp \ - XidCache.cpp \ - ActionCache.cpp \ - BlockCache.cpp \ - BlockCacheSet.cpp \ - StaticCompressor.cpp \ - Unpack.cpp \ - Alpha.cpp \ - Colormap.cpp \ - Jpeg.cpp \ - Pgn.cpp \ - Bitmap.cpp \ - Rgb.cpp \ - Rle.cpp \ - Z.cpp \ - ChangeProperty.cpp \ - SendEvent.cpp \ - ChangeGC.cpp \ - CreateGC.cpp \ - CreatePixmap.cpp \ - SetClipRectangles.cpp \ - CopyArea.cpp \ - PolyLine.cpp \ - PolySegment.cpp \ - PolyFillRectangle.cpp \ - PutImage.cpp \ - TranslateCoords.cpp \ - GetImage.cpp \ - ClearArea.cpp \ - ConfigureWindow.cpp \ - PolyText8.cpp \ - PolyText16.cpp \ - ImageText8.cpp \ - ImageText16.cpp \ - PolyPoint.cpp \ - PolyFillArc.cpp \ - PolyArc.cpp \ - FillPoly.cpp \ - InternAtom.cpp \ - GetProperty.cpp \ - SetUnpackGeometry.cpp \ - SetUnpackColormap.cpp \ - SetUnpackAlpha.cpp \ - PutPackedImage.cpp \ - ShapeExtension.cpp \ - RenderExtension.cpp \ - GenericRequest.cpp \ - QueryFontReply.cpp \ - ListFontsReply.cpp \ - GetImageReply.cpp \ - GetPropertyReply.cpp \ - GenericReply.cpp \ - RenderGenericRequest.cpp \ - RenderCreatePicture.cpp \ - RenderChangePicture.cpp \ - RenderFreePicture.cpp \ - RenderPictureClip.cpp \ - RenderPictureTransform.cpp \ - RenderPictureFilter.cpp \ - RenderCreateGlyphSet.cpp \ - RenderFreeGlyphSet.cpp \ - RenderAddGlyphs.cpp \ - RenderComposite.cpp \ - RenderCompositeGlyphs.cpp \ - RenderFillRectangles.cpp \ - RenderTrapezoids.cpp \ - RenderTriangles.cpp - -MOBJ = $(MSRC:.c=.o) -COBJ = $(CSRC:.c=.o) -CXXOBJ = $(CXXSRC:.cpp=.o) - -$(LIBFULL): $(CXXOBJ) $(COBJ) - $(CXX) -o $@ $(LDFLAGS) $(LIBFLAGS) $(CXXOBJ) $(COBJ) $(LIBS) - -$(LIBLOAD): $(LIBFULL) - rm -f $(LIBLOAD) - ln -s $(LIBFULL) $(LIBLOAD) - -$(LIBSHARED): $(LIBFULL) - rm -f $(LIBSHARED) - ln -s $(LIBFULL) $(LIBSHARED) - -$(LIBARCHIVE): $(CXXOBJ) $(COBJ) - rm -f $(LIBARCHIVE) - ar clq $(LIBARCHIVE) $(CXXOBJ) $(COBJ) - ranlib $(LIBARCHIVE) - -$(LIBCYGSHARED): $(LIBARCHIVE) - $(CC) -shared -o $(LIBCYGSHARED) \ - -Wl,--out-implib=$(LIBCYGARCHIVE) \ - -Wl,--export-all-symbols \ - -Wl,--enable-auto-import \ - -Wl,--whole-archive $(LIBARCHIVE) \ - -Wl,--no-whole-archive $(LIBS) \ - $(LDFLAGS) - -$(LIBCYGARCHIVE): $(LIBCYGSHARED) - -depends: depend.status - -depend: depend.status - -depend.status: - if [ -n "$(MAKEDEPEND)" ] && [ -x "$(MAKEDEPEND)" ] ; then \ - $(MAKEDEPEND) $(CXXINCLUDES) $(CCINCLUDES) \ - $(DEPENDINCLUDES) -f Makefile $(MSRC) $(CSRC) \ - $(CXXSRC) 2>/dev/null; \ - fi - touch depend.status - -install: install.bin install.lib install.man - -install.bin: - -install.lib: all - ./mkinstalldirs $(DESTDIR)${libdir} - ./mkinstalldirs $(DESTDIR)${includedir}/nx - ./mkinstalldirs $(DESTDIR)${pkgconfigdir} - $(INSTALL_DATA) $(LIBFULL) $(DESTDIR)${libdir} - $(INSTALL_LINK) $(LIBLOAD) $(DESTDIR)${libdir} - $(INSTALL_LINK) $(LIBSHARED) $(DESTDIR)${libdir} - $(INSTALL_DATA) $(LIBARCHIVE) $(DESTDIR)${libdir} - $(INSTALL_DATA) MD5.h $(DESTDIR)${includedir}/nx - $(INSTALL_DATA) NX.h $(DESTDIR)${includedir}/nx - $(INSTALL_DATA) NXalert.h $(DESTDIR)${includedir}/nx - $(INSTALL_DATA) NXpack.h $(DESTDIR)${includedir}/nx - $(INSTALL_DATA) NXproto.h $(DESTDIR)${includedir}/nx - $(INSTALL_DATA) NXvars.h $(DESTDIR)${includedir}/nx - $(INSTALL_DATA) nxcomp.pc $(DESTDIR)${pkgconfigdir} - echo "Running ldconfig tool, this may take a while..." && ldconfig || true - -install.man: - -uninstall: uninstall.bin uninstall.lib uninstall.man - -uninstall.bin: - -uninstall.lib: - $(RM_FILE) $(DESTDIR)${libdir}/$(LIBFULL) - $(RM_FILE) $(DESTDIR)${libdir}/$(LIBLOAD) - $(RM_FILE) $(DESTDIR)${libdir}/$(LIBSHARED) - $(RM_FILE) $(DESTDIR)${libdir}/$(LIBARCHIVE) - $(RM_FILE) $(DESTDIR)${includedir}/nx/NXalert.h - $(RM_FILE) $(DESTDIR)${includedir}/nx/NX.h - $(RM_FILE) $(DESTDIR)${includedir}/nx/NXpack.h - $(RM_FILE) $(DESTDIR)${includedir}/nx/NXproto.h - $(RM_FILE) $(DESTDIR)${includedir}/nx/NXvars.h - $(RM_FILE) $(DESTDIR)${includedir}/nx/MD5.h - $(RM_FILE) $(DESTDIR)${pkgconfigdir}/nxcomp.pc - echo "Running ldconfig tool, this may take a while..." && ldconfig || true - -uninstall.man: - -clean: - -rm -f *~ *.o *.bak *.orig *.rej st?????? core core.* *.out.* *.pc \ - @ALL@ - -distclean: clean - -rm -rf autom4te.cache config.status config.log \ - config.cache depend.status Makefile tags configure diff --git a/nxcomp/Message.cpp b/nxcomp/Message.cpp deleted file mode 100644 index 530b6b5a8..000000000 --- a/nxcomp/Message.cpp +++ /dev/null @@ -1,2339 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include - -#include - -#include "Misc.h" - -// -// We need channel's cache data. -// - -#include "Message.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. You also -// need to define DUMP in Misc.cpp -// if DUMP is defined here. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Define this to log when messages -// are allocated and deallocated. -// - -#undef REFERENCES - -// -// Keep track of how many bytes are -// occupied by cache. -// - -int MessageStore::totalLocalStorageSize_ = 0; -int MessageStore::totalRemoteStorageSize_ = 0; - -// -// These are used for reference count. -// - -#ifdef REFERENCES - -int Message::references_ = 0; -int MessageStore::references_ = 0; - -#endif - -// -// Here are the methods to handle cached messages. -// - -MessageStore::MessageStore(StaticCompressor *compressor) - - : compressor_(compressor) -{ - // - // Public members. - // - - enableCache = MESSAGE_ENABLE_CACHE; - enableData = MESSAGE_ENABLE_DATA; - enableSplit = MESSAGE_ENABLE_SPLIT; - enableCompress = MESSAGE_ENABLE_COMPRESS; - - dataLimit = MESSAGE_DATA_LIMIT; - dataOffset = MESSAGE_DATA_OFFSET; - - cacheSlots = MESSAGE_CACHE_SLOTS; - cacheThreshold = MESSAGE_CACHE_THRESHOLD; - cacheLowerThreshold = MESSAGE_CACHE_LOWER_THRESHOLD; - - #ifdef TEST - *logofs << "MessageStore: Static compressor is at " - << compressor_ << ".\n" << logofs_flush; - #endif - - md5_state_ = new md5_state_t(); - - #ifdef DEBUG - *logofs << "MessageStore: Created MD5 state for object at " - << this << ".\n" << logofs_flush; - #endif - - lastAdded = cacheSlots; - lastHit = 0; - lastRemoved = 0; - lastRated = nothing; - lastAction = is_discarded; - - // - // Private members. - // - - localStorageSize_ = 0; - remoteStorageSize_ = 0; - - #ifdef TEST - *logofs << "MessageStore: Size of total cache is " - << totalLocalStorageSize_ << " bytes at local side and " - << totalRemoteStorageSize_ << " bytes at remote side.\n" - << logofs_flush; - #endif - - messages_ = new T_messages(); - checksums_ = new T_checksums(); - - temporary_ = NULL; - - #ifdef REFERENCES - - references_++; - - *logofs << "MessageStore: Created new store at " - << this << "out of " << references_ - << " allocated stores.\n" << logofs_flush; - - #endif -} - -MessageStore::~MessageStore() -{ - // - // The virtual destructor of specialized class - // must get rid of both messages in container - // and temporary. - // - - #ifdef DEBUG - *logofs << "MessageStore: Deleting MD5 state for object at " - << this << ".\n" << logofs_flush; - #endif - - delete md5_state_; - - delete messages_; - delete checksums_; - - // - // Update the static members tracking - // size of total memory allocated for - // all stores. - // - - totalLocalStorageSize_ -= localStorageSize_; - totalRemoteStorageSize_ -= remoteStorageSize_; - - #ifdef TEST - *logofs << "MessageStore: Size of total cache is " - << totalLocalStorageSize_ << " bytes at local side and " - << totalRemoteStorageSize_ << " bytes at remote side.\n" - << logofs_flush; - #endif - - #ifdef REFERENCES - - references_--; - - *logofs << "MessageStore: Deleted store at " - << this << " out of " << references_ - << " allocated stores.\n" << logofs_flush; - - #endif -} - -// -// Here are the methods to parse and cache -// messages in the message stores. -// - -int MessageStore::parse(Message *message, int split, const unsigned char *buffer, - unsigned int size, T_checksum_action checksumAction, - T_data_action dataAction, int bigEndian) -{ - // - // Save the message size as received on the link. - // This information will be used to create an ap- - // propriate buffer at the time the message will - // be unparsed. - // - - message -> size_ = size; - message -> i_size_ = identitySize(buffer, size); - message -> c_size_ = 0; - - validateSize(size); - - if (checksumAction == use_checksum) - { - beginChecksum(message); - - parseIdentity(message, buffer, size, bigEndian); - - identityChecksum(message, buffer, size, bigEndian); - - parseData(message, split, buffer, size, checksumAction, dataAction, bigEndian); - - endChecksum(message); - } - else - { - parseIdentity(message, buffer, size, bigEndian); - - parseData(message, split, buffer, size, checksumAction, dataAction, bigEndian); - } - - return 1; -} - -int MessageStore::parse(Message *message, const unsigned char *buffer, - unsigned int size, const unsigned char *compressedData, - const unsigned int compressedDataSize, - T_checksum_action checksumAction, - T_data_action dataAction, int bigEndian) -{ - int offset = identitySize(buffer, size); - - message -> size_ = size; - message -> i_size_ = offset; - message -> c_size_ = compressedDataSize + offset; - - validateSize(message -> size_ - offset, compressedDataSize); - - if (checksumAction == use_checksum) - { - beginChecksum(message); - - parseIdentity(message, buffer, size, bigEndian); - - identityChecksum(message, buffer, size, bigEndian); - - parseData(message, buffer, size, compressedData, compressedDataSize, - checksumAction, dataAction, bigEndian); - - endChecksum(message); - } - else - { - parseIdentity(message, buffer, size, bigEndian); - - parseData(message, buffer, size, compressedData, compressedDataSize, - checksumAction, dataAction, bigEndian); - } - - return 1; -} - -int MessageStore::parseData(Message *message, int split, const unsigned char *buffer, - unsigned int size, T_checksum_action checksumAction, - T_data_action dataAction, int bigEndian) -{ - if ((int) size > message -> i_size_) - { - unsigned int dataSize = size - message -> i_size_; - - if (checksumAction == use_checksum) - { - #ifdef DEBUG - *logofs << name() << ": Calculating checksum of object at " - << message << " with data size " << dataSize - << ".\n" << logofs_flush; - #endif - - dataChecksum(message, buffer, size, bigEndian); - } - - if (dataAction == discard_data) - { - #ifdef DEBUG - *logofs << name() << ": Discarded " << dataSize - << " bytes of plain data. Real size is " - << message -> size_ << " compressed size is " - << message -> c_size_ << ".\n" << logofs_flush; - #endif - - return 1; - } - - // - // Accept anyway data beyond the - // expected limit. - // - - #ifdef TEST - - if (dataSize > (unsigned int) dataLimit) - { - *logofs << name() << ": WARNING! Data is " << dataSize - << " bytes. Ignoring the established limit.\n" - << logofs_flush; - } - - #endif - - if (dataSize != message -> data_.size()) - { - #ifdef DEBUG - *logofs << name() << ": Data will be resized from " - << message -> data_.size() << " to hold a plain buffer of " - << dataSize << " bytes.\n" << logofs_flush; - #endif - - message -> data_.clear(); - - message -> data_.resize(dataSize); - } - - if (split == 0) - { - memcpy(message -> data_.begin(), buffer + message -> i_size_, dataSize); - } - #ifdef TEST - else - { - *logofs << name() << ": Not copied " << dataSize - << " bytes of fake data for the split message.\n" - << logofs_flush; - } - #endif - - #ifdef DEBUG - *logofs << name() << ": Parsed " << dataSize - << " bytes of plain data. Real size is " - << message -> size_ << " compressed size is " - << message -> c_size_ << ".\n" << logofs_flush; - #endif - } - - return 1; -} - -// -// Store the data part in compressed format. -// - -int MessageStore::parseData(Message *message, const unsigned char *buffer, - unsigned int size, const unsigned char *compressedData, - const unsigned int compressedDataSize, - T_checksum_action checksumAction, - T_data_action dataAction, int bigEndian) -{ - if ((int) size > message -> i_size_) - { - unsigned int dataSize = size - message -> i_size_; - - if (checksumAction == use_checksum) - { - #ifdef DEBUG - *logofs << name() << ": Calculating checksum of object at " - << message << " with data size " << dataSize - << ".\n" << logofs_flush; - #endif - - dataChecksum(message, buffer, size, bigEndian); - } - - if (dataAction == discard_data) - { - #ifdef DEBUG - *logofs << name() << ": Discarded " << dataSize - << " bytes of compressed data. Real size is " - << message -> size_ << " compressed size is " - << message -> c_size_ << ".\n" << logofs_flush; - #endif - - return 1; - } - - #ifdef WARNING - if (dataSize > (unsigned int) dataLimit) - { - *logofs << name() << ": WARNING! Data is " << dataSize - << " bytes. Ignoring the established limit!\n" - << logofs_flush; - } - #endif - - dataSize = compressedDataSize; - - if (dataSize != message -> data_.size()) - { - #ifdef DEBUG - *logofs << name() << ": Data will be resized from " - << message -> data_.size() << " to hold a compressed buffer of " - << dataSize << " bytes.\n" << logofs_flush; - #endif - - message -> data_.clear(); - - message -> data_.resize(compressedDataSize); - } - - memcpy(message -> data_.begin(), compressedData, compressedDataSize); - - #ifdef DEBUG - *logofs << name() << ": Parsed " << dataSize - << " bytes of compressed data. Real size is " - << message -> size_ << " compressed size is " - << message -> c_size_ << ".\n" << logofs_flush; - #endif - } - - return 1; -} - -int MessageStore::unparseData(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) -{ - // - // Copy data, if any, to the buffer. - // - - if ((int) size > message -> i_size_) - { - // - // Check if message has been stored - // in compressed format. - // - - if (message -> c_size_ == 0) - { - memcpy(buffer + message -> i_size_, message -> data_.begin(), size - message -> i_size_); - - #ifdef DEBUG - *logofs << name() << ": Unparsed " << message -> size_ - message -> i_size_ - << " bytes of data to a buffer of " << message -> size_ - message -> i_size_ - << ".\n" << logofs_flush; - #endif - } - else - { - #ifdef DEBUG - *logofs << name() << ": Using static compressor at " << (void *) compressor_ - << ".\n" << logofs_flush; - #endif - - if (compressor_ -> - decompressBuffer(buffer + message -> i_size_, - size - message -> i_size_, - message -> data_.begin(), - message -> c_size_ - message -> i_size_) < 0) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Data decompression failed.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Data decompression failed.\n"; - - return -1; - } - - #ifdef DEBUG - *logofs << name() << ": Unparsed " << message -> c_size_ - message -> i_size_ - << " bytes of compressed data to a buffer of " - << message -> size_ - message -> i_size_ << ".\n" << logofs_flush; - #endif - } - } - - // - // We could write size to the buffer but this - // is something the channel class is doing by - // itself. - // - // PutUINT(size >> 2, buffer + 2, bigEndian); - // - - return 1; -} - -void MessageStore::dumpData(const Message *message) const -{ - #ifdef DUMP - - *logofs << name() << ": Dumping enumerated data:\n" << logofs_flush; - - DumpData(message -> data_.begin(), message -> data_.size()); - - #endif - - #ifdef DUMP - - *logofs << name() << ": Dumping checksum data:\n" << logofs_flush; - - DumpData(message -> md5_digest_, MD5_LENGTH); - - #endif -} - -T_checksum MessageStore::getChecksum(const unsigned char *buffer, - unsigned int size, int bigEndian) -{ - Message *message = getTemporary(); - - message -> size_ = size; - message -> i_size_ = identitySize(buffer, size); - message -> c_size_ = 0; - - validateSize(size); - - beginChecksum(message); - - // - // We don't need to extract the identity - // data from the buffer. - // - // parseIdentity(message, buffer, size, bigEndian); - // - - identityChecksum(message, buffer, size, bigEndian); - - parseData(message, 0, buffer, size, use_checksum, discard_data, bigEndian); - - endChecksum(message); - - // - // The caller will have to explicitly - // deallocated the memory after use. - // - - T_checksum checksum = new md5_byte_t[MD5_LENGTH]; - - memcpy(checksum, message -> md5_digest_, MD5_LENGTH); - - return checksum; -} - -int MessageStore::clean(T_checksum_action checksumAction) -{ - int position = lastRemoved + 1; - - if (position >= cacheSlots) - { - position = 0; - } - - #ifdef DEBUG - *logofs << name() << ": Searching a message to remove " - << "starting at position " << position - << " with " << checksums_ -> size() - << " elements in cache.\n" - << logofs_flush; - #endif - - while (position != lastRemoved) - { - #ifdef DEBUG - *logofs << name() << ": Examining position " - << position << ".\n" << logofs_flush; - #endif - - if ((*messages_)[position] != NULL) - { - if (getRating((*messages_)[position], rating_for_clean) == 0) - { - break; - } - else - { - untouch((*messages_)[position]); - } - } - - if (++position == cacheSlots) - { - #ifdef DEBUG - *logofs << name() << ": Rolled position at " - << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - position = 0; - } - } - - // - // If no message is a good candidate, - // then try the object at the next slot - // in respect to last element removed. - // - - if (position == lastRemoved) - { - position = lastRemoved + 1; - - if (position >= cacheSlots) - { - position = 0; - } - - if ((*messages_)[position] == NULL || - (*messages_)[position] -> locks_ != 0) - { - #ifdef DEBUG - *logofs << name() << ": WARNING! No message found " - << "to be actually removed.\n" - << logofs_flush; - #endif - - return nothing; - } - - #ifdef DEBUG - *logofs << name() << ": WARNING! Assuming object " - << "at position " << position << ".\n" - << logofs_flush; - #endif - } - - return position; -} - -// -// This is the insertion method used at local side -// side. Cache at remote side side will be kept in -// sync by telling the to other party where to -// store the message. -// - -int MessageStore::findOrAdd(Message *message, T_checksum_action checksumAction, - T_data_action dataAction, int &added, int &locked) -{ - if (checksumAction != use_checksum) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Internal error in context [A]. " - << "Cannot find or add message to repository " - << "without using checksum.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Internal error in context [A]. " - << "Cannot find or add message to repository " - << "without using checksum.\n"; - - HandleAbort(); - } - - // - // Set added to true only if message - // is inserted in cache. - // - - added = 0; - locked = 0; - - // - // First of all figure out where to - // store this object. - // - - #ifdef DEBUG - *logofs << name() << ": Searching an empty slot " - << "with last rated " << lastRated << " and " - << "last added " << lastAdded << ".\n" - << logofs_flush; - #endif - - int position = lastRated; - - if (position == nothing) - { - position = lastAdded + 1; - - if (position >= cacheSlots) - { - position = 0; - } - - #ifdef DEBUG - *logofs << name() << ": Searching an empty slot " - << "starting at position " << position - << " with " << checksums_ -> size() - << " elements in cache.\n" - << logofs_flush; - #endif - - while (position != lastAdded) - { - #ifdef DEBUG - *logofs << name() << ": Examining position " - << position << ".\n" << logofs_flush; - #endif - - if ((*messages_)[position] == NULL) - { - break; - } - else if (getRating((*messages_)[position], rating_for_insert) == 0) - { - break; - } - else - { - untouch((*messages_)[position]); - } - - if (++position == cacheSlots) - { - #ifdef DEBUG - *logofs << name() << ": Rolled position at " - << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - position = 0; - } - } - } - #ifdef DEBUG - else - { - *logofs << name() << ": Using last rated position " - << position << ".\n" << logofs_flush; - } - #endif - - // - // If we made an extensive check but did not - // find neither a free slot or a message to - // replace, assume slot at next position in - // respect to last added. This can happen if - // all objects in repository have got an hit - // recently. - // - - if (position == lastAdded) - { - position = lastAdded + 1; - - if (position >= cacheSlots) - { - position = 0; - } - - #ifdef DEBUG - *logofs << name() << ": WARNING! Assuming slot " - << "at position " << position << ".\n" - << logofs_flush; - #endif - } - #ifdef DEBUG - else - { - *logofs << name() << ": Found candidate slot " - << "at position " << position << ".\n" - << logofs_flush; - } - #endif - - // - // Save the search result so if the message - // is found in cache, we can use the slot - // at next run. - // - - lastRated = position; - - if ((*messages_)[position] != NULL && - (*messages_)[position] -> locks_ != 0) - { - #ifdef WARNING - *logofs << name() << ": WARNING! Insertion at position " - << position << " would replace a locked message. " - << "Forcing channel to discard the message.\n" - << logofs_flush; - #endif - - #ifdef TEST - *logofs << name() << ": Invalidating rating of object " - << "at position " << position << ".\n" - << logofs_flush; - #endif - - return (lastRated = nothing); - } - - if (checksumAction == use_checksum) - { - T_checksum checksum = getChecksum(message); - - #ifdef TEST - *logofs << name() << ": Searching checksum [" - << DumpChecksum(checksum) << "] in repository.\n" - << logofs_flush; - - #endif - - pair result; - - result = checksums_ -> insert(T_checksums::value_type(checksum, position)); - - // - // Message was found in cache or - // insertion couldn't take place. - // - - if (result.second == 0) - { - if (result.first == checksums_ -> end()) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Failed to insert object " - << "in the cache.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to insert object of type " - << name() << " in the cache.\n"; - - return nothing; - } - - // - // Message is in cache. - // - - #ifdef TEST - *logofs << name() << ": Object is already in cache " - << "at position " << (result.first) -> second - << ".\n" << logofs_flush; - #endif - - #ifdef DEBUG - - printStorageSize(); - - #endif - - // - // Message is locked, probably because - // it has not completely recomposed at - // remote side after a split. - // - - if ((*messages_)[(result.first) -> second] -> locks_ != 0) - { - #ifdef TEST - *logofs << name() << ": WARNING! Object at position " - << (result.first) -> second << " is locked.\n" - << logofs_flush; - #endif - - locked = 1; - } - - // - // Object got a hit, so prevent - // its removal. - // - - if (lastRated == (result.first) -> second) - { - #ifdef TEST - *logofs << name() << ": Resetting rating of object " - << "at position " << (result.first) -> second - << ".\n" << logofs_flush; - #endif - - lastRated = nothing; - } - - return (result.first) -> second; - } - - #ifdef DEBUG - *logofs << name() << ": Could not find message in cache.\n" - << logofs_flush; - #endif - } - - // - // Message not found in hash table (or insertion - // of checksum in hash table was not requested). - // Message was added to cache. - // - - added = 1; - - // - // Log data about the missed message. - // - - #ifdef TEST - - if (opcode() == X_PutImage || opcode() == X_NXPutPackedImage) - { - #ifdef WARNING - *logofs << name() << ": WARNING! Dumping identity of " - << "missed image object of type " << name() - << ".\n" << logofs_flush; - #endif - - dumpIdentity(message); - } - - #endif - - if ((*messages_)[position] != NULL) - { - #ifdef DEBUG - *logofs << name() << ": The message replaces " - << "the old one at position " << position - << ".\n" << logofs_flush; - #endif - - remove(position, checksumAction, dataAction); - } - - (*messages_)[position] = message; - - // - // We used the slot. Perform a new - // search at next run. - // - - lastRated = nothing; - - #ifdef TEST - *logofs << name() << ": Stored message object of size " - << plainSize(position) << " (" << message -> size_ - << "/" << message -> c_size_ << ") at position " - << position << ".\n" << logofs_flush; - #endif - - unsigned int localSize; - unsigned int remoteSize; - - storageSize(message, localSize, remoteSize); - - localStorageSize_ += localSize; - remoteStorageSize_ += remoteSize; - - totalLocalStorageSize_ += localSize; - totalRemoteStorageSize_ += remoteSize; - - #ifdef DEBUG - - printStorageSize(); - - #endif - - // - // Set hits and timestamp at insertion in cache. - // - - message -> hits_ = control -> StoreHitsAddBonus; - message -> last_ = (getTimestamp()).tv_sec; - - message -> locks_ = 0; - - #ifdef DEBUG - *logofs << name() << ": Set last hit of object at " - << strMsTimestamp() << " with a bonus of " - << message -> hits_ << ".\n" << logofs_flush; - #endif - - return position; -} - -// -// Add a parsed message to repository. It is normally used -// at decoding side or at encoding side when we load store -// from disk. To handle messages coming from network, the -// encoding side uses the optimized method findOrAdd(). -// - -int MessageStore::add(Message *message, const int position, - T_checksum_action checksumAction, T_data_action dataAction) -{ - if (position < 0 || position >= cacheSlots) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Cannot add a message " - << "at non existing position " << position - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot add a message " - << "at non existing position " << position - << ".\n"; - - HandleAbort(); - } - - if ((*messages_)[position] != NULL) - { - #ifdef DEBUG - *logofs << name() << ": The message will replace " - << "the old one at position " << position - << ".\n" << logofs_flush; - #endif - - remove(position, checksumAction, dataAction); - } - - #ifdef DEBUG - *logofs << name() << ": Inserting object in repository at position " - << position << ".\n" << logofs_flush; - #endif - - (*messages_)[position] = message; - - // - // Get the object's checksum value - // and insert it in the table. - // - - if (checksumAction == use_checksum) - { - #ifdef DEBUG - *logofs << name() << ": Inserting object's checksum in repository.\n"; - #endif - - T_checksum checksum = getChecksum(message); - - checksums_ -> insert(T_checksums::value_type(checksum, position)); - } - - #ifdef DEBUG - *logofs << name() << ": Stored message object of size " - << plainSize(position) << " (" << message -> size_ - << "/" << message -> c_size_ << ") at position " - << position << ".\n" << logofs_flush; - #endif - - unsigned int localSize; - unsigned int remoteSize; - - storageSize(message, localSize, remoteSize); - - localStorageSize_ += localSize; - remoteStorageSize_ += remoteSize; - - totalLocalStorageSize_ += localSize; - totalRemoteStorageSize_ += remoteSize; - - #ifdef DEBUG - - printStorageSize(); - - #endif - - // - // Set hits and timestamp at insertion in cache. - // - - message -> hits_ = control -> StoreHitsAddBonus; - message -> last_ = (getTimestamp()).tv_sec; - - message -> locks_ = 0; - - #ifdef DEBUG - *logofs << name() << ": Set last hit of object at " - << strMsTimestamp() << " with a bonus of " - << message -> hits_ << ".\n" << logofs_flush; - #endif - - return position; -} - -// -// The following functions don't modify data, -// so they are supposed to be called only at -// the encoding side. -// - -void MessageStore::updateData(const int position, unsigned int dataSize, - unsigned int compressedDataSize) -{ - Message *message = (*messages_)[position]; - - validateSize(dataSize, compressedDataSize); - - if (compressedDataSize != 0) - { - unsigned int localSize; - unsigned int remoteSize; - - storageSize(message, localSize, remoteSize); - - localStorageSize_ -= localSize; - remoteStorageSize_ -= remoteSize; - - totalLocalStorageSize_ -= localSize; - totalRemoteStorageSize_ -= remoteSize; - - message -> c_size_ = compressedDataSize + message -> i_size_; - - #ifdef TEST - - if (message -> size_ != (int) (dataSize + message -> i_size_)) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Size of object looks " - << message -> size_ << " bytes while it " - << "should be " << dataSize + message -> i_size_ - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Size of object looks " - << message -> size_ << " bytes while it " - << "should be " << dataSize + message -> i_size_ - << ".\n"; - - HandleAbort(); - } - - #endif - - storageSize(message, localSize, remoteSize); - - localStorageSize_ += localSize; - remoteStorageSize_ += remoteSize; - - totalLocalStorageSize_ += localSize; - totalRemoteStorageSize_ += remoteSize; - - #ifdef DEBUG - - printStorageSize(); - - #endif - } -} - -void MessageStore::updateData(const T_checksum checksum, unsigned int compressedDataSize) -{ - #ifdef TEST - *logofs << name() << ": Searching checksum [" - << DumpChecksum(checksum) << "] in repository.\n" - << logofs_flush; - #endif - - T_checksums::iterator found = checksums_ -> find(checksum); - - if (found != checksums_ -> end()) - { - Message *message = (*messages_)[found -> second]; - - #ifdef TEST - *logofs << name() << ": Message found in cache at " - << "position " << found -> second << " with size " - << message -> size_ << " and compressed size " - << message -> c_size_ << ".\n" << logofs_flush; - #endif - - updateData(found -> second, message -> size_ - - message -> i_size_, compressedDataSize); - } - #ifdef TEST - else if (checksums_ -> size() > 0) - { - *logofs << name() << ": WARNING! Can't locate the " - << "checksum [" << DumpChecksum(checksum) - << "] for the update.\n" << logofs_flush; - } - #endif -} - -// -// This function replaces the data part of the message -// and updates the information about its size. Split -// messages are advertised to the decoding side with -// their uncompressed size, data is then compressed -// before sending the first chunk. This function is -// called by the decoding side after the split message -// is fully recomposed to replace the dummy data and -// set the real size. -// - -void MessageStore::updateData(const int position, const unsigned char *newData, - unsigned int dataSize, unsigned int compressedDataSize) -{ - Message *message = (*messages_)[position]; - - validateSize(dataSize, compressedDataSize); - - #ifdef TEST - - if (message -> size_ != (int) (dataSize + message -> i_size_)) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Data of object looks " - << dataSize << " bytes while it " << "should be " - << message -> size_ - message -> i_size_ - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Data of object looks " - << dataSize << " bytes while it " << "should be " - << message -> size_ - message -> i_size_ - << ".\n"; - - HandleAbort(); - } - - #endif - - // - // A compressed data size of 0 means that - // message's data was not compressed. - // - - if (compressedDataSize != 0) - { - unsigned int localSize; - unsigned int remoteSize; - - storageSize(message, localSize, remoteSize); - - localStorageSize_ -= localSize; - remoteStorageSize_ -= remoteSize; - - totalLocalStorageSize_ -= localSize; - totalRemoteStorageSize_ -= remoteSize; - - if (message -> c_size_ != (int) compressedDataSize + - message -> i_size_) - { - #ifdef TEST - *logofs << name() << ": Resizing data of message at " - << "position " << position << " from " << message -> - c_size_ << " to " << compressedDataSize + - message -> i_size_ << " bytes.\n" - << logofs_flush; - #endif - - message -> data_.clear(); - - message -> data_.resize(compressedDataSize); - } - - memcpy(message -> data_.begin(), newData, compressedDataSize); - - #ifdef TEST - *logofs << name() << ": Data of message at position " - << position << " has size " << message -> data_.size() - << " and capacity " << message -> data_.capacity() - << ".\n" << logofs_flush; - #endif - - message -> c_size_ = compressedDataSize + message -> i_size_; - - storageSize(message, localSize, remoteSize); - - localStorageSize_ += localSize; - remoteStorageSize_ += remoteSize; - - totalLocalStorageSize_ += localSize; - totalRemoteStorageSize_ += remoteSize; - - #ifdef DEBUG - - printStorageSize(); - - #endif - } - else - { - #ifdef TEST - *logofs << name() << ": No changes to data size for message " - << "at position " << position << ".\n" << logofs_flush; - #endif - - memcpy(message -> data_.begin(), newData, dataSize); - } -} - -int MessageStore::remove(const int position, T_checksum_action checksumAction, - T_data_action dataAction) -{ - Message *message; - - if (position < 0 || position >= cacheSlots || - (message = (*messages_)[position]) == NULL) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Cannot remove " - << "a non existing message at position " - << position << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot remove " - << "a non existing message at position " - << position << ".\n"; - - HandleAbort(); - } - - #if defined(TEST) || defined(INFO) - - if (opcode() == X_PutImage || opcode() == X_NXPutPackedImage) - { - #ifdef WARNING - *logofs << name() << ": WARNING! Discarding image object " - << "of type " << name() << " at position " - << position << ".\n" << logofs_flush; - #endif - } - - #endif - - // - // The checksum is only stored at the encoding - // side. - // - - if (checksumAction == use_checksum) - { - #ifdef DEBUG - *logofs << name() << ": Removing checksum for object at " - << "position " << position << ".\n" << logofs_flush; - #endif - - // - // TODO: If we had stored the iterator and - // not the pointer to the message, we could - // have removed the message without having - // to look up the checksum. - // - - T_checksum checksum = getChecksum(message); - - #ifdef TEST - *logofs << name() << ": Searching checksum [" - << DumpChecksum(checksum) << "] in repository.\n" - << logofs_flush; - #endif - - T_checksums::iterator found = checksums_ -> find(checksum); - - if (found == checksums_ -> end()) - { - #ifdef PANIC - *logofs << name() << ": PANIC! No checksum found for " - << "object at position " << position << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": No checksum found for " - << "object at position " << position << ".\n"; - - HandleAbort(); - } - - #ifdef TEST - - else if (position != found -> second) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Value of position for object " - << "doesn't match position " << position << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Value of position for object " - << "doesn't match position " << position << ".\n"; - - HandleAbort(); - } - - #endif - - checksums_ -> erase(found); - } - - #ifdef DEBUG - *logofs << name() << ": Removing message at position " - << position << " of size " << plainSize(position) - << " (" << message -> size_ << "/" << message -> c_size_ - << ").\n" << logofs_flush; - #endif - - unsigned int localSize; - unsigned int remoteSize; - - storageSize(message, localSize, remoteSize); - - localStorageSize_ -= localSize; - remoteStorageSize_ -= remoteSize; - - totalLocalStorageSize_ -= localSize; - totalRemoteStorageSize_ -= remoteSize; - - recycle(message); - - (*messages_)[position] = NULL; - - #ifdef DEBUG - - printStorageSize(); - - #endif - - return position; -} - -// -// This should only be called at encoding side. -// The decoding side can't rely on the counter -// as it is decremented by the encoding side -// every time the repository is searched for a -// message to be removed. -// - -int MessageStore::getRating(Message *message, T_rating type) const -{ - if (message -> locks_ != 0) - { - #ifdef TEST - *logofs << name() << ": Rate set to -1 as locks of object are " - << (int) message -> locks_ << ".\n" - << logofs_flush; - #endif - - return -1; - } - else if ((type == rating_for_clean || - (int) checksums_ -> size() == cacheSlots) && - message -> hits_ <= control -> StoreHitsLoadBonus) - { - // - // We don't have any free slot or we exceeded the - // available storage size. This is likely to happen - // after having loaded objects from persistent cache. - // It's not a bad idea to discard some messages that - // were restored but never referenced. - // - - #ifdef TEST - - if (type == rating_for_clean) - { - *logofs << name() << ": Rate set to 0 with hits " - << message -> hits_ << " as maximum storage size " - << "was exceeded.\n" << logofs_flush; - } - else - { - *logofs << name() << ": Rate set to 0 with hits " - << message -> hits_ << " as there are no available " - << "slots in store.\n" << logofs_flush; - } - - #endif - - return 0; - } - else if (type == rating_for_clean && - (getTimestamp()).tv_sec - message -> last_ >= - control -> StoreTimeLimit) - { - #ifdef TEST - *logofs << name() << ": Rate set to 0 as last hit of object was " - << (getTimestamp()).tv_sec - message -> last_ - << " seconds ago with limit set to " << control -> - StoreTimeLimit << ".\n" << logofs_flush; - #endif - - return 0; - } - else - { - #ifdef TEST - if (message -> hits_ < 0) - { - *logofs << name() << ": PANIC! Rate of object shouldn't be " - << message -> hits_ << ".\n" << logofs_flush; - - cerr << "Error" << ": Rate of object of type " << name() - << " shouldn't be " << message -> hits_ << ".\n"; - - HandleAbort(); - } - #endif - - #ifdef TEST - *logofs << name() << ": Rate of object is " << message -> hits_ - << " with last hit " << (getTimestamp()).tv_sec - - message -> last_ << " seconds ago.\n" - << logofs_flush; - #endif - - return message -> hits_; - } -} - -int MessageStore::touch(Message *message) const -{ - message -> last_ = (getTimestamp()).tv_sec; - - message -> hits_ += control -> StoreHitsTouch; - - if (message -> hits_ > control -> StoreHitsLimit) - { - message -> hits_ = control -> StoreHitsLimit; - } - - #ifdef TEST - *logofs << name() << ": Increased hits of object to " - << message -> hits_ << " at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - return message -> hits_; -} - -int MessageStore::untouch(Message *message) const -{ - message -> hits_ -= control -> StoreHitsUntouch; - - if (message -> hits_ < 0) - { - message -> hits_ = 0; - } - - #ifdef TEST - *logofs << name() << ": Decreased hits of object to " - << message -> hits_ << ".\n" - << logofs_flush; - #endif - - return message -> hits_; -} - -int MessageStore::lock(const int position) const -{ - Message *message = (*messages_)[position]; - - if (message == NULL) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Can't lock the null " - << "object at position " << position - << ".\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef DEBUG - *logofs << name() << ": Increasing locks of object to " - << (int) message -> locks_ + 1 << ".\n" - << logofs_flush; - #endif - - return ++(message -> locks_); -} - -int MessageStore::unlock(const int position) const -{ - Message *message = (*messages_)[position]; - - if (message == NULL) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Can't unlock the null " - << "object at position " << position - << ".\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef DEBUG - *logofs << name() << ": Decreasing locks of object to " - << (int) message -> locks_ - 1 << ".\n" - << logofs_flush; - #endif - - return --(message -> locks_); -} - -int MessageStore::saveStore(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient, T_checksum_action checksumAction, - T_data_action dataAction, int bigEndian) -{ - Message *message; - - #ifdef TEST - *logofs << name() << ": Opcode of this store is " - << (unsigned int) opcode() << " default size of " - << "identity is " << dataOffset << ".\n" - << logofs_flush; - #endif - - unsigned char *identityBuffer = new unsigned char[dataOffset]; - unsigned char *sizeBuffer = new unsigned char[4 * 2]; - unsigned char *positionBuffer = new unsigned char[4]; - unsigned char *opcodeBuffer = new unsigned char[4]; - - #ifdef DUMP - - char *md5ClientDump = new char[dataOffset * 2 + 128]; - - #endif - - unsigned char value; - - int offset; - - int failed = 0; - - for (int position = 0; position < cacheSlots; position++) - { - message = (*messages_)[position]; - - // - // Don't save split messages. - // - - if (message != NULL && message -> locks_ == 0) - { - // - // Use the total size if offset is - // beyond the real end of message. - // - - offset = dataOffset; - - if (offset > message -> size_) - { - offset = message -> size_; - } - - #ifdef TEST - *logofs << name() << ": Going to save message at position " - << position << ".\n" << logofs_flush; - #endif - - value = 1; - - PutULONG(position, positionBuffer, bigEndian); - PutULONG(opcode(), opcodeBuffer, bigEndian); - - md5_append(md5StateClient, positionBuffer, 4); - md5_append(md5StateClient, opcodeBuffer, 4); - - #ifdef DUMP - - *logofs << "Name=" << name() << logofs_flush; - - sprintf(md5ClientDump," Pos=%d Op=%d\n", position, opcode()); - - *logofs << md5ClientDump << logofs_flush; - - #endif - - if (PutData(cachefs, &value, 1) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure writing " << 1 - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, &value, 1); - - PutULONG(message -> size_, sizeBuffer, bigEndian); - PutULONG(message -> c_size_, sizeBuffer + 4, bigEndian); - - // - // Note that the identity size is not saved with - // the message and will be determined from the - // data read when restoring the identity. - // - - if (PutData(cachefs, sizeBuffer, 4 * 2) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure writing " << 4 * 2 - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, sizeBuffer, 4 * 2); - md5_append(md5StateClient, sizeBuffer, 4 * 2); - - #ifdef DUMP - - sprintf(md5ClientDump, "size = %d c_size = %d\n", - message -> size_, message -> c_size_); - - *logofs << md5ClientDump << logofs_flush; - - #endif - - // - // Prepare a clean buffer for unparse. - // - - CleanData(identityBuffer, offset); - - unparseIdentity(message, identityBuffer, offset, bigEndian); - - if (PutData(cachefs, identityBuffer, offset) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure writing " << offset - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, identityBuffer, offset); - md5_append(md5StateClient, identityBuffer, offset); - - #ifdef DUMP - - for (int i = 0; i < offset; i++) - { - sprintf(md5ClientDump + (i * 2), "%02X", identityBuffer[i]); - } - - *logofs << "Identity = " << md5ClientDump << "\n" << logofs_flush; - - #endif - - // - // Set the real identity size before - // saving the data. - // - - offset = message -> i_size_; - - if (offset > message -> size_) - { - offset = message -> size_; - } - - if (checksumAction == use_checksum) - { - if (PutData(cachefs, message -> md5_digest_, MD5_LENGTH) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure writing " << MD5_LENGTH - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, message -> md5_digest_, MD5_LENGTH); - } - else if (dataAction == use_data) - { - int dataSize = (message -> c_size_ == 0 ? - message -> size_ - offset : - message -> c_size_ - offset); - if (dataSize > 0) - { - if (PutData(cachefs, message -> data_.begin(), dataSize) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure writing " << dataSize - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, message -> data_.begin(), dataSize); - } - } - } - else - { - #ifdef TEST - *logofs << name() << ": Not saving message at position " - << position << ".\n" << logofs_flush; - #endif - - value = 0; - - if (PutData(cachefs, &value, 1) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure writing " << 1 - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, &value, 1); - } - } - - if (failed == 1) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Write to persistent cache file failed.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Write to persistent cache file failed.\n"; - } - - delete [] identityBuffer; - delete [] sizeBuffer; - delete [] positionBuffer; - delete [] opcodeBuffer; - - #ifdef DUMP - - delete [] md5ClientDump; - - #endif - - return (failed == 0 ? 1 : -1); -} - -int MessageStore::loadStore(istream *cachefs, md5_state_t *md5StateStream, - T_checksum_action checksumAction, T_data_action dataAction, - int bigEndian) -{ - Message *message; - - #ifdef TEST - *logofs << name() << ": Opcode of this store is " - << (unsigned int) opcode() << " default size of " - << "identity is " << dataOffset << " slots are " - << cacheSlots << ".\n" << logofs_flush; - #endif - - // - // If packed images or the render extension has been - // disabled we don't need to restore these messages - // in the cache. Encoding of RENDER in 1.4.0 is also - // changed so we want to skip messages saved using - // the old format. We want to restore all the other - // messages so we'll need to skip these one by one. - // - - int skip = 0; - - if ((opcode() == X_NXPutPackedImage && - control -> PersistentCacheLoadPacked == 0) || - (opcode() == X_NXInternalRenderExtension && - control -> PersistentCacheLoadRender == 0)) - { - #ifdef TEST - *logofs << name() << ": All messages for OPCODE#" - << (unsigned int) opcode() << " will be discarded.\n" - << logofs_flush; - #endif - - skip = 1; - } - - unsigned char *identityBuffer = new unsigned char[dataOffset]; - unsigned char *sizeBuffer = new unsigned char[4 * 2]; - - unsigned char value; - - int offset; - - int failed = 0; - - for (int position = 0; position < cacheSlots; position++) - { - if (GetData(cachefs, &value, 1) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure reading " << 1 - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, &value, 1); - - if (value == 1) - { - #ifdef TEST - *logofs << name() << ": Going to load message at position " - << position << ".\n" << logofs_flush; - #endif - - if (GetData(cachefs, sizeBuffer, 4 * 2) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure reading " << 4 * 2 - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, sizeBuffer, 4 * 2); - - message = getTemporary(); - - if (message == NULL) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Can't access temporary storage " - << "for message in context [B].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't access temporary storage " - << "for message in context [B].\n"; - - failed = 1; - - break; - } - - message -> size_ = GetULONG(sizeBuffer, bigEndian); - message -> c_size_ = GetULONG(sizeBuffer + 4, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Size is " << message -> size_ - << " compressed size is " << message -> c_size_ - << ".\n" << logofs_flush; - #endif - - // - // Use the total size if offset is - // beyond the real end of message. - // - - offset = dataOffset; - - if (offset > message -> size_) - { - offset = message -> size_; - } - - if (GetData(cachefs, identityBuffer, offset) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure reading " << offset - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, identityBuffer, offset); - - // - // Get the real identity size based on the value - // reported by the message store. The dataOffset - // value is guaranteed to be greater or equal to - // the maximum identity size of the messages in - // the major store. - // - - offset = identitySize(identityBuffer, offset); - - if (offset > message -> size_) - { - offset = message -> size_; - } - - message -> i_size_ = offset; - - // - // Get identity of message from the buffer we just - // created. Don't calculate neither checksum nor - // data, restore them from stream. Don't pass the - // message's size but the default size of identity. - // - - parseIdentity(message, identityBuffer, offset, bigEndian); - - if (checksumAction == use_checksum) - { - if (message -> md5_digest_ == NULL) - { - message -> md5_digest_ = new md5_byte_t[MD5_LENGTH]; - } - - if (GetData(cachefs, message -> md5_digest_, MD5_LENGTH) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure reading " << MD5_LENGTH - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - // - // Add message's checksum to checksum that will - // be saved together with this cache. Checksum - // will be verified when cache file is restored - // to ensure file is not corrupted. - // - - md5_append(md5StateStream, message -> md5_digest_, MD5_LENGTH); - - if (skip == 1) - { - #ifdef TEST - *logofs << name() << ": Discarding message for OPCODE#" - << (unsigned int) opcode() << ".\n" - << logofs_flush; - #endif - - continue; - } - } - else if (dataAction == use_data) - { - // - // Restore the data part. - // - - int dataSize = (message -> c_size_ == 0 ? - message -> size_ - offset : - message -> c_size_ - offset); - - if (dataSize < 0 || dataSize > control -> MaximumMessageSize) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Bad data size " - << dataSize << " loading persistent cache.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Bad data size " << dataSize - << " loading persistent cache.\n"; - - failed = 1; - - break; - } - else if (dataSize > 0) - { - // - // If need to skip the message let anyway - // it to be part of the calculated MD5. - // - - if (skip == 1) - { - unsigned char *dummy = new unsigned char[dataSize]; - - if (dummy == NULL) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Can't allocate dummy buffer " - << "of size " << dataSize << " loading cache.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate dummy buffer " - << "of size " << dataSize << " loading cache.\n"; - - failed = 1; - - break; - } - - if (GetData(cachefs, dummy, dataSize) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure reading " << dataSize - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - md5_append(md5StateStream, dummy, dataSize); - - delete [] dummy; - - #ifdef TEST - *logofs << name() << ": Discarding message for OPCODE#" - << (unsigned int) opcode() << ".\n" - << logofs_flush; - #endif - - continue; - } - else - { - message -> data_.clear(); - - message -> data_.resize(dataSize); - - if (GetData(cachefs, message -> data_.begin(), dataSize) < 0) - { - #ifdef DEBUG - *logofs << name() << ": PANIC! Failure reading " << dataSize - << " bytes.\n" << logofs_flush; - #endif - - failed = 1; - - break; - } - - // - // Add message's data to cache checksum. - // - - md5_append(md5StateStream, message -> data_.begin(), dataSize); - } - } - else - { - // - // We are here if data part is zero. - // - - if (skip == 1) - { - #ifdef TEST - *logofs << name() << ": Discarding message for OPCODE#" - << (unsigned int) opcode() << ".\n" - << logofs_flush; - #endif - - continue; - } - } - } - - int added; - - added = add(message, position, checksumAction, dataAction); - - if (added != position) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Can't store message " - << "in the cache at position " << position - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't store message " - << "in the cache at position " << position - << ".\n"; - - failed = 1; - - break; - } - else - { - // - // Replace default value of hits set by add - // function. Messages read from cache start - // with a lower bonus than fresh messages - // inserted. - // - - message -> hits_ = control -> StoreHitsLoadBonus; - - #ifdef DEBUG - *logofs << name() << ": Updated last hit of object at " - << strMsTimestamp() << " with a bonus of " - << message -> hits_ << ".\n" << logofs_flush; - #endif - - resetTemporary(); - } - } - else if ((*messages_)[position] != NULL) - { - #ifdef TEST - *logofs << name() << ": Going to remove message at position " - << position << ".\n" << logofs_flush; - #endif - - int removed; - - removed = remove(position, checksumAction, dataAction); - - if (removed != position) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Can't remove message from cache " - << "at position " << position << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't remove message from cache " - << "at position " << position << ".\n"; - - failed = 1; - - break; - } - } - #ifdef TEST - else - { - *logofs << name() << ": Not loading message at position " - << position << ".\n" << logofs_flush; - } - #endif - } - - #ifdef WARNING - - if (failed == 1) - { - *logofs << name() << ": WARNING! Read from persistent cache file failed.\n" - << logofs_flush; - } - - #endif - - delete [] identityBuffer; - delete [] sizeBuffer; - - return (failed == 0 ? 1 : -1); -} - -void MessageStore::storageSize(const Message *message, unsigned int &local, - unsigned int &remote) const -{ - local = remote = storage(); - - // - // Encoding side includes 48 bytes for - // the map of checksums and 24 bytes - // of adjustment for total overhead. - // - - local += MD5_LENGTH + 48 + 24; - - // - // At decoding side we include size of - // data part and 24 bytes of adjustment - // for total overhead. - // - - if (message -> c_size_ == 0) - { - remote += message -> size_ + 24; - } - else - { - remote += message -> c_size_ + 24; - } - - // - // Check if we are the encoding or the - // decoding side and, if needed, swap - // the values. - // - - if (message -> md5_digest_ == NULL) - { - unsigned int t = local; - - local = remote; - - remote = t; - } -} - -void MessageStore::printStorageSize() -{ - #ifdef TEST - - *logofs << name() << ": There are " - << checksums_ -> size() << " checksums in this store " - << "out of " << cacheSlots << " slots.\n" - << logofs_flush; - - *logofs << name() << ": Size of this store is " - << localStorageSize_ << " bytes at local side and " - << remoteStorageSize_ << " bytes at remote side.\n" - << logofs_flush; - - *logofs << name() << ": Size of total cache is " - << totalLocalStorageSize_ << " bytes at local side and " - << totalRemoteStorageSize_ << " bytes at remote side.\n" - << logofs_flush; - - #endif -} diff --git a/nxcomp/Message.h b/nxcomp/Message.h deleted file mode 100644 index 30883f101..000000000 --- a/nxcomp/Message.h +++ /dev/null @@ -1,1089 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Message_H -#define Message_H - -#include - -#include "NXproto.h" - -#include "Misc.h" -#include "Control.h" - -#include "Types.h" -#include "Timestamp.h" - -#include "ActionCache.h" - -#include "StaticCompressor.h" - -// -// Forward class declarations. -// - -class ChannelCache; - -class EncodeBuffer; -class DecodeBuffer; - -class WriteBuffer; - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Define this to know how many messages -// are allocated and deallocated. -// - -#undef REFERENCES - -// -// Set default values. We limit the maximum -// size of a request to 262144 but we need to -// consider the replies, whose size may be up -// to 4MB. -// - -#define MESSAGE_ENABLE_CACHE 0 -#define MESSAGE_ENABLE_DATA 0 -#define MESSAGE_ENABLE_SPLIT 0 -#define MESSAGE_ENABLE_COMPRESS 0 - -#define MESSAGE_DATA_LIMIT 4194304 - 4 -#define MESSAGE_DATA_OFFSET 4 - -#define MESSAGE_CACHE_SLOTS 6000 -#define MESSAGE_CACHE_THRESHOLD 50 -#define MESSAGE_CACHE_LOWER_THRESHOLD 5 - -// -// Base message class. -// - -class Message -{ - friend class MessageStore; - friend class RenderExtensionStore; - - public: - - Message() - { - hits_ = 0; - last_ = 0; - locks_ = 0; - - size_ = 0; - c_size_ = 0; - - md5_digest_ = NULL; - - #ifdef REFERENCES - - references_++; - - *logofs << "Message: Created new message at " - << this << " out of " << references_ - << " allocated messages.\n" - << logofs_flush; - - #endif - } - - Message(const Message &message) - { - size_ = message.size_; - c_size_ = message.c_size_; - i_size_ = message.i_size_; - - hits_ = message.hits_; - last_ = message.last_; - locks_ = message.locks_; - - data_ = message.data_; - - #ifdef REFERENCES - - references_++; - - *logofs << "Message: Creating new copied message at " - << this << " out of " << references_ - << " allocated messages.\n" - << logofs_flush; - #endif - - if (message.md5_digest_ != NULL) - { - md5_digest_ = new md5_byte_t[MD5_LENGTH]; - - memcpy(md5_digest_, message.md5_digest_, MD5_LENGTH); - - #ifdef DEBUG - *logofs << "Message: Created MD5 digest for object at " - << this << ".\n" << logofs_flush; - #endif - } - else - { - md5_digest_ = NULL; - } - } - - ~Message() - { - #ifdef DEBUG - if (md5_digest_ != NULL) - { - *logofs << "Message: Deleted MD5 digest for object at " - << this << ".\n" << logofs_flush; - } - #endif - - delete [] md5_digest_; - - #ifdef REFERENCES - - references_--; - - *logofs << "Message: Deleted message at " - << this << " out of " << references_ - << " allocated messages.\n" - << logofs_flush; - #endif - } - - // - // This is the original message size - // including the data part regardless - // data is still stored in the object. - // - - int size_; - - // - // This is the size of the identity. - // - - int i_size_; - - // - // This is the size, including identity, - // after message has been 'updated' to - // reflect storage of data in compressed - // format. - // - - int c_size_; - - protected: - - // - // This is the data part. - // - - T_data data_; - - // - // Time of last hit. - // - - time_t last_; - - // - // This is the number of cache hits - // registered for the object. - // - - short int hits_; - - // - // This is used to mark messages - // that have been split. - // - - short int locks_; - - // - // This is the MD5 checksum. - // - - md5_byte_t *md5_digest_; - - // - // Keep a reference counter - // of allocated objects. - // - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -// -// Repository of messages. -// - -class MessageStore -{ - public: - - // - // Enable or disable cache of messages in store. - // - - int enableCache; - - // - // Does message have a distinct data part. - // - - int enableData; - - // - // Enable or disable split of data part. - // - - int enableSplit; - - // - // Enable or disable compression of data part. - // - - int enableCompress; - - // - // Set starting point of data part in the message. - // - - int dataOffset; - - // - // Set maximum size for the data part of each message. - // - - int dataLimit; - - // - // Set maximum elements in cache. - // - - int cacheSlots; - - // - // Set the percentage of total cache memory which - // a given type of message is allowed to occupy. - // When threshold is exceeded store is cleaned to - // make room for a new message of the same type. - // - - int cacheThreshold; - - // - // Don't clean the store if percentage of cache - // memory occupied by messages of this type is - // below the threshold. - // - - int cacheLowerThreshold; - - // - // Last operation performed on cache. - // - - T_store_action lastAction; - - // - // Position of last element stored in cache. - // - - short int lastAdded; - - // - // Positions of last element found in cache. - // - - short int lastHit; - - // - // Position of last element erased. - // - - short int lastRemoved; - - // - // Used to encode the the action to - // perform on the store and the slot - // involved. - // - - ActionCache lastActionCache; - - // - // Position in cache where next insertion - // is going to take place. - // - - short int lastRated; - - // - // Constructors and destructors. - // - - public: - - MessageStore(StaticCompressor *compressor = NULL); - - virtual ~MessageStore(); - - virtual const char *name() const = 0; - - virtual unsigned char opcode() const = 0; - - virtual unsigned int storage() const = 0; - - // - // These are members that must be specialized. - // - - public: - - virtual Message *create() const = 0; - - virtual Message *create(const Message &message) const = 0; - - virtual void destroy(Message *message) const = 0; - - void validateSize(int size) - { - if (size < control -> MinimumMessageSize || - size > control -> MaximumMessageSize) - { - *logofs << name() << ": PANIC! Invalid size " << size - << " for message.\n" << logofs_flush; - - cerr << "Error" << ": Invalid size " << size - << " for message opcode " << opcode() << ".\n"; - - HandleAbort(); - } - } - - void validateSize(int dataSize, int compressedDataSize) - { - if (dataSize < 0 || dataSize > control -> - MaximumMessageSize - 4 || compressedDataSize < 0 || - compressedDataSize >= dataSize) - { - *logofs << name() << ": PANIC! Invalid data size " - << dataSize << " and compressed data size " - << compressedDataSize << " for message.\n" - << logofs_flush; - - cerr << "Error" << ": Invalid data size " - << dataSize << " and compressed data size " - << compressedDataSize << " for message " - << "opcode " << (unsigned) opcode() << ".\n"; - - HandleAbort(); - } - } - - // - // Determine if the message can be stored - // in the cache. - // - - virtual int validateMessage(const unsigned char *buffer, int size) - { - return (size >= control -> MinimumMessageSize && - size <= control -> MaximumMessageSize); - } - - // - // Get data offset based on major and minor - // opcode of the message. - // - - virtual int identitySize(const unsigned char *buffer, unsigned int size) - { - return dataOffset; - } - - // - // Encode identity and data using the - // specific message encoding. - // - // Some messages do not implement these - // methods because the encoding is done - // directly in the channel loop. Should - // move the encoding methods in in the - // message classes. - // - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const - { - return 1; - } - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const - { - return 1; - } - - // - // Encode differences between message - // in cache and the one to be encoded. - // - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, ChannelCache *channelCache) const - { - } - - // - // Decode differences and update the - // cached version of the same message. - // - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const - { - } - - // - // Post process the message information - // contained in the store by either up- - // dating the size record or the actual - // data part once the message has been - // completely sent to our peer. - // - - void updateData(const int position, unsigned int dataSize, - unsigned int compressedDataSize); - - void updateData(const T_checksum checksum, unsigned int compressedDataSize); - - void updateData(const int position, const unsigned char *newData, - unsigned int dataSize, unsigned int compressedDataSize); - - // - // These members, used internally - // in the message store class, are - // mandatory. - // - - protected: - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const = 0; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const = 0; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const = 0; - - virtual void dumpIdentity(const Message *message) const = 0; - - // - // Design should preserve these from being - // virtual. - // - - int parseData(Message *message, int split, const unsigned char *buffer, - unsigned int size, T_checksum_action checksumAction, - T_data_action dataAction, int bigEndian); - - int parseData(Message *message, const unsigned char *buffer, - unsigned int size, const unsigned char *compressedData, - const unsigned int compressedDataSize, T_checksum_action checksumAction, - T_data_action dataAction, int bigEndian); - - int unparseData(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian); - - // - // Manage efficient allocation of messages - // in the heap. - // - - void recycle(Message *message) - { - #ifdef TEST - - if (message == NULL) - { - *logofs << name() << ": PANIC! Cannot recycle a null message.\n" - << logofs_flush; - - cerr << "Error" << ": Cannot recycle a null message.\n"; - - HandleAbort(); - } - - #endif - - if (temporary_ == NULL) - { - // - // Be careful when reusing the message as - // it can contain valid data that must be - // explicitly deallocated if not needed. - // Note also that you cannot count on the - // initialization made in costructor. - // - - temporary_ = message; - } - else - { - destroy(message); - } - } - - void beginChecksum(Message *message) - { - if (message -> md5_digest_ == NULL) - { - message -> md5_digest_ = new md5_byte_t[MD5_LENGTH]; - - #ifdef DEBUG - *logofs << name() << ": Created MD5 digest structure " - << "for object at " << message << ".\n" - << logofs_flush; - #endif - } - #ifdef DEBUG - else - { - *logofs << name() << ": Using existing MD5 digest structure " - << "for object at " << message << ".\n" - << logofs_flush; - } - #endif - - #ifdef DEBUG - *logofs << name() << ": Prepared MD5 digest for object at " - << message << ".\n" << logofs_flush; - #endif - - md5_init(md5_state_); - } - - void endChecksum(Message *message) - { - md5_finish(md5_state_, message -> md5_digest_); - - #ifdef DEBUG - *logofs << name() << ": Calculated checksum for object at " - << message << ".\n" << logofs_flush; - #endif - } - - void dataChecksum(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) - { - // - // Messages that have a data part starting - // at an offset possibly beyond the end of - // the message, must include the size in - // the identity checksum. - // - - if ((int) size > message -> i_size_) - { - md5_append(md5_state_, buffer + message -> i_size_, - size - message -> i_size_); - } - } - - // - // Repository handling methods. - // - - public: - - // - // Extract identity and data from buffer. - // The size field will be updated at the - // time of data parsing. - // - - int parse(Message *message, int split, const unsigned char *buffer, unsigned int size, - T_checksum_action checksumAction, T_data_action dataAction, int bigEndian); - - int parse(Message *message, const unsigned char *buffer, unsigned int size, - const unsigned char *compressedData, const unsigned int compressedDataSize, - T_checksum_action checksumAction, T_data_action dataAction, int bigEndian); - - // - // From identity and data write the - // final message to the raw buffer. - // - - int unparse(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) - { - return (unparseData(message, buffer, size, bigEndian) && - unparseIdentity(message, buffer, size, bigEndian)); - } - - void dump(const Message *message) const - { - dumpIdentity(message); - - dumpData(message); - } - - void dumpData(const Message *message) const; - - // - // This returns the original message size as it - // was received on the link. It takes in account - // the data part, regardless data is still stored - // in the message object. This information will - // be used at the time message is unparsed. - // - - int plainSize(const int position) const - { - return (*messages_)[position] -> size_; - } - - // - // This returns either the size of identity plus - // the compressed data part or 0 if message is - // stored in uncompressed format. - // - - int compressedSize(const int position) const - { - return (*messages_)[position] -> c_size_; - } - - // - // Returns a pointer to message - // given its position in cache. - // - - Message *get(const int position) const - { - if (position < 0 || position >= cacheSlots) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Requested position " - << position << " is not inside the " - << "container.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Requested position " - << position << " is not inside the" - << "container.\n"; - - HandleAbort(); - } - else if ((*messages_)[position] == NULL) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Message at position " - << position << " is NULL.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Message at position " - << position << " is NULL.\n"; - - HandleAbort(); - } - - return (*messages_)[position]; - } - - // - // This is the method called at encoding - // side to add a message to cache. - // - - int findOrAdd(Message *message, T_checksum_action checksumAction, - T_data_action dataAction, int &added, int &locked); - - // - // Utility interfaces to message insertion - // and deletion. - // - - int add(Message *message, const int position, - T_checksum_action checksumAction, T_data_action dataAction); - - int remove(const int position, T_checksum_action checksumAction, - T_data_action dataAction); - - // - // Make space in the repository by remove - // the first suitable message object. - // - - int clean(T_checksum_action checksumAction); - - // - // Increase or decrease the "rating" of - // the message object. - // - - int touch(Message *message) const; - int untouch(Message *message) const; - - int getTouches(const int position) const - { - Message *message = (*messages_)[position]; - - if (message == NULL) - { - return 0; - } - - return message -> hits_; - } - - // - // Gives a 'weight' to the cached message. A zero - // value means object can be safely removed. A value - // greater than zero means it is advisable to retain - // the object. A negative result means it is mandato- - // ry to keep object in cache. - // - - int getRating(Message *message, T_rating type) const; - - // - // Increase or decrease locks of message at given - // position. A locked message will not be removed - // from the message store until the lock counter - // is zero. - // - - int lock(const int position) const; - int unlock(const int position) const; - - int getLocks(const int position) const - { - Message *message = (*messages_)[position]; - - if (message == NULL) - { - return 0; - } - - return message -> locks_; - } - - T_checksum const getChecksum(const int position) const - { - return getChecksum(get(position)); - } - - T_checksum const getChecksum(const Message *message) const - { - if (message -> md5_digest_ == NULL) - { - #ifdef PANIC - *logofs << name() << ": PANIC! Checksum not initialized " - << "for object at " << message << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Checksum not initialized " - << "for object at " << message << ".\n"; - - HandleAbort(); - } - - #ifdef DEBUG - *logofs << name() << ": Got checksum for object at " - << message << ".\n" << logofs_flush; - #endif - - return message -> md5_digest_; - } - - // - // Calculate the checksum on the fly based the - // opcode in the buffer. Useful in the case a - // message was not processed or was not stored - // in the cache. The returned checksum must be - // explicitly deallocated by the caller, after - // use. - // - - T_checksum getChecksum(const unsigned char *buffer, - unsigned int size, int bigEndian); - - const unsigned char *getData(const Message *message) const - { - return message -> data_.begin(); - } - - int plainSize(const Message *message) const - { - return message -> size_; - } - - int identitySize(Message *message) - { - return message -> i_size_; - } - - int compressedSize(const Message *message) const - { - return message -> c_size_; - } - - Message *getTemporary() - { - if (temporary_ == NULL) - { - temporary_ = create(); - } - - return temporary_; - } - - void resetTemporary() - { - temporary_ = NULL; - } - - // - // On side where we don't have checksums, we - // count how many messages are in the array. - // This is obviously expensive and should be - // only performed when reporting statistics. - // - - int getSize() const - { - int size = checksums_ -> size(); - - if (size == 0) - { - for (int i = 0; i < cacheSlots; i++) - { - if ((*messages_)[i] != NULL) - { - size++; - } - } - } - - return size; - } - - int getLocalStorageSize() const - { - return localStorageSize_; - } - - int getRemoteStorageSize() const - { - return remoteStorageSize_; - } - - int getLocalTotalStorageSize() const - { - return totalLocalStorageSize_; - } - - int getRemoteTotalStorageSize() const - { - return totalRemoteStorageSize_; - } - - static int getCumulativeTotalStorageSize() - { - return (totalLocalStorageSize_ > totalRemoteStorageSize_ ? - totalLocalStorageSize_ : totalRemoteStorageSize_); - } - - int saveStore(ostream *cachefs, md5_state_t *md5_state_stream, - md5_state_t *md5_state_client, T_checksum_action checksumAction, - T_data_action dataAction, int bigEndian); - - int loadStore(istream *cachefs, md5_state_t *md5_state_stream, - T_checksum_action checksumAction, T_data_action dataAction, - int bigEndian); - - protected: - - // - // Estimate the memory requirements of given - // instance of message. Size includes memory - // allocated from heap to store checksum and - // data. - // - - void storageSize(const Message *message, unsigned int &local, - unsigned int &remote) const; - - // - // Just used for debug. - // - - void printStorageSize(); - - // - // Repositories where to save cached messages. - // First is a vector of pointers, the second - // is a hash table used for fast lookups. - // - - T_messages *messages_; - T_checksums *checksums_; - - // - // A message object to be used as a temporary. - // Reuse the temporary object if possible, if - // not, create a new instance. - // - - Message *temporary_; - - // - // Used to calculate message's checksum. - // - - md5_state_t *md5_state_; - - private: - - // - // Used to compress data payload. - // - - StaticCompressor *compressor_; - - // - // Keep track of how many bytes - // are taken by cache. - // - - int localStorageSize_; - int remoteStorageSize_; - - static int totalLocalStorageSize_; - static int totalRemoteStorageSize_; - - // - // Used to track object allocation and deallocation. - // - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -// -// This is an ancillary class of the message -// store, used to encode extensions based on -// the minor opcode. -// - -class MinorMessageStore -{ - public: - - virtual ~MinorMessageStore() - { - } - - virtual const char *name() const = 0; - - virtual int identitySize(const unsigned char *buffer, unsigned int size) = 0; - - virtual int encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const - { - return 1; - } - - virtual int decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, unsigned char type, int bigEndian, - WriteBuffer *writeBuffer, ChannelCache *channelCache) const - { - return 1; - } - - virtual void encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const - { - } - - virtual void decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const - { - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const = 0; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const = 0; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const - { - } - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const - { - } - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, md5_state_t *md5_state, - int bigEndian) const = 0; -}; - -#endif /* Message_H */ - diff --git a/nxcomp/Misc.cpp b/nxcomp/Misc.cpp deleted file mode 100644 index 09a0b29d2..000000000 --- a/nxcomp/Misc.cpp +++ /dev/null @@ -1,1930 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include - -#include "NXproto.h" - -#include "MD5.h" - -#include "Misc.h" -#include "Proxy.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#define OPCODES -#undef TEST -#undef DEBUG - -// -// By default nxproxy binds to all network interfaces, setting -// DEFAULT_LOOPBACK_BIND to 1 enables binding to the loopback -// device only. -// - -const int DEFAULT_LOOPBACK_BIND = 0; - -// -// TCP port offset applied to any NX port specification. -// - -const int DEFAULT_NX_PROXY_PORT_OFFSET = 4000; - -// -// Default TCP port used by client proxy to listen to -// X clients and by server proxy to connect to remote. -// - -const int DEFAULT_NX_PROXY_PORT = 8; - -// -// Default X display number that client proxy imitates. -// - -const int DEFAULT_NX_X_PORT = 8; - -// -// Default ports used for listening for cups, samba, http, -// multimedia and auxiliary X connections. Arbitrary ports -// can be used by passing the service's port at the proxy -// startup. By default ports are determined by adding the -// offset below to the offset of the proxied display. For -// example, if the proxy is impersonating the display :8, -// SMB tunnels can be created by connecting to port 3008. -// -// Considering that the NX server uses to start the first -// session at display offset 1000, we must lower the CUPS -// and SMB ports to avoid interference with normal X ses- -// sions run on the server. -// -// Font server connections are used to let the X server on -// the client connect to a font server on the NX server. -// -// Slave channels can be originated by both sides so we need -// different offsets in the case the user runs both proxies -// on the same host. -// - -const int DEFAULT_NX_CUPS_PORT_OFFSET = 2000; -const int DEFAULT_NX_SMB_PORT_OFFSET = 3000; -const int DEFAULT_NX_MEDIA_PORT_OFFSET = 7000; -const int DEFAULT_NX_AUX_PORT_OFFSET = 8000; -const int DEFAULT_NX_HTTP_PORT_OFFSET = 9000; -const int DEFAULT_NX_FONT_PORT_OFFSET = 10000; - -const int DEFAULT_NX_SLAVE_PORT_CLIENT_OFFSET = 11000; -const int DEFAULT_NX_SLAVE_PORT_SERVER_OFFSET = 12000; - -// -// Usage info and copyright. -// - -static const char UsageInfo[] = -"\n\ - Usage: nxproxy [OPTIONS] host:port\n\ -\n\ - -C Specify that nxproxy has to run on the 'X client'\n\ - side, listening for connections and impersonating\n\ - an X server.\n\ -\n\ - -S Specify that nxproxy has to run in 'X server' mode,\n\ - thus forwarding the connections to daemons running\n\ - on the client.\n\ -\n\ - -h Print this message.\n\ -\n\ - -v Print version information.\n\ -\n\ - host:port Put at the end, specifies the host and port of the\n\ - listening proxy.\n\ -\n\ - name=value Set the NX option to the provided value.\n\ -\n\ - Multiple NX options can be specified in the DISPLAY environment\n\ - or on the command line, by using the nx/nx,option=value notation.\n\ -\n\ - Options:\n\ -\n\ - link=s An indication of the link speed that is going to be\n\ - used between the proxies. Usually the compression\n\ - and the other link parameters depend on this setting.\n\ - The value can be either 'modem', 'isdn', 'adsl',\n\ - 'wan', 'lan', 'local' or a bandwidth specification,\n\ - like for example '56k', '1m', '100m', etc.\n\ -\n\ - type=s Type of session, for example 'windows', 'unix-kde'.\n\ - 'unix-application', etc.\n\ -\n\ - display=s Specify the real display where X connections have\n\ - to be forwarded by the proxy running on the client.\n\ -\n\ - listen=n Local port used for accepting the proxy connection.\n\ -\n\ - loopback=b Bind to the loopback device only.\n\ -\n\ - accept=s Name or IP of host that can connect to the proxy.\n\ -\n\ - connect=s Name or IP of host that the proxy will connect to.\n\ -\n\ - port=n Remote port used for the connection.\n\ -\n\ - retry=n Number of connection atempts.\n\ -\n\ - root=s The root directory for the session. Usually is the\n\ - C-* or S-* in the .nx directory in the user's home,\n\ - with '*' being the virtual display.\n\ -\n\ - session=s Name of the session file. The default is the name\n\ - 'session' in the session directory.\n\ -\n\ - errors=s Name of the log file used by the proxy. The default\n\ - is the name 'errors' in the session directory.\n\ -\n\ - stats=s Name of the file where are written the proxy stat-\n\ - istics. The default is a file 'stats' in the session\n\ - directory. The proxy replaces the data in the file\n\ - whenever it receives a SIGUSR1 or SIGUSR2 signal:\n\ -\n\ - SIGUSR1 Gives total statistics, i.e. statistics\n\ - collected since the beginning of the\n\ - session.\n\ -\n\ - SIGUSR2 Gives partial statistics, i.e. statist-\n\ - ics collected since the last time this\n\ - signal was received.\n\ -\n\ - cookie=s Use the provided cookie for authenticating to the\n\ - remote proxy. The same cookie is used as the fake\n\ - value used for the X authorization. The fake cookie\n\ - is replaced on the X server side with the real cookie\n\ - to be used for the display, so that the real cookie\n\ - doesn't have to travel over the net. When not using\n\ - a proxy cookie, any host will be able to connect to\n\ - the proxy. See also the 'accept' parameter.\n\ -\n\ - nodelay=b A boolean indicating if TCP_NODELAY has to be set\n\ - on the proxy link. Old Linux kernels had problems\n\ - with handling TCP_NODELAY on PPP links.\n\ -\n\ - policy=b Let or not the agent decide when it is the best time\n\ - to flush the proxy link. If set to 0, the proxy will\n\ - flush any encoded data immediately. The option has\n\ - only effect on the X client side proxy.\n\ -\n\ - render=b Enable or disable use of the RENDER extension.\n\ -\n\ - taint=b Try to suppress trivial sources of X roundtrips by\n\ - generating the reply on the X client side.\n\ -\n\ - delta=b Enable X differential compression.\n\ -\n\ - data=n Enable or disable the ZLIB data compression. It is\n\ - possible to specify a value between 0 and 9. Usual-\n\ - ly the value is chosen automatically based on the\n\ - requested link setting.\n\ -\n\ - stream=n Enable or disable the ZLIB stream compression. The\n\ - value, between 0 and 9, is usually determined accor-\n\ - ding to the requested link setting.\n\ -\n\ - limit=n Specify a bitrate limit allowed for this session.\n\ -\n\ - memory=n Trigger memory optimizations used to keep small the\n\ - size of X buffers. This is useful on embedded plat-\n\ - forms, or where memory is scarce.\n\ -\n\ - cache=n Size of the in-memory X message cache. Setting the\n\ - value to 0 will disable the memory cache as well\n\ - as the NX differential compression.\n\ -\n\ - images=n Size of the persistent image cache.\n\ -\n\ - shseg=n Enable the use of the MIT-SHM extension between the\n\ - NX client proxy and the real X server. A value greater\n\ - than 1 is assumed to be the size of requested shared\n\ - memory segment. By default, the size of the segment is\n\ - determined based on the size of the in-memory cache.\n\ -\n\ - load=b Enable loading a persistent X message cache at the\n\ - proxy startup.\n\ -\n\ - save=b Enable saving a persistent X message cache at the\n\ - end of session.\n\ -\n\ - cups=n Enable or disable forwarding of CUPS connections,\n\ - by listening on the optional port 'n'.\n\ -\n\ - aux=n Enable or disable forwarding of the auxiliary X chan-\n\ - nel used for controlling the keyboard. The 'keybd=n'\n\ - form is accepted for backward compatibility.\n\ -\n\ - smb=n Enable or disable forwarding of SMB connections. The\n\ - 'samba=n' form is accepted for backward compatibility.\n\ -\n\ - media=n Enable forwarding of audio connections.\n\ -\n\ - http=n Enable forwarding of HTTP connections.\n\ -\n\ - font=n Enable forwarding of reversed connections to a font\n\ - server running on the NX server.\n\ -\n\ - file=n Enable forwarding of file transfer connections.\n\ -\n\ - mask=n Determine the distribution of channel ids between the\n\ - proxies. By default, channels whose ids are multiple\n\ - of 8 (starting from 0) are reserved for the NX client\n\ - side. All the other channels can be allocated by the\n\ - NX server side.\n\ -\n\ - timeout=t Specify the keep-alive timeout used by proxies to\n\ - determine if there is a network problem preventing\n\ - communication with the remote peer. A value of 0\n\ - disables the check.\n\ -\n\ - cleanup=t Specify the number of seconds the proxy has to wait\n\ - at session shutdown before closing all channels.\n\ - The feature is used by the NX server to ensure that\n\ - services are disconnected before shutting down the\n\ - link.\n\ -\n\ - pack=s Determine the method used to compress images.\n\ -\n\ - product=s The product id of the client or server. The value is\n\ - ignored by the proxy, but the client or server can\n\ - provide it to facilitate the support.\n\ -\n\ - core=b Enable production of core dumps when aborting the\n\ - proxy connection.\n\ -\n\ - options=s Specify an additional file containing options that\n\ - has to be merged with option read from the command\n\ - line or the environment.\n\ -\n\ - kill=n Add the given process to the list of daemons that\n\ - must be terminated at session shutdown. Multiple\n\ - 'kill=n' options can be specified. The proxy will\n\ - send them a SIGTERM signal just before exiting.\n\ -\n\ - strict=b Optimize for responsiveness, rather than for the best\n\ - use of all the available bandwidth.\n\ -\n\ - encryption=b Should be set to 1 if the proxy is running as part of\n\ - a program providing encryption of the point to point\n\ - communication.\n\ -\n\ -rootless=b\n\ -geometry=s\n\ -resize=b\n\ -fullscreen=b\n\ -keyboard=s\n\ -clipboard=s\n\ -streaming=n\n\ -backingstore=n\n\ -composite=n\n\ -xinerama=n\n\ -shmem=b\n\ -shpix=b\n\ -kbtype=s\n\ -client=s\n\ -shadow=n\n\ -shadowuid=n\n\ -shadowmode=s\n\ -defer=n\n\ -tile=s\n\ -menu=n\n\ -sleep=n\n\ -tolerancechecks=s\n\ - These options are interpreted by the NX agent. They\n\ - are ignored by the proxy.\n\ -\n\ - Environment:\n\ -\n\ - NX_ROOT The root NX directory is the place where the session\n\ - directory and the cache files are created. This is\n\ - usually overridden by passing the 'root=' option. By\n\ - default, the root NX directory is assumed to be the\n\ - directory '.nx' in the user's home.\n\ -\n\ - NX_SYSTEM The directory where NX programs and libraries reside.\n\ - If not set, the value is assumed to be '/usr/NX'.\n\ - Programs, libraries and data files are respectedly\n\ - searched in the 'bin', 'lib' and 'share' subdirecto-\n\ - ries.\n\ -\n\ - NX_HOME The NX user's home directory. If NX_ROOT is not set\n\ - or invalid, the user's NX directory is created here.\n\ -\n\ - NX_TEMP The directory where the X11 Unix Domain Sockets and\n\ - all temporary files are to be created.\n\ -\n\ - NX_CLIENT The full path to the nxclient executable. If the va-\n\ - riable is not set, the nxclient executable will be\n\ - run assuming that the program is in the system path.\n\ - This can be useful on platforms like Windows and the\n\ - Mac where nxclient is located in a different direct-\n\ - ory compared to the other programs, to make easier\n\ - for the user to execute the program from the shell.\n\ -\n\ - NX_SLAVE_CMD The full path to the slave channel handler. When the\n\ - slave channel is enabled, the agent will listen on a\n\ - port and forward the connection to the NX_SLAVE_CMD\n\ - program. This can be used to implement agent/proxy\n\ - communication for applications such as serial port and\n\ - USB forwarding.\n\ -\n\ - Shell environment:\n\ -\n\ - HOME The variable is checked in the case NX_HOME is not\n\ - set, null or invalid.\n\ -\n\ - TEMP The variable is checked whenever the NX_TEMP direct-\n\ - ory is not set, null or invalid.\n\ -\n\ - PATH The path where all executables are searched, except\n\ - nxclient. If NX_CLIENT is not set, also the client\n\ - executable is searched in the system path.\n\ -\n\ - LD_LIBRARY_PATH\n\ - System-wide library search order. This should be set\n\ - by the program invoking the proxy.\n\ -\n\ - DISPLAY On the X server side, the DISPLAY variable indicates\n\ - the location of the X11 server. When nxcomp is used\n\ - as a transport library, the DISPLAY may represent a\n\ - NX transport specification and options can passed in\n\ - the form nx/nx,option=value...\n\ -\n\ - XAUTHORITY This is the file containing the X11 authorization\n\ - cookie. If not set, the file is assumed to be in\n\ - the user's home (either NX_HOME or HOME).\n\ -\n\ -"; - -const char *GetUsageInfo() -{ - return UsageInfo; -} - -static const char CopyrightInfo[] = -"\ -Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com)\n\ -Copyright (c) 2008-2014 Oleksandr Shneyder \n\ -Copyright (c) 2014-2016 Ulrich Sibiller \n\ -Copyright (c) 2014-2016 Mihai Moldovan \n\ -Copyright (c) 2011-2016 Mike Gabriel \n\ -Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com)\n\ -\n\ -NXCOMP, NX protocol compression and NX extensions to this software\n\ -are copyright of the aforementioned persons and companies.\n\ -\n\ -Redistribution and use of the present software is allowed according\n\ -to terms specified in the file LICENSE.nxcomp which comes in the\n\ -source distribution.\n\ -\n\ -All rights reserved.\n\ -\n\ -NOTE: This software has received contributions from various other\n\ -contributors, only the core maintainers and supporters are listed as\n\ -copyright holders. Please contact us, if you feel you should be listed\n\ -as copyright holder, as well.\n\ -"; - -const char *GetCopyrightInfo() -{ - return CopyrightInfo; -} - -static const char OtherCopyrightInfo[] = -"\ -NX protocol compression is derived from DXPC project.\n\ -\n\ -Copyright (c) 1995,1996 Brian Pane\n\ -Copyright (c) 1996,1997 Zachary Vonler and Brian Pane\n\ -Copyright (c) 1999 Kevin Vigor and Brian Pane\n\ -Copyright (c) 2000,2003 Gian Filippo Pinzari and Brian Pane\n\ -\n\ -All rights reserved.\n\ -"; - -const char *GetOtherCopyrightInfo() -{ - return OtherCopyrightInfo; -} - -int _hostBigEndian = 0; -int _storeBigEndian = 0; - -const unsigned int IntMask[33] = -{ - 0x00000000, - 0x00000001, - 0x00000003, - 0x00000007, - 0x0000000f, - 0x0000001f, - 0x0000003f, - 0x0000007f, - 0x000000ff, - 0x000001ff, - 0x000003ff, - 0x000007ff, - 0x00000fff, - 0x00001fff, - 0x00003fff, - 0x00007fff, - 0x0000ffff, - 0x0001ffff, - 0x0003ffff, - 0x0007ffff, - 0x000fffff, - 0x001fffff, - 0x003fffff, - 0x007fffff, - 0x00ffffff, - 0x01ffffff, - 0x03ffffff, - 0x07ffffff, - 0x0fffffff, - 0x1fffffff, - 0x3fffffff, - 0x7fffffff, - 0xffffffff -}; - -unsigned int GetUINT(unsigned const char *buffer, int bigEndian) -{ - // - // It doesn't work on SPARCs if the buffer - // is not aligned to the word boundary. We - // should check the CPU, not the OS as this - // surely applies to other architectures. - // - - #ifndef __sun - - if (_hostBigEndian == bigEndian) - { - return *((unsigned short *) buffer); - } - - #else - - if (_hostBigEndian == bigEndian && ((unsigned int) buffer) & 0x1 == 0) - { - return *((unsigned short *) buffer); - } - - #endif - - unsigned int result; - - if (bigEndian) - { - result = *buffer; - - result <<= 8; - - result += buffer[1]; - } - else - { - result = buffer[1]; - - result <<= 8; - - result += *buffer; - } - - return result; -} - -unsigned int GetULONG(unsigned const char *buffer, int bigEndian) -{ - // - // It doesn't work on SPARCs if the buffer - // is not aligned to word the boundary. - // - - #ifndef __sun - - if (_hostBigEndian == bigEndian) - { - return *((unsigned int *) buffer); - } - - #else - - if (_hostBigEndian == bigEndian && ((unsigned int) buffer) & 0x3 == 0) - { - return *((unsigned int *) buffer); - } - - #endif - - const unsigned char *next = (bigEndian ? buffer : buffer + 3); - - unsigned int result = 0; - - for (int i = 0; i < 4; i++) - { - result <<= 8; - - result += *next; - - if (bigEndian) - { - next++; - } - else - { - next--; - } - } - - return result; -} - -void PutUINT(unsigned int value, unsigned char *buffer, int bigEndian) -{ - if (_hostBigEndian == bigEndian) - { - *((unsigned short *) buffer) = value; - - return; - } - - if (bigEndian) - { - buffer[1] = (unsigned char) (value & 0xff); - - value >>= 8; - - *buffer = (unsigned char) value; - } - else - { - *buffer = (unsigned char) (value & 0xff); - - value >>= 8; - - buffer[1] = (unsigned char) value; - } -} - -void PutULONG(unsigned int value, unsigned char *buffer, int bigEndian) -{ - if (_hostBigEndian == bigEndian) - { - *((unsigned int *) buffer) = value; - - return; - } - - if (bigEndian) - { - buffer += 3; - - for (int i = 4; i > 0; i--) - { - *buffer-- = (unsigned char) (value & 0xff); - - value >>= 8; - } - } - else - { - for (int i = 4; i > 0; i--) - { - *buffer++ = (unsigned char) (value & 0xff); - - value >>= 8; - } - } -} - -int CheckData(istream *fs) -{ - if (fs == NULL || fs -> fail()) - { - return -1; - } - - return 1; -} - -int CheckData(ostream *fs) -{ - if (fs == NULL || fs -> fail()) - { - return -1; - } - - return 1; -} - -int PutData(ostream *fs, const unsigned char *buffer, int size) -{ - fs -> write((char *) buffer, size); - - #ifdef DEBUG - *logofs << "PutData: Written " << size << " bytes with eof " - << fs -> eof() << " fail " << fs -> fail() << " and bad " - << fs -> bad() << ".\n" << logofs_flush; - #endif - - if (fs -> fail()) - { - return -1; - } - - return size; -} - -int GetData(istream *fs, unsigned char *buffer, int size) -{ - fs -> read((char *) buffer, size); - - #ifdef DEBUG - *logofs << "GetData: Read " << size << " bytes with eof " - << fs -> eof() << " fail " << fs -> fail() - << " and bad " << fs -> bad() << ".\n" - << logofs_flush; - #endif - - #ifdef __APPLE__ - - if (fs -> bad()) - { - return -1; - } - - #else - - if (fs -> fail()) - { - return -1; - } - - #endif - - return size; -} - -int FlushData(ostream *fs) -{ - fs -> flush(); - - if (fs -> fail()) - { - return -1; - } - - return 1; -} - -unsigned int RoundUp2(unsigned int x) -{ - unsigned int y = x / 2; - - y *= 2; - - if (y != x) - { - y += 2; - } - - return y; -} - -unsigned int RoundUp4(unsigned int x) -{ - unsigned int y = x / 4; - - y *= 4; - - if (y != x) - { - y += 4; - } - - return y; -} - -unsigned int RoundUp8(unsigned int x) -{ - unsigned int y = x / 8; - - y *= 8; - - if (y != x) - { - y += 8; - } - - return y; -} - -const char *DumpSignal(int signal) -{ - switch (signal) - { - case SIGCHLD: - { - return "SIGCHLD"; - } - case SIGUSR1: - { - return "SIGUSR1"; - } - case SIGUSR2: - { - return "SIGUSR2"; - } - case SIGHUP: - { - return "SIGHUP"; - } - case SIGINT: - { - return "SIGINT"; - } - case SIGTERM: - { - return "SIGTERM"; - } - case SIGPIPE: - { - return "SIGPIPE"; - } - case SIGALRM: - { - return "SIGALRM"; - } - case SIGVTALRM: - { - return "SIGVTALRM"; - } - case SIGWINCH: - { - return "SIGWINCH"; - } - case SIGIO: - { - return "SIGIO"; - } - case SIGTSTP: - { - return "SIGTSTP"; - } - case SIGTTIN: - { - return "SIGTTIN"; - } - case SIGTTOU: - { - return "SIGTTOU"; - } - case SIGSEGV: - { - return "SIGSEGV"; - } - case SIGABRT: - { - return "SIGABRT"; - } - default: - { - return "Unknown"; - } - } -} - -const char *DumpPolicy(int type) -{ - switch ((T_flush_policy) type) - { - case policy_immediate: - { - return "immediate"; - } - case policy_deferred: - { - return "deferred"; - } - default: - { - #ifdef PANIC - *logofs << "Misc: PANIC! Unknown policy type '" - << type << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unknown policy type '" - << type << "'.\n"; - - HandleCleanup(); - } - } -} - -const char *DumpAction(int type) -{ - T_store_action action = (T_store_action) type; - - if (action == IS_HIT) - { - return "is_hit"; - } - else if (action == IS_ADDED) - { - return "is_added"; - } - else if (action == is_discarded) - { - return "is_discarded"; - } - else if (action == is_removed) - { - return "is_removed"; - } - else - { - #ifdef PANIC - *logofs << "Misc: PANIC! Unknown store action '" - << type << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unknown store action '" - << type << "'.\n"; - - HandleCleanup(); - } -} - -const char *DumpState(int type) -{ - switch ((T_split_state) type) - { - case split_added: - { - return "split_added"; - } - case split_missed: - { - return "split_missed"; - } - case split_loaded: - { - return "split_loaded"; - } - case split_aborted: - { - return "split_aborted"; - } - case split_notified: - { - return "split_notified"; - } - default: - { - #ifdef PANIC - *logofs << "Misc: PANIC! Unknown split state '" - << type << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unknown split state '" - << type << "'.\n"; - - HandleCleanup(); - } - } -} - -const char *DumpControl(int code) -{ - switch ((T_proxy_code) code) - { - case code_new_x_connection: - { - return "code_new_x_connection"; - } - case code_new_cups_connection: - { - return "code_new_cups_connection"; - } - case code_new_aux_connection: - { - return "code_new_aux_connection"; - } - case code_new_smb_connection: - { - return "code_new_smb_connection"; - } - case code_new_media_connection: - { - return "code_new_media_connection"; - } - case code_switch_connection: - { - return "code_switch_connection"; - } - case code_drop_connection: - { - return "code_drop_connection"; - } - case code_finish_connection: - { - return "code_finish_connection"; - } - case code_begin_congestion: - { - return "code_begin_congestion"; - } - case code_end_congestion: - { - return "code_end_congestion"; - } - case code_alert_request: - { - return "code_alert_request"; - } - case code_alert_reply: - { - return "code_alert_reply"; - } - case code_reset_request: - { - return "code_reset_request"; - } - case code_reset_reply: - { - return "code_reset_reply"; - } - case code_load_request: - { - return "code_load_request"; - } - case code_load_reply: - { - return "code_load_reply"; - } - case code_save_request: - { - return "code_save_request"; - } - case code_save_reply: - { - return "code_save_reply"; - } - case code_shutdown_request: - { - return "code_shutdown_request"; - } - case code_shutdown_reply: - { - return "code_shutdown_reply"; - } - case code_control_token_request: - { - return "code_control_token_request"; - } - case code_control_token_reply: - { - return "code_control_token_reply"; - } - case code_configuration_request: - { - return "code_configuration_request"; - } - case code_configuration_reply: - { - return "code_configuration_reply"; - } - case code_statistics_request: - { - return "code_statistics_request"; - } - case code_statistics_reply: - { - return "code_statistics_reply"; - } - case code_new_http_connection: - { - return "code_new_http_connection"; - } - case code_sync_request: - { - return "code_sync_request"; - } - case code_sync_reply: - { - return "code_sync_reply"; - } - case code_new_font_connection: - { - return "code_new_font_connection"; - } - case code_new_slave_connection: - { - return "code_new_slave_connection"; - } - case code_finish_listeners: - { - return "code_finish_listeners"; - } - case code_split_token_request: - { - return "code_split_token_request"; - } - case code_split_token_reply: - { - return "code_split_token_reply"; - } - case code_data_token_request: - { - return "code_data_token_request"; - } - case code_data_token_reply: - { - return "code_data_token_reply"; - } - default: - { - #ifdef WARNING - *logofs << "Misc: WARNING! Unknown control code '" - << code << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Unknown control code '" - << code << "'.\n"; - - return "unknown"; - } - } -} - -const char *DumpSession(int code) -{ - switch ((T_session_mode) code) - { - case session_agent: - { - return "session_agent"; - } - case session_shadow: - { - return "session_shadow"; - } - case session_proxy: - { - return "session_proxy"; - } - default: - { - #ifdef WARNING - *logofs << "Misc: WARNING! Unknown session type '" - << code << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Unknown session type '" - << code << "'.\n"; - - return "unknown"; - } - } -} - -const char *DumpToken(int type) -{ - switch ((T_token_type) type) - { - case token_control: - { - return "token_control"; - } - case token_split: - { - return "token_split"; - } - case token_data: - { - return "token_data"; - } - default: - { - #ifdef WARNING - *logofs << "Misc: WARNING! Unknown token type '" - << type << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Unknown token type '" - << type << "'.\n"; - - return "unknown"; - } - } -} - -// -// Always include this in code as it is generally -// needed to test channels and split store. -// - -const char *DumpChecksum(const void *checksum) -{ - static char string[MD5_LENGTH * 2 + 1]; - - if (checksum != NULL) - { - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - sprintf(string + (i * 2), "%02X", ((unsigned char *) checksum)[i]); - } - } - else - { - strcpy(string, "null"); - } - - return string; -} - -// -// Define OPCODES here and in the channel -// if you want to log the opcode literal. -// - -#ifdef OPCODES - -const char *DumpOpcode(const int &opcode) -{ - switch (opcode) - { - case X_CreateWindow: - { - return "X_CreateWindow"; - } - case X_ChangeWindowAttributes: - { - return "X_ChangeWindowAttributes"; - } - case X_GetWindowAttributes: - { - return "X_GetWindowAttributes"; - } - case X_DestroyWindow: - { - return "X_DestroyWindow"; - } - case X_DestroySubwindows: - { - return "X_DestroySubwindows"; - } - case X_ChangeSaveSet: - { - return "X_ChangeSaveSet"; - } - case X_ReparentWindow: - { - return "X_ReparentWindow"; - } - case X_MapWindow: - { - return "X_MapWindow"; - } - case X_MapSubwindows: - { - return "X_MapSubwindows"; - } - case X_UnmapWindow: - { - return "X_UnmapWindow"; - } - case X_UnmapSubwindows: - { - return "X_UnmapSubwindows"; - } - case X_ConfigureWindow: - { - return "X_ConfigureWindow"; - } - case X_CirculateWindow: - { - return "X_CirculateWindow"; - } - case X_GetGeometry: - { - return "X_GetGeometry"; - } - case X_QueryTree: - { - return "X_QueryTree"; - } - case X_InternAtom: - { - return "X_InternAtom"; - } - case X_GetAtomName: - { - return "X_GetAtomName"; - } - case X_ChangeProperty: - { - return "X_ChangeProperty"; - } - case X_DeleteProperty: - { - return "X_DeleteProperty"; - } - case X_GetProperty: - { - return "X_GetProperty"; - } - case X_ListProperties: - { - return "X_ListProperties"; - } - case X_SetSelectionOwner: - { - return "X_SetSelectionOwner"; - } - case X_GetSelectionOwner: - { - return "X_GetSelectionOwner"; - } - case X_ConvertSelection: - { - return "X_ConvertSelection"; - } - case X_SendEvent: - { - return "X_SendEvent"; - } - case X_GrabPointer: - { - return "X_GrabPointer"; - } - case X_UngrabPointer: - { - return "X_UngrabPointer"; - } - case X_GrabButton: - { - return "X_GrabButton"; - } - case X_UngrabButton: - { - return "X_UngrabButton"; - } - case X_ChangeActivePointerGrab: - { - return "X_ChangeActivePointerGrab"; - } - case X_GrabKeyboard: - { - return "X_GrabKeyboard"; - } - case X_UngrabKeyboard: - { - return "X_UngrabKeyboard"; - } - case X_GrabKey: - { - return "X_GrabKey"; - } - case X_UngrabKey: - { - return "X_UngrabKey"; - } - case X_AllowEvents: - { - return "X_AllowEvents"; - } - case X_GrabServer: - { - return "X_GrabServer"; - } - case X_UngrabServer: - { - return "X_UngrabServer"; - } - case X_QueryPointer: - { - return "X_QueryPointer"; - } - case X_GetMotionEvents: - { - return "X_GetMotionEvents"; - } - case X_TranslateCoords: - { - return "X_TranslateCoords"; - } - case X_WarpPointer: - { - return "X_WarpPointer"; - } - case X_SetInputFocus: - { - return "X_SetInputFocus"; - } - case X_GetInputFocus: - { - return "X_GetInputFocus"; - } - case X_QueryKeymap: - { - return "X_QueryKeymap"; - } - case X_OpenFont: - { - return "X_OpenFont"; - } - case X_CloseFont: - { - return "X_CloseFont"; - } - case X_QueryFont: - { - return "X_QueryFont"; - } - case X_QueryTextExtents: - { - return "X_QueryTextExtents"; - } - case X_ListFonts: - { - return "X_ListFonts"; - } - case X_ListFontsWithInfo: - { - return "X_ListFontsWithInfo"; - } - case X_SetFontPath: - { - return "X_SetFontPath"; - } - case X_GetFontPath: - { - return "X_GetFontPath"; - } - case X_CreatePixmap: - { - return "X_CreatePixmap"; - } - case X_FreePixmap: - { - return "X_FreePixmap"; - } - case X_CreateGC: - { - return "X_CreateGC"; - } - case X_ChangeGC: - { - return "X_ChangeGC"; - } - case X_CopyGC: - { - return "X_CopyGC"; - } - case X_SetDashes: - { - return "X_SetDashes"; - } - case X_SetClipRectangles: - { - return "X_SetClipRectangles"; - } - case X_FreeGC: - { - return "X_FreeGC"; - } - case X_ClearArea: - { - return "X_ClearArea"; - } - case X_CopyArea: - { - return "X_CopyArea"; - } - case X_CopyPlane: - { - return "X_CopyPlane"; - } - case X_PolyPoint: - { - return "X_PolyPoint"; - } - case X_PolyLine: - { - return "X_PolyLine"; - } - case X_PolySegment: - { - return "X_PolySegment"; - } - case X_PolyRectangle: - { - return "X_PolyRectangle"; - } - case X_PolyArc: - { - return "X_PolyArc"; - } - case X_FillPoly: - { - return "X_FillPoly"; - } - case X_PolyFillRectangle: - { - return "X_PolyFillRectangle"; - } - case X_PolyFillArc: - { - return "X_PolyFillArc"; - } - case X_PutImage: - { - return "X_PutImage"; - } - case X_GetImage: - { - return "X_GetImage"; - } - case X_PolyText8: - { - return "X_PolyText8"; - } - case X_PolyText16: - { - return "X_PolyText16"; - } - case X_ImageText8: - { - return "X_ImageText8"; - } - case X_ImageText16: - { - return "X_ImageText16"; - } - case X_CreateColormap: - { - return "X_CreateColormap"; - } - case X_FreeColormap: - { - return "X_FreeColormap"; - } - case X_CopyColormapAndFree: - { - return "X_CopyColormapAndFree"; - } - case X_InstallColormap: - { - return "X_InstallColormap"; - } - case X_UninstallColormap: - { - return "X_UninstallColormap"; - } - case X_ListInstalledColormaps: - { - return "X_ListInstalledColormaps"; - } - case X_AllocColor: - { - return "X_AllocColor"; - } - case X_AllocNamedColor: - { - return "X_AllocNamedColor"; - } - case X_AllocColorCells: - { - return "X_AllocColorCells"; - } - case X_AllocColorPlanes: - { - return "X_AllocColorPlanes"; - } - case X_FreeColors: - { - return "X_FreeColors"; - } - case X_StoreColors: - { - return "X_StoreColors"; - } - case X_StoreNamedColor: - { - return "X_StoreNamedColor"; - } - case X_QueryColors: - { - return "X_QueryColors"; - } - case X_LookupColor: - { - return "X_LookupColor"; - } - case X_CreateCursor: - { - return "X_CreateCursor"; - } - case X_CreateGlyphCursor: - { - return "X_CreateGlyphCursor"; - } - case X_FreeCursor: - { - return "X_FreeCursor"; - } - case X_RecolorCursor: - { - return "X_RecolorCursor"; - } - case X_QueryBestSize: - { - return "X_QueryBestSize"; - } - case X_QueryExtension: - { - return "X_QueryExtension"; - } - case X_ListExtensions: - { - return "X_ListExtensions"; - } - case X_ChangeKeyboardMapping: - { - return "X_ChangeKeyboardMapping"; - } - case X_GetKeyboardMapping: - { - return "X_GetKeyboardMapping"; - } - case X_ChangeKeyboardControl: - { - return "X_ChangeKeyboardControl"; - } - case X_GetKeyboardControl: - { - return "X_GetKeyboardControl"; - } - case X_Bell: - { - return "X_Bell"; - } - case X_ChangePointerControl: - { - return "X_ChangePointerControl"; - } - case X_GetPointerControl: - { - return "X_GetPointerControl"; - } - case X_SetScreenSaver: - { - return "X_SetScreenSaver"; - } - case X_GetScreenSaver: - { - return "X_GetScreenSaver"; - } - case X_ChangeHosts: - { - return "X_ChangeHosts"; - } - case X_ListHosts: - { - return "X_ListHosts"; - } - case X_SetAccessControl: - { - return "X_SetAccessControl"; - } - case X_SetCloseDownMode: - { - return "X_SetCloseDownMode"; - } - case X_KillClient: - { - return "X_KillClient"; - } - case X_RotateProperties: - { - return "X_RotateProperties"; - } - case X_ForceScreenSaver: - { - return "X_ForceScreenSaver"; - } - case X_SetPointerMapping: - { - return "X_SetPointerMapping"; - } - case X_GetPointerMapping: - { - return "X_GetPointerMapping"; - } - case X_SetModifierMapping: - { - return "X_SetModifierMapping"; - } - case X_GetModifierMapping: - { - return "X_GetModifierMapping"; - } - case X_NoOperation: - { - return "X_NoOperation"; - } - case X_NXInternalGenericData: - { - return "X_NXInternalGenericData"; - } - // - // case X_NXInternalGenericReply: - // { - // return "X_NXInternalGenericReply"; - // } - // - case X_NXInternalGenericRequest: - { - return "X_NXInternalGenericRequest"; - } - case X_NXInternalShapeExtension: - { - return "X_NXInternalShapeExtension"; - } - case X_NXGetControlParameters: - { - return "X_NXGetControlParameters"; - } - case X_NXGetCleanupParameters: - { - return "X_NXGetCleanupParameters"; - } - case X_NXGetImageParameters: - { - return "X_NXGetImageParameters"; - } - case X_NXGetUnpackParameters: - { - return "X_NXGetUnpackParameters"; - } - case X_NXGetShmemParameters: - { - return "X_NXGetShmemParameters"; - } - case X_NXGetFontParameters: - { - return "X_NXGetFontParameters"; - } - case X_NXSetExposeParameters: - { - return "X_NXSetExposeParameters"; - } - case X_NXSetCacheParameters: - { - return "X_NXSetCacheParameters"; - } - case X_NXStartSplit: - { - return "X_NXStartSplit"; - } - case X_NXEndSplit: - { - return "X_NXEndSplit"; - } - case X_NXSplitData: - { - return "X_NXSplitData"; - } - case X_NXSplitEvent: - { - return "X_NXSplitEvent"; - } - case X_NXCommitSplit: - { - return "X_NXCommitSplit"; - } - case X_NXFinishSplit: - { - return "X_NXFinishSplit"; - } - case X_NXAbortSplit: - { - return "X_NXAbortSplit"; - } - case X_NXFreeSplit: - { - return "X_NXFreeSplit"; - } - case X_NXSetUnpackGeometry: - { - return "X_NXSetUnpackGeometry"; - } - case X_NXSetUnpackColormap: - { - return "X_NXSetUnpackColormap"; - } - case X_NXSetUnpackAlpha: - { - return "X_NXSetUnpackAlpha"; - } - case X_NXPutPackedImage: - { - return "X_NXPutPackedImage"; - } - case X_NXFreeUnpack: - { - return "X_NXFreeUnpack"; - } - default: - { - if (opcode > 127) - { - return "Extension"; - } - else - { - return "?"; - } - } - } -} - -#else /* #ifdef OPCODES */ - -const char *DumpOpcode(const int &opcode) -{ - return "?"; -} - -#endif /* #ifdef OPCODES */ - -void DumpData(const unsigned char *buffer, unsigned int size) -{ - if (buffer != NULL) - { - unsigned int i = 0; - - while (i < size) - { - *logofs << "[" << i << "]\t"; - - for (unsigned int ii = 0; i < size && ii < 8; i++, ii++) - { - *logofs << (unsigned int) (buffer[i]) << "\t"; - } - - *logofs << "\n" << logofs_flush; - } - } -} - -void DumpChecksum(const unsigned char *buffer, unsigned int size) -{ - if (buffer != NULL) - { - md5_byte_t md5_digest[MD5_LENGTH]; - - md5_state_t md5_state; - - md5_init(&md5_state); - - md5_append(&md5_state, buffer, size); - - md5_finish(&md5_state, md5_digest); - - char md5_string[MD5_LENGTH * 2 + 1]; - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - sprintf(md5_string + (i * 2), "%02X", md5_digest[i]); - } - - *logofs << "[" << md5_string << "]" << logofs_flush; - } -} - -void DumpBlockChecksums(const unsigned char *buffer, - unsigned int size, unsigned int block) -{ - for (unsigned int i = 0; i < (size / block); i++) - { - *logofs << "[" << i * block << "]"; - - DumpChecksum(buffer + (i * block), block); - - *logofs << "\n"; - } - - if (size % block > 0) - { - *logofs << "[" << size / block * block << "]"; - - DumpChecksum(buffer + (size / block * block), size % block); - - *logofs << "\n"; - } -} - -void DumpHexData(const unsigned char *buffer, unsigned int size) -{ - char message [65536]; - char ascii [17]; - - unsigned int index = 0; - unsigned int linescan = 0; - unsigned int index_ascii = 0; - - sprintf (message,"\n#### Start Dump Buffer of [%.5d] Bytes ####\n\n",size); - - *logofs << message << logofs_flush; - - // - // "Index 0 1 2 3 4 5 6 7 8 9 a b c d e f Ascii " - // "----- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------" - // "00000 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................" - // - - sprintf (message,"Index 0 1 2 3 4 5 6 7 8 9 a b c d e f Ascii \n"); - *logofs << message << logofs_flush; - sprintf (message,"----- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------\n"); - *logofs << message << logofs_flush; - - index = 0; - - while (index < size) - { - memset (ascii, ' ', sizeof(ascii)); - - ascii[16] = '\0'; - - sprintf (message,"%.5d ", index); - - for (index_ascii = 0, linescan = index; - ((index < (linescan + 16)) && (index < size)); - index++, index_ascii++) - { - if (isprint(buffer [index])) - { - ascii[index_ascii] = buffer [index]; - } - else - { - ascii[index_ascii] = '.'; - } - - sprintf (&message [strlen (message)],"%.2x ", (unsigned char) buffer [index]); - } - - for (linescan = index_ascii; linescan < 16; linescan++) - { - strcat (&message [strlen (message)], " "); - } - - sprintf (&message [strlen (message)]," %s\n", ascii); - - *logofs << message << logofs_flush; - } - - sprintf (message,"\n#### End Dump Buffer ####\n\n"); - - *logofs << message << logofs_flush; -} diff --git a/nxcomp/Misc.h b/nxcomp/Misc.h deleted file mode 100644 index 997630137..000000000 --- a/nxcomp/Misc.h +++ /dev/null @@ -1,279 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Misc_H -#define Misc_H - -#include -#include - -#include -#include - -#ifdef __sun - -#include - -#endif - -using namespace std; - -// -// This is MD5 length. -// - -#define MD5_LENGTH 16 - -// -// Error handling macros. -// - -#define ESET(e) (errno = (e)) -#define EGET() (errno) -#define ESTR() strerror(errno) - -// -// TCP port offset applied to NX port specification. -// - -extern const int DEFAULT_NX_PROXY_PORT_OFFSET; - -// -// Default TCP port used by client proxy to listen -// to X clients and by server proxy to connect to -// remote. -// - -extern const int DEFAULT_NX_PROXY_PORT; - -// -// Default X display number that client -// proxy imitates. -// - -extern const int DEFAULT_NX_X_PORT; - -// -// Establish the port offsets for the additional -// services. -// - -extern const int DEFAULT_NX_CUPS_PORT_OFFSET; -extern const int DEFAULT_NX_SMB_PORT_OFFSET; -extern const int DEFAULT_NX_MEDIA_PORT_OFFSET; -extern const int DEFAULT_NX_AUX_PORT_OFFSET; -extern const int DEFAULT_NX_HTTP_PORT_OFFSET; -extern const int DEFAULT_NX_FONT_PORT_OFFSET; - -// -// Slave channels can be originated by both sides -// so they need to have different port offsets -// in the case the user runs both proxies on the -// same host. -// - -extern const int DEFAULT_NX_SLAVE_PORT_CLIENT_OFFSET; -extern const int DEFAULT_NX_SLAVE_PORT_SERVER_OFFSET; - -// -// NX proxy binds to all network interfaces by default -// With the -loopback parameter, you can switch -// over to binding to the loopback device only. -// - -extern const int DEFAULT_LOOPBACK_BIND; - -// -// Return strings containing various info. -// - -const char *GetUsageInfo(); -const char *GetCopyrightInfo(); -const char *GetOtherCopyrightInfo(); - -// -// Define this if you want immediate flush of -// the log output. -// - -#define FLUSH_LOGOFS - -// -// Global objects providing shared functions. -// - -class Auth; -class Control; -class Statistics; - -extern Auth *auth; -extern Control *control; -extern Statistics *statistics; - -// -// Log file. -// - -extern ostream *logofs; - -// -// Cleanup code. -// - -void HandleAbort() __attribute__((noreturn)); -void HandleShutdown() __attribute__((noreturn)); - -extern "C" -{ - void HandleCleanup(int code = 0) __attribute__((noreturn)); - void HandleCleanupForReconnect(); -} - -// -// Manage signal handlers. -// - -void DisableSignals(); -void EnableSignals(); - -// -// Manage timers. -// - -void SetTimer(int value); -void ResetTimer(); - -// -// Show a dialog asking the user if he/she -// wants to close the current session. Look -// in the alerts file for the known critical -// events. -// - -void HandleAlert(int code, int local); - -// -// Run the callback registered by the proxy -// or the agent. -// - -void KeeperCallback(); -void FlushCallback(int length); - -// -// Return the string literal corresponding -// the value. -// - -const char *DumpSignal(int signal); -const char *DumpPolicy(int type); -const char *DumpControl(int code); -const char *DumpSession(int code); -const char *DumpAction(int type); -const char *DumpState(int type); -const char *DumpToken(int type); - -// -// Print out content of buffer to log file. -// You need to define DUMP or OPCODES in -// the source to have these compiled. -// - -const char *DumpOpcode(const int &opcode); -const char *DumpChecksum(const void *checksum); - -void DumpData(const unsigned char *data, unsigned int length); -void DumpHexData(const unsigned char *data, unsigned int length); -void DumpChecksum(const unsigned char *data, unsigned int length); -void DumpBlockChecksums(const unsigned char *data, unsigned int length, - unsigned int block); - -// -// Defines logofs_flush as an empty string to -// avoid calling the corresponding ostream's -// flush() function. -// - -#ifdef FLUSH_LOGOFS - -#define logofs_flush "" ; logofs -> flush() - -#else - -#define logofs_flush "" - -#endif - -// -// Is the host where local proxy is running -// big-endian? -// - -extern int _hostBigEndian; -extern int _storeBigEndian; - -inline void setHostBigEndian(int flag) -{ - _hostBigEndian = flag; -} - -inline int hostBigEndian() -{ - return _hostBigEndian; -} - -inline int storeBigEndian() -{ - return _storeBigEndian; -} - -extern const unsigned int IntMask[33]; - -unsigned int GetUINT(unsigned const char *buffer, int bigEndian); -unsigned int GetULONG(unsigned const char *buffer, int bigEndian); -void PutUINT(unsigned int value, unsigned char *buffer, int bigEndian); -void PutULONG(unsigned int value, unsigned char *buffer, int bigEndian); - -inline void CleanData(unsigned char *buffer, int size) -{ - unsigned char *end = buffer + size; - - while (buffer < end) - { - *buffer++ = 0x00; - } -} - -int CheckData(istream *fs); -int CheckData(ostream *fs); -int PutData(ostream *fs, const unsigned char *buffer, int size); -int GetData(istream *fs, unsigned char *buffer, int size); -int FlushData(ostream *fs); - -unsigned int RoundUp2(unsigned int x); -unsigned int RoundUp4(unsigned int x); -unsigned int RoundUp8(unsigned int x); - -#endif /* Misc_H */ diff --git a/nxcomp/NX.h b/nxcomp/NX.h deleted file mode 100644 index 7ec79b4b1..000000000 --- a/nxcomp/NX.h +++ /dev/null @@ -1,471 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef NX_H -#define NX_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include -#include -#include - -#define NX_FD_ANY -1 - -#define NX_MODE_ANY -1 -#define NX_MODE_CLIENT 1 -#define NX_MODE_SERVER 2 - -#define NX_DISPLAY_ANY NULL - -#define NX_SIGNAL_ANY -1 -#define NX_SIGNAL_ENABLE 1 -#define NX_SIGNAL_DISABLE 2 -#define NX_SIGNAL_RAISE 3 -#define NX_SIGNAL_FORWARD 4 - -#define NX_POLICY_IMMEDIATE 1 -#define NX_POLICY_DEFERRED 2 - -#define NX_ALERT_REMOTE 0 -#define NX_ALERT_LOCAL 1 - -#define NX_HANDLER_FLUSH 0 -#define NX_HANDLER_STATISTICS 1 - -#define NX_STATISTICS_PARTIAL 0 -#define NX_STATISTICS_TOTAL 1 - -#define NX_CHANNEL_X11 0 -#define NX_CHANNEL_CUPS 1 -#define NX_CHANNEL_SMB 2 -#define NX_CHANNEL_MEDIA 3 -#define NX_CHANNEL_HTTP 4 -#define NX_CHANNEL_FONT 5 -#define NX_CHANNEL_SLAVE 6 - -#define NX_FILE_SESSION 0 -#define NX_FILE_ERRORS 1 -#define NX_FILE_OPTIONS 2 -#define NX_FILE_STATS 3 - -/* - * The following are the new interfaces to the NX transport. The - * NX proxy software is now intended to be run as a library of a - * higher level communication manager (nxssh, nxhttp, nxrtp, etc, - * not only nxproxy). This is a work-in-progress, so expect these - * interfaces to change in future. At the present moment, as an - * example, there is no provision for creating and managing mul- - * tiple proxy connections. - */ - -/* - * Attach a NX transport to the provided descriptor. This should be - * done after having created a pair of connected sockets. - */ - -extern int NXTransCreate(int fd, int mode, const char *options); - -/* - * Tell the proxy to use the second descriptor as its own end of - * the internal connection to the NX agent. The NX agent will use - * the first descriptor. Setting an agent connection will have the - * effect of disabling further X client connections and, if it is - * possible, will trigger the use of the memory-to-memory transport. - */ - -extern int NXTransAgent(int fd[2]); - -/* - * Prepare the file sets and the timeout for a later execution of - * the select(). The masks and the timeout must persist across all - * the calls, so if you don't need any of the values, it is requi- - * red that you create empty masks and a default timeout. To save - * a check at each run, all the functions below assume that valid - * pointers are passed. - */ - -extern int NXTransPrepare(int *maxfds, fd_set *readfds, - fd_set *writefds, struct timeval *timeout); - -/* - * Call select() to find out the descriptors in the sets having - * pending data. - */ - -extern int NXTransSelect(int *result, int *error, int *maxfds, fd_set *readfds, - fd_set *writefds, struct timeval *timeout); - -/* - * Perform the required I/O on all the NX descriptors having pen- - * ding data. This can include reading and writing to the NX chan- - * nels, encoding and decoding the proxy data or managing any of - * the other NX resources. - */ - -extern int NXTransExecute(int *result, int *error, int *maxfds, fd_set *readfds, - fd_set *writefds, struct timeval *timeout); - -/* - * Run an empty loop, giving to the NX transport a chance to check - * its descriptors. - */ - -extern int NXTransContinue(struct timeval *timeout); - -/* - * Perform I/O on the given descriptors. If memory-to-memory trans- - * port has been activated and the descriptor is recognized as a - * valid agent connection, then the functions will read and write - * the data directly to the proxy buffer, otherwise the correspond- - * ing network operation will be performed. - */ - -extern int NXTransRead(int fd, char *data, int size); -extern int NXTransWrite(int fd, char *data, int size); -extern int NXTransReadable(int fd, int *readable); - -extern int NXTransReadVector(int fd, struct iovec *iovdata, int iovsize); -extern int NXTransWriteVector(int fd, struct iovec *iovdata, int iovsize); - -extern int NXTransClose(int fd); - -/* - * Return true if the NX transport is running. The fd parameter can - * be either the local descriptor attached to the NX transport or - * NX_FD_ANY. - */ - -extern int NXTransRunning(int fd); - -/* - * Close down the NX transport and free all the allocated resources. - * The fd parameter can be either the local descriptor or NX_FD_ANY. - * This must be explicitly called by the agent before the proxy can - * start the tear down procedure. - */ - -extern int NXTransDestroy(int fd); - -/* - * Tell to the proxy how to handle the standard POSIX signals. For - * example, given the SIGINT signal, the caller can specify any of - * the following actions: - * - * NX_SIGNAL_ENABLE: A signal handler will have to be installed by - * the library, so that it can be intercepted by - * the proxy. - * - * NX_SIGNAL_DISABLE: The signal will be handled by the caller and, - * eventually, forwarded to the proxy by calling - * NXTransSignal() explicitly. - * - * NX_SIGNAL_RAISE: The signal must be handled now, as if it had - * been delivered by the operating system. This - * function can be called by the agent with the - * purpose of propagating a signal to the proxy. - * - * NX_SIGNAL_FORWARD: A signal handler will have to be installed by - * the library but the library will have to call - * the original signal handler when the signal - * is received. - * - * As a rule of thumb, agents should let the proxy handle SIGUSR1 - * and SIGUSR2, used for producing the NX protocol statistics, and - * SIGHUP, used for disconnecting the NX transport. - * - * The following signals are blocked by default upon creation of the - * NX transport: - * - * SIGCHLD These signals should be always put under the control - * SIGUSR1 of the proxy. If agents are intercepting them, agents - * SIGUSR2 should later call NXTransSignal(..., NX_SIGNAL_RAISE) - * SIGHUP to forward the signal to the proxy. As an alternative - * they can specify a NX_SIGNAL_FORWARD action, so they, - * in turn, can be notified about the signal. This can - * be especially useful for SIGCHLD. - * - * SIGINT These signals should be intercepted by agents. Agents - * SIGTERM should ensure that NXTransDestroy() is called before - * exiting, to give the proxy a chance to shut down the - * NX transport. - * - * SIGPIPE This signal is blocked by the proxy, but not used to - * implement any functionality. It can be handled by the - * NX agent without affecting the proxy. - * - * SIGALRM This is now used by the proxy and agents should not - * redefine it. Agents can use the signal to implement - * their own timers but should not interleave calls to - * the NX transport and should restore the old handler - * when the timeout is raised. - * - * SIGVTALRM These signals are not used but may be used in future - * SIGWINCH versions of the library. - * SIGIO - * SIGTSTP - * SIGTTIN - * SIGTTOU - * - * By calling NXTransSignal(..., NX_SIGNAL_DISABLE) nxcomp will res- - * tore the signal handler that was saved at the time the proxy hand- - * ler was installed. This means that you should call the function - * just after the XOpenDisplay() or any other function used to init- - * ialize the NX transport. - */ - -extern int NXTransSignal(int signal, int action); - -/* - * Return a value between 0 and 9 indicating the congestion level - * based on the tokens still available. A value of 9 means that - * the link is congested and no further data can be sent. - */ - -extern int NXTransCongestion(int fd); - -/* - * Let the application to be notified by the proxy when an event oc- - * curs. The parameter, as set at the time the handler is installed, - * is passed each time to the callback function. The parameter is - * presumably the display pointer, given that at the present moment - * the NX transport doesn't have access to the display structure and - * so wouldn't be able to determine the display to pass to the call- - * back function. - * - * NX_HANDLER_FLUSH: The handler function is called when some - * more data has been written to the proxy - * link. - * - * The data is the number of bytes written. - * - * NX_HANDLER_STATISTICS: This handler is called to let the agent - * include arbitrary data in the transport - * statistics. The parameter, in this case, - * is a pointer to a pointer to a null term- - * inated string. The pointer is set at the - * time the handler is registered. The point- - * ed string will have to be filled by the - * agent with its statistics data. - * - * The data can be NX_STATISTICS_PARTIAL or NX_STATISTICS_TOTAL. The - * agent can refer to the value by using the NXStatisticsPartial and - * NXStatisticsTotal constants defined in NXvars.h. - * - * Note that these interfaces are used by Xlib and nxcompext. Agents - * should never call these interfaces directly, but use the nxcompext - * wrapper. - */ - -extern int NXTransHandler(int fd, int type, void (*handler)(void *parameter, - int reason), void *parameter); - -/* - * Set the policy to be used by the NX transport to write data to the - * proxy link: - * - * NX_POLICY_IMMEDIATE: When set to immediate, the proxy will try to - * write the data just after having encoded it. - * - * NX_POLICY_DEFERRED: When policy is set to deferred, data will be - * accumulated in a buffer and written to the - * remote proxy when NXTransFlush() is called by - * the agent. - */ - -extern int NXTransPolicy(int fd, int type); - -/* - * Query the number of bytes that have been accumulated for a deferred - * flush. - */ - -extern int NXTransFlushable(int fd); - -/* - * Tell to the NX transport to write all the accumulated data to the - * remote proxy. - */ - -extern int NXTransFlush(int fd); - -/* - * Create a new channel of the given type. It returns 1 on success, - * 0 if the NX transport is not running, or -1 in the case of error. - * On success, the descriptor provided by the caller can be later - * used for the subsequent I/O. The type parameter not only tells to - * the proxy the remote port where the channel has to be connected, - * but also gives a hint about the type of data that will be carried - * by the channel, so that the proxy can try to optimize the traffic - * on the proxy link. - * - * NX_CHANNEL_X: The channel will carry X traffic and it - * will be connected to the remote X display. - * - * NX_CHANNEL_CUPS: The channel will carry CUPS/IPP protocol. - * - * NX_CHANNEL_SMB: The channel will carry SMB/CIFS protocol. - * - * NX_CHANNEL_MEDIA: The channel will transport audio or other - * multimedia data. - * - * NX_CHANNEL_HTTP: The channel will carry HTTP protocol. - * - * NX_CHANNEL_FONT: The channel will forward a X font server - * connection. - * - * Only a proxy running at the NX server/X client side will be able - * to create a X, CUPS, SMB, MEDIA and HTTP channel. A proxy running - * at the NX client/X server side can create font server connections. - * The channel creation will also fail if the remote end has not been - * set up to forward the connection. - * - * To create a new channel the agent will have to set up a socketpair - * and pass to the proxy one of the socket descriptors. - * - * Example: - * - * #include - * #include - * - * int fds[2]; - * - * if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) - * { - * ... - * } - * else - * { - * // - * // Use fds[0] locally and let the - * // proxy use fds[1]. - * // - * - * if (NXTransChannel(NX_FD_ANY, fds[1], NX_CHANNEL_X) <= 0) - * { - * ... - * } - * - * // - * // The agent can now use fds[0] in - * // read(), write() and select() - * // system calls. - * // - * - * ... - * } - * - * Note that all the I/O on the descriptor should be non-blocking, to - * give a chance to the NX transport to run in the background and handle - * the data that will be fed to the agent's side of the socketpair. This - * will happen automatically, as long as the agent uses the XSelect() - * version of the select() function (as it is normal whenever performing - * Xlib I/O). In all the other cases, like presumably in the agent's main - * loop, the agent will have to loop through NXTransPrepare(), NXTrans- - * Select() and NXTransExecute() functions explicitly, adding to the sets - * the descriptors that are awaited by the agent. Please check the imple- - * mentation of _XSelect() in nx-X11/lib/X11/XlibInt.c for an example. - */ - -extern int NXTransChannel(int fd, int channelfd, int type); - -/* - * Return the name of the files used by the proxy for the current session. - * - * The type parameter can be: - * - * NX_FILE_SESSION: Usually the file 'session' in the user's session - * directory. - * - * NX_FILE_ERRORS: The file used for the diagnostic output. Usually - * the file 'errors' in the session directory. - * - * NX_FILE_OPTIONS: The file containing the NX options, if any. - * - * NX_FILE_STATS: The file used for the statistics output. - * - * The returned string is allocated in static memory. The caller should - * copy the string upon returning from the function, without freeing the - * pointer. - */ - -extern const char *NXTransFile(int type); - -/* - * Return the time in milliseconds elapsed since the last call to this - * same function. - */ - -extern long NXTransTime(void); - -/* - * Other interfaces to the internal transport functions. - */ - -extern int NXTransProxy(int fd, int mode, const char *display); - -extern int NXTransClient(const char *display); - -extern int NXTransDialog(const char *caption, const char *message, - const char *window, const char *type, int local, - const char *display); - -extern int NXTransAlert(int code, int local); - -extern int NXTransWatchdog(int timeout); - -extern int NXTransKeeper(int caches, int images, const char *root); - -extern void NXTransExit(int code) __attribute__((noreturn)); - -extern int NXTransParseCommandLine(int argc, const char **argv); -extern int NXTransParseEnvironment(const char *env, int force); - -extern void NXTransCleanup(void) __attribute__((noreturn)); - -/* - * Cleans up the global and local state - * (the same way as NXTransCleanup does) - * but does not exit the process - * Needed for IOS platform - */ -extern void NXTransCleanupForReconnect(void); - -extern const char* NXVersion(void); -extern int NXMajorVersion(void); -extern int NXMinorVersion(void); -extern int NXPatchVersion(void); -extern int NXMaintenancePatchVersion(void); - -#ifdef __cplusplus -} -#endif - -#endif /* NX_H */ diff --git a/nxcomp/NXalert.h b/nxcomp/NXalert.h deleted file mode 100644 index dca2f44ca..000000000 --- a/nxcomp/NXalert.h +++ /dev/null @@ -1,276 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef NXalert_H -#define NXalert_H - -#define ALERT_CAPTION_PREFIX "NX - " - -#define INTERNAL_ERROR_ALERT 1 -#define INTERNAL_ERROR_ALERT_TYPE "error" -#define INTERNAL_ERROR_ALERT_STRING \ -"\ -An unrecoverable internal error was detected.\n\ -Press OK to terminate the current session.\n\ -" - -#define CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT 2 -#define CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT_TYPE "yesno" -#define CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT_STRING \ -"\ -One of the applications currently in use is not responding.\n\ -Do you want to terminate the current session?\n\ -" - -#define CLOSE_DEAD_X_CONNECTION_SERVER_ALERT 3 -#define CLOSE_DEAD_X_CONNECTION_SERVER_ALERT_TYPE "yesno" -#define CLOSE_DEAD_X_CONNECTION_SERVER_ALERT_STRING \ -"\ -One of the applications did not behave correctly and caused\n\ -the X server to stop responding in a timely fashion. Do you\n\ -want to terminate the current session?\n\ -" - -#define CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT 4 -#define CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT_TYPE NULL -#define CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT_STRING NULL - -#define CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT 5 -#define CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT_TYPE "yesno" -#define CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT_STRING \ -"\ -No response received from the remote server.\n\ -Do you want to terminate the current session?\n\ -" - -#define RESTART_DEAD_PROXY_CONNECTION_CLIENT_ALERT 6 -#define RESTART_DEAD_PROXY_CONNECTION_CLIENT_ALERT_TYPE NULL -#define RESTART_DEAD_PROXY_CONNECTION_CLIENT_ALERT_STRING NULL - -#define RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT 7 -#define RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT_TYPE "yesno" -#define RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT_STRING \ -"\ -Connection with remote server was shut down. NX will try\n\ -to establish a new server connection. Session could have\n\ -been left in a unusable state. Do you want to terminate\n\ -the session?\n\ -" - -#define CLOSE_UNRESPONSIVE_X_SERVER_ALERT 8 -#define CLOSE_UNRESPONSIVE_X_SERVER_ALERT_TYPE "panic" -#define CLOSE_UNRESPONSIVE_X_SERVER_ALERT_STRING \ -"\ -You pressed the key sequence CTRL+ALT+SHIFT+ESC.\n\ -This is probably because your X server has become\n\ -unresponsive. Session will be terminated in 30\n\ -seconds unless you abort the procedure by pressing\n\ -the Cancel button.\n\ -" - -#define WRONG_PROXY_VERSION_ALERT 9 -#define WRONG_PROXY_VERSION_ALERT_TYPE "ok" -#define WRONG_PROXY_VERSION_ALERT_STRING \ -"\ -Local NX libraries version " VERSION " do not match the NX\n\ -version of the remote server. Please check the error\n\ -log on the server to find out which client version you\n\ -need to install to be able to access this server.\n\ -" - -#define FAILED_PROXY_CONNECTION_CLIENT_ALERT 10 -#define FAILED_PROXY_CONNECTION_CLIENT_ALERT_TYPE NULL -#define FAILED_PROXY_CONNECTION_CLIENT_ALERT_STRING NULL - -#define FAILED_PROXY_CONNECTION_SERVER_ALERT 11 -#define FAILED_PROXY_CONNECTION_SERVER_ALERT_TYPE "yesno" -#define FAILED_PROXY_CONNECTION_SERVER_ALERT_STRING \ -"\ -Could not yet establish the connection to the remote\n\ -proxy. Do you want to terminate the current session?\n\ -" - -#define MISSING_PROXY_CACHE_ALERT 12 -#define MISSING_PROXY_CACHE_ALERT_TYPE "ok" -#define MISSING_PROXY_CACHE_ALERT_STRING \ -"\ -NX was unable to negotiate a cache for this session.\n\ -This may happen if this is the first time you run a\n\ -session on this server or if cache was corrupted or\n\ -produced by an incompatible NX version.\n\ -" - -#define ABORT_PROXY_CONNECTION_ALERT 13 -#define ABORT_PROXY_CONNECTION_ALERT_TYPE "ok" -#define ABORT_PROXY_CONNECTION_ALERT_STRING \ -"\ -The connection with the remote server was shut down.\n\ -Please check the state of your network connection.\n\ -" - -/* - * The one below is a special alert, used to close - * a previous alert that is running on the given - * side. This can be used to get rid of a message - * that has ceased to hold true. - */ - -#define DISPLACE_MESSAGE_ALERT 14 -#define DISPLACE_MESSAGE_ALERT_TYPE NULL -#define DISPLACE_MESSAGE_ALERT_STRING NULL - -/* - * These are the other alert messages that were - * added in the 1.5.0 release. The first is never - * shown and is intended just for testing. - */ - -#define GREETING_MESSAGE_ALERT 15 -#define GREETING_MESSAGE_ALERT_TYPE "ok" -#define GREETING_MESSAGE_ALERT_STRING \ -"\ -Welcome to NX from the NoMachine team. We really\n\ -hope you will enjoy this wonderful software as much\n\ -as we had fun making it ;-).\n\ -" - -/* - * These alerts are intended to notify the user - * of the reason why the agent failed to resume - * the session. - */ - -#define START_RESUME_SESSION_ALERT 16 -#define START_RESUME_SESSION_ALERT_TYPE "ok" -#define START_RESUME_SESSION_ALERT_STRING \ -"\ -You appear to run your NX session across a slow network\n\ -connection. Resuming the session may require some time.\n\ -Please wait.\ -" - -#define FAILED_RESUME_DISPLAY_ALERT 17 -#define FAILED_RESUME_DISPLAY_ALERT_TYPE "error" -#define FAILED_RESUME_DISPLAY_ALERT_STRING \ -"\ -Failed to open the display. Can't resume the NX\n\ -session on this display.\n\ -" - -#define FAILED_RESUME_DISPLAY_BROKEN_ALERT 18 -#define FAILED_RESUME_DISPLAY_BROKEN_TYPE "error" -#define FAILED_RESUME_DISPLAY_BROKEN_STRING \ -"\ -The display connection was broken while trying to\n\ -resume the session. Please, check your network\n\ -connection and try again.\n\ -" - -#define FAILED_RESUME_VISUALS_ALERT 19 -#define FAILED_RESUME_VISUALS_ALERT_TYPE "error" -#define FAILED_RESUME_VISUALS_ALERT_STRING \ -"\ -Failed to restore all the required visuals.\n\ -Can't resume the NX session on this display.\n\ -" - -#define FAILED_RESUME_COLORMAPS_ALERT 20 -#define FAILED_RESUME_COLORMAPS_ALERT_TYPE "error" -#define FAILED_RESUME_COLORMAPS_ALERT_STRING \ -"\ -The number of available colormaps is different\n\ -on the new display. Can't resume the NX session\n\ -on this display.\n\ -" - -#define FAILED_RESUME_PIXMAPS_ALERT 21 -#define FAILED_RESUME_PIXMAPS_ALERT_TYPE "error" -#define FAILED_RESUME_PIXMAPS_ALERT_STRING \ -"\ -Failed to restore all the required pixmap formats.\n\ -Can't resume the NX session on this display.\n\ -" - -#define FAILED_RESUME_DEPTHS_ALERT 22 -#define FAILED_RESUME_DEPTHS_ALERT_TYPE "error" -#define FAILED_RESUME_DEPTHS_ALERT_STRING \ -"\ -Failed to restore all the required screen depths.\n\ -Can't resume the NX session on this display.\n\ -" - -#define FAILED_RESUME_RENDER_ALERT 23 -#define FAILED_RESUME_RENDER_ALERT_TYPE "error" -#define FAILED_RESUME_RENDER_ALERT_STRING \ -"\ -The render extension is missing or an incompatible\n\ -version was detected on your X server. Can't resume\n\ -the NX session on this display.\n\ -" - -#define FAILED_RESUME_FONTS_ALERT 24 -#define FAILED_RESUME_FONTS_ALERT_TYPE "error" -#define FAILED_RESUME_FONTS_ALERT_STRING \ -"\ -One or more of the fonts that are in use by the\n\ -session are missing. Can't resume the NX session\n\ -on this display.\n\ -" - -#define ABORT_PROXY_NEGOTIATION_ALERT 62 -#define ABORT_PROXY_NEGOTIATION_ALERT_TYPE "ok" -#define ABORT_PROXY_NEGOTIATION_ALERT_STRING \ -"\ -The remote proxy closed the connection while negotiating\n\ -the session. This may be due to the wrong authentication\n\ -credentials passed to the server.\n\ -" - -#define ABORT_PROXY_SHUTDOWN_ALERT 64 -#define ABORT_PROXY_SHUTDOWN_ALERT_TYPE "ok" -#define ABORT_PROXY_SHUTDOWN_ALERT_STRING \ -"\ -No response received from the remote proxy while\n\ -waiting for the session shutdown.\n\ -" - -#define FAILED_XDMCP_CONNECTION_ALERT 65 -#define FAILED_XDMCP_CONNECTION_ALERT_TYPE "ok" -#define FAILED_XDMCP_CONNECTION_ALERT_STRING \ -"\ -The XDM host that was contacted by the NX server doesn't\n\ -seem to be able to start the session. Please check your\n\ -server configuration.\n\ -" - -/* - * Used to handle the backward compatibility. - * Update the numbers if you add a new alert. - */ - -#define LAST_PROTO_STEP_6_ALERT 63 -#define LAST_PROTO_STEP_7_ALERT 65 - -#endif /* NXalert_H */ diff --git a/nxcomp/NXmitshm.h b/nxcomp/NXmitshm.h deleted file mode 100644 index 939d488fb..000000000 --- a/nxcomp/NXmitshm.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef NXmitshm_H -#define NXmitshm_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Import opcodes from - * to get rid of weird dependencies from other - * headers of X environment. - */ - -#define X_ShmQueryVersion 0 -#define X_ShmAttach 1 -#define X_ShmDetach 2 -#define X_ShmPutImage 3 -#define X_ShmGetImage 4 -#define X_ShmCreatePixmap 5 - -#define ShmCompletion 0 -#define ShmNumberEvents (ShmCompletion + 1) - -#define BadShmSeg 0 -#define ShmNumberErrors (BadShmSeg + 1) - -#ifdef __cplusplus -} -#endif - -#endif /* NXmitshm_H */ diff --git a/nxcomp/NXpack.h b/nxcomp/NXpack.h deleted file mode 100644 index 3eade6855..000000000 --- a/nxcomp/NXpack.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef NXpack_H -#define NXpack_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define MASK_METHOD_LIMIT 10 - -#define NO_MASK 0 - -#define MASK_8_COLORS 1 -#define MASK_64_COLORS 2 -#define MASK_256_COLORS 3 -#define MASK_512_COLORS 4 -#define MASK_4K_COLORS 5 -#define MASK_32K_COLORS 6 -#define MASK_64K_COLORS 7 -#define MASK_256K_COLORS 8 -#define MASK_2M_COLORS 9 -#define MASK_16M_COLORS 10 - -#define PACK_METHOD_LIMIT 128 - -#define NO_PACK 0 - -#define PACK_MASKED_8_COLORS 1 -#define PACK_MASKED_64_COLORS 2 -#define PACK_MASKED_256_COLORS 3 -#define PACK_MASKED_512_COLORS 4 -#define PACK_MASKED_4K_COLORS 5 -#define PACK_MASKED_32K_COLORS 6 -#define PACK_MASKED_64K_COLORS 7 -#define PACK_MASKED_256K_COLORS 8 -#define PACK_MASKED_2M_COLORS 9 -#define PACK_MASKED_16M_COLORS 10 - -#define PACK_RAW_8_BITS 3 -#define PACK_RAW_16_BITS 7 -#define PACK_RAW_24_BITS 10 - -#define PACK_COLORMAP_256_COLORS 11 - -#define PACK_JPEG_8_COLORS 26 -#define PACK_JPEG_64_COLORS 27 -#define PACK_JPEG_256_COLORS 28 -#define PACK_JPEG_512_COLORS 29 -#define PACK_JPEG_4K_COLORS 30 -#define PACK_JPEG_32K_COLORS 31 -#define PACK_JPEG_64K_COLORS 32 -#define PACK_JPEG_256K_COLORS 33 -#define PACK_JPEG_2M_COLORS 34 -#define PACK_JPEG_16M_COLORS 35 - -#define PACK_PNG_8_COLORS 37 -#define PACK_PNG_64_COLORS 38 -#define PACK_PNG_256_COLORS 39 -#define PACK_PNG_512_COLORS 40 -#define PACK_PNG_4K_COLORS 41 -#define PACK_PNG_32K_COLORS 42 -#define PACK_PNG_64K_COLORS 43 -#define PACK_PNG_256K_COLORS 44 -#define PACK_PNG_2M_COLORS 45 -#define PACK_PNG_16M_COLORS 46 - -#define PACK_RGB_16M_COLORS 63 -#define PACK_RLE_16M_COLORS 64 - -#define PACK_ALPHA 65 -#define PACK_COLORMAP 66 - -#define PACK_BITMAP_16M_COLORS 67 - -/* - * Not really pack methods. These values - * allow dynamic selection of the pack - * method by the agent. - */ - -#define PACK_NONE 0 -#define PACK_LOSSY 253 -#define PACK_LOSSLESS 254 -#define PACK_ADAPTIVE 255 - -/* - * Reduce the number of colors in the - * image by applying a mask. - */ - -typedef struct -{ - unsigned int color_mask; - unsigned int correction_mask; - unsigned int white_threshold; - unsigned int black_threshold; - -} ColorMask; - -extern const ColorMask Mask8TrueColor; -extern const ColorMask Mask64TrueColor; -extern const ColorMask Mask512TrueColor; -extern const ColorMask Mask4KTrueColor; -extern const ColorMask Mask32KTrueColor; -extern const ColorMask Mask256KTrueColor; -extern const ColorMask Mask2MTrueColor; -extern const ColorMask Mask16MTrueColor; - -const ColorMask *MethodColorMask(unsigned int method); - -int MethodBitsPerPixel(unsigned int method); - -#ifdef __cplusplus -} -#endif - -#endif /* NXpack_H */ diff --git a/nxcomp/NXproto.h b/nxcomp/NXproto.h deleted file mode 100644 index 7b988bdbf..000000000 --- a/nxcomp/NXproto.h +++ /dev/null @@ -1,447 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef NXproto_H -#define NXproto_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -/* - * Force the size to match the wire protocol. - */ - -#define Drawable CARD32 -#define GContext CARD32 - -#define sz_xNXGetControlParametersReq 4 -#define sz_xNXGetCleanupParametersReq 4 -#define sz_xNXGetImageParametersReq 4 -#define sz_xNXGetUnpackParametersReq 8 -#define sz_xNXGetShmemParametersReq 16 -#define sz_xNXGetFontParametersReq 4 -#define sz_xNXSetExposeParametersReq 8 -#define sz_xNXSetCacheParametersReq 8 -#define sz_xNXStartSplitReq 8 -#define sz_xNXEndSplitReq 4 -#define sz_xNXCommitSplitReq 12 -#define sz_xNXSetUnpackGeometryReq 24 -#define sz_xNXSetUnpackColormapReq 16 -#define sz_xNXSetUnpackAlphaReq 16 -#define sz_xNXPutPackedImageReq 40 -#define sz_xNXFreeUnpackReq 4 -#define sz_xNXFinishSplitReq 4 -#define sz_xNXAbortSplitReq 4 -#define sz_xNXFreeSplitReq 4 - -#define sz_xGetControlParametersReply 32 -#define sz_xGetCleanupParametersReply 32 -#define sz_xGetImageParametersReply 32 -#define sz_xGetUnpackParametersReply 32 -#define sz_xGetShmemParametersReply 32 - -#define LINK_TYPE_LIMIT 5 - -#define LINK_TYPE_NONE 0 -#define LINK_TYPE_MODEM 1 -#define LINK_TYPE_ISDN 2 -#define LINK_TYPE_ADSL 3 -#define LINK_TYPE_WAN 4 -#define LINK_TYPE_LAN 5 - -/* - * NX Replies. - */ - -/* - * The following reply has 4 new boolean - * fields in the last protocol version. - */ - -typedef struct _NXGetControlParametersReply { - BYTE type; /* Is X_Reply. */ - CARD8 linkType; - CARD16 sequenceNumber B16; - CARD32 length B32; /* Is 0. */ - CARD8 localMajor; - CARD8 localMinor; - CARD8 localPatch; - CARD8 remoteMajor; - CARD8 remoteMinor; - CARD8 remotePatch; - CARD16 splitTimeout B16; - CARD16 motionTimeout B16; - CARD8 splitMode; - CARD8 pad1; - CARD32 splitSize B32; - CARD8 packMethod; - CARD8 packQuality; - CARD8 dataLevel; - CARD8 streamLevel; - CARD8 deltaLevel; - CARD8 loadCache; - CARD8 saveCache; - CARD8 startupCache; -} xNXGetControlParametersReply; - -typedef struct _NXGetCleanupParametersReply { - BYTE type; /* Is X_Reply. */ - BYTE pad; - CARD16 sequenceNumber B16; - CARD32 length B32; /* Is 0. */ - BOOL cleanGet; - BOOL cleanAlloc; - BOOL cleanFlush; - BOOL cleanSend; - BOOL cleanImages; - BYTE pad1, pad2, pad3; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; -} xNXGetCleanupParametersReply; - -typedef struct _NXGetImageParametersReply { - BYTE type; /* Is X_Reply. */ - BYTE pad; - CARD16 sequenceNumber B16; - CARD32 length B32; /* Is 0. */ - BOOL imageSplit; - BOOL imageMask; - BOOL imageFrame; - CARD8 imageMaskMethod; - CARD8 imageSplitMethod; - BYTE pad1, pad2, pad3; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; -} xNXGetImageParametersReply; - -/* - * Data is made of PACK_METHOD_LIMIT values of - * type BOOL telling which unpack capabilities - * are implemented in proxy. - */ - -typedef struct _NXGetUnpackParametersReply { - BYTE type; /* Is X_Reply. */ - BYTE pad; - CARD16 sequenceNumber B16; - CARD32 length B32; /* Is PACK_METHOD_LIMIT / 4 from NXpack.h. */ - CARD8 entries; /* Is PACK_METHOD_LIMIT. */ - BYTE pad1, pad2, pad3; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - CARD32 pad8 B32; -} xNXGetUnpackParametersReply; - -typedef struct _NXGetShmemParametersReply { - BYTE type; /* Is X_Reply. */ - CARD8 stage; /* As in the corresponding request. */ - CARD16 sequenceNumber B16; - CARD32 length B32; /* Is 0. */ - BOOL clientEnabled; /* SHM on path agent to proxy. */ - BOOL serverEnabled; /* SHM on path proxy to X server. */ - BYTE pad1, pad2; /* Previous values can be checked */ - CARD32 clientSize B32; /* at end of stage 2. */ - CARD32 serverSize B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; -} xNXGetShmemParametersReply; - -typedef struct _NXGetFontParametersReply { - BYTE type; /* Is X_Reply. */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* Is length of path string + 1 / 4. */ - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; -} xNXGetFontParametersReply; - -/* - * NX Requests. - */ - -typedef struct _NXGetControlParametersReq { - CARD8 reqType; - BYTE pad; - CARD16 length B16; -} xNXGetControlParametersReq; - -typedef struct _NXGetCleanupParametersReq { - CARD8 reqType; - BYTE pad; - CARD16 length B16; -} xNXGetCleanupParametersReq; - -typedef struct _NXGetImageParametersReq { - CARD8 reqType; - BYTE pad; - CARD16 length B16; -} xNXGetImageParametersReq; - -typedef struct _NXGetUnpackParametersReq { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD8 entries; - BYTE pad1, pad2, pad3; -} xNXGetUnpackParametersReq; - -typedef struct _NXGetShmemParametersReq { - CARD8 reqType; - CARD8 stage; /* It is between 0 and 2. */ - CARD16 length B16; - BOOL enableClient; /* X client side support is */ - BOOL enableServer; /* not implemented yet. */ - BYTE pad1, pad2; - CARD32 clientSegment; /* XID identifying the shared */ - CARD32 serverSegment; /* memory segments. */ -} xNXGetShmemParametersReq; - -typedef struct _NXGetFontParametersReq { - CARD8 reqType; - CARD8 pad; - CARD16 length B16; -} xNXGetFontParametersReq; - -/* - * The available split modes. - */ - -#define NXSplitModeDefault 0 -#define NXSplitModeAsync 1 -#define NXSplitModeSync 2 - -typedef struct _NXStartSplitReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; - CARD8 mode; - BYTE pad1, pad2, pad3; -} xNXStartSplitReq; - -typedef struct _NXEndSplitReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; -} xNXEndSplitReq; - -typedef struct _NXCommitSplitReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; - CARD8 propagate; - CARD8 request; - BYTE pad1, pad2; - CARD32 position B32; -} xNXCommitSplitReq; - -typedef struct _NXFinishSplitReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; -} xNXFinishSplitReq; - -typedef struct _NXAbortSplitReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; -} xNXAbortSplitReq; - -typedef struct _NXFreeSplitReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; -} xNXFreeSplitReq; - -typedef struct _NXSetExposeParametersReq { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - BOOL expose; - BOOL graphicsExpose; - BOOL noExpose; - BYTE pad1; -} xNXSetExposeParametersReq; - -typedef struct _NXSetCacheParametersReq { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - BOOL enableCache; - BOOL enableSplit; - BOOL enableSave; - BOOL enableLoad; -} xNXSetCacheParametersReq; - -typedef struct _NXSetUnpackGeometryReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; - CARD8 depth1Bpp; - CARD8 depth4Bpp; - CARD8 depth8Bpp; - CARD8 depth16Bpp; - CARD8 depth24Bpp; - CARD8 depth32Bpp; - BYTE pad1, pad2; - CARD32 redMask B32; - CARD32 greenMask B32; - CARD32 blueMask B32; -} xNXSetUnpackGeometryReq; - -typedef struct _NXSetUnpackColormapReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; - CARD8 method; - BYTE pad1, pad2, pad3; - CARD32 srcLength B32; - CARD32 dstLength B32; -} xNXSetUnpackColormapReq; - -typedef struct _NXSetUnpackAlphaReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; - CARD8 method; - BYTE pad1, pad2, pad3; - CARD32 srcLength B32; - CARD32 dstLength B32; -} xNXSetUnpackAlphaReq; - -typedef struct _NXPutPackedImageReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - CARD8 method; - CARD8 format; - CARD8 srcDepth; - CARD8 dstDepth; - CARD32 srcLength B32; - CARD32 dstLength B32; - INT16 srcX B16, srcY B16; - CARD16 srcWidth B16, srcHeight B16; - INT16 dstX B16, dstY B16; - CARD16 dstWidth B16, dstHeight B16; -} xNXPutPackedImageReq; - -typedef struct _NXFreeUnpackReq { - CARD8 reqType; - CARD8 resource; - CARD16 length B16; -} xNXFreeUnpackReq; - -/* - * The X_NXSplitData and X_NXSplitEvent opcodes - * are used internally and are ignored if coming - * from the agent. - */ - -#define X_NXInternalGenericData 0 -#define X_NXInternalGenericReply 1 -#define X_NXInternalGenericRequest 255 - -#define X_NXInternalShapeExtension 128 -#define X_NXInternalRenderExtension 129 - -#define X_NXFirstOpcode 230 -#define X_NXLastOpcode 252 - -#define X_NXGetControlParameters 230 -#define X_NXGetCleanupParameters 231 -#define X_NXGetImageParameters 232 -#define X_NXGetUnpackParameters 233 -#define X_NXStartSplit 234 -#define X_NXEndSplit 235 -#define X_NXSplitData 236 -#define X_NXCommitSplit 237 -#define X_NXSetExposeParameters 240 -#define X_NXSetUnpackGeometry 241 -#define X_NXSetUnpackColormap 242 -#define X_NXPutPackedImage 243 -#define X_NXSplitEvent 244 -#define X_NXGetShmemParameters 245 -#define X_NXSetUnpackAlpha 246 -#define X_NXFreeUnpack 247 -#define X_NXFinishSplit 248 -#define X_NXAbortSplit 249 -#define X_NXFreeSplit 250 -#define X_NXGetFontParameters 251 -#define X_NXSetCacheParameters 252 - -/* - * The following events are received by the agent - * in the form of a ClientMessage with the value - * 0 in fields atom and window. The format is - * always 32. Event specific data starts at byte - * offset 12. - * - * These events are sent by the NX transport to - * notify the agent about the result of a split - * operation. - */ - -#define NXNoSplitNotify 1 -#define NXStartSplitNotify 2 -#define NXCommitSplitNotify 3 -#define NXEndSplitNotify 4 -#define NXEmptySplitNotify 5 - -/* - * Notifications of collect events. These events - * don't come from the NX transport but are put - * back in client's event queue by NXlib. - */ - -#define NXCollectImageNotify 8 -#define NXCollectPropertyNotify 9 -#define NXCollectGrabPointerNotify 10 -#define NXCollectInputFocusNotify 11 - -#undef Drawable -#undef GContext - -#ifdef __cplusplus -} -#endif - -#endif /* NXproto_H */ diff --git a/nxcomp/NXrender.h b/nxcomp/NXrender.h deleted file mode 100644 index 280715833..000000000 --- a/nxcomp/NXrender.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef NXrender_H -#define NXrender_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Import this from - * to compile under old XFree86 distributions - * when render extension was not present yet. - */ - -#define X_RenderQueryVersion 0 -#define X_RenderQueryPictFormats 1 -#define X_RenderQueryPictIndexValues 2 -#define X_RenderQueryDithers 3 -#define X_RenderCreatePicture 4 -#define X_RenderChangePicture 5 -#define X_RenderSetPictureClipRectangles 6 -#define X_RenderFreePicture 7 -#define X_RenderComposite 8 -#define X_RenderScale 9 -#define X_RenderTrapezoids 10 -#define X_RenderTriangles 11 -#define X_RenderTriStrip 12 -#define X_RenderTriFan 13 -#define X_RenderColorTrapezoids 14 -#define X_RenderColorTriangles 15 -#define X_RenderTransform 16 -#define X_RenderCreateGlyphSet 17 -#define X_RenderReferenceGlyphSet 18 -#define X_RenderFreeGlyphSet 19 -#define X_RenderAddGlyphs 20 -#define X_RenderAddGlyphsFromPicture 21 -#define X_RenderFreeGlyphs 22 -#define X_RenderCompositeGlyphs8 23 -#define X_RenderCompositeGlyphs16 24 -#define X_RenderCompositeGlyphs32 25 -#define X_RenderFillRectangles 26 -/* 0.5 */ -#define X_RenderCreateCursor 27 -/* 0.6 */ -#define X_RenderSetPictureTransform 28 -#define X_RenderQueryFilters 29 -#define X_RenderSetPictureFilter 30 -#define X_RenderCreateAnimCursor 31 - -#ifdef __cplusplus -} -#endif - -#endif /* NXrender_H */ diff --git a/nxcomp/NXvars.h b/nxcomp/NXvars.h deleted file mode 100644 index f514000d7..000000000 --- a/nxcomp/NXvars.h +++ /dev/null @@ -1,201 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef NXvars_H -#define NXvars_H - -/* - * This can be included by the proxy or another - * layer that doesn't use Xlib. - */ - -#if !defined(_XLIB_H_) && !defined(_XKBSRV_H_) - -#define NeedFunctionPrototypes 1 - -#define Display void - -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Display flush policies. - */ - -#define NXPolicyImmediate 1 -#define NXPolicyDeferred 2 - -/* - * Type of flush. - */ - -#define NXFlushBuffer 0 -#define NXFlushLink 1 - -/* - * Type of statistics. - */ - -#define NXStatisticsPartial 0 -#define NXStatisticsTotal 1 - -/* - * Reason why the display is blocking. - */ - -#define NXBlockRead 1 -#define NXBlockWrite 2 - -/* - * Set if the client is interested in ignoring - * the display error and continue with the exe- - * cution of the program. By default the usual - * Xlib behaviour is gotten, and the library - * will call an exit(). - */ - -extern int _NXHandleDisplayError; - -/* - * The function below is called whenever Xlib is - * going to perform an I/O operation. The funct- - * ion can be redefined to include additional - * checks aimed at detecting if the display needs - * to be closed, for example because of an event - * or a signal mandating the end of the session. - * In this way the client program can regain the - * control before Xlib blocks waiting for input - * from the network. - */ - -typedef int (*NXDisplayErrorPredicate)( -#if NeedFunctionPrototypes - Display* /* display */, - int /* reason */ -#endif -); - -extern NXDisplayErrorPredicate _NXDisplayErrorFunction; - -/* - * This is called when Xlib is going to block - * waiting for the display to become readable or - * writable. The client can use the hook to run - * any arbitrary operation that may require some - * time to complete. The user should not try to - * read or write to the display inside the call- - * back routine. - */ - -typedef void (*NXDisplayBlockHandler)( -#if NeedFunctionPrototypes - Display* /* display */, - int /* reason */ -#endif -); - -extern NXDisplayBlockHandler _NXDisplayBlockFunction; - -/* - * Used to notify the program when more data - * is written to the socket. - */ - -typedef void (*NXDisplayWriteHandler)( -#if NeedFunctionPrototypes - Display* /* display */, - int /* length */ -#endif -); - -extern NXDisplayWriteHandler _NXDisplayWriteFunction; - -/* - * This callback is used to notify the agent - * that the proxy link has been flushed. - */ - -typedef void (*NXDisplayFlushHandler)( -#if NeedFunctionPrototypes - Display* /* display */, - int /* length */ -#endif -); - -extern NXDisplayFlushHandler _NXDisplayFlushFunction; - -/* - * Used by the NX transport to get an arbitrary - * string to add to its protocol statistics. - */ - -typedef void (*NXDisplayStatisticsHandler)( -#if NeedFunctionPrototypes - Display* /* display */, - char* /* buffer */, - int /* size */ -#endif -); - -extern NXDisplayStatisticsHandler _NXDisplayStatisticsFunction; - -/* - * Let users redefine the function printing an - * error message in the case of a out-of-order - * sequence number. - */ - -typedef void (*NXLostSequenceHandler)( -#if NeedFunctionPrototypes - Display* /* display */, - unsigned long /* newseq */, - unsigned long /* lastseq */, - unsigned int /* type */ -#endif -); - -extern NXLostSequenceHandler _NXLostSequenceFunction; - -/* - * Let the X server run the children processes - * (as for example the keyboard initialization - * utilities) by using the native system libra- - * ries, instead of the libraries shipped with - * the NX environment. If set, the Popen() in - * the X server will remove the LD_LIBRARY_PATH - * setting from the environment before calling - * the execl() function in the child process. - */ - -extern int _NXUnsetLibraryPath; - -#ifdef __cplusplus -} -#endif - -#endif /* NXvars_H */ diff --git a/nxcomp/OpcodeCache.h b/nxcomp/OpcodeCache.h deleted file mode 100644 index e07a1b997..000000000 --- a/nxcomp/OpcodeCache.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef OpcodeCache_H -#define OpcodeCache_H - -#include "CharCache.h" - -class OpcodeCache -{ - friend class EncodeBuffer; - friend class DecodeBuffer; - - public: - - OpcodeCache() - { - slot_ = 0; - } - - ~OpcodeCache() - { - } - - private: - - CharCache base_[256]; - unsigned char slot_; -}; - -#endif /* OpcodeCache_H */ diff --git a/nxcomp/OpcodeStore.cpp b/nxcomp/OpcodeStore.cpp deleted file mode 100644 index 66a425d53..000000000 --- a/nxcomp/OpcodeStore.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "OpcodeStore.h" - -OpcodeStore::OpcodeStore() -{ - // - // Assign values of the specific - // NX opcodes. - // - - getControlParameters = X_NXGetControlParameters; - getCleanupParameters = X_NXGetCleanupParameters; - getImageParameters = X_NXGetImageParameters; - getUnpackParameters = X_NXGetUnpackParameters; - getShmemParameters = X_NXGetShmemParameters; - getFontParameters = X_NXGetFontParameters; - - startSplit = X_NXStartSplit; - endSplit = X_NXEndSplit; - commitSplit = X_NXCommitSplit; - finishSplit = X_NXFinishSplit; - abortSplit = X_NXAbortSplit; - - splitData = X_NXSplitData; - splitEvent = X_NXSplitEvent; - - setCacheParameters = X_NXSetCacheParameters; - setExposeParameters = X_NXSetExposeParameters; - - setUnpackGeometry = X_NXSetUnpackGeometry; - setUnpackColormap = X_NXSetUnpackColormap; - setUnpackAlpha = X_NXSetUnpackAlpha; - - putPackedImage = X_NXPutPackedImage; - - freeUnpack = X_NXFreeUnpack; - freeSplit = X_NXFreeSplit; - - // - // These values must be fetched - // from the X server. - // - - shapeExtension = 0; - renderExtension = 0; - - // - // Events sent as ClientMessage. - // - - noSplitNotify = NXNoSplitNotify; - startSplitNotify = NXStartSplitNotify; - commitSplitNotify = NXCommitSplitNotify; - endSplitNotify = NXEndSplitNotify; - emptySplitNotify = NXEmptySplitNotify; -} - -OpcodeStore::~OpcodeStore() -{ -} diff --git a/nxcomp/OpcodeStore.h b/nxcomp/OpcodeStore.h deleted file mode 100644 index d041ed4b8..000000000 --- a/nxcomp/OpcodeStore.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef OpcodeStore_H -#define OpcodeStore_H - -#include "NXproto.h" - -class OpcodeStore -{ - public: - - OpcodeStore(); - - ~OpcodeStore(); - - // - // Map NX protocol messages. At the moment mapping is hard- - // coded. Opcodes should be instead agreed with the proxied - // X server (by excluding all opcodes used for extensions) - // and exported by the proxy class to channels. - // - // Some toolkits query the server only once for extensions' - // opcodes and share the same settings across all channels. - // This could be a problem as channels needed to monitor the - // traffic to find out the extensions' opcodes themselves, - // so it is important that proxy passes an instance of this - // class to new channels. - // - - unsigned char getControlParameters; - unsigned char getCleanupParameters; - unsigned char getImageParameters; - unsigned char getUnpackParameters; - unsigned char getShmemParameters; - unsigned char getFontParameters; - - unsigned char startSplit; - unsigned char endSplit; - unsigned char commitSplit; - unsigned char finishSplit; - unsigned char abortSplit; - - unsigned char splitData; - unsigned char splitEvent; - - unsigned char setCacheParameters; - unsigned char setExposeParameters; - - unsigned char setUnpackGeometry; - unsigned char setUnpackColormap; - unsigned char setUnpackAlpha; - - unsigned char putPackedImage; - - unsigned char freeUnpack; - unsigned char freeSplit; - - unsigned char shapeExtension; - unsigned char renderExtension; - - unsigned char noSplitNotify; - unsigned char startSplitNotify; - unsigned char commitSplitNotify; - unsigned char endSplitNotify; - unsigned char emptySplitNotify; -}; - -#endif /* OpcodeStore_H */ diff --git a/nxcomp/Pack.c b/nxcomp/Pack.c deleted file mode 100644 index 97fb93b5f..000000000 --- a/nxcomp/Pack.c +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include "NXpack.h" - -const ColorMask Mask8TrueColor = { 128, 63, 240, 7 }; -const ColorMask Mask64TrueColor = { 192, 7, 240, 4 }; -const ColorMask Mask256TrueColor = { 255, 0, 255, 0 }; -const ColorMask Mask512TrueColor = { 224, 5, 240, 4 }; -const ColorMask Mask4KTrueColor = { 240, 4, 240, 2 }; -const ColorMask Mask32KTrueColor = { 248, 3, 248, 2 }; -const ColorMask Mask64KTrueColor = { 255, 0, 255, 0 }; -const ColorMask Mask256KTrueColor = { 252, 1, 252, 1 }; -const ColorMask Mask2MTrueColor = { 255, 0, 254, 1 }; -const ColorMask Mask16MTrueColor = { 255, 0, 255, 0 }; - -const ColorMask *MethodColorMask(unsigned int method) -{ - switch (method) - { - case MASK_8_COLORS: - { - return &Mask8TrueColor; - } - case MASK_64_COLORS: - { - return &Mask64TrueColor; - } - case MASK_256_COLORS: - { - return &Mask256TrueColor; - } - case MASK_512_COLORS: - { - return &Mask512TrueColor; - } - case MASK_4K_COLORS: - { - return &Mask4KTrueColor; - } - case MASK_32K_COLORS: - { - return &Mask32KTrueColor; - } - case MASK_64K_COLORS: - { - return &Mask64KTrueColor; - } - case MASK_256K_COLORS: - { - return &Mask256KTrueColor; - } - case MASK_2M_COLORS: - { - return &Mask2MTrueColor; - } - case MASK_16M_COLORS: - { - return &Mask16MTrueColor; - } - default: - { - return NULL; - } - } -} - -int MethodBitsPerPixel(unsigned int method) -{ - switch (method) - { - case PACK_MASKED_8_COLORS: - case PACK_JPEG_8_COLORS: - case PACK_PNG_8_COLORS: - { - return 8; - } - case PACK_MASKED_64_COLORS: - case PACK_JPEG_64_COLORS: - case PACK_PNG_64_COLORS: - { - return 8; - } - case PACK_MASKED_256_COLORS: - case PACK_JPEG_256_COLORS: - case PACK_PNG_256_COLORS: - { - return 8; - } - case PACK_MASKED_512_COLORS: - case PACK_JPEG_512_COLORS: - case PACK_PNG_512_COLORS: - { - return 16; - } - case PACK_MASKED_4K_COLORS: - case PACK_JPEG_4K_COLORS: - case PACK_PNG_4K_COLORS: - { - return 16; - } - case PACK_MASKED_32K_COLORS: - case PACK_JPEG_32K_COLORS: - case PACK_PNG_32K_COLORS: - { - return 16; - } - case PACK_MASKED_64K_COLORS: - case PACK_JPEG_64K_COLORS: - case PACK_PNG_64K_COLORS: - { - return 16; - } - case PACK_MASKED_256K_COLORS: - case PACK_JPEG_256K_COLORS: - case PACK_PNG_256K_COLORS: - { - return 24; - } - case PACK_MASKED_2M_COLORS: - case PACK_JPEG_2M_COLORS: - case PACK_PNG_2M_COLORS: - { - return 24; - } - case PACK_MASKED_16M_COLORS: - case PACK_JPEG_16M_COLORS: - case PACK_PNG_16M_COLORS: - { - return 24; - } - case PACK_BITMAP_16M_COLORS: - case PACK_RGB_16M_COLORS: - case PACK_RLE_16M_COLORS: - { - return 24; - } - default: - { - return 0; - } - } -} - -#ifdef __cplusplus -} -#endif diff --git a/nxcomp/Pgn.cpp b/nxcomp/Pgn.cpp deleted file mode 100644 index 17e1702d4..000000000 --- a/nxcomp/Pgn.cpp +++ /dev/null @@ -1,805 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// This file obviously supports PNG -// decompression. It was renamed to -// avoid name clashes on Windows. -// - -#include - -#ifdef ANDROID -#include -#endif -#include -#include -#include - -#include "Unpack.h" -#include "Pgn.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#define RGB24_TO_PIXEL(bpp,r,g,b) \ - ((((CARD##bpp)(r) & 0xFF) * srcRedMax2 + 127) / 255 \ - << srcRedShift2 | \ - (((CARD##bpp)(g) & 0xFF) * srcGreenMax2 + 127) / 255 \ - << srcGreenShift2 | \ - (((CARD##bpp)(b) & 0xFF) * srcBlueMax2 + 127) / 255 \ - << srcBlueShift2) - -#define RGB24_TO_PIXEL32(r,g,b) \ - (((CARD32)(r) & 0xFF) << srcRedShift2 | \ - ((CARD32)(g) & 0xFF) << srcGreenShift2 | \ - ((CARD32)(b) & 0xFF) << srcBlueShift2) - -// -// Functions from Unpack.cpp -// - -extern int Unpack32To32(const T_colormask *colormask, const unsigned int *data, - unsigned int *out, unsigned int *end); - -extern int Unpack24To24(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -extern int Unpack16To16(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -// -// Local functions used for the png decompression. -// - -static int DecompressPng16(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, - int byteOrder); - -static int DecompressPng24(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, - int byteOrder); - -static int DecompressPng32(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, - int byteOrder); - -static void PngReadData(png_structp png_ptr, png_bytep data, png_size_t length); - -// -// Colormap stuff. -// - -CARD16 srcRedMax2, srcGreenMax2, srcBlueMax2; -CARD8 srcRedShift2, srcGreenShift2, srcBlueShift2; - -// -// Attributes used for the png decompression. -// - -static char *tmpBuf; -static int tmpBufSize = 0; -static int streamPos; - -int UnpackPng(T_geometry *geometry, unsigned char method, unsigned char *srcData, - int srcSize, int dstBpp, int dstWidth, int dstHeight, - unsigned char *dstData, int dstSize) -{ - int byteOrder = geometry -> image_byte_order; - - // - // Check if data is coming from a failed unsplit. - // - - if (srcSize < 2 || (srcData[0] == SPLIT_PATTERN && - srcData[1] == SPLIT_PATTERN)) - { - #ifdef WARNING - *logofs << "UnpackPng: WARNING! Skipping unpack of dummy data.\n" - << logofs_flush; - #endif - - return -1; - } - - #ifdef DEBUG - *logofs << "UnpackPng: Decompressing image with " - << "srcSize " << srcSize << " and bpp " - << dstBpp << ".\n" << logofs_flush; - #endif - - srcRedShift2 = ffs(geometry -> red_mask) - 1; - srcGreenShift2 = ffs(geometry -> green_mask) - 1; - srcBlueShift2 = ffs(geometry -> blue_mask) - 1; - srcRedMax2 = geometry -> red_mask >> srcRedShift2; - srcGreenMax2 = geometry -> green_mask >> srcGreenShift2; - srcBlueMax2 = geometry -> blue_mask >> srcBlueShift2; - - // - // Make enough space in the temporary - // buffer to have one complete row of - // the image with 3 bytes per pixel. - // - - tmpBufSize = dstWidth * 3; - tmpBuf = new char [tmpBufSize]; - - if (tmpBuf == NULL) - { - #ifdef PANIC - *logofs << "UnpackPng: PANIC! Cannot allocate " - << dstWidth * 3 << " bytes for PNG " - << "decompressed data.\n" << logofs_flush; - #endif - - delete [] tmpBuf; - - return -1; - } - - int result = 1; - - switch (dstBpp) - { - case 8: - { - // - // Simply move the data from srcData to dstData - // taking into consideration the correct padding. - // - - int row; - - unsigned char * dstBuff = dstData; - unsigned char * srcBuff = srcData; - - for (row = 0; row < dstHeight; row++) - { - memcpy(dstBuff, srcBuff, dstWidth ); - - dstBuff += RoundUp4(dstWidth); - srcBuff += dstWidth; - } - } - case 16: - { - result = DecompressPng16(srcData, srcSize, dstWidth, - dstHeight, dstData, byteOrder); - break; - } - case 24: - { - result = DecompressPng24(srcData, srcSize, dstWidth, - dstHeight, dstData, byteOrder); - break; - } - case 32: - { - result = DecompressPng32(srcData, srcSize, dstWidth, - dstHeight, dstData, byteOrder); - break; - } - default: - { - #ifdef PANIC - *logofs << "UnpackPng: PANIC! Error in PNG compression. " - << " Unsupported Bpp value " << dstBpp - << " for the PNG compression" - << ".\n" << logofs_flush; - #endif - - delete [] tmpBuf; - - result = -1; - } - } - - if (result == -1) - { - delete [] tmpBuf; - - return result; - } - - // - // Apply the correction for the brightness - // - - int maskMethod; - - switch (method) - { - case PACK_PNG_8_COLORS: - { - maskMethod = MASK_8_COLORS; - - break; - } - case PACK_PNG_64_COLORS: - { - maskMethod = MASK_64_COLORS; - - break; - } - case PACK_PNG_256_COLORS: - { - maskMethod = MASK_256_COLORS; - - break; - } - case PACK_PNG_512_COLORS: - { - maskMethod = MASK_512_COLORS; - - break; - } - case PACK_PNG_4K_COLORS: - { - maskMethod = MASK_4K_COLORS; - - break; - } - case PACK_PNG_32K_COLORS: - { - maskMethod = MASK_32K_COLORS; - - break; - } - case PACK_PNG_64K_COLORS: - { - maskMethod = MASK_64K_COLORS; - - break; - } - case PACK_PNG_256K_COLORS: - { - maskMethod = MASK_256K_COLORS; - - break; - } - case PACK_PNG_2M_COLORS: - { - maskMethod = MASK_2M_COLORS; - - break; - } - case PACK_PNG_16M_COLORS: - { - maskMethod = MASK_16M_COLORS; - - break; - } - default: - { - #ifdef PANIC - *logofs << "DecompressPng16: PANIC! " - << " No matching decompression method.\n" - << logofs_flush; - #endif - - delete [] tmpBuf; - - return -1; - } - } - - const T_colormask *colorMask = MethodColorMask(maskMethod); - - unsigned char *dstBuff = dstData; - - switch (dstBpp) - { - case 16: - { - Unpack16To16(colorMask, dstBuff, dstBuff, dstBuff + dstSize); - - break; - } - case 24: - { - break; - } - case 32: - { - Unpack32To32(colorMask, (unsigned int *)dstBuff, (unsigned int *)dstBuff, - (unsigned int *)(dstBuff + dstSize)); - break; - } - default: - { - #ifdef PANIC - *logofs << "DecompressPng16: PANIC! " - << " No matching destination bits per plane.\n" - << logofs_flush; - #endif - - delete [] tmpBuf; - - return -1; - } - } - - delete [] tmpBuf; - - return 1; -} - - -// -// Functions that actually do -// the PNG decompression. -// - -int DecompressPng16(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) -{ - unsigned char *data; - unsigned int dx, dy; - - png_structp pngPtr; - png_infop infoPtr; - png_bytep rowPointers; - - - streamPos = 0; - - pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - if (!pngPtr) - { - #ifdef PANIC - *logofs << "DecompressPng16: PANIC! " - << " Failed png_create_read_struct operation" - << ".\n" << logofs_flush; - #endif - - return -1; - } - - infoPtr = png_create_info_struct(pngPtr); - - if (!infoPtr) - { - #ifdef PANIC - *logofs << "DecompressPng16: PANIC! " - << "Failed png_create_info_struct operation" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, NULL, NULL); - - return -1; - } - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng16: PANIC! " - << "Error during IO initialization" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - png_set_read_fn(pngPtr, (void *)compressedData, PngReadData); - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng16: PANIC! " - << "Error during read of PNG header" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - png_read_info(pngPtr, infoPtr); - - if (png_get_color_type(pngPtr, infoPtr) == PNG_COLOR_TYPE_PALETTE) - { - png_set_expand(pngPtr); - } - - // - // data points to dstBuf which is - // already padded correctly for the final - // image to put - // - - data = dstBuf; - rowPointers = (png_byte *) tmpBuf; - - // - // We use setjmp() to save our context. - // The PNG library will call longjmp() - // in case of error. - // - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng16: PANIC! " - << "Error during read of PNG rows" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - unsigned long pixel; - - for (dy = 0; dy < h; dy++) - { - png_read_row(pngPtr, rowPointers, NULL); - - for (dx = 0; dx < w; dx++) - { - pixel = RGB24_TO_PIXEL(16, tmpBuf[dx*3], tmpBuf[dx*3+1], tmpBuf[dx*3+2]); - - // - // Follow the server byte order when arranging data. - // - - if (byteOrder == LSBFirst) - { - data[0] = (unsigned char) (pixel & 0xff); - data[1] = (unsigned char) ((pixel >> 8) & 0xff); - } - else - { - data[1] = (unsigned char) (pixel & 0xff); - data[0] = (unsigned char) ((pixel >> 8) & 0xff); - } - - data += 2; - } - - // - // Move pixelPtr at the beginning of the - // next line. - // - - data = data + (RoundUp4(w * 2) - w * 2); - } - - png_destroy_read_struct(&pngPtr, &infoPtr,NULL); - - #ifdef DEBUG - *logofs << "DecompressPng16: Decompression finished." - << dy << " lines handled.\n" - << logofs_flush; - #endif - - return 1; -} - -int DecompressPng24(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) -{ - static CARD8 *pixelPtr = NULL; - unsigned int dx, dy; - - png_structp pngPtr; - png_infop infoPtr; - png_bytep rowPointers; - - - streamPos = 0; - - pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - if (!pngPtr) - { - #ifdef PANIC - *logofs << "DecompressPng24: PANIC! " - << "Failed png_create_read_struct operation" - << ".\n" << logofs_flush; - #endif - - return -1; - } - - infoPtr = png_create_info_struct(pngPtr); - - if (!infoPtr) - { - #ifdef PANIC - *logofs << "DecompressPng24: PANIC! " - << "Failed png_create_info_struct operation" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, NULL, NULL); - - return -1; - } - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng24: PANIC! " - << "Error during IO initialization" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - png_set_read_fn(pngPtr, (void *)compressedData, PngReadData); - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng24: PANIC! " - << "Error during read of PNG header" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - png_read_info( pngPtr, infoPtr ) ; - - if (png_get_color_type(pngPtr, infoPtr) == PNG_COLOR_TYPE_PALETTE) - { - png_set_expand(pngPtr); - } - - // - // PixelPtr points to dstBuf which is - // already padded correctly for the final - // image to put - // - - pixelPtr = (CARD8 *) dstBuf; - - rowPointers = (png_byte *)tmpBuf; - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng24: PANIC! " - << "Error during read of PNG rows" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - for (dy = 0; dy < h; dy++) - { - png_read_row(pngPtr, rowPointers, NULL); - - for (dx = 0; dx < w; dx++) - { - // - // Follow the server byte order when arranging data. - // - - if (byteOrder == LSBFirst) - { - pixelPtr[0] = tmpBuf[dx * 3]; - pixelPtr[1] = tmpBuf[dx * 3 + 1]; - pixelPtr[2] = tmpBuf[dx * 3 + 2]; - } - else - { - pixelPtr[2] = tmpBuf[dx * 3]; - pixelPtr[1] = tmpBuf[dx * 3 + 1]; - pixelPtr[0] = tmpBuf[dx * 3 + 2]; - } - - pixelPtr += 3; - } - - // - // Go to the next line. - // - - pixelPtr = (CARD8 *) (((char *) pixelPtr) + (RoundUp4(w * 3) - w * 3)); - } - - png_destroy_read_struct(&pngPtr, &infoPtr,NULL); - - #ifdef DEBUG - *logofs << "DecompressPng24: Decompression finished." - << dy << " lines handled.\n" - << logofs_flush; - #endif - - return 1; -} - -int DecompressPng32(unsigned char *compressedData, int compressedLen, - unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) -{ - unsigned char *data; - - unsigned int dx, dy; - - png_structp pngPtr; - png_infop infoPtr; - png_bytep rowPointers; - - streamPos = 0; - - pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - if (!pngPtr) - { - #ifdef PANIC - *logofs << "DecompressPng32: PANIC! " - << "Failed png_create_read_struct operation" - << ".\n" << logofs_flush; - #endif - - return -1; - } - - infoPtr = png_create_info_struct(pngPtr); - - if (!infoPtr) - { - #ifdef PANIC - *logofs << "DecompressPng32: PANIC! " - << "Failed png_create_info_struct operation." - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, NULL, NULL); - - return -1; - } - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng32: PANIC! " - << "Error during IO initialization" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - png_set_read_fn(pngPtr, (void *)compressedData, PngReadData); - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng32: PANIC! " - << "Error during read of PNG header" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - png_read_info(pngPtr, infoPtr) ; - - - if (png_get_color_type(pngPtr, infoPtr) == PNG_COLOR_TYPE_PALETTE) - { - png_set_expand(pngPtr); - } - - // - // data points to dstBuf which is - // already padded correctly for the final - // image to put - // - - data = dstBuf; - - rowPointers = (png_byte *) tmpBuf; - - if (setjmp(png_jmpbuf(pngPtr))) - { - #ifdef PANIC - *logofs << "DecompressPng32: PANIC! " - << "Error during read of PNG rows" - << ".\n" << logofs_flush; - #endif - - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - - return -1; - } - - unsigned long pixel; - - int i; - - for (dy = 0; dy < h; dy++) - { - png_read_row(pngPtr, rowPointers, NULL); - - for (dx = 0; dx < w; dx++) - { - pixel = RGB24_TO_PIXEL(32, tmpBuf[dx * 3], tmpBuf[dx * 3 + 1], - tmpBuf[dx * 3 + 2]); - - // - // Follow the server byte order when arranging data. - // - - if (byteOrder == LSBFirst) - { - for (i = 0; i < 4; i++) - { - data[i] = (unsigned char)(pixel & 0xff); - pixel >>= 8; - } - } - else - { - for (i = 3; i >= 0; i--) - { - data[i] = (unsigned char) (pixel & 0xff); - pixel >>= 8; - } - } - - data += 4; - } - } - - png_destroy_read_struct(&pngPtr, &infoPtr,NULL); - - #ifdef DEBUG - *logofs << "DecompressPng32: Decompression finished." - << dy << " lines handled.\n" - << logofs_flush; - #endif - - return 1; -} - -static void PngReadData(png_structp png_ptr, png_bytep data, png_size_t length) -{ - memcpy((char *) data, (char *) png_get_io_ptr(png_ptr) + streamPos, length); - - streamPos += length; -} diff --git a/nxcomp/Pgn.h b/nxcomp/Pgn.h deleted file mode 100644 index e5ea36715..000000000 --- a/nxcomp/Pgn.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Pgn_H -#define Pgn_H - -// -// This file obviously supports PNG -// decompression. It was renamed to -// avoid name clashes on Windows. -// - -#include "Misc.h" -#include "Unpack.h" - -int UnpackPng(T_geometry *geometry, unsigned char method, unsigned char *srcData, - int srcSize, int dstBpp, int dstWidth, int dstHeight, - unsigned char *dstData, int dstSize); - -#endif /* Pgn_H */ diff --git a/nxcomp/Pipe.cpp b/nxcomp/Pipe.cpp deleted file mode 100644 index 88f10edb4..000000000 --- a/nxcomp/Pipe.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#include "Pipe.h" -#include "Misc.h" -#include "Fork.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -extern void RegisterChild(int child); - -static int Psplit(const char *command, char *parameters[], int limit); - -// -// These are slightly modified versions of popen(3) and pclose(3) -// that don't rely on a shell to be available on the system, so -// that they can also work on Windows. As an additional benefit, -// these functions give up all privileges before running the com- -// mand. Code is taken from the X distribution and, in turn, is -// based on libc from FreeBSD 2.2. -// - -static struct pid -{ - struct pid *next; - FILE *fp; - int self; - -} *pidlist; - -// -// A very unsofisticated attempt to parse the command line and -// split each parameter in distinct strings. This is not going -// to work when dealing with parameters containing spaces, even -// if they are enclosed in quotes. -// - -int Psplit(const char *command, char *parameters[], int limit) -{ - char *line; - char *value; - - int number; - - // - // Preapare the list of parameters. - // - - for (number = 0; number < limit; number++) - { - parameters[number] = NULL; - } - - // - // Copy the command to get rid of the - // const qualifier. - // - - line = new char[strlen(command) + 1]; - - if (line == NULL) - { - goto PsplitError; - } - - strcpy(line, command); - - number = 0; - - value = strtok(line, " "); - - while (value != NULL && number < limit) - { - #ifdef DEBUG - *logofs << "Psplit: Got parameter '" << value - << "'.\n" << logofs_flush; - #endif - - parameters[number] = new char[strlen(value) + 1]; - - if (parameters[number] == NULL) - { - goto PsplitError; - } - - strcpy(parameters[number], value); - - number++; - - // - // If this is the first parameter, then - // copy it in the second position and - // use it as the name of the command. - // - - if (number == 1) - { - parameters[number] = new char[strlen(value) + 1]; - - if (parameters[number] == NULL) - { - goto PsplitError; - } - - strcpy(parameters[number], value); - - number++; - } - - value = strtok(NULL, " "); - } - - // - // Needs at least to have the command itself and - // the first argument, being again the name of - // the command. - // - - if (number < 2) - { - goto PsplitError; - } - - return number; - -PsplitError: - - #ifdef PANIC - *logofs << "Psplit: PANIC! Can't split command line '" - << command << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't split command line '" - << command << "'.\n"; - - delete [] line; - - return -1; -} - -FILE *Popen(char * const parameters[], const char *type) -{ - FILE *iop; - - struct pid *cur; - int pdes[2], pid; - - if (parameters == NULL || type == NULL) - { - return NULL; - } - - if ((*type != 'r' && *type != 'w') || type[1]) - { - return NULL; - } - - if ((cur = (struct pid *) malloc(sizeof(struct pid))) == NULL) - { - return NULL; - } - - if (pipe(pdes) < 0) - { - free(cur); - - return NULL; - } - - // - // Block all signals until command is exited. - // We need to gather information about the - // child in Pclose(). - // - - DisableSignals(); - - switch (pid = Fork()) - { - case -1: - { - // - // Error. - // - - #ifdef PANIC - *logofs << "Popen: PANIC! Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Function fork failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - close(pdes[0]); - close(pdes[1]); - - free(cur); - - return NULL; - } - case 0: - { - // - // Child. - // - - struct passwd *pwent = getpwuid(getuid()); - if (pwent) initgroups(pwent->pw_name,getgid()); - if (setgid(getgid()) == -1) - { - _exit(127); - } - if (setuid(getuid()) == -1) - { - _exit(127); - } - - if (*type == 'r') - { - if (pdes[1] != 1) - { - // - // Set up stdout. - // - - dup2(pdes[1], 1); - close(pdes[1]); - } - - close(pdes[0]); - } - else - { - if (pdes[0] != 0) - { - // - // Set up stdin. - // - - dup2(pdes[0], 0); - close(pdes[0]); - } - - close(pdes[1]); - } - - execvp(parameters[0], parameters + 1); - - exit(127); - } - } - - // - // Parent. Save data about the child. - // - - RegisterChild(pid); - - if (*type == 'r') - { - iop = fdopen(pdes[0], type); - - close(pdes[1]); - } - else - { - iop = fdopen(pdes[1], type); - - close(pdes[0]); - } - - cur -> fp = iop; - cur -> self = pid; - cur -> next = pidlist; - - pidlist = cur; - - #ifdef TEST - *logofs << "Popen: Executing "; - - for (int i = 0; i < 256 && parameters[i] != NULL; i++) - { - *logofs << "[" << parameters[i] << "]"; - } - - *logofs << " with descriptor " << fileno(iop) - << ".\n" << logofs_flush; - #endif - - return iop; -} - -FILE *Popen(const char *command, const char *type) -{ - char *parameters[256]; - - if (Psplit(command, parameters, 256) > 0) - { - FILE *file = Popen(parameters, type); - - for (int i = 0; i < 256; i++) - { - delete [] parameters[i]; - } - - return file; - } - else - { - #ifdef PANIC - *logofs << "Popen: PANIC! Failed to parse command '" - << command << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to parse command '" - << command << "'.\n"; - - return NULL; - } -} - -int Pclose(FILE *iop) -{ - struct pid *cur, *last; - - int pstat; - int pid; - - #ifdef TEST - *logofs << "Pclose: Closing command with output " - << "on descriptor " << fileno(iop) << ".\n" - << logofs_flush; - #endif - - fclose((FILE *) iop); - - for (last = NULL, cur = pidlist; cur; last = cur, cur = cur -> next) - { - if (cur -> fp == iop) - { - break; - } - } - - if (cur == NULL) - { - #ifdef PANIC - *logofs << "Pclose: PANIC! Failed to find the process " - << "for descriptor " << fileno(iop) << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to find the process " - << "for descriptor " << fileno(iop) << ".\n"; - - return -1; - } - - do - { - #ifdef TEST - *logofs << "Pclose: Going to wait for process " - << "with pid '" << cur -> self << "'.\n" - << logofs_flush; - #endif - - pid = waitpid(cur -> self, &pstat, 0); - } - while (pid == -1 && errno == EINTR); - - if (last == NULL) - { - pidlist = cur -> next; - } - else - { - last -> next = cur -> next; - } - - free(cur); - - // - // Child has finished and we called the - // waitpid(). We can enable signals again. - // - - EnableSignals(); - - return (pid == -1 ? -1 : pstat); -} diff --git a/nxcomp/Pipe.h b/nxcomp/Pipe.h deleted file mode 100644 index fd1061d30..000000000 --- a/nxcomp/Pipe.h +++ /dev/null @@ -1,35 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// These are slightly modified versions of popen(3) and pclose(3) -// that don't rely on a shell to be available on the system, so -// that they can also work on Windows. -// - -extern FILE *Popen(char * const parameters[], const char *type); -extern FILE *Popen(const char *command, const char *type); - -extern int Pclose(FILE *file); diff --git a/nxcomp/PolyArc.cpp b/nxcomp/PolyArc.cpp deleted file mode 100644 index 8996c6f15..000000000 --- a/nxcomp/PolyArc.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PolyArc.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int PolyArcStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyArcMessage *polyArc = (PolyArcMessage *) message; - - // - // Here is the fingerprint. - // - - polyArc -> drawable = GetULONG(buffer + 4, bigEndian); - polyArc -> gcontext = GetULONG(buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PolyArcStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyArcMessage *polyArc = (PolyArcMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(polyArc -> drawable, buffer + 4, bigEndian); - PutULONG(polyArc -> gcontext, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PolyArcStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PolyArcMessage *polyArc = (PolyArcMessage *) message; - - *logofs << name() << ": Identity drawable " << polyArc -> drawable - << ", gcontext " << polyArc -> gcontext - << ", size " << polyArc -> size_ << ".\n" << logofs_flush; - #endif -} - -void PolyArcStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} - -void PolyArcStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - PolyArcMessage *polyArc = (PolyArcMessage *) message; - PolyArcMessage *cachedPolyArc = (PolyArcMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyArc -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyArc -> drawable, clientCache -> drawableCache); - - cachedPolyArc -> drawable = polyArc -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyArc -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyArc -> gcontext, clientCache -> gcCache); - - cachedPolyArc -> gcontext = polyArc -> gcontext; -} - -void PolyArcStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - PolyArcMessage *polyArc = (PolyArcMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - polyArc -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyArc -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - polyArc -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyArc -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/PolyArc.h b/nxcomp/PolyArc.h deleted file mode 100644 index d744d6a10..000000000 --- a/nxcomp/PolyArc.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PolyArc_H -#define PolyArc_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define POLYARC_ENABLE_CACHE 1 -#define POLYARC_ENABLE_DATA 0 -#define POLYARC_ENABLE_SPLIT 0 -#define POLYARC_ENABLE_COMPRESS 0 - -#define POLYARC_DATA_LIMIT 1980 -#define POLYARC_DATA_OFFSET 12 - -#define POLYARC_CACHE_SLOTS 2000 -#define POLYARC_CACHE_THRESHOLD 2 -#define POLYARC_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class PolyArcMessage : public Message -{ - friend class PolyArcStore; - - public: - - PolyArcMessage() - { - } - - ~PolyArcMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int drawable; - unsigned int gcontext; -}; - -class PolyArcStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PolyArcStore() : MessageStore() - { - enableCache = POLYARC_ENABLE_CACHE; - enableData = POLYARC_ENABLE_DATA; - enableSplit = POLYARC_ENABLE_SPLIT; - enableCompress = POLYARC_ENABLE_COMPRESS; - - dataLimit = POLYARC_DATA_LIMIT; - dataOffset = POLYARC_DATA_OFFSET; - - cacheSlots = POLYARC_CACHE_SLOTS; - cacheThreshold = POLYARC_CACHE_THRESHOLD; - cacheLowerThreshold = POLYARC_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~PolyArcStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "PolyArc"; - } - - virtual unsigned char opcode() const - { - return X_PolyArc; - } - - virtual unsigned int storage() const - { - return sizeof(PolyArcMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new PolyArcMessage(); - } - - virtual Message *create(const Message &message) const - { - return new PolyArcMessage((const PolyArcMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (PolyArcMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PolyArc_H */ diff --git a/nxcomp/PolyFillArc.cpp b/nxcomp/PolyFillArc.cpp deleted file mode 100644 index f995a8815..000000000 --- a/nxcomp/PolyFillArc.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PolyFillArc.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int PolyFillArcStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; - - // - // Here is the fingerprint. - // - - polyFillArc -> drawable = GetULONG(buffer + 4, bigEndian); - polyFillArc -> gcontext = GetULONG(buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PolyFillArcStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(polyFillArc -> drawable, buffer + 4, bigEndian); - PutULONG(polyFillArc -> gcontext, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PolyFillArcStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; - - *logofs << name() << ": Identity drawable " << polyFillArc -> drawable - << ", gcontext " << polyFillArc -> gcontext - << ", size " << polyFillArc -> size_ << ".\n" << logofs_flush; - #endif -} - -void PolyFillArcStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} - -void PolyFillArcStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; - PolyFillArcMessage *cachedPolyFillArc = (PolyFillArcMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyFillArc -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyFillArc -> drawable, clientCache -> drawableCache); - - cachedPolyFillArc -> drawable = polyFillArc -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyFillArc -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyFillArc -> gcontext, clientCache -> gcCache); - - cachedPolyFillArc -> gcontext = polyFillArc -> gcontext; -} - -void PolyFillArcStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - polyFillArc -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyFillArc -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - polyFillArc -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyFillArc -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/PolyFillArc.h b/nxcomp/PolyFillArc.h deleted file mode 100644 index a4eff5b48..000000000 --- a/nxcomp/PolyFillArc.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PolyFillArc_H -#define PolyFillArc_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define POLYFILLARC_ENABLE_CACHE 1 -#define POLYFILLARC_ENABLE_DATA 0 -#define POLYFILLARC_ENABLE_SPLIT 0 -#define POLYFILLARC_ENABLE_COMPRESS 0 - -#define POLYFILLARC_DATA_LIMIT 6144 -#define POLYFILLARC_DATA_OFFSET 12 - -#define POLYFILLARC_CACHE_SLOTS 2000 -#define POLYFILLARC_CACHE_THRESHOLD 2 -#define POLYFILLARC_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class PolyFillArcMessage : public Message -{ - friend class PolyFillArcStore; - - public: - - PolyFillArcMessage() - { - } - - ~PolyFillArcMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int drawable; - unsigned int gcontext; -}; - -class PolyFillArcStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PolyFillArcStore() : MessageStore() - { - enableCache = POLYFILLARC_ENABLE_CACHE; - enableData = POLYFILLARC_ENABLE_DATA; - enableSplit = POLYFILLARC_ENABLE_SPLIT; - enableCompress = POLYFILLARC_ENABLE_COMPRESS; - - dataLimit = POLYFILLARC_DATA_LIMIT; - dataOffset = POLYFILLARC_DATA_OFFSET; - - cacheSlots = POLYFILLARC_CACHE_SLOTS; - cacheThreshold = POLYFILLARC_CACHE_THRESHOLD; - cacheLowerThreshold = POLYFILLARC_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~PolyFillArcStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "PolyFillArc"; - } - - virtual unsigned char opcode() const - { - return X_PolyFillArc; - } - - virtual unsigned int storage() const - { - return sizeof(PolyFillArcMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new PolyFillArcMessage(); - } - - virtual Message *create(const Message &message) const - { - return new PolyFillArcMessage((const PolyFillArcMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (PolyFillArcMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PolyFillArc_H */ diff --git a/nxcomp/PolyFillRectangle.cpp b/nxcomp/PolyFillRectangle.cpp deleted file mode 100644 index d0f1452b2..000000000 --- a/nxcomp/PolyFillRectangle.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PolyFillRectangle.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int PolyFillRectangleStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; - - // - // Here is the fingerprint. - // - - polyFillRectangle -> drawable = GetULONG(buffer + 4, bigEndian); - polyFillRectangle -> gcontext = GetULONG(buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PolyFillRectangleStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(polyFillRectangle -> drawable, buffer + 4, bigEndian); - PutULONG(polyFillRectangle -> gcontext, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PolyFillRectangleStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; - - *logofs << name() << ": Identity drawable " << polyFillRectangle -> drawable - << ", gcontext " << polyFillRectangle -> gcontext - << ", size " << polyFillRectangle -> size_ << ".\n" << logofs_flush; - #endif -} - -void PolyFillRectangleStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} - -void PolyFillRectangleStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; - PolyFillRectangleMessage *cachedPolyFillRectangle = (PolyFillRectangleMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding value " << polyFillRectangle -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyFillRectangle -> drawable, clientCache -> drawableCache); - - cachedPolyFillRectangle -> drawable = polyFillRectangle -> drawable; - - #ifdef DEBUG - *logofs << name() << ": Encoding value " << polyFillRectangle -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyFillRectangle -> gcontext, clientCache -> gcCache); - - cachedPolyFillRectangle -> gcontext = polyFillRectangle -> gcontext; -} - -void PolyFillRectangleStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - polyFillRectangle -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyFillRectangle -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - polyFillRectangle -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyFillRectangle -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/PolyFillRectangle.h b/nxcomp/PolyFillRectangle.h deleted file mode 100644 index 7ebb9270d..000000000 --- a/nxcomp/PolyFillRectangle.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PolyFillRectangle_H -#define PolyFillRectangle_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define POLYFILLRECTANGLE_ENABLE_CACHE 1 -#define POLYFILLRECTANGLE_ENABLE_DATA 0 -#define POLYFILLRECTANGLE_ENABLE_SPLIT 0 -#define POLYFILLRECTANGLE_ENABLE_COMPRESS 0 - -#define POLYFILLRECTANGLE_DATA_LIMIT 2048 -#define POLYFILLRECTANGLE_DATA_OFFSET 12 - -#define POLYFILLRECTANGLE_CACHE_SLOTS 4000 -#define POLYFILLRECTANGLE_CACHE_THRESHOLD 5 -#define POLYFILLRECTANGLE_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class PolyFillRectangleMessage : public Message -{ - friend class PolyFillRectangleStore; - - public: - - PolyFillRectangleMessage() - { - } - - ~PolyFillRectangleMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int drawable; - unsigned int gcontext; -}; - -class PolyFillRectangleStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PolyFillRectangleStore() : MessageStore() - { - enableCache = POLYFILLRECTANGLE_ENABLE_CACHE; - enableData = POLYFILLRECTANGLE_ENABLE_DATA; - enableSplit = POLYFILLRECTANGLE_ENABLE_SPLIT; - enableCompress = POLYFILLRECTANGLE_ENABLE_COMPRESS; - - dataLimit = POLYFILLRECTANGLE_DATA_LIMIT; - dataOffset = POLYFILLRECTANGLE_DATA_OFFSET; - - cacheSlots = POLYFILLRECTANGLE_CACHE_SLOTS; - cacheThreshold = POLYFILLRECTANGLE_CACHE_THRESHOLD; - cacheLowerThreshold = POLYFILLRECTANGLE_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~PolyFillRectangleStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "PolyFillRectangle"; - } - - virtual unsigned char opcode() const - { - return X_PolyFillRectangle; - } - - virtual unsigned int storage() const - { - return sizeof(PolyFillRectangleMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new PolyFillRectangleMessage(); - } - - virtual Message *create(const Message &message) const - { - return new PolyFillRectangleMessage((const PolyFillRectangleMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (PolyFillRectangleMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PolyFillRectangle_H */ diff --git a/nxcomp/PolyLine.cpp b/nxcomp/PolyLine.cpp deleted file mode 100644 index 845985728..000000000 --- a/nxcomp/PolyLine.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PolyLine.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int PolyLineStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyLineMessage *polyLine = (PolyLineMessage *) message; - - // - // Here is the fingerprint. - // - - polyLine -> mode = *(buffer + 1); - - polyLine -> drawable = GetULONG(buffer + 4, bigEndian); - polyLine -> gcontext = GetULONG(buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PolyLineStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyLineMessage *polyLine = (PolyLineMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = polyLine -> mode; - - PutULONG(polyLine -> drawable, buffer + 4, bigEndian); - PutULONG(polyLine -> gcontext, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PolyLineStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PolyLineMessage *polyLine = (PolyLineMessage *) message; - - *logofs << name() << ": Identity drawable " << polyLine -> drawable - << ", gcontext " << polyLine -> gcontext - << ", size " << polyLine -> size_ << ".\n" << logofs_flush; - #endif -} - -void PolyLineStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // Since ProtoStep8 (#issue 108) - md5_append(md5_state_, buffer + 1, 1); -} - -void PolyLineStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - PolyLineMessage *polyLine = (PolyLineMessage *) message; - PolyLineMessage *cachedPolyLine = (PolyLineMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyLine -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyLine -> drawable, clientCache -> drawableCache); - - cachedPolyLine -> drawable = polyLine -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyLine -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyLine -> gcontext, clientCache -> gcCache); - - cachedPolyLine -> gcontext = polyLine -> gcontext; -} - -void PolyLineStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - PolyLineMessage *polyLine = (PolyLineMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - polyLine -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyLine -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - polyLine -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyLine -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/PolyLine.h b/nxcomp/PolyLine.h deleted file mode 100644 index 66fa5df1a..000000000 --- a/nxcomp/PolyLine.h +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PolyLine_H -#define PolyLine_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define POLYLINE_ENABLE_CACHE 1 -#define POLYLINE_ENABLE_DATA 0 -#define POLYLINE_ENABLE_SPLIT 0 -#define POLYLINE_ENABLE_COMPRESS 0 - -#define POLYLINE_DATA_LIMIT 144 -#define POLYLINE_DATA_OFFSET 12 - -#define POLYLINE_CACHE_SLOTS 3000 -#define POLYLINE_CACHE_THRESHOLD 3 -#define POLYLINE_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class PolyLineMessage : public Message -{ - friend class PolyLineStore; - - public: - - PolyLineMessage() - { - } - - ~PolyLineMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char mode; - unsigned int drawable; - unsigned int gcontext; -}; - -class PolyLineStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PolyLineStore() : MessageStore() - { - enableCache = POLYLINE_ENABLE_CACHE; - enableData = POLYLINE_ENABLE_DATA; - enableSplit = POLYLINE_ENABLE_SPLIT; - enableCompress = POLYLINE_ENABLE_COMPRESS; - - dataLimit = POLYLINE_DATA_LIMIT; - dataOffset = POLYLINE_DATA_OFFSET; - - cacheSlots = POLYLINE_CACHE_SLOTS; - cacheThreshold = POLYLINE_CACHE_THRESHOLD; - cacheLowerThreshold = POLYLINE_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~PolyLineStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "PolyLine"; - } - - virtual unsigned char opcode() const - { - return X_PolyLine; - } - - virtual unsigned int storage() const - { - return sizeof(PolyLineMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new PolyLineMessage(); - } - - virtual Message *create(const Message &message) const - { - return new PolyLineMessage((const PolyLineMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (PolyLineMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PolyLine_H */ diff --git a/nxcomp/PolyPoint.cpp b/nxcomp/PolyPoint.cpp deleted file mode 100644 index dfd77f40b..000000000 --- a/nxcomp/PolyPoint.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PolyPoint.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int PolyPointStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyPointMessage *polyPoint = (PolyPointMessage *) message; - - // - // Here is the fingerprint. - // - - polyPoint -> mode = *(buffer + 1); - - polyPoint -> drawable = GetULONG(buffer + 4, bigEndian); - polyPoint -> gcontext = GetULONG(buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PolyPointStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyPointMessage *polyPoint = (PolyPointMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = polyPoint -> mode; - - PutULONG(polyPoint -> drawable, buffer + 4, bigEndian); - PutULONG(polyPoint -> gcontext, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PolyPointStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PolyPointMessage *polyPoint = (PolyPointMessage *) message; - - *logofs << name() << ": Identity drawable " << polyPoint -> drawable - << ", gcontext " << polyPoint -> gcontext - << ", size " << polyPoint -> size_ << ".\n" << logofs_flush; - #endif -} - -void PolyPointStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // Since ProtoStep8 (#issue 108) - md5_append(md5_state_, buffer + 1, 1); -} - -void PolyPointStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - PolyPointMessage *polyPoint = (PolyPointMessage *) message; - PolyPointMessage *cachedPolyPoint = (PolyPointMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyPoint -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyPoint -> drawable, clientCache -> drawableCache); - - cachedPolyPoint -> drawable = polyPoint -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyPoint -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyPoint -> gcontext, clientCache -> gcCache); - - cachedPolyPoint -> gcontext = polyPoint -> gcontext; -} - -void PolyPointStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - PolyPointMessage *polyPoint = (PolyPointMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - polyPoint -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyPoint -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - polyPoint -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyPoint -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/PolyPoint.h b/nxcomp/PolyPoint.h deleted file mode 100644 index b8ea183bf..000000000 --- a/nxcomp/PolyPoint.h +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PolyPoint_H -#define PolyPoint_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define POLYPOINT_ENABLE_CACHE 1 -#define POLYPOINT_ENABLE_DATA 0 -#define POLYPOINT_ENABLE_SPLIT 0 -#define POLYPOINT_ENABLE_COMPRESS 0 - -#define POLYPOINT_DATA_LIMIT 3200 -#define POLYPOINT_DATA_OFFSET 12 - -#define POLYPOINT_CACHE_SLOTS 3000 -#define POLYPOINT_CACHE_THRESHOLD 3 -#define POLYPOINT_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class PolyPointMessage : public Message -{ - friend class PolyPointStore; - - public: - - PolyPointMessage() - { - } - - ~PolyPointMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char mode; - unsigned int drawable; - unsigned int gcontext; -}; - -class PolyPointStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PolyPointStore() : MessageStore() - { - enableCache = POLYPOINT_ENABLE_CACHE; - enableData = POLYPOINT_ENABLE_DATA; - enableSplit = POLYPOINT_ENABLE_SPLIT; - enableCompress = POLYPOINT_ENABLE_COMPRESS; - - dataLimit = POLYPOINT_DATA_LIMIT; - dataOffset = POLYPOINT_DATA_OFFSET; - - cacheSlots = POLYPOINT_CACHE_SLOTS; - cacheThreshold = POLYPOINT_CACHE_THRESHOLD; - cacheLowerThreshold = POLYPOINT_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~PolyPointStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "PolyPoint"; - } - - virtual unsigned char opcode() const - { - return X_PolyPoint; - } - - virtual unsigned int storage() const - { - return sizeof(PolyPointMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new PolyPointMessage(); - } - - virtual Message *create(const Message &message) const - { - return new PolyPointMessage((const PolyPointMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (PolyPointMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PolyPoint_H */ diff --git a/nxcomp/PolySegment.cpp b/nxcomp/PolySegment.cpp deleted file mode 100644 index 34c2461f1..000000000 --- a/nxcomp/PolySegment.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PolySegment.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int PolySegmentStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolySegmentMessage *polySegment = (PolySegmentMessage *) message; - - // - // Here is the fingerprint. - // - - polySegment -> drawable = GetULONG(buffer + 4, bigEndian); - polySegment -> gcontext = GetULONG(buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PolySegmentStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolySegmentMessage *polySegment = (PolySegmentMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(polySegment -> drawable, buffer + 4, bigEndian); - PutULONG(polySegment -> gcontext, buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PolySegmentStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PolySegmentMessage *polySegment = (PolySegmentMessage *) message; - - *logofs << name() << ": Identity drawable " << polySegment -> drawable - << ", gcontext " << polySegment -> gcontext - << ", size " << polySegment -> size_ << ".\n" << logofs_flush; - #endif -} - -void PolySegmentStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} - -void PolySegmentStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - PolySegmentMessage *polySegment = (PolySegmentMessage *) message; - PolySegmentMessage *cachedPolySegment = (PolySegmentMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polySegment -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polySegment -> drawable, clientCache -> drawableCache); - - cachedPolySegment -> drawable = polySegment -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polySegment -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polySegment -> gcontext, clientCache -> gcCache); - - cachedPolySegment -> gcontext = polySegment -> gcontext; -} - -void PolySegmentStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - PolySegmentMessage *polySegment = (PolySegmentMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - polySegment -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polySegment -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - polySegment -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polySegment -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/PolySegment.h b/nxcomp/PolySegment.h deleted file mode 100644 index 53fd42c60..000000000 --- a/nxcomp/PolySegment.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PolySegment_H -#define PolySegment_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define POLYSEGMENT_ENABLE_CACHE 1 -#define POLYSEGMENT_ENABLE_DATA 0 -#define POLYSEGMENT_ENABLE_SPLIT 0 -#define POLYSEGMENT_ENABLE_COMPRESS 0 - -#define POLYSEGMENT_DATA_LIMIT 8192 -#define POLYSEGMENT_DATA_OFFSET 12 - -#define POLYSEGMENT_CACHE_SLOTS 3000 -#define POLYSEGMENT_CACHE_THRESHOLD 5 -#define POLYSEGMENT_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class PolySegmentMessage : public Message -{ - friend class PolySegmentStore; - - public: - - PolySegmentMessage() - { - } - - ~PolySegmentMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int drawable; - unsigned int gcontext; -}; - -class PolySegmentStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PolySegmentStore() : MessageStore() - { - enableCache = POLYSEGMENT_ENABLE_CACHE; - enableData = POLYSEGMENT_ENABLE_DATA; - enableSplit = POLYSEGMENT_ENABLE_SPLIT; - enableCompress = POLYSEGMENT_ENABLE_COMPRESS; - - dataLimit = POLYSEGMENT_DATA_LIMIT; - dataOffset = POLYSEGMENT_DATA_OFFSET; - - cacheSlots = POLYSEGMENT_CACHE_SLOTS; - cacheThreshold = POLYSEGMENT_CACHE_THRESHOLD; - cacheLowerThreshold = POLYSEGMENT_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~PolySegmentStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "PolySegment"; - } - - virtual unsigned char opcode() const - { - return X_PolySegment; - } - - virtual unsigned int storage() const - { - return sizeof(PolySegmentMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new PolySegmentMessage(); - } - - virtual Message *create(const Message &message) const - { - return new PolySegmentMessage((const PolySegmentMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (PolySegmentMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PolySegment_H */ diff --git a/nxcomp/PolyText16.cpp b/nxcomp/PolyText16.cpp deleted file mode 100644 index 80c77a70f..000000000 --- a/nxcomp/PolyText16.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PolyText16.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int PolyText16Store::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyText16Message *polyText16 = (PolyText16Message *) message; - - // - // Here is the fingerprint. - // - - polyText16 -> drawable = GetULONG(buffer + 4, bigEndian); - polyText16 -> gcontext = GetULONG(buffer + 8, bigEndian); - - polyText16 -> x = GetUINT(buffer + 12, bigEndian); - polyText16 -> y = GetUINT(buffer + 14, bigEndian); - - // - // Clean up padding bytes. - // - - #ifdef DUMP - - DumpData(buffer, size); - - *logofs << "\n" << logofs_flush; - - #endif - - if ((int) size > dataOffset) - { - int current; - int length; - int delta; - int item; - - unsigned int nitem; - - unsigned char *pad = NULL; - unsigned char *end = NULL; - - delta = 1; - nitem = 0; - - #ifdef DUMP - *logofs << name() << " Size " << size << ".\n" << logofs_flush; - #endif - - // - // Data is a list of TextItem where element - // can be a string or a font shift. - // - - current = POLYTEXT16_DATA_OFFSET; - length = POLYTEXT16_DATA_OFFSET; - - do - { - #ifdef DUMP - *logofs << name() << " Current " << current << ".\n" << logofs_flush; - #endif - - item = GetUINT(buffer + length , bigEndian); - - if (item < 255) - { - // - // Text element. Number represents - // the 'Length of CHAR2B string' - // field. - // - - length += ((item * 2) + delta + 1); - - nitem++; - } - else if (item == 255) - { - // - // Element is a font shift. - // - - length += 5; - - nitem++; - } - - #ifdef DUMP - *logofs << name() << " Item " << item << ".\n" << logofs_flush; - #endif - - current += length; - } - while(current < (int) size && item != 0); - - #ifdef DUMP - *logofs << name() << " Final length " << length << ".\n" << logofs_flush; - #endif - - end = ((unsigned char *) buffer) + size; - - pad = ((unsigned char *) buffer) + length; - - for (; pad < end && nitem >= 1; pad++) - { - #ifdef DUMP - *logofs << name() << " Padding " << " .\n" << logofs_flush; - #endif - - *pad = 0; - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PolyText16Store::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyText16Message *polyText16 = (PolyText16Message *) message; - - // - // Fill all the message's fields. - // - - PutULONG(polyText16 -> drawable, buffer + 4, bigEndian); - PutULONG(polyText16 -> gcontext, buffer + 8, bigEndian); - - PutUINT(polyText16 -> x, buffer + 12, bigEndian); - PutUINT(polyText16 -> y, buffer + 14, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PolyText16Store::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PolyText16Message *polyText16 = (PolyText16Message *) message; - - *logofs << name() << ": Identity drawable " << polyText16 -> drawable - << ", gcontext " << polyText16 -> gcontext << ", x " << polyText16 -> x - << ", y " << polyText16 -> y << ", size " << polyText16 -> size_ - << ".\n"; - - #endif -} - -void PolyText16Store::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} - -void PolyText16Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - PolyText16Message *polyText16 = (PolyText16Message *) message; - PolyText16Message *cachedPolyText16 = (PolyText16Message *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyText16 -> drawable - << " as " << "drawable" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyText16 -> drawable, clientCache -> drawableCache); - - cachedPolyText16 -> drawable = polyText16 -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyText16 -> gcontext - << " as " << "gcontext" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyText16 -> gcontext, clientCache -> gcCache); - - cachedPolyText16 -> gcontext = polyText16 -> gcontext; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyText16 -> x - << " as " << "x" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_x = polyText16 -> x - cachedPolyText16 -> x; - - encodeBuffer.encodeCachedValue(diff_x, 16, - clientCache -> polyTextCacheX); - - cachedPolyText16 -> x = polyText16 -> x; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyText16 -> y - << " as " << "y" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_y = polyText16 -> y - cachedPolyText16 -> y; - - encodeBuffer.encodeCachedValue(diff_y, 16, - clientCache -> polyTextCacheY); - - cachedPolyText16 -> y = polyText16 -> y; -} - -void PolyText16Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - PolyText16Message *polyText16 = (PolyText16Message *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - polyText16 -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyText16 -> drawable - << " as " << "drawable" << " field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - polyText16 -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyText16 -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> polyTextCacheX); - - polyText16 -> x += value; - polyText16 -> x &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyText16 -> x - << " as x field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> polyTextCacheY); - - polyText16 -> y += value; - polyText16 -> y &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyText16 -> y - << " as y field.\n" << logofs_flush; - #endif -} - - diff --git a/nxcomp/PolyText16.h b/nxcomp/PolyText16.h deleted file mode 100644 index 805e1fa04..000000000 --- a/nxcomp/PolyText16.h +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PolyText16_H -#define PolyText16_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define POLYTEXT16_ENABLE_CACHE 1 -#define POLYTEXT16_ENABLE_DATA 0 -#define POLYTEXT16_ENABLE_SPLIT 0 -#define POLYTEXT16_ENABLE_COMPRESS 0 - -#define POLYTEXT16_DATA_LIMIT 420 -#define POLYTEXT16_DATA_OFFSET 16 - -#define POLYTEXT16_CACHE_SLOTS 3000 -#define POLYTEXT16_CACHE_THRESHOLD 4 -#define POLYTEXT16_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class PolyText16Message : public Message -{ - friend class PolyText16Store; - - public: - - PolyText16Message() - { - } - - ~PolyText16Message() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int drawable; - unsigned int gcontext; - - unsigned short x; - unsigned short y; -}; - -class PolyText16Store : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PolyText16Store() : MessageStore() - { - enableCache = POLYTEXT16_ENABLE_CACHE; - enableData = POLYTEXT16_ENABLE_DATA; - enableSplit = POLYTEXT16_ENABLE_SPLIT; - enableCompress = POLYTEXT16_ENABLE_COMPRESS; - - dataLimit = POLYTEXT16_DATA_LIMIT; - dataOffset = POLYTEXT16_DATA_OFFSET; - - cacheSlots = POLYTEXT16_CACHE_SLOTS; - cacheThreshold = POLYTEXT16_CACHE_THRESHOLD; - cacheLowerThreshold = POLYTEXT16_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~PolyText16Store() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "PolyText16"; - } - - virtual unsigned char opcode() const - { - return X_PolyText16; - } - - virtual unsigned int storage() const - { - return sizeof(PolyText16Message); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new PolyText16Message(); - } - - virtual Message *create(const Message &message) const - { - return new PolyText16Message((const PolyText16Message &) message); - } - - virtual void destroy(Message *message) const - { - delete (PolyText16Message *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PolyText16_H */ diff --git a/nxcomp/PolyText8.cpp b/nxcomp/PolyText8.cpp deleted file mode 100644 index 50c21f79e..000000000 --- a/nxcomp/PolyText8.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PolyText8.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int PolyText8Store::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyText8Message *polyText8 = (PolyText8Message *) message; - - // - // Here is the fingerprint. - // - - polyText8 -> drawable = GetULONG(buffer + 4, bigEndian); - polyText8 -> gcontext = GetULONG(buffer + 8, bigEndian); - - polyText8 -> x = GetUINT(buffer + 12, bigEndian); - polyText8 -> y = GetUINT(buffer + 14, bigEndian); - - // - // Clean up padding bytes. - // - - #ifdef DUMP - - DumpData(buffer, size); - - *logofs << "\n\n" << logofs_flush; - - #endif - - if ((int) size > dataOffset) - { - int length; - int current; - int delta; - int item; - - unsigned int nitem; - - unsigned char *pad = NULL; - unsigned char *end = NULL; - - delta = 1; - nitem = 0; - - #ifdef DUMP - *logofs << name() << " Size " << size << ".\n" << logofs_flush; - #endif - - // - // Data is a list of TextItem where element - // can be a string or a font shift. - // - - current = POLYTEXT8_DATA_OFFSET; - length = POLYTEXT8_DATA_OFFSET; - - do - { - #ifdef DUMP - *logofs << name() << " Current " << current << ".\n" << logofs_flush; - #endif - - item = GetUINT(buffer + length , bigEndian); - - if (item < 255) - { - // - // Text element. Number represents - // the 'Length of string' field. - // - - length += (item + delta + 1); - - nitem++; - } - else if (item == 255) - { - // - // Element is a font shift. - // - - length += 5; - - nitem++; - } - - #ifdef DUMP - *logofs << name() << " Item " << item << ".\n" << logofs_flush; - #endif - - current += length; - } - while(current < (int) size && item != 0); - - - #ifdef DUMP - *logofs << name() << " Final length " << length << ".\n" << logofs_flush; - #endif - - end = ((unsigned char *) buffer) + size; - - pad = ((unsigned char *) buffer) + length; - - for (; pad < end && nitem >= 1; pad++) - { - #ifdef DUMP - *logofs << name() << " Padding " << " .\n" << logofs_flush; - #endif - - *pad = 0; - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PolyText8Store::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PolyText8Message *polyText8 = (PolyText8Message *) message; - - // - // Fill all the message's fields. - // - - PutULONG(polyText8 -> drawable, buffer + 4, bigEndian); - PutULONG(polyText8 -> gcontext, buffer + 8, bigEndian); - - PutUINT(polyText8 -> x, buffer + 12, bigEndian); - PutUINT(polyText8 -> y, buffer + 14, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PolyText8Store::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PolyText8Message *polyText8 = (PolyText8Message *) message; - - *logofs << name() << ": Identity drawable " << polyText8 -> drawable - << ", gcontext " << polyText8 -> gcontext << ", x " << polyText8 -> x - << ", y " << polyText8 -> y << ", size " << polyText8 -> size_ - << ".\n"; - - #endif -} - -void PolyText8Store::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} - -void PolyText8Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - PolyText8Message *polyText8 = (PolyText8Message *) message; - PolyText8Message *cachedPolyText8 = (PolyText8Message *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyText8 -> drawable - << " as " << "drawable" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyText8 -> drawable, clientCache -> drawableCache); - - cachedPolyText8 -> drawable = polyText8 -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyText8 -> gcontext - << " as " << "gcontext" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(polyText8 -> gcontext, clientCache -> gcCache); - - cachedPolyText8 -> gcontext = polyText8 -> gcontext; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyText8 -> x - << " as " << "x" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_x = polyText8 -> x - cachedPolyText8 -> x; - - encodeBuffer.encodeCachedValue(diff_x, 16, - clientCache -> polyTextCacheX); - - cachedPolyText8 -> x = polyText8 -> x; - - #ifdef TEST - *logofs << name() << ": Encoding value " << polyText8 -> y - << " as " << "y" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_y = polyText8 -> y - cachedPolyText8 -> y; - - encodeBuffer.encodeCachedValue(diff_y, 16, - clientCache -> polyTextCacheY); - - cachedPolyText8 -> y = polyText8 -> y; -} - -void PolyText8Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - PolyText8Message *polyText8 = (PolyText8Message *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - polyText8 -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyText8 -> drawable - << " as " << "drawable" << " field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - polyText8 -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyText8 -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> polyTextCacheX); - - polyText8 -> x += value; - polyText8 -> x &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyText8 -> x - << " as x field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> polyTextCacheY); - - polyText8 -> y += value; - polyText8 -> y &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << polyText8 -> y - << " as y field.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/PolyText8.h b/nxcomp/PolyText8.h deleted file mode 100644 index 3d5ff533a..000000000 --- a/nxcomp/PolyText8.h +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PolyText8_H -#define PolyText8_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define POLYTEXT8_ENABLE_CACHE 1 -#define POLYTEXT8_ENABLE_DATA 0 -#define POLYTEXT8_ENABLE_SPLIT 0 -#define POLYTEXT8_ENABLE_COMPRESS 0 - -#define POLYTEXT8_DATA_LIMIT 380 -#define POLYTEXT8_DATA_OFFSET 16 - -#define POLYTEXT8_CACHE_SLOTS 3000 -#define POLYTEXT8_CACHE_THRESHOLD 5 -#define POLYTEXT8_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class PolyText8Message : public Message -{ - friend class PolyText8Store; - - public: - - PolyText8Message() - { - } - - ~PolyText8Message() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int drawable; - unsigned int gcontext; - - unsigned short x; - unsigned short y; -}; - -class PolyText8Store : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PolyText8Store() : MessageStore() - { - enableCache = POLYTEXT8_ENABLE_CACHE; - enableData = POLYTEXT8_ENABLE_DATA; - enableSplit = POLYTEXT8_ENABLE_SPLIT; - enableCompress = POLYTEXT8_ENABLE_COMPRESS; - - dataLimit = POLYTEXT8_DATA_LIMIT; - dataOffset = POLYTEXT8_DATA_OFFSET; - - cacheSlots = POLYTEXT8_CACHE_SLOTS; - cacheThreshold = POLYTEXT8_CACHE_THRESHOLD; - cacheLowerThreshold = POLYTEXT8_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~PolyText8Store() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "PolyText8"; - } - - virtual unsigned char opcode() const - { - return X_PolyText8; - } - - virtual unsigned int storage() const - { - return sizeof(PolyText8Message); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new PolyText8Message(); - } - - virtual Message *create(const Message &message) const - { - return new PolyText8Message((const PolyText8Message &) message); - } - - virtual void destroy(Message *message) const - { - delete (PolyText8Message *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PolyText8_H */ diff --git a/nxcomp/Proxy.cpp b/nxcomp/Proxy.cpp deleted file mode 100644 index 3a7a42362..000000000 --- a/nxcomp/Proxy.cpp +++ /dev/null @@ -1,6525 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef ANDROID -#include -#include -#include -#endif - -#include "Misc.h" - -#if defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun) -#include -#endif - -#ifndef ANDROID -#include -#include -#include -#endif - -#include "NXalert.h" -#include "NXvars.h" - -#include "Proxy.h" - -#include "Socket.h" -#include "Channel.h" -#include "Statistics.h" - -#include "ClientChannel.h" -#include "ServerChannel.h" -#include "GenericChannel.h" -#include "ChannelEndPoint.h" - -// -// We need to adjust some values related -// to these messages at the time the mes- -// sage stores are reconfigured. -// - -#include "PutImage.h" -#include "ChangeGC.h" -#include "PolyFillRectangle.h" -#include "PutPackedImage.h" - -// -// This is from the main loop. -// - -extern void CleanupListeners(); - -extern int HandleChild(int); - -// -// Default size of string buffers. -// - -#define DEFAULT_STRING_LENGTH 512 - -// -// Set the verbosity level. You also need -// to define DUMP in Misc.cpp if DUMP is -// defined here. -// - -#define WARNING -#define PANIC -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Log the important tracepoints related -// to writing packets to the peer proxy. -// - -#undef FLUSH - -// -// Log the operations related to splits. -// - -#undef SPLIT - -// -// Log the operations related to sending -// and receiving the control tokens. -// - -#undef TOKEN - -// -// Log the operations related to setting -// the token limits. -// - -#undef LIMIT - -// -// Log a warning if no data is written by -// the proxy within a timeout. -// - -#undef TIME - -// -// Log the operation related to generating -// the ping message at idle time. -// - -#undef PING - -Proxy::Proxy(int fd) - - : transport_(new ProxyTransport(fd)), fd_(fd), readBuffer_(transport_) -{ - for (int channelId = 0; - channelId < CONNECTIONS_LIMIT; - channelId++) - { - channels_[channelId] = NULL; - transports_[channelId] = NULL; - congestions_[channelId] = 0; - - fdMap_[channelId] = nothing; - channelMap_[channelId] = nothing; - slavePidMap_[channelId] = nothing; - } - - inputChannel_ = nothing; - outputChannel_ = nothing; - - controlLength_ = 0; - - operation_ = operation_in_negotiation; - - draining_ = 0; - priority_ = 0; - finish_ = 0; - shutdown_ = 0; - congestion_ = 0; - - timer_ = 0; - alert_ = 0; - - agent_ = nothing; - - // - // Set null timeouts. This will require - // a new link configuration. - // - - timeouts_.split = 0; - timeouts_.motion = 0; - - timeouts_.readTs = getTimestamp(); - timeouts_.writeTs = getTimestamp(); - - timeouts_.loopTs = getTimestamp(); - timeouts_.pingTs = getTimestamp(); - timeouts_.alertTs = nullTimestamp(); - timeouts_.loadTs = nullTimestamp(); - - timeouts_.splitTs = nullTimestamp(); - timeouts_.motionTs = nullTimestamp(); - - // - // Initialize the token counters. This - // will require a new link configuration. - // - - for (int i = token_control; i <= token_data; i++) - { - tokens_[i].size = 0; - tokens_[i].limit = 0; - - tokens_[i].bytes = 0; - tokens_[i].remaining = 0; - } - - tokens_[token_control].request = code_control_token_request; - tokens_[token_control].reply = code_control_token_reply; - tokens_[token_control].type = token_control; - - tokens_[token_split].request = code_split_token_request; - tokens_[token_split].reply = code_split_token_reply; - tokens_[token_split].type = token_split; - - tokens_[token_data].request = code_data_token_request; - tokens_[token_data].reply = code_data_token_reply; - tokens_[token_data].type = token_data; - - currentStatistics_ = NULL; - - // - // Create compressor and decompressor - // for image and data payload. - // - - compressor_ = new StaticCompressor(control -> LocalDataCompressionLevel, - control -> LocalDataCompressionThreshold); - - // - // Create object storing NX specific - // opcodes. - // - - opcodeStore_ = new OpcodeStore(); - - // - // Create the message stores. - // - - clientStore_ = new ClientStore(compressor_); - serverStore_ = new ServerStore(compressor_); - - clientCache_ = new ClientCache(); - serverCache_ = new ServerCache(); - - if (clientCache_ == NULL || serverCache_ == NULL) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Failed to create the channel cache.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to create the channel cache.\n"; - - HandleCleanup(); - } - - // - // Prepare for image decompression. - // - - UnpackInit(); - - #ifdef DEBUG - *logofs << "Proxy: Created new object at " << this - << ".\n" << logofs_flush; - #endif -} - -Proxy::~Proxy() -{ - for (int channelId = 0; - channelId < CONNECTIONS_LIMIT; - channelId++) - { - if (channels_[channelId] != NULL) - { - deallocateTransport(channelId); - - delete channels_[channelId]; - channels_[channelId] = NULL; - } - } - - // - // Kill all active slave channel children, and - // give them 5 seconds to exit nicely. - - #ifdef DEBUG - *logofs << "Proxy: Killing active slaves" << endl; - #endif - - int slave_count = 999; - int loop_count = 0; - - while(slave_count > 0 && loop_count < 50) - { - slave_count = 0; - - for (int channelId = 0; channelId 1) { - slave_count++; - - #ifdef DEBUG - *logofs << "Proxy: Active slave with pid " << pid << logofs_flush; - #endif - - if ( loop_count == 0 ) - { - #ifdef DEBUG - *logofs << "Proxy: Sending SIGTERM to " << pid << logofs_flush; - #endif - kill(pid, SIGTERM); - } - else if ( loop_count == 25 ) - { - #ifdef DEBUG - *logofs << "Proxy: Sending SIGKILL to " << pid << logofs_flush; - #endif - kill(pid, SIGKILL); - } - - if (HandleChild(pid)) - { - #ifdef DEBUG - *logofs << "Proxy: Slave " << pid << " terminated" << logofs_flush; - #endif - slavePidMap_[channelId] = nothing; - } - } - } - - if ( slave_count > 0 ) - { - cerr << "Proxy: Error: Failed to kill all slave channel processes. " << slave_count << " processes still remaining." << endl; - } - - usleep(200000); - loop_count++; - } - - delete transport_; - delete compressor_; - - // - // Delete storage shared among channels. - // - - delete opcodeStore_; - - delete clientStore_; - delete serverStore_; - - delete clientCache_; - delete serverCache_; - - // - // Get rid of the image decompression - // resources. - // - - UnpackDestroy(); - - #ifdef DEBUG - *logofs << "Proxy: Deleted proxy object at " << this - << ".\n" << logofs_flush; - #endif -} - -int Proxy::setOperational() -{ - #ifdef TEST - *logofs << "Proxy: Entering operational mode.\n" - << logofs_flush; - #endif - - operation_ = operation_in_messages; - - return 1; -} - -int Proxy::setReadDescriptors(fd_set *fdSet, int &fdMax, T_timestamp &tsMax) -{ - // - // Set the initial timeout to the time of - // the next ping. If the congestion count - // is greater than zero, anyway, use a - // shorter timeout to force a congestion - // update. - // - - if (agent_ != nothing && congestions_[agent_] == 0 && - statistics -> getCongestionInFrame() >= 1 && - tokens_[token_control].remaining >= - (tokens_[token_control].limit - 1)) - { - setMinTimestamp(tsMax, control -> IdleTimeout); - - #ifdef TEST - *logofs << "Proxy: Initial timeout is " << tsMax.tv_sec - << " S and " << (double) tsMax.tv_usec / - 1000 << " Ms with congestion " - << statistics -> getCongestionInFrame() - << ".\n" << logofs_flush; - #endif - } - else - { - setMinTimestamp(tsMax, control -> PingTimeout); - - #ifdef TEST - *logofs << "Proxy: Initial timeout is " << tsMax.tv_sec - << " S and " << (double) tsMax.tv_usec / - 1000 << " Ms.\n" << logofs_flush; - #endif - } - - int fd = -1; - - if (isTimeToRead() == 1) - { - // - // If we don't have split tokens available - // don't set the timeout. - // - - if (tokens_[token_split].remaining > 0 && - isTimestamp(timeouts_.splitTs) == 1) - { - int diffTs = getTimeToNextSplit(); - - #if defined(TEST) || defined(INFO) || \ - defined(FLUSH) || defined(SPLIT) - - if (diffTimestamp(timeouts_.splitTs, - getTimestamp()) > timeouts_.split) - { - *logofs << "Proxy: FLUSH! SPLIT! WARNING! Running with " - << diffTimestamp(timeouts_.splitTs, getTimestamp()) - << " Ms elapsed since the last split.\n" - << logofs_flush; - } - - *logofs << "Proxy: FLUSH! SPLIT! Requesting timeout of " - << diffTs << " Ms as there are splits to send.\n" - << logofs_flush; - - #endif - - setMinTimestamp(tsMax, diffTs); - } - #if defined(TEST) || defined(INFO) - else if (isTimestamp(timeouts_.splitTs) == 1) - { - *logofs << "Proxy: WARNING! Not requesting a split " - << "timeout with " << tokens_[token_split].remaining - << " split tokens remaining.\n" << logofs_flush; - } - #endif - - // - // Loop through the valid channels and set - // the descriptors selected for read and - // the timeout. - // - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] == NULL) - { - continue; - } - - fd = getFd(channelId); - - if (channels_[channelId] -> getFinish() == 0 && - (channels_[channelId] -> getType() == channel_x11 || - tokens_[token_data].remaining > 0) && - congestions_[channelId] == 0) - { - FD_SET(fd, fdSet); - - if (fd >= fdMax) - { - fdMax = fd + 1; - } - - #ifdef TEST - *logofs << "Proxy: Descriptor FD#" << fd - << " selected for read with buffer length " - << transports_[channelId] -> length() - << ".\n" << logofs_flush; - #endif - - // - // Wakeup the proxy if there are motion - // events to flush. - // - - if (isTimestamp(timeouts_.motionTs) == 1) - { - int diffTs = getTimeToNextMotion(); - - #if defined(TEST) || defined(INFO) - - if (diffTimestamp(timeouts_.motionTs, - getTimestamp()) > timeouts_.motion) - { - *logofs << "Proxy: FLUSH! WARNING! Running with " - << diffTimestamp(timeouts_.motionTs, getTimestamp()) - << " Ms elapsed since the last motion.\n" - << logofs_flush; - } - - *logofs << "Proxy: FLUSH! Requesting timeout of " - << diffTs << " Ms as FD#" << fd << " has motion " - << "events to send.\n" << logofs_flush; - - #endif - - setMinTimestamp(tsMax, diffTs); - } - } - #if defined(TEST) || defined(INFO) - else - { - if (channels_[channelId] -> getType() != channel_x11 && - tokens_[token_data].remaining <= 0) - { - *logofs << "Proxy: WARNING! Descriptor FD#" << fd - << " not selected for read with " - << tokens_[token_data].remaining << " data " - << "tokens remaining.\n" << logofs_flush; - } - } - #endif - } - } - #if defined(TEST) || defined(INFO) - else - { - *logofs << "Proxy: WARNING! Disabled reading from channels.\n" - << logofs_flush; - - *logofs << "Proxy: WARNING! Congestion is " << congestion_ - << " pending " << transport_ -> pending() << " blocked " - << transport_ -> blocked() << " length " << transport_ -> - length() << ".\n" << logofs_flush; - } - #endif - - // - // Include the proxy descriptor. - // - - FD_SET(fd_, fdSet); - - if (fd_ >= fdMax) - { - fdMax = fd_ + 1; - } - - #ifdef TEST - *logofs << "Proxy: Proxy descriptor FD#" << fd_ - << " selected for read with buffer length " - << transport_ -> length() << ".\n" - << logofs_flush; - #endif - - return 1; -} - -// -// Add to the mask the file descriptors of all -// X connections to write to. -// - -int Proxy::setWriteDescriptors(fd_set *fdSet, int &fdMax, T_timestamp &tsMax) -{ - int fd = -1; - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL) - { - fd = getFd(channelId); - - if (transports_[channelId] -> length() > 0) - { - FD_SET(fd, fdSet); - - #ifdef TEST - *logofs << "Proxy: Descriptor FD#" << fd << " selected " - << "for write with blocked " << transports_[channelId] -> - blocked() << " and length " << transports_[channelId] -> - length() << ".\n" << logofs_flush; - #endif - - if (fd >= fdMax) - { - fdMax = fd + 1; - } - } - #ifdef TEST - else - { - *logofs << "Proxy: Descriptor FD#" << fd << " not selected " - << "for write with blocked " << transports_[channelId] -> - blocked() << " and length " << transports_[channelId] -> - length() << ".\n" << logofs_flush; - } - #endif - - #if defined(TEST) || defined(INFO) - - if (transports_[channelId] -> getType() != - transport_agent && transports_[channelId] -> - length() > 0 && transports_[channelId] -> - blocked() != 1) - { - *logofs << "Proxy: PANIC! Descriptor FD#" << fd - << " has data to write but blocked flag is " - << transports_[channelId] -> blocked() - << ".\n" << logofs_flush; - - cerr << "Error" << ": Descriptor FD#" << fd - << " has data to write but blocked flag is " - << transports_[channelId] -> blocked() - << ".\n"; - - HandleCleanup(); - } - - #endif - } - } - - // - // Check if the proxy transport has data - // from a previous blocking write. - // - - if (transport_ -> blocked() == 1) - { - FD_SET(fd_, fdSet); - - #ifdef TEST - *logofs << "Proxy: Proxy descriptor FD#" - << fd_ << " selected for write. Blocked is " - << transport_ -> blocked() << " length is " - << transport_ -> length() << ".\n" - << logofs_flush; - #endif - - if (fd_ >= fdMax) - { - fdMax = fd_ + 1; - } - } - #ifdef TEST - else - { - *logofs << "Proxy: Proxy descriptor FD#" - << fd_ << " not selected for write. Blocked is " - << transport_ -> blocked() << " length is " - << transport_ -> length() << ".\n" - << logofs_flush; - } - #endif - - // - // We are entering the main select. Save - // the timestamp of the last loop so that - // we can detect the clock drifts. - // - - timeouts_.loopTs = getTimestamp(); - - return 1; -} - -int Proxy::getChannels(T_channel_type type) -{ - int channels = 0; - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL && - (type == channel_none || - type == channels_[channelId] -> - getType())) - { - channels++; - } - } - - return channels; -} - -T_channel_type Proxy::getType(int fd) -{ - int channelId = getChannel(fd); - - if (channelId < 0 || channels_[channelId] == NULL) - { - return channel_none; - } - - return channels_[channelId] -> getType(); -} - -const char *Proxy::getTypeName(T_channel_type type) -{ - switch (type) - { - case channel_x11: - { - return "X"; - } - case channel_cups: - { - return "CUPS"; - } - case channel_smb: - { - return "SMB"; - } - case channel_media: - { - return "media"; - } - case channel_http: - { - return "HTTP"; - } - case channel_font: - { - return "font"; - } - case channel_slave: - { - return "slave"; - } - default: - { - return "unknown"; - } - } -} - -const char *Proxy::getComputerName() -{ - // - // Strangely enough, under some Windows OSes SMB - // service doesn't bind to localhost. Fall back - // to localhost if can't find computer name in - // the environment. In future we should try to - // bind to localhost and then try the other IPs. - // - - const char *hostname = NULL; - - #ifdef __CYGWIN32__ - - hostname = getenv("COMPUTERNAME"); - - #endif - - if (hostname == NULL) - { - hostname = "localhost"; - } - - return hostname; -} - -// -// Handle data from channels selected for read. -// - -int Proxy::handleRead(int &resultFds, fd_set &readSet) -{ - #ifdef DEBUG - *logofs << "Proxy: Checking descriptors selected for read.\n" - << logofs_flush; - #endif - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - #ifdef DEBUG - *logofs << "Proxy: Looping with current channel " - << *j << ".\n" << logofs_flush; - #endif - - int fd = getFd(*j); - - if (fd >= 0 && resultFds > 0 && FD_ISSET(fd, &readSet)) - { - #ifdef DEBUG - *logofs << "Proxy: Going to read messages from FD#" - << fd << ".\n" << logofs_flush; - #endif - - int result = handleRead(fd); - - if (result < 0) - { - #ifdef TEST - *logofs << "Proxy: Failure reading messages from FD#" - << fd << ".\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef DEBUG - *logofs << "Proxy: Clearing the read descriptor " - << "for FD#" << fd << ".\n" << logofs_flush; - #endif - - FD_CLR(fd, &readSet); - - resultFds--; - } - } - - if (resultFds > 0 && FD_ISSET(fd_, &readSet)) - { - #ifdef DEBUG - *logofs << "Proxy: Going to read messages from " - << "proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - if (handleRead() < 0) - { - #ifdef TEST - *logofs << "Proxy: Failure reading from proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef DEBUG - *logofs << "Proxy: Clearing the read descriptor " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - FD_CLR(fd_, &readSet); - - resultFds--; - } - - return 1; -} - -// -// Perform flush on descriptors selected for write. -// - -int Proxy::handleFlush(int &resultFds, fd_set &writeSet) -{ - #ifdef DEBUG - *logofs << "Proxy: Checking descriptors selected for write.\n" - << logofs_flush; - #endif - - if (resultFds > 0 && FD_ISSET(fd_, &writeSet)) - { - #ifdef TEST - *logofs << "Proxy: FLUSH! Proxy descriptor FD#" << fd_ - << " reported to be writable.\n" - << logofs_flush; - #endif - - if (handleFlush() < 0) - { - #ifdef TEST - *logofs << "Proxy: Failure flushing the writable " - << "proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - return -1; - } - - #ifdef DEBUG - *logofs << "Proxy: Clearing the write descriptor " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - FD_CLR(fd_, &writeSet); - - resultFds--; - } - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - resultFds > 0 && j != channelList.end(); j++) - { - #ifdef DEBUG - *logofs << "Proxy: Looping with current channel " - << *j << ".\n" << logofs_flush; - #endif - - int fd = getFd(*j); - - if (fd >= 0 && FD_ISSET(fd, &writeSet)) - { - #ifdef TEST - *logofs << "Proxy: X descriptor FD#" << fd - << " reported to be writable.\n" - << logofs_flush; - #endif - - // - // It can happen that, in handling reads, we - // have destroyed the buffer associated to a - // closed socket, so don't complain about - // the errors. - // - - handleFlush(fd); - - // - // Clear the descriptor from the mask so - // we don't confuse the agent if it's - // not checking only its own descriptors. - // - - #ifdef DEBUG - *logofs << "Proxy: Clearing the write descriptor " - << "for FD#" << fd << ".\n" - << logofs_flush; - #endif - - FD_CLR(fd, &writeSet); - - resultFds--; - } - } - - return 1; -} - -int Proxy::handleRead() -{ - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Decoding data from proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - // - // Decode all the available messages from - // the remote proxy until is not possible - // to read more. - // - - for (;;) - { - int result = readBuffer_.readMessage(); - - #if defined(TEST) || defined(DEBUG) || defined(INFO) - *logofs << "Proxy: Read result on proxy FD#" << fd_ - << " is " << result << ".\n" - << logofs_flush; - #endif - - if (result < 0) - { - if (shutdown_ == 0) - { - if (finish_ == 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Failure reading from the " - << "peer proxy on FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure reading from the " - << "peer proxy.\n"; - } - } - #ifdef TEST - else - { - *logofs << "Proxy: Closure of the proxy link detected " - << "after clean shutdown.\n" << logofs_flush; - } - #endif - - priority_ = 0; - finish_ = 1; - congestion_ = 0; - - return -1; - } - else if (result == 0) - { - #if defined(TEST) || defined(DEBUG) || defined(INFO) - *logofs << "Proxy: No data read from proxy FD#" - << fd_ << "\n" << logofs_flush; - #endif - - return 0; - } - - // - // We read some data from the remote. If we set - // the congestion flag because we couldn't read - // before the timeout and have tokens available, - // then reset the congestion flag. - // - - if (congestion_ == 1 && - tokens_[token_control].remaining > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Exiting congestion due to " - << "proxy data with " << tokens_[token_control].remaining - << " tokens.\n" << logofs_flush; - #endif - - congestion_ = 0; - } - - // - // Set the timestamp of the last read - // operation from the remote proxy and - // enable again showing the 'no data - // received' dialog at the next timeout. - // - - timeouts_.readTs = getTimestamp(); - - if (alert_ != 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Displacing the dialog " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - HandleAlert(DISPLACE_MESSAGE_ALERT, 1); - } - - timeouts_.alertTs = nullTimestamp(); - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Getting messages from proxy FD#" << fd_ - << " with " << readBuffer_.getLength() << " bytes " - << "in the read buffer.\n" << logofs_flush; - #endif - - unsigned int controlLength; - unsigned int dataLength; - - const unsigned char *message; - - while ((message = readBuffer_.getMessage(controlLength, dataLength)) != NULL) - { - statistics -> addFrameIn(); - - if (controlLength == 3 && *message == 0 && - *(message + 1) < code_last_tag) - { - if (handleControlFromProxy(message) < 0) - { - return -1; - } - } - else if (operation_ == operation_in_messages) - { - int channelId = inputChannel_; - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Identified message of " << dataLength - << " bytes for FD#" << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - if (channelId >= 0 && channelId < CONNECTIONS_LIMIT && - channels_[channelId] != NULL) - { - int finish = channels_[channelId] -> getFinish(); - - #ifdef WARNING - - if (finish == 1) - { - *logofs << "Proxy: WARNING! Handling data for finishing " - << "FD#" << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - } - - #endif - - // - // We need to decode all the data to preserve - // the consistency of the cache, so can't re- - // turn as soon as the first error is encount- - // ered. Check if this is the first time that - // the failure is detected. - // - - int result = channels_[channelId] -> handleWrite(message, dataLength); - - if (result < 0 && finish == 0) - { - #ifdef TEST - *logofs << "Proxy: Failed to write proxy data to FD#" - << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - if (handleFinish(channelId) < 0) - { - return -1; - } - } - - // - // Check if we have splits or motion - // events to send. - // - - setSplitTimeout(channelId); - setMotionTimeout(channelId); - } - #ifdef WARNING - else - { - *logofs << "Proxy: WARNING! Received data for " - << "invalid channel ID#" << channelId - << ".\n" << logofs_flush; - } - #endif - } - else if (operation_ == operation_in_statistics) - { - #ifdef TEST - *logofs << "Proxy: Received statistics data from remote proxy.\n" - << logofs_flush; - #endif - - if (handleStatisticsFromProxy(message, dataLength) < 0) - { - return -1; - } - - operation_ = operation_in_messages; - } - else if (operation_ == operation_in_negotiation) - { - #ifdef TEST - *logofs << "Proxy: Received new negotiation data from remote proxy.\n" - << logofs_flush; - #endif - - if (handleNegotiationFromProxy(message, dataLength) < 0) - { - return -1; - } - } - - // - // if (controlLength == 3 && *message == 0 && ...) ... - // else if (operation_ == operation_in_statistics) ... - // else if (operation_ == operation_in_messages) ... - // else if (operation_ == operation_in_negotiation) ... - // else ... - // - - else - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Unrecognized message received on proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unrecognized message received on proxy FD#" - << fd_ << ".\n"; - - return -1; - } - - } // while ((message = readBuffer_.getMessage(controlLength, dataLength)) != NULL) ... - - // - // Reset the read buffer. - // - - readBuffer_.fullReset(); - - // - // Give up if no data is readable. - // - - if (transport_ -> readable() == 0) - { - break; - } - - } // End of for (;;) ... - - return 1; -} - -int Proxy::handleControlFromProxy(const unsigned char *message) -{ - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Received message '" << DumpControl(*(message + 1)) - << "' at " << strMsTimestamp() << " with data ID#" - << (int) *(message + 2) << ".\n" << logofs_flush; - #endif - - T_channel_type channelType = channel_none; - - switch (*(message + 1)) - { - case code_switch_connection: - { - int channelId = *(message + 2); - - // - // If channel is invalid further messages will - // be ignored. The acknowledged shutdown of - // channels should prevent this. - // - - inputChannel_ = channelId; - - break; - } - case code_begin_congestion: - { - // - // Set the congestion state for the - // channel reported by the remote. - // - - int channelId = *(message + 2); - - if (channels_[channelId] != NULL) - { - congestions_[channelId] = 1; - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Received a begin congestion " - << "for channel id ID#" << channelId - << ".\n" << logofs_flush; - #endif - - if (channelId == agent_ && congestions_[agent_] != 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Forcing an update of the congestion " - << "counter with agent congested.\n" - << logofs_flush; - #endif - - statistics -> updateCongestion(-tokens_[token_control].remaining, - tokens_[token_control].limit); - } - } - #ifdef WARNING - else - { - *logofs << "Proxy: WARNING! Received a begin congestion " - << "for invalid channel id ID#" << channelId - << ".\n" << logofs_flush; - } - #endif - - break; - } - case code_end_congestion: - { - // - // Attend again to the channel. - // - - int channelId = *(message + 2); - - if (channels_[channelId] != NULL) - { - congestions_[channelId] = 0; - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Received an end congestion " - << "for channel id ID#" << channelId - << ".\n" << logofs_flush; - #endif - - if (channelId == agent_ && congestions_[agent_] != 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Forcing an update of the congestion " - << "counter with agent decongested.\n" - << logofs_flush; - #endif - - statistics -> updateCongestion(tokens_[token_control].remaining, - tokens_[token_control].limit); - } - } - #ifdef WARNING - else - { - *logofs << "Proxy: WARNING! Received an end congestion " - << "for invalid channel id ID#" << channelId - << ".\n" << logofs_flush; - } - #endif - - break; - } - case code_control_token_request: - { - T_proxy_token &token = tokens_[token_control]; - - if (handleTokenFromProxy(token, *(message + 2)) < 0) - { - return -1; - } - - break; - } - case code_split_token_request: - { - T_proxy_token &token = tokens_[token_split]; - - if (handleTokenFromProxy(token, *(message + 2)) < 0) - { - return -1; - } - - break; - } - case code_data_token_request: - { - T_proxy_token &token = tokens_[token_data]; - - if (handleTokenFromProxy(token, *(message + 2)) < 0) - { - return -1; - } - - break; - } - case code_control_token_reply: - { - T_proxy_token &token = tokens_[token_control]; - - if (handleTokenReplyFromProxy(token, *(message + 2)) < 0) - { - return -1; - } - - break; - } - case code_split_token_reply: - { - T_proxy_token &token = tokens_[token_split]; - - if (handleTokenReplyFromProxy(token, *(message + 2)) < 0) - { - return -1; - } - - break; - } - case code_data_token_reply: - { - T_proxy_token &token = tokens_[token_data]; - - if (handleTokenReplyFromProxy(token, *(message + 2)) < 0) - { - return -1; - } - - break; - } - case code_new_x_connection: - { - // - // Opening the channel is handled later. - // - - channelType = channel_x11; - - break; - } - case code_new_cups_connection: - { - channelType = channel_cups; - - break; - } - case code_new_aux_connection: - { - // - // Starting from version 1.5.0 we create real X - // connections for the keyboard channel. We need - // to refuse old auxiliary X connections because - // they would be unable to leverage the new fake - // authorization cookie. - // - - #ifdef WARNING - *logofs << "Proxy: WARNING! Can't open outdated auxiliary X " - << "channel for code " << *(message + 1) << ".\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Can't open outdated auxiliary X " - << "channel for code " << *(message + 1) << ".\n"; - - if (handleControl(code_drop_connection, *(message + 2)) < 0) - { - return -1; - } - - break; - } - case code_new_smb_connection: - { - channelType = channel_smb; - - break; - } - case code_new_media_connection: - { - channelType = channel_media; - - break; - } - case code_new_http_connection: - { - channelType = channel_http; - - break; - } - case code_new_font_connection: - { - channelType = channel_font; - - break; - } - case code_new_slave_connection: - { - channelType = channel_slave; - - break; - } - case code_drop_connection: - { - int channelId = *(message + 2); - - if (channelId >= 0 && channelId < CONNECTIONS_LIMIT && - channels_[channelId] != NULL) - { - handleDropFromProxy(channelId); - } - #ifdef WARNING - else - { - *logofs << "Proxy: WARNING! Received a drop message " - << "for invalid channel id ID#" << channelId - << ".\n" << logofs_flush; - } - #endif - - break; - } - case code_finish_connection: - { - int channelId = *(message + 2); - - if (channelId >= 0 && channelId < CONNECTIONS_LIMIT && - channels_[channelId] != NULL) - { - // - // Force the finish state on the channel. - // We can receive this message while in - // the read loop, so we only mark the - // channel for deletion. - // - - #ifdef TEST - *logofs << "Proxy: Received a finish message for FD#" - << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - handleFinishFromProxy(channelId); - } - #ifdef WARNING - else - { - *logofs << "Proxy: WARNING! Received a finish message " - << "for invalid channel id ID#" << channelId - << ".\n" << logofs_flush; - } - #endif - - break; - } - case code_finish_listeners: - { - // - // This is from the main loop. - // - - #ifdef TEST - *logofs << "Proxy: Closing down all local listeners.\n" - << logofs_flush; - #endif - - CleanupListeners(); - - finish_ = 1; - - break; - } - case code_reset_request: - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Proxy reset not supported " - << "in this version.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Proxy reset not supported " - << "in this version.\n"; - - HandleCleanup(); - } - case code_shutdown_request: - { - // - // Time to rest in peace. - // - - shutdown_ = 1; - - break; - } - case code_load_request: - { - if (handleLoadFromProxy() < 0) - { - return -1; - } - - break; - } - case code_save_request: - { - // - // Don't abort the connection - // if can't write to disk. - // - - handleSaveFromProxy(); - - break; - } - case code_statistics_request: - { - int type = *(message + 2); - - if (handleStatisticsFromProxy(type) < 0) - { - return -1; - } - - break; - } - case code_statistics_reply: - { - operation_ = operation_in_statistics; - - break; - } - case code_alert_request: - { - HandleAlert(*(message + 2), 1); - - break; - } - case code_sync_request: - { - int channelId = *(message + 2); - - if (handleSyncFromProxy(channelId) < 0) - { - return -1; - } - - break; - } - case code_sync_reply: - { - // - // We are not the one that issued - // the request. - // - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: PANIC! Received an unexpected " - << "synchronization reply.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Received an unexpected " - << "synchronization reply.\n"; - - HandleCleanup(); - } - default: - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Received bad control message number " - << (unsigned int) *(message + 1) << " with attribute " - << (unsigned int) *(message + 2) << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Received bad control message number " - << (unsigned int) *(message + 1) << " with attribute " - << (unsigned int) *(message + 2) << ".\n"; - - HandleCleanup(); - } - - } // End of switch (*(message + 1)) ... - - if (channelType == channel_none) - { - return 1; - } - - // - // Handle the channel allocation that we - // left from the main switch case. - // - - int channelId = *(message + 2); - - // - // Check if the channel has been dropped. - // - - if (channels_[channelId] != NULL && - (channels_[channelId] -> getDrop() == 1 || - channels_[channelId] -> getClosing() == 1)) - { - #ifdef TEST - *logofs << "Proxy: Dropping the descriptor FD#" - << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - handleDrop(channelId); - } - - // - // Check if the channel is in the valid - // range. - // - - int result = checkChannelMap(channelId); - - if (result >= 0) - { - result = handleNewConnectionFromProxy(channelType, channelId); - } - - if (result < 0) - { - // - // Realization of new channel failed. - // Send channel shutdown message to - // the peer proxy. - // - - if (handleControl(code_drop_connection, channelId) < 0) - { - return -1; - } - } - else - { - int fd = getFd(channelId); - - if (getReadable(fd) > 0) - { - #ifdef TEST - *logofs << "Proxy: Trying to read immediately " - << "from descriptor FD#" << fd << ".\n" - << logofs_flush; - #endif - - if (handleRead(fd) < 0) - { - return -1; - } - } - #ifdef TEST - *logofs << "Proxy: Nothing to read immediately " - << "from descriptor FD#" << fd << ".\n" - << logofs_flush; - #endif - } - - return 1; -} - -int Proxy::handleRead(int fd, const char *data, int size) -{ - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Handling data for connection on FD#" - << fd << ".\n" << logofs_flush; - #endif - - if (canRead(fd) == 0) - { - #if defined(TEST) || defined(INFO) - - if (getChannel(fd) < 0) - { - *logofs << "Proxy: PANIC! Can't read from invalid FD#" - << fd << ".\n" << logofs_flush; - - HandleCleanup(); - } - else - { - *logofs << "Proxy: WARNING! Read method called for FD#" - << fd << " but operation is not possible.\n" - << logofs_flush; - } - - #endif - - return 0; - } - - int channelId = getChannel(fd); - - // - // Let the channel object read all the new data from - // its file descriptor, isolate messages, compress - // those messages, and append the compressed form to - // the encode buffer. - // - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Reading messages from FD#" << fd - << " channel ID#" << channelId << ".\n" - << logofs_flush; - #endif - - int result = channels_[channelId] -> handleRead(encodeBuffer_, (const unsigned char *) data, - (unsigned int) size); - - // - // Even in the case of a failure, write the produced - // data to the proxy connection. To keep the stores - // synchronized, the remote side needs to decode any - // message encoded by this side, also if the X socket - // was closed in the meanwhile. If this is the case, - // the decompressed output will be silently discarded. - // - - if (result < 0) - { - #ifdef TEST - *logofs << "Proxy: Failed to read data from connection FD#" - << fd << " channel ID#" << channelId << ".\n" - << logofs_flush; - #endif - - if (handleFinish(channelId) < 0) - { - return -1; - } - } - - // - // Check if there are new splits or - // motion events to send. - // - - setSplitTimeout(channelId); - setMotionTimeout(channelId); - - return 1; -} - -int Proxy::handleEvents() -{ - #ifdef TEST - *logofs << "Proxy: Going to check the events on channels.\n" - << logofs_flush; - #endif - - // - // Check if we can safely write to the - // proxy link. - // - - int read = isTimeToRead(); - - // - // Loop on channels and send the pending - // events. We must copy the list because - // channels can be removed in the middle - // of the loop. - // - - T_list channelList = activeChannels_.copyList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] == NULL) - { - continue; - } - - // - // Check if we need to drop the channel. - // - - if (channels_[channelId] -> getDrop() == 1 || - channels_[channelId] -> getClosing() == 1) - { - #ifdef TEST - *logofs << "Proxy: Dropping the descriptor FD#" - << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - if (handleDrop(channelId) < 0) - { - return -1; - } - - continue; - } - else if (channels_[channelId] -> getFinish() == 1) - { - #ifdef TEST - *logofs << "Proxy: Skipping finishing " - << "descriptor FD#" << getFd(channelId) - << " channel ID#" << channelId << ".\n" - << logofs_flush; - #endif - - continue; - } - - // - // If the proxy link or the channel is - // in congestion state, don't handle - // the further events. - // - - if (read == 0 || congestions_[channelId] == 1) - { - #ifdef TEST - - if (read == 0) - { - *logofs << "Proxy: Can't handle events for FD#" - << getFd(channelId) << " channel ID#" - << channelId << " with proxy not available.\n" - << logofs_flush; - } - else - { - *logofs << "Proxy: Can't handle events for FD#" - << getFd(channelId) << " channel ID#" - << channelId << " with channel congested.\n" - << logofs_flush; - } - - #endif - - continue; - } - - // - // Handle the timeouts on the channel - // operations. - // - - int result = 0; - - // - // Handle the motion events. - // - - if (result >= 0 && channels_[channelId] -> needMotion() == 1) - { - if (isTimeToMotion() == 1) - { - #if defined(TEST) || defined(INFO) || defined(FLUSH) - - *logofs << "Proxy: FLUSH! Motion timeout expired after " - << diffTimestamp(timeouts_.motionTs, getTimestamp()) - << " Ms.\n" << logofs_flush; - - #endif - - result = channels_[channelId] -> handleMotion(encodeBuffer_); - - #ifdef TEST - - if (result < 0) - { - *logofs << "Proxy: Failed to handle motion events for FD#" - << getFd(channelId) << " channel ID#" << channelId - << ".\n" << logofs_flush; - } - - #endif - - timeouts_.motionTs = nullTimestamp(); - - setMotionTimeout(channelId); - } - #if defined(TEST) || defined(INFO) - else if (isTimestamp(timeouts_.motionTs) == 1) - { - *logofs << "Proxy: Running with " - << diffTimestamp(timeouts_.motionTs, getTimestamp()) - << " Ms elapsed since the last motion.\n" - << logofs_flush; - } - #endif - } - - if (result >= 0 && channels_[channelId] -> needSplit() == 1) - { - // - // Check if it is time to send more splits - // and how many bytes are going to be sent. - // - - if (isTimeToSplit() == 1) - { - #if defined(TEST) || defined(INFO) || defined(SPLIT) - *logofs << "Proxy: SPLIT! Split timeout expired after " - << diffTimestamp(timeouts_.splitTs, getTimestamp()) - << " Ms.\n" << logofs_flush; - #endif - - #if defined(TEST) || defined(INFO) || defined(SPLIT) - - *logofs << "Proxy: SPLIT! Encoding splits for FD#" - << getFd(channelId) << " at " << strMsTimestamp() - << " with " << clientStore_ -> getSplitTotalStorageSize() - << " total bytes and " << control -> SplitDataPacketLimit - << " bytes " << "to write.\n" - << logofs_flush; - - #endif - - result = channels_[channelId] -> handleSplit(encodeBuffer_); - - #ifdef TEST - - if (result < 0) - { - *logofs << "Proxy: Failed to handle splits for FD#" - << getFd(channelId) << " channel ID#" << channelId - << ".\n" << logofs_flush; - } - - #endif - - timeouts_.splitTs = nullTimestamp(); - - setSplitTimeout(channelId); - } - #if defined(TEST) || defined(INFO) || defined(SPLIT) - else if (channels_[channelId] -> needSplit() == 1 && - isTimestamp(timeouts_.splitTs) == 0) - { - *logofs << "Proxy: SPLIT! WARNING! Channel for FD#" - << getFd(channelId) << " has split to send but " - << "there is no timeout.\n" << logofs_flush; - } - else if (isTimestamp(timeouts_.splitTs) == 1) - { - *logofs << "Proxy: SPLIT! Running with " - << diffTimestamp(timeouts_.splitTs, getTimestamp()) - << " Ms elapsed since the last split.\n" - << logofs_flush; - } - #endif - } - - if (result < 0) - { - #ifdef TEST - *logofs << "Proxy: Error handling events for FD#" - << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - if (handleFinish(channelId) < 0) - { - return -1; - } - } - } - - return 1; -} - -int Proxy::handleFrame(T_frame_type type) -{ - // - // Write any outstanding control message, followed by the - // content of the encode buffer, to the proxy transport. - // - // This code assumes that the encode buffer data is at an - // offset several bytes from start of the buffer, so that - // the length header and any necessary control bytes can - // be inserted in front of the data already in the buffer. - // This is the easiest way to encapsulate header and data - // together in a single frame. - // - // The way framing is implemented is very efficient but - // inherently limited and does not allow for getting the - // best performance, especially when running over a fast - // link. Framing should be rewritten to include the length - // of the packets in a fixed size header and, possibly, - // to incapsulate the control messages and the channel's - // data in a pseudo X protocol message, so that the proxy - // itself would be treated like any other channel. - // - - #if defined(TEST) || defined(INFO) - - if (congestion_ == 1) - { - // - // This can happen because there may be control - // messages to send, like a proxy shutdown mes- - // sage or a statistics request. All the other - // cases should be considered an error. - // - - #ifdef WARNING - *logofs << "Proxy: WARNING! Data is to be sent while " - << "congestion is " << congestion_ << ".\n" - << logofs_flush; - #endif - } - - #endif - - // - // Check if there is any data available on - // the socket. Recent Linux kernels are very - // picky. They require that we read often or - // they assume that the process is non-inter- - // active. - // - - if (handleAsyncEvents() < 0) - { - return -1; - } - - // - // Check if this is a ping, not a data frame. - // - - if (type == frame_ping) - { - if (handleToken(frame_ping) < 0) - { - return -1; - } - } - - unsigned int dataLength = encodeBuffer_.getLength(); - - #ifdef DEBUG - *logofs << "Proxy: Data length is " << dataLength - << " control length is " << controlLength_ - << ".\n" << logofs_flush; - #endif - - if (dataLength > 0) - { - // - // If this is a generic channel we need - // to add the completion bits. Data can - // also have been encoded because of a - // statistics request, even if no output - // channel was currently selected. - // - - if (outputChannel_ != -1) - { - #if defined(TEST) || defined(INFO) - - if (channels_[outputChannel_] == NULL) - { - *logofs << "Proxy: PANIC! A new frame was requested " - << "but the channel is invalid.\n" - << logofs_flush; - - HandleCleanup(); - } - - #endif - - channels_[outputChannel_] -> handleCompletion(encodeBuffer_); - - dataLength = encodeBuffer_.getLength(); - } - } - else if (controlLength_ == 0) - { - #if defined(TEST) || defined(INFO) - - *logofs << "Proxy: PANIC! A new frame was requested " - << "but there is no data to write.\n" - << logofs_flush; - - HandleCleanup(); - - #endif - - return 0; - } - - #ifdef DEBUG - *logofs << "Proxy: Data length is now " << dataLength - << " control length is " << controlLength_ - << ".\n" << logofs_flush; - #endif - - // - // Check if this frame needs to carry a new - // token request. - // - - if (type == frame_data) - { - if (handleToken(frame_data) < 0) - { - return -1; - } - } - - #ifdef DEBUG - *logofs << "Proxy: Adding a new frame for the remote proxy.\n" - << logofs_flush; - #endif - - unsigned char temp[5]; - - unsigned int lengthLength = 0; - unsigned int shift = dataLength; - - while (shift) - { - temp[lengthLength++] = (unsigned char) (shift & 0x7f); - - shift >>= 7; - } - - unsigned char *data = encodeBuffer_.getData(); - - unsigned char *outputMessage = data - (controlLength_ + lengthLength); - - unsigned char *nextDest = outputMessage; - - for (int i = 0; i < controlLength_; i++) - { - *nextDest++ = controlCodes_[i]; - } - - for (int j = lengthLength - 1; j > 0; j--) - { - *nextDest++ = (temp[j] | 0x80); - } - - if (lengthLength) - { - *nextDest++ = temp[0]; - } - - unsigned int outputLength = dataLength + controlLength_ + lengthLength; - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Produced plain output for " << dataLength << "+" - << controlLength_ << "+" << lengthLength << " out of " - << outputLength << " bytes.\n" << logofs_flush; - #endif - - #if defined(TEST) || defined(INFO) || defined(FLUSH) || defined(TIME) - - T_timestamp nowTs = getTimestamp(); - - *logofs << "Proxy: FLUSH! Immediate with blocked " << transport_ -> - blocked() << " length " << transport_ -> length() - << " new " << outputLength << " flushable " << transport_ -> - flushable() << " tokens " << tokens_[token_control].remaining - << " after " << diffTimestamp(timeouts_.writeTs, nowTs) - << " Ms.\n" << logofs_flush; - - *logofs << "Proxy: FLUSH! Immediate flush to proxy FD#" << fd_ - << " of " << outputLength << " bytes at " << strMsTimestamp() - << " with priority " << priority_ << ".\n" << logofs_flush; - - *logofs << "Proxy: FLUSH! Current bitrate is " - << statistics -> getBitrateInShortFrame() << " with " - << statistics -> getBitrateInLongFrame() << " in the " - << "long frame and top " << statistics -> - getTopBitrate() << ".\n" << logofs_flush; - #endif - - statistics -> addWriteOut(); - - int result = transport_ -> write(write_immediate, outputMessage, outputLength); - - #ifdef TIME - - if (diffTimestamp(timeouts_.writeTs, nowTs) > 50) - { - *logofs << "Proxy: WARNING! TIME! Data written to proxy FD#" - << fd_ << " at " << strMsTimestamp() << " after " - << diffTimestamp(timeouts_.writeTs, nowTs) - << " Ms.\n" << logofs_flush; - } - - #endif - - #ifdef DUMP - *logofs << "Proxy: Sent " << outputLength << " bytes of data " - << "with checksum "; - - DumpChecksum(outputMessage, outputLength); - - *logofs << " on proxy FD#" << fd_ << ".\n" << logofs_flush; - #endif - - #ifdef DUMP - *logofs << "Proxy: Partial checksums are:\n"; - - DumpBlockChecksums(outputMessage, outputLength, 256); - - *logofs << logofs_flush; - #endif - - // - // Clean up the encode buffer and - // bring it to the initial size. - // - - encodeBuffer_.fullReset(); - - // - // Close the connection if we got - // an error. - // - - if (result < 0) - { - #ifdef TEST - *logofs << "Proxy: Failed write to proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - return -1; - } - - // - // Account for the data frame and the - // framing overhead. - // - - if (dataLength > 0) - { - statistics -> addFrameOut(); - } - - statistics -> addFramingBits((controlLength_ + lengthLength) << 3); - - controlLength_ = 0; - - // - // Reset all buffers, counters and the - // priority flag. - // - - handleResetFlush(); - - // - // Check if more data became available - // after writing. - // - - if (handleAsyncEvents() < 0) - { - return -1; - } - - // - // Drain the proxy link if we are in - // congestion state. - // - // if (needDrain() == 1 && draining_ == 0) - // { - // if (handleDrain() < 0) - // { - // return -1; - // } - // } - // - - return result; -} - -int Proxy::handleFlush() -{ - // - // We can have data in the encode buffer or - // control bytes to send. In the case make - // up a new frame. - // - - if (encodeBuffer_.getLength() + controlLength_ > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Flushing data in the encode buffer.\n" - << logofs_flush; - #endif - - priority_ = 1; - - if (handleFrame(frame_data) < 0) - { - return -1; - } - } - - // - // Check if we have something to write. - // - - if (transport_ -> length() + transport_ -> flushable() == 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Nothing else to flush for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - return 0; - } - - #if defined(TEST) || defined(INFO) - - if (transport_ -> blocked() == 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Proxy descriptor FD#" << fd_ - << " has data to flush but the transport " - << "is not blocked.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Proxy descriptor FD#" << fd_ - << " has data to flush but the transport " - << "is not blocked.\n"; - - HandleCleanup(); - } - - #endif - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "Proxy: FLUSH! Deferred with blocked " << transport_ -> - blocked() << " length " << transport_ -> length() - << " flushable " << transport_ -> flushable() << " tokens " - << tokens_[token_control].remaining << ".\n" - << logofs_flush; - - *logofs << "Proxy: FLUSH! Deferred flush to proxy FD#" << fd_ - << " of " << transport_ -> length() + transport_ -> - flushable() << " bytes at " << strMsTimestamp() - << " with priority " << priority_ << ".\n" - << logofs_flush; - - *logofs << "Proxy: FLUSH! Current bitrate is " - << statistics -> getBitrateInShortFrame() << " with " - << statistics -> getBitrateInLongFrame() << " in the " - << "long frame and top " << statistics -> - getTopBitrate() << ".\n" << logofs_flush; - #endif - - statistics -> addWriteOut(); - - int result = transport_ -> flush(); - - if (result < 0) - { - return -1; - } - - // - // Reset the counters and update the - // timestamp of the last write. - // - - handleResetFlush(); - - return result; -} - -int Proxy::handleDrain() -{ - // - // If the proxy is run in the same process - // as SSH, we can't block or the program - // would not have a chance to read or write - // its data. - // - - if (control -> LinkEncrypted == 1) - { - return 0; - } - - if (needDrain() == 0 || draining_ == 1) - { - #if defined(TEST) || defined(INFO) - - if (draining_ == 1) - { - *logofs << "Proxy: WARNING! Already draining proxy FD#" - << fd_ << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - } - else - { - *logofs << "Proxy: WARNING! No need to drain proxy FD#" - << fd_ << " with congestion " << congestion_ - << " length " << transport_ -> length() - << " and blocked " << transport_ -> blocked() - << ".\n" << logofs_flush; - } - - #endif - - return 0; - } - - draining_ = 1; - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Going to drain the proxy FD#" << fd_ - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - int timeout = control -> PingTimeout / 2; - - T_timestamp startTs = getNewTimestamp(); - - T_timestamp nowTs = startTs; - - int remaining; - int result; - - // - // Keep draining the proxy socket while - // reading the incoming messages until - // the timeout is expired. - // - - for (;;) - { - remaining = timeout - diffTimestamp(startTs, nowTs); - - if (remaining <= 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Timeout raised while draining " - << "FD#" << fd_ << " at " << strMsTimestamp() - << " after " << diffTimestamp(startTs, nowTs) - << " Ms.\n" << logofs_flush; - #endif - - result = 0; - - goto ProxyDrainEnd; - } - - if (transport_ -> length() > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Trying to write to FD#" << fd_ - << " at " << strMsTimestamp() << " with length " - << transport_ -> length() << " and " - << remaining << " Ms remaining.\n" - << logofs_flush; - #endif - - result = transport_ -> drain(0, remaining); - - if (result == -1) - { - result = -1; - - goto ProxyDrainEnd; - } - else if (result == 0 && transport_ -> readable() > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Decoding more data from proxy FD#" - << fd_ << " at " << strMsTimestamp() << " with " - << transport_ -> length() << " bytes to write and " - << transport_ -> readable() << " readable.\n" - << logofs_flush; - #endif - - if (handleRead() < 0) - { - result = -1; - - goto ProxyDrainEnd; - } - } - #if defined(TEST) || defined(INFO) - else if (result == 1) - { - *logofs << "Proxy: Transport for proxy FD#" << fd_ - << " drained down to " << transport_ -> length() - << " bytes.\n" << logofs_flush; - } - #endif - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Waiting for more data from proxy " - << "FD#" << fd_ << " at " << strMsTimestamp() - << " with " << remaining << " Ms remaining.\n" - << logofs_flush; - #endif - - - result = transport_ -> wait(remaining); - - if (result == -1) - { - result = -1; - - goto ProxyDrainEnd; - } - else if (result > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Decoding more data from proxy FD#" - << fd_ << " at " << strMsTimestamp() << " with " - << transport_ -> readable() << " bytes readable.\n" - << logofs_flush; - #endif - - if (handleRead() < 0) - { - result = -1; - - goto ProxyDrainEnd; - } - } - } - - // - // Check if we finally got the tokens - // that would allow us to come out of - // the congestion state. - // - - if (needDrain() == 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Got decongestion for proxy FD#" - << fd_ << " at " << strMsTimestamp() << " after " - << diffTimestamp(startTs, getTimestamp()) - << " Ms.\n" << logofs_flush; - #endif - - result = 1; - - goto ProxyDrainEnd; - } - - nowTs = getNewTimestamp(); - } - -ProxyDrainEnd: - - draining_ = 0; - - return result; -} - -int Proxy::handleFlush(int fd) -{ - int channelId = getChannel(fd); - - if (channelId < 0 || channels_[channelId] == NULL) - { - #ifdef TEST - *logofs << "Proxy: WARNING! Skipping flush on invalid " - << "descriptor FD#" << fd << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - return 0; - } - else if (channels_[channelId] -> getFinish() == 1) - { - #ifdef TEST - *logofs << "Proxy: Skipping flush on finishing " - << "descriptor FD#" << fd << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - return 0; - } - - #ifdef TEST - *logofs << "Proxy: Going to flush FD#" << fd - << " with blocked " << transports_[channelId] -> blocked() - << " length " << transports_[channelId] -> length() - << ".\n" << logofs_flush; - #endif - - if (channels_[channelId] -> handleFlush() < 0) - { - #ifdef TEST - *logofs << "Proxy: Failed to flush data to FD#" - << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - handleFinish(channelId); - - return -1; - } - - return 1; -} - -int Proxy::handleStatistics(int type, ostream *stream) -{ - if (stream == NULL || control -> EnableStatistics == 0) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! Cannot produce statistics " - << " for proxy FD#" << fd_ << ". Invalid settings " - << "for statistics or stream.\n" << logofs_flush; - #endif - - return 0; - } - else if (currentStatistics_ != NULL) - { - // - // Need to update the stream pointer as the - // previous one could have been destroyed. - // - - #ifdef WARNING - *logofs << "Proxy: WARNING! Replacing stream while producing " - << "statistics in stream at " << currentStatistics_ - << " for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - } - - currentStatistics_ = stream; - - // - // Get statistics of remote peer. - // - - if (handleControl(code_statistics_request, type) < 0) - { - return -1; - } - - return 1; -} - -int Proxy::handleStatisticsFromProxy(int type) -{ - if (needFlush() == 1) - { - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "Proxy: WARNING! Data for the previous " - << "channel ID#" << outputChannel_ - << " flushed in statistics.\n" - << logofs_flush; - #endif - - if (handleFrame(frame_data) < 0) - { - return -1; - } - } - - if (control -> EnableStatistics == 1) - { - // - // Allocate a buffer for the output. - // - - char *buffer = new char[STATISTICS_LENGTH]; - - *buffer = '\0'; - - if (control -> ProxyMode == proxy_client) - { - #ifdef TEST - *logofs << "Proxy: Producing " - << (type == TOTAL_STATS ? "total" : "partial") - << " client statistics for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - statistics -> getClientProtocolStats(type, buffer); - - statistics -> getClientOverallStats(type, buffer); - } - else - { - #ifdef TEST - *logofs << "Proxy: Producing " - << (type == TOTAL_STATS ? "total" : "partial") - << " server statistics for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - statistics -> getServerProtocolStats(type, buffer); - } - - if (type == PARTIAL_STATS) - { - statistics -> resetPartialStats(); - } - - unsigned int length = strlen((char *) buffer) + 1; - - encodeBuffer_.encodeValue(type, 8); - - encodeBuffer_.encodeValue(length, 32); - - #ifdef TEST - *logofs << "Proxy: Encoding " << length - << " bytes of statistics data for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - encodeBuffer_.encodeMemory((unsigned char *) buffer, length); - - // - // Account statistics data as framing bits. - // - - statistics -> addFramingBits(length << 3); - - delete [] buffer; - } - else - { - #ifdef WARNING - *logofs << "Proxy: WARNING! Got statistics request " - << "but local statistics are disabled.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Got statistics request " - << "but local statistics are disabled.\n"; - - type = NO_STATS; - - encodeBuffer_.encodeValue(type, 8); - - #ifdef TEST - *logofs << "Proxy: Sending error code to remote proxy on FD#" - << fd_ << ".\n" << logofs_flush; - #endif - } - - // - // The next write will flush the statistics - // data and the control message. - // - - if (handleControl(code_statistics_reply, type) < 0) - { - return -1; - } - - return 1; -} - -int Proxy::handleStatisticsFromProxy(const unsigned char *message, unsigned int length) -{ - if (currentStatistics_ == NULL) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! Unexpected statistics data received " - << "from remote proxy on FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Unexpected statistics data received " - << "from remote proxy.\n"; - - return 0; - } - - // - // Allocate the decode buffer and at least - // the 'type' field to see if there was an - // error. - // - - DecodeBuffer decodeBuffer(message, length); - - unsigned int type; - - decodeBuffer.decodeValue(type, 8); - - if (type == NO_STATS) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Couldn't get statistics from remote " - << "proxy on FD#" << fd_ << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Couldn't get statistics from remote proxy.\n"; - } - else if (type != TOTAL_STATS && type != PARTIAL_STATS) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Cannot produce statistics " - << "with qualifier '" << type << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Cannot produce statistics " - << "with qualifier '" << type << "'.\n"; - - return -1; - } - else - { - unsigned int size; - - decodeBuffer.decodeValue(size, 32); - - char *buffer = new char[STATISTICS_LENGTH]; - - *buffer = '\0'; - - if (control -> EnableStatistics == 1) - { - if (control -> ProxyMode == proxy_client) - { - #ifdef TEST - *logofs << "Proxy: Finalizing " - << (type == TOTAL_STATS ? "total" : "partial") - << " client statistics for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - statistics -> getClientCacheStats(type, buffer); - - #ifdef TEST - *logofs << "Proxy: Decoding " << size - << " bytes of statistics data for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - strncat(buffer, (char *) decodeBuffer.decodeMemory(size), size); - - statistics -> getClientProtocolStats(type, buffer); - - statistics -> getClientOverallStats(type, buffer); - } - else - { - #ifdef TEST - *logofs << "Proxy: Finalizing " - << (type == TOTAL_STATS ? "total" : "partial") - << " server statistics for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - statistics -> getServerCacheStats(type, buffer); - - statistics -> getServerProtocolStats(type, buffer); - - #ifdef TEST - *logofs << "Proxy: Decoding " << size - << " bytes of statistics data for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - strncat(buffer, (char *) decodeBuffer.decodeMemory(size), size); - } - - if (type == PARTIAL_STATS) - { - statistics -> resetPartialStats(); - } - - *currentStatistics_ << buffer; - - // - // Mark the end of text to help external parsing. - // - - *currentStatistics_ << '\4'; - - *currentStatistics_ << flush; - } - else - { - // - // It can be that statistics were enabled at the time - // we issued the request (otherwise we could not have - // set the stream), but now they have been disabled - // by user. We must decode statistics data if we want - // to keep the connection. - // - - #ifdef TEST - *logofs << "Proxy: Discarding " << size - << " bytes of statistics data for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - strncat(buffer, (char *) decodeBuffer.decodeMemory(size), size); - } - - delete [] buffer; - } - - currentStatistics_ = NULL; - - return 1; -} - -int Proxy::handleNegotiation(const unsigned char *message, unsigned int length) -{ - #ifdef PANIC - *logofs << "Proxy: PANIC! Writing data during proxy " - << "negotiation is not implemented.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Writing data during proxy " - << "negotiation is not implemented.\n"; - - return -1; -} - -int Proxy::handleNegotiationFromProxy(const unsigned char *message, unsigned int length) -{ - #ifdef PANIC - *logofs << "Proxy: PANIC! Reading data during proxy " - << "negotiation is not implemented.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Reading data during proxy " - << "negotiation is not implemented.\n"; - - return -1; -} - -int Proxy::handleAlert(int alert) -{ - if (handleControl(code_alert_request, alert) < 0) - { - return -1; - } - - return 1; -} - -int Proxy::handleCloseConnection(int clientFd) -{ - int channelId = getChannel(clientFd); - - if (channels_[channelId] != NULL && - channels_[channelId] -> getFinish() == 0) - { - #ifdef TEST - *logofs << "Proxy: Closing down the channel for FD#" - << clientFd << ".\n" << logofs_flush; - #endif - - if (handleFinish(channelId) < 0) - { - return -1; - } - - return 1; - } - - return 0; -} - -int Proxy::handleCloseAllXConnections() -{ - #ifdef TEST - *logofs << "Proxy: Closing down any remaining X channel.\n" - << logofs_flush; - #endif - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL && - channels_[channelId] -> getType() == channel_x11 && - channels_[channelId] -> getFinish() == 0) - { - #ifdef TEST - *logofs << "Proxy: Closing down the channel for FD#" - << getFd(channelId) << ".\n" << logofs_flush; - #endif - - if (handleFinish(channelId) < 0) - { - return -1; - } - } - } - - return 1; -} - -int Proxy::handleCloseAllListeners() -{ - // Since ProtoStep7 (#issue 108) - if (finish_ == 0) - { - #ifdef TEST - *logofs << "Proxy: Closing down all remote listeners.\n" - << logofs_flush; - #endif - - if (handleControl(code_finish_listeners) < 0) - { - return -1; - } - - finish_ = 1; - } - - return 1; -} - -void Proxy::handleResetAlert() -{ - if (alert_ != 0) - { - #ifdef TEST - *logofs << "Proxy: The proxy alert '" << alert_ - << "' was displaced.\n" << logofs_flush; - #endif - - alert_ = 0; - } - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL) - { - channels_[channelId] -> handleResetAlert(); - } - } -} - -int Proxy::handleFinish(int channelId) -{ - // - // Send any outstanding encoded data and - // do any finalization needed on the - // channel. - // - - if (needFlush(channelId) == 1) - { - if (channels_[channelId] -> getFinish() == 1) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! The finishing channel ID#" - << channelId << " has data to flush.\n" - << logofs_flush; - #endif - } - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "Proxy: WARNING! Flushing data for the " - << "finishing channel ID#" << channelId - << ".\n" << logofs_flush; - #endif - - if (handleFrame(frame_data) < 0) - { - return -1; - } - } - - // - // Reset the congestion state and the - // timeouts, if needed. - // - - congestions_[channelId] = 0; - - setSplitTimeout(channelId); - setMotionTimeout(channelId); - - if (channels_[channelId] -> getFinish() == 0) - { - channels_[channelId] -> handleFinish(); - - // - // Force a failure in the case somebody - // would try to read from the channel. - // - - shutdown(getFd(channelId), SHUT_RD); - - // - // If the failure was not originated by - // the remote, send a channel shutdown - // message. - // - - if (channels_[channelId] -> getClosing() == 0) - { - #ifdef TEST - *logofs << "Proxy: Finishing channel for FD#" - << getFd(channelId) << " channel ID#" - << channelId << " because of failure.\n" - << logofs_flush; - #endif - - if (handleControl(code_finish_connection, channelId) < 0) - { - return -1; - } - } - } - - return 1; -} - -int Proxy::handleFinishFromProxy(int channelId) -{ - // - // Check if this channel has pending - // data to send. - // - - if (needFlush(channelId) == 1) - { - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "Proxy: WARNING! Flushing data for the " - << "finishing channel ID#" << channelId - << ".\n" << logofs_flush; - #endif - - if (handleFrame(frame_data) < 0) - { - return -1; - } - } - - // - // Mark the channel. We will free its - // resources at the next loop and will - // send the drop message to the remote. - // - - if (channels_[channelId] -> getClosing() == 0) - { - #ifdef TEST - *logofs << "Proxy: Marking channel for FD#" - << getFd(channelId) << " channel ID#" - << channelId << " as closing.\n" - << logofs_flush; - #endif - - channels_[channelId] -> handleClosing(); - } - - if (channels_[channelId] -> getFinish() == 0) - { - #ifdef TEST - *logofs << "Proxy: Finishing channel for FD#" - << getFd(channelId) << " channel ID#" - << channelId << " because of proxy.\n" - << logofs_flush; - #endif - - channels_[channelId] -> handleFinish(); - } - - if (handleFinish(channelId) < 0) - { - return -1; - } - - return 1; -} - -int Proxy::handleDropFromProxy(int channelId) -{ - // - // Only mark the channel. - // - - #ifdef TEST - *logofs << "Proxy: Marking channel for FD#" - << getFd(channelId) << " channel ID#" - << channelId << " as being dropped.\n" - << logofs_flush; - #endif - - if (channels_[channelId] -> getDrop() == 0) - { - channels_[channelId] -> handleDrop(); - } - - return 1; -} - -// -// Close the channel and deallocate all its -// resources. -// - -int Proxy::handleDrop(int channelId) -{ - // - // Check if this channel has pending - // data to send. - // - - if (needFlush(channelId) == 1) - { - if (channels_[channelId] -> getFinish() == 1) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! The dropping channel ID#" - << channelId << " has data to flush.\n" - << logofs_flush; - #endif - } - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "Proxy: WARNING! Flushing data for the " - << "dropping channel ID#" << channelId - << ".\n" << logofs_flush; - #endif - - if (handleFrame(frame_data) < 0) - { - return -1; - } - } - - #ifdef TEST - *logofs << "Proxy: Dropping channel for FD#" - << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - if (channels_[channelId] -> getFinish() == 0) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! The channel for FD#" - << getFd(channelId) << " channel ID#" - << channelId << " was not marked as " - << "finishing.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": The channel for FD#" - << getFd(channelId) << " channel ID#" - << channelId << " was not marked as " - << "finishing.\n"; - - channels_[channelId] -> handleFinish(); - } - - // - // Send the channel shutdown message - // to the peer proxy. - // - - if (channels_[channelId] -> getClosing() == 1) - { - if (handleControl(code_drop_connection, channelId) < 0) - { - return -1; - } - } - - // - // Get rid of the channel. - // - - if (channels_[channelId] -> getType() != channel_x11) - { - #ifdef TEST - *logofs << "Proxy: Closed connection to " - << getTypeName(channels_[channelId] -> getType()) - << " server.\n" << logofs_flush; - #endif - - cerr << "Info" << ": Closed connection to " - << getTypeName(channels_[channelId] -> getType()) - << " server.\n"; - } - - delete channels_[channelId]; - channels_[channelId] = NULL; - - cleanupChannelMap(channelId); - - // - // Get rid of the transport. - // - - deallocateTransport(channelId); - - congestions_[channelId] = 0; - - decreaseChannels(channelId); - - // - // Check if the channel was the - // one currently selected for - // output. - // - - if (outputChannel_ == channelId) - { - outputChannel_ = -1; - } - - return 1; -} - -// -// Send an empty message to the remote peer -// to verify if the link is alive and let -// the remote proxy detect a congestion. -// - -int Proxy::handlePing() -{ - T_timestamp nowTs = getTimestamp(); - - #if defined(DEBUG) || defined(PING) - - *logofs << "Proxy: Checking ping at " - << strMsTimestamp(nowTs) << logofs_flush; - - *logofs << " with last loop at " - << strMsTimestamp(timeouts_.loopTs) << ".\n" - << logofs_flush; - - *logofs << "Proxy: Last bytes in at " - << strMsTimestamp(timeouts_.readTs) << logofs_flush; - - *logofs << " last bytes out at " - << strMsTimestamp(timeouts_.writeTs) << ".\n" - << logofs_flush; - - *logofs << "Proxy: Last ping at " - << strMsTimestamp(timeouts_.pingTs) << ".\n" - << logofs_flush; - - #endif - - // - // Be sure we take into account any clock drift. This - // can be caused by the user changing the system timer - // or by small adjustments introduced by the operating - // system making the clock go backward. - // - - if (checkDiffTimestamp(timeouts_.loopTs, nowTs) == 0) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! Detected drift in system " - << "timer. Resetting to current time.\n" - << logofs_flush; - #endif - - timeouts_.pingTs = nowTs; - timeouts_.readTs = nowTs; - timeouts_.writeTs = nowTs; - } - - // - // Check timestamp of last read from remote proxy. It can - // happen that we stayed in the main loop long enough to - // have idle timeout expired, for example if the proxy was - // stopped and restarted or because of an extremely high - // load of the system. In this case we don't complain if - // there is something new to read from the remote. - // - - int diffIn = diffTimestamp(timeouts_.readTs, nowTs); - - if (diffIn >= (control -> PingTimeout * 2) - - control -> LatencyTimeout) - { - // - // Force a read to detect whether the remote proxy - // aborted the connection. - // - - int result = handleRead(); - - if (result < 0) - { - #if defined(TEST) || defined(INFO) || defined(PING) - *logofs << "Proxy: WARNING! Detected shutdown waiting " - << "for the ping after " << diffIn / 1000 - << " seconds.\n" << logofs_flush; - #endif - - return -1; - } - else if (result > 0) - { - diffIn = diffTimestamp(timeouts_.readTs, nowTs); - - if (handleFlush() < 0) - { - return -1; - } - } - } - - if (diffIn >= (control -> PingTimeout * 2) - - control -> LatencyTimeout) - { - #if defined(TEST) || defined(INFO) || defined(PING) - *logofs << "Proxy: Detected congestion at " - << strMsTimestamp() << " with " << diffIn / 1000 - << " seconds since the last read.\n" - << logofs_flush; - #endif - - // - // There are two types of proxy congestion. The first, - // affecting the ability of the proxy to write the - // encoded data to the network, is controlled by the - // congestion_ flag. The flag is raised when no data - // is received from the remote proxy within a timeout. - // On the X client side, the flag is also raised when - // the proxy runs out of tokens. - // - - if (control -> ProxyMode == proxy_server) - { - // - // At X server side we must return to read data - // from the channels after a while, because we - // need to give a chance to the channel to read - // the key sequence CTRL+ALT+SHIFT+ESC. - // - - if (congestion_ == 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Forcibly entering congestion due to " - << "timeout with " << tokens_[token_control].remaining - << " tokens.\n" << logofs_flush; - #endif - - congestion_ = 1; - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Forcibly exiting congestion due to " - << "timeout with " << tokens_[token_control].remaining - << " tokens.\n" << logofs_flush; - #endif - - congestion_ = 0; - } - } - else - { - #if defined(TEST) || defined(INFO) - - if (congestion_ == 0) - { - *logofs << "Proxy: Entering congestion due to timeout " - << "with " << tokens_[token_control].remaining - << " tokens.\n" << logofs_flush; - } - - #endif - - congestion_ = 1; - } - - if (control -> ProxyTimeout > 0 && - diffIn >= (control -> ProxyTimeout - - control -> LatencyTimeout)) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! No data received from " - << "remote proxy on FD#" << fd_ << " within " - << (diffIn + control -> LatencyTimeout) / 1000 - << " seconds.\n" << logofs_flush; - #endif - - cerr << "Error" << ": No data received from remote " - << "proxy within " << (diffIn + control -> - LatencyTimeout) / 1000 << " seconds.\n"; - - HandleAbort(); - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: WARNING! No data received from " - << "remote proxy on FD#" << fd_ << " since " - << diffIn << " Ms.\n" << logofs_flush; - #endif - - if (control -> ProxyTimeout > 0 && - isTimestamp(timeouts_.alertTs) == 0 && - diffIn >= (control -> ProxyTimeout - - control -> LatencyTimeout) / 4) - { - // - // If we are in the middle of a shutdown - // procedure but the remote is not resp- - // onding, force the closure of the link. - // - - if (finish_ != 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! No response received from " - << "the remote proxy on FD#" << fd_ << " while " - << "waiting for the shutdown.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": No response received from remote " - << "proxy while waiting for the shutdown.\n"; - - HandleAbort(); - } - else - { - cerr << "Warning" << ": No data received from remote " - << "proxy within " << (diffIn + control -> - LatencyTimeout) / 1000 << " seconds.\n"; - - if (alert_ == 0) - { - if (control -> ProxyMode == proxy_client) - { - alert_ = CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT; - } - else - { - alert_ = CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT; - } - - HandleAlert(alert_, 1); - } - - timeouts_.alertTs = nowTs; - } - } - } - } - - // - // Check if we need to update the congestion - // counter. - // - - int diffOut = diffTimestamp(timeouts_.writeTs, nowTs); - - if (agent_ != nothing && congestions_[agent_] == 0 && - statistics -> getCongestionInFrame() >= 1 && - diffOut >= (control -> IdleTimeout - - control -> LatencyTimeout * 5)) - { - #if defined(TEST) || defined(INFO) || defined(PING) - *logofs << "Proxy: Forcing an update of the " - << "congestion counter after timeout.\n" - << logofs_flush; - #endif - - statistics -> updateCongestion(tokens_[token_control].remaining, - tokens_[token_control].limit); - } - - // - // Send a new token if we didn't send any data to - // the remote for longer than the ping timeout. - // The client side sends a token, the server side - // responds with a token reply. - // - // VMWare virtual machines can have the system - // timer deadly broken. Try to send a ping regard- - // less we are the client or the server proxy to - // force a write by the remote. - // - - if (control -> ProxyMode == proxy_client || - diffIn >= (control -> PingTimeout * 4) - - control -> LatencyTimeout) - { - // - // We need to send a new ping even if we didn't - // receive anything from the remote within the - // ping timeout. The server side will respond - // to our ping, so we use the ping to force the - // remote end to send some data. - // - - if (diffIn >= (control -> PingTimeout - - control -> LatencyTimeout * 5) || - diffOut >= (control -> PingTimeout - - control -> LatencyTimeout * 5)) - { - int diffPing = diffTimestamp(timeouts_.pingTs, nowTs); - - if (diffPing < 0 || diffPing >= (control -> PingTimeout - - control -> LatencyTimeout * 5)) - { - #if defined(TEST) || defined(INFO) || defined(PING) - *logofs << "Proxy: Sending a new ping at " << strMsTimestamp() - << " with " << tokens_[token_control].remaining - << " tokens and elapsed in " << diffIn << " out " - << diffOut << " ping " << diffPing - << ".\n" << logofs_flush; - #endif - - if (handleFrame(frame_ping) < 0) - { - return -1; - } - - timeouts_.pingTs = nowTs; - } - #if defined(TEST) || defined(INFO) || defined(PING) - else - { - *logofs << "Proxy: Not sending a new ping with " - << "elapsed in " << diffIn << " out " - << diffOut << " ping " << diffPing - << ".\n" << logofs_flush; - } - #endif - } - } - - return 1; -} - -int Proxy::handleSyncFromProxy(int channelId) -{ - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: WARNING! Received a synchronization " - << "request from the remote proxy.\n" - << logofs_flush; - #endif - - if (handleControl(code_sync_reply, channelId) < 0) - { - return -1; - } - - return 1; -} - -int Proxy::handleResetStores() -{ - // - // Recreate the message stores. - // - - delete clientStore_; - delete serverStore_; - - clientStore_ = new ClientStore(compressor_); - serverStore_ = new ServerStore(compressor_); - - timeouts_.loadTs = nullTimestamp(); - - // - // Replace message stores in channels. - // - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL) - { - if (channels_[channelId] -> setStores(clientStore_, serverStore_) < 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Failed to replace message stores in " - << "channel for FD#" << getFd(channelId) << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to replace message stores in " - << "channel for FD#" << getFd(channelId) << ".\n"; - - return -1; - } - #ifdef TEST - else - { - *logofs << "Proxy: Replaced message stores in channel " - << "for FD#" << getFd(channelId) << ".\n" - << logofs_flush; - } - #endif - } - } - - return 1; -} - -int Proxy::handleResetPersistentCache() -{ - char *fullName = new char[strlen(control -> PersistentCachePath) + - strlen(control -> PersistentCacheName) + 2]; - - strcpy(fullName, control -> PersistentCachePath); - strcat(fullName, "/"); - strcat(fullName, control -> PersistentCacheName); - - #ifdef TEST - *logofs << "Proxy: Going to remove persistent cache file '" - << fullName << "'\n" << logofs_flush; - #endif - - unlink(fullName); - - delete [] fullName; - - delete [] control -> PersistentCacheName; - - control -> PersistentCacheName = NULL; - - return 1; -} - -void Proxy::handleResetFlush() -{ - #ifdef TEST - *logofs << "Proxy: Going to reset flush counters " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - // - // Reset the proxy priority flag. - // - - priority_ = 0; - - // - // Restore buffers to their initial - // size. - // - - transport_ -> partialReset(); - - // - // Update the timestamp of the last - // write operation performed on the - // socket. - // - - timeouts_.writeTs = getTimestamp(); -} - -int Proxy::handleFinish() -{ - // - // Reset the timestamps to give the proxy - // another chance to show the 'no response' - // dialog if the shutdown message doesn't - // come in time. - // - - timeouts_.readTs = getTimestamp(); - - timeouts_.alertTs = nullTimestamp(); - - finish_ = 1; - - return 1; -} - -int Proxy::handleShutdown() -{ - // - // Send shutdown message to remote proxy. - // - - shutdown_ = 1; - - handleControl(code_shutdown_request); - - #ifdef TEST - *logofs << "Proxy: Starting shutdown procedure " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - // - // Ensure that all the data accumulated - // in the transport buffer is flushed - // to the network layer. - // - - for (int i = 0; i < 100; i++) - { - if (canFlush() == 1) - { - handleFlush(); - } - else - { - break; - } - - usleep(100000); - } - - // - // Now wait for the network layers to - // consume all the data. - // - - for (int i = 0; i < 100; i++) - { - if (transport_ -> queued() <= 0) - { - break; - } - - usleep(100000); - } - - // - // Give time to the remote end to read - // the shutdown message and close the - // connection. - // - - transport_ -> wait(10000); - - #ifdef TEST - *logofs << "Proxy: Ending shutdown procedure " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - return 1; -} - -int Proxy::handleChannelConfiguration() -{ - if (activeChannels_.getSize() == 0) - { - #ifdef TEST - *logofs << "Proxy: Going to initialize the static " - << "members in channels for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - Channel::setReferences(); - - ClientChannel::setReferences(); - ServerChannel::setReferences(); - - GenericChannel::setReferences(); - } - - return 1; -} - -int Proxy::handleSocketConfiguration() -{ - // - // Set linger mode on proxy to correctly - // get shutdown notification. - // - - SetLingerTimeout(fd_, 30); - - // - // Set keep-alive on socket so that if remote link - // terminates abnormally (as killed hard or because - // of a power-off) process will get a SIGPIPE. In - // practice this is useless as proxies already ping - // each other every few seconds. - // - - if (control -> OptionProxyKeepAlive == 1) - { - SetKeepAlive(fd_); - } - - // - // Set 'priority' flag at TCP layer for path - // proxy-to-proxy. Look at IPTOS_LOWDELAY in - // man 7 ip. - // - - if (control -> OptionProxyLowDelay == 1) - { - SetLowDelay(fd_); - } - - // - // Update size of TCP send and receive buffers. - // - - if (control -> OptionProxySendBuffer != -1) - { - SetSendBuffer(fd_, control -> OptionProxySendBuffer); - } - - if (control -> OptionProxyReceiveBuffer != -1) - { - SetReceiveBuffer(fd_, control -> OptionProxyReceiveBuffer); - } - - // - // Update TCP_NODELAY settings. Note that on old Linux - // kernels turning off the Nagle algorithm didn't work - // when proxy was run through a PPP link. Trying to do - // so caused the kernel to stop delivering data to us - // if a serious network congestion was encountered. - // - - if (control -> ProxyMode == proxy_client) - { - if (control -> OptionProxyClientNoDelay != -1) - { - SetNoDelay(fd_, control -> OptionProxyClientNoDelay); - } - } - else - { - if (control -> OptionProxyServerNoDelay != -1) - { - SetNoDelay(fd_, control -> OptionProxyServerNoDelay); - } - } - - return 1; -} - -int Proxy::handleLinkConfiguration() -{ - #ifdef TEST - *logofs << "Proxy: Propagating parameters to " - << "channels' read buffers.\n" - << logofs_flush; - #endif - - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL) - { - channels_[channelId] -> handleConfiguration(); - } - } - - #ifdef TEST - *logofs << "Proxy: Propagating parameters to " - << "proxy buffers.\n" - << logofs_flush; - #endif - - readBuffer_.setSize(control -> ProxyInitialReadSize, - control -> ProxyMaximumBufferSize); - - encodeBuffer_.setSize(control -> TransportProxyBufferSize, - control -> TransportProxyBufferThreshold, - control -> TransportMaximumBufferSize); - - transport_ -> setSize(control -> TransportProxyBufferSize, - control -> TransportProxyBufferThreshold, - control -> TransportMaximumBufferSize); - - #ifdef TEST - *logofs << "Proxy: Configuring the proxy timeouts.\n" - << logofs_flush; - #endif - - timeouts_.split = control -> SplitTimeout; - timeouts_.motion = control -> MotionTimeout; - - #ifdef TEST - *logofs << "Proxy: Configuring the proxy tokens.\n" - << logofs_flush; - #endif - - tokens_[token_control].size = control -> TokenSize; - tokens_[token_control].limit = control -> TokenLimit; - - if (tokens_[token_control].limit < 1) - { - tokens_[token_control].limit = 1; - } - - #if defined(TEST) || defined(INFO) || defined(LIMIT) - *logofs << "Proxy: TOKEN! LIMIT! Setting token [" - << DumpToken(token_control) << "] size to " - << tokens_[token_control].size << " and limit to " - << tokens_[token_control].limit << ".\n" - << logofs_flush; - #endif - - tokens_[token_split].size = control -> TokenSize; - tokens_[token_split].limit = control -> TokenLimit / 2; - - if (tokens_[token_split].limit < 1) - { - tokens_[token_split].limit = 1; - } - - #if defined(TEST) || defined(INFO) || defined(LIMIT) - *logofs << "Proxy: TOKEN! LIMIT! Setting token [" - << DumpToken(token_split) << "] size to " - << tokens_[token_split].size << " and limit to " - << tokens_[token_split].limit << ".\n" - << logofs_flush; - #endif - - tokens_[token_data].size = control -> TokenSize; - tokens_[token_data].limit = control -> TokenLimit / 4; - - if (tokens_[token_data].limit < 1) - { - tokens_[token_data].limit = 1; - } - - #if defined(TEST) || defined(INFO) || defined(LIMIT) - *logofs << "Proxy: TOKEN! LIMIT! Setting token [" - << DumpToken(token_data) << "] size to " - << tokens_[token_data].size << " and limit to " - << tokens_[token_data].limit << ".\n" - << logofs_flush; - #endif - - for (int i = token_control; i <= token_data; i++) - { - tokens_[i].remaining = tokens_[i].limit; - } - - #if defined(TEST) || defined(INFO) || defined(LIMIT) - *logofs << "Proxy: LIMIT! Using client bitrate " - << "limit " << control -> ClientBitrateLimit - << " server bitrate limit " << control -> - ServerBitrateLimit << " with local limit " - << control -> LocalBitrateLimit << ".\n" - << logofs_flush; - #endif - - // - // Set the other parameters based on - // the token size. - // - - int base = control -> TokenSize; - - control -> SplitDataThreshold = base * 4; - control -> SplitDataPacketLimit = base / 2; - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: LIMIT! Setting split data threshold " - << "to " << control -> SplitDataThreshold - << " split packet limit to " << control -> - SplitDataPacketLimit << " with base " - << base << ".\n" << logofs_flush; - #endif - - // - // Set the number of bytes read from the - // data channels at each loop. This will - // basically determine the maximum band- - // width available for the generic chan- - // nels. - // - - control -> GenericInitialReadSize = base / 2; - control -> GenericMaximumBufferSize = base / 2; - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: LIMIT! Setting generic channel " - << "initial read size to " << control -> - GenericInitialReadSize << " maximum read " - << "size to " << control -> GenericMaximumBufferSize - << " with base " << base << ".\n" - << logofs_flush; - #endif - - return 1; -} - -int Proxy::handleCacheConfiguration() -{ - #ifdef TEST - *logofs << "Proxy: Configuring cache according to pack parameters.\n" - << logofs_flush; - #endif - - // - // Further adjust the cache parameters. If - // packing of the images is enabled, reduce - // the size available for plain images. - // - - if (control -> SessionMode == session_agent) - { - if (control -> PackMethod != NO_PACK) - { - clientStore_ -> getRequestStore(X_PutImage) -> - cacheThreshold = PUTIMAGE_CACHE_THRESHOLD_IF_PACKED; - - clientStore_ -> getRequestStore(X_PutImage) -> - cacheLowerThreshold = PUTIMAGE_CACHE_LOWER_THRESHOLD_IF_PACKED; - } - } - - // - // If this is a shadow session increase the - // size of the image cache. - // - - if (control -> SessionMode == session_shadow) - { - if (control -> PackMethod != NO_PACK) - { - clientStore_ -> getRequestStore(X_NXPutPackedImage) -> - cacheThreshold = PUTPACKEDIMAGE_CACHE_THRESHOLD_IF_PACKED_SHADOW; - - clientStore_ -> getRequestStore(X_NXPutPackedImage) -> - cacheLowerThreshold = PUTPACKEDIMAGE_CACHE_LOWER_THRESHOLD_IF_PACKED_SHADOW; - } - else - { - clientStore_ -> getRequestStore(X_PutImage) -> - cacheThreshold = PUTIMAGE_CACHE_THRESHOLD_IF_SHADOW; - - clientStore_ -> getRequestStore(X_PutImage) -> - cacheLowerThreshold = PUTIMAGE_CACHE_LOWER_THRESHOLD_IF_SHADOW; - } - } - - return 1; -} - -int Proxy::handleSaveStores() -{ - // - // Save content of stores on disk. - // - - char *cacheToAdopt = NULL; - - // - // Set to false the indicator for cumulative store - // size too small - // - bool isTooSmall = false; - - if (control -> PersistentCacheEnableSave) - { - #ifdef TEST - *logofs << "Proxy: Going to save content of client store.\n" - << logofs_flush; - #endif - - cacheToAdopt = handleSaveAllStores(control -> PersistentCachePath, isTooSmall); - } - #ifdef TEST - else - { - if (control -> ProxyMode == proxy_client) - { - *logofs << "Proxy: Saving persistent cache to disk disabled.\n" - << logofs_flush; - } - else - { - *logofs << "Proxy: PANIC! Protocol violation in command save.\n" - << logofs_flush; - - cerr << "Error" << ": Protocol violation in command save.\n"; - - HandleCleanup(); - } - } - #endif - - if (cacheToAdopt != NULL) - { - // - // Do we have a cache already? - // - - if (control -> PersistentCacheName != NULL) - { - // - // Check if old and new cache are the same. - // In this case don't remove the old cache. - // - - if (strcasecmp(control -> PersistentCacheName, cacheToAdopt) != 0) - { - handleResetPersistentCache(); - } - - delete [] control -> PersistentCacheName; - } - - #ifdef TEST - *logofs << "Proxy: Setting current persistent cache file to '" - << cacheToAdopt << "'\n" << logofs_flush; - #endif - - control -> PersistentCacheName = cacheToAdopt; - - return 1; - } - else - { - #ifdef TEST - *logofs << "Proxy: No cache file produced from message stores.\n" - << logofs_flush; - #endif - - // - // It can be that we didn't generate a new cache - // because store was too small or persistent cache - // was disabled. This is not an error. - // - - if (control -> PersistentCacheEnableSave && !isTooSmall) - { - return -1; - } - else - { - return 0; - } - } -} - -int Proxy::handleLoadStores() -{ - // - // Restore the content of the client store - // from disk if a valid cache was negotiated - // at session startup. - // - - if (control -> PersistentCacheEnableLoad == 1 && - control -> PersistentCachePath != NULL && - control -> PersistentCacheName != NULL) - { - #ifdef TEST - *logofs << "Proxy: Going to load content of client store.\n" - << logofs_flush; - #endif - - // - // Returns the same string passed as name of - // the cache, or NULL if it was not possible - // to load the cache from disk. - // - - if (handleLoadAllStores(control -> PersistentCachePath, - control -> PersistentCacheName) == NULL) - { - // - // The corrupted cache should have been - // removed from disk. Get rid of the - // reference so we don't try to delete - // it once again. - // - - if (control -> PersistentCacheName != NULL) - { - delete [] control -> PersistentCacheName; - } - - control -> PersistentCacheName = NULL; - - return -1; - } - - // - // Set timestamp of last time cache - // was loaded from data on disk. - // - - timeouts_.loadTs = getTimestamp(); - - return 1; - } - #ifdef TEST - else - { - if (control -> ProxyMode == proxy_client) - { - *logofs << "Proxy: Loading of cache disabled or no cache file selected.\n" - << logofs_flush; - } - else - { - *logofs << "Proxy: PANIC! Protocol violation in command load.\n" - << logofs_flush; - - cerr << "Error" << ": Protocol violation in command load.\n"; - - HandleCleanup(); - } - } - #endif - - return 0; -} - -int Proxy::handleControl(T_proxy_code code, int data) -{ - // - // Send the given control messages - // to the remote proxy. - // - - #if defined(TEST) || defined(INFO) - - if (data != -1) - { - if (code == code_control_token_reply || - code == code_split_token_reply || - code == code_data_token_reply) - { - *logofs << "Proxy: TOKEN! Sending message '" << DumpControl(code) - << "' at " << strMsTimestamp() << " with count " - << data << ".\n" << logofs_flush; - } - else - { - *logofs << "Proxy: Sending message '" << DumpControl(code) - << "' at " << strMsTimestamp() << " with data ID#" - << data << ".\n" << logofs_flush; - } - } - else - { - *logofs << "Proxy: Sending message '" << DumpControl(code) - << "' at " << strMsTimestamp() << ".\n" - << logofs_flush; - } - - #endif - - // - // Add the control message and see if the - // data has to be flushed immediately. - // - - if (addControlCodes(code, data) < 0) - { - return -1; - } - - switch (code) - { - // - // Append the first data read from the opened - // channel to the control code. - // - - case code_new_x_connection: - case code_new_cups_connection: - case code_new_aux_connection: - case code_new_smb_connection: - case code_new_media_connection: - case code_new_http_connection: - case code_new_font_connection: - case code_new_slave_connection: - - // - // Do we send the token reply immediately? - // The control messages are put at the begin- - // ning of the of the encode buffer, so we may - // reply to multiple tokens before having the - // chance of handling the actual frame data. - // On the other hand, the sooner we reply, the - // sooner the remote proxy is restarted. - // - - case code_control_token_reply: - case code_split_token_reply: - case code_data_token_reply: - { - break; - } - - // - // Also send the congestion control codes - // immediately. - // - // case code_begin_congestion: - // case code_end_congestion: - // - - default: - { - priority_ = 1; - - break; - } - } - - if (priority_ == 1) - { - if (handleFrame(frame_data) < 0) - { - return -1; - } - } - - return 1; -} - -int Proxy::handleSwitch(int channelId) -{ - // - // If data is for a different channel than last - // selected for output, prepend to the data the - // new channel id. - // - - #ifdef DEBUG - *logofs << "Proxy: Requested a switch with " - << "current channel ID#" << outputChannel_ - << " new channel ID#" << channelId << ".\n" - << logofs_flush; - #endif - - if (channelId != outputChannel_) - { - if (needFlush() == 1) - { - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "Proxy: WARNING! Flushing data for the " - << "previous channel ID#" << outputChannel_ - << ".\n" << logofs_flush; - #endif - - if (handleFrame(frame_data) < 0) - { - return -1; - } - } - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Sending message '" - << DumpControl(code_switch_connection) << "' at " - << strMsTimestamp() << " with FD#" << getFd(channelId) - << " channel ID#" << channelId << ".\n" - << logofs_flush; - #endif - - if (addControlCodes(code_switch_connection, channelId) < 0) - { - return -1; - } - - outputChannel_ = channelId; - } - - return 1; -} - -int Proxy::addTokenCodes(T_proxy_token &token) -{ - #if defined(TEST) || defined(INFO) || defined(TOKEN) - *logofs << "Proxy: TOKEN! Sending token [" - << DumpToken(token.type) << "] with " - << token.bytes << " bytes accumulated size " - << token.size << " and " << token.remaining - << " available.\n" << logofs_flush; - #endif - - // - // Give a 'weight' to the token. The tokens - // remaining can become negative if we sent - // a packet that was exceptionally big. - // - - int count = 0; - - // Since ProtoStep7 (#issue 108) - count = token.bytes / token.size; - - // - // Force a count of 1, for example - // if this is a ping. - // - - if (count < 1) - { - count = 1; - - token.bytes = 0; - } - else - { - // Since ProtoStep7 (#issue 108) - if (count > 255) - { - count = 255; - } - - // - // Let the next token account for the - // remaining bytes. - // - - token.bytes %= token.size; - } - - #if defined(TEST) || defined(INFO) || defined(TOKEN) - *logofs << "Proxy: Sending message '" - << DumpControl(token.request) << "' at " - << strMsTimestamp() << " with count " << count - << ".\n" << logofs_flush; - #endif - - controlCodes_[controlLength_++] = 0; - controlCodes_[controlLength_++] = (unsigned char) token.request; - controlCodes_[controlLength_++] = (unsigned char) count; - - statistics -> addFrameOut(); - - token.remaining -= count; - - return 1; -} - -int Proxy::handleToken(T_frame_type type) -{ - #if defined(TEST) || defined(INFO) || defined(TOKEN) - *logofs << "Proxy: TOKEN! Checking tokens with " - << "frame type ["; - - *logofs << (type == frame_ping ? "frame_ping" : "frame_data"); - - *logofs << "] with stream ratio " << statistics -> - getStreamRatio() << ".\n" << logofs_flush; - #endif - - if (type == frame_data) - { - // - // Since ProtoStep7 (#issue 108) - // - - // Send a distinct token for each data type. - // We don't want to slow down the sending of - // the X events, X replies and split confir- - // mation events on the X server side, so - // take care only of the generic data token. - // - - if (control -> ProxyMode == proxy_client) - { - statistics -> updateControlToken(tokens_[token_control].bytes); - - if (tokens_[token_control].bytes > tokens_[token_control].size) - { - if (addTokenCodes(tokens_[token_control]) < 0) - { - return -1; - } - - #if defined(TEST) || defined(INFO) || defined(TOKEN) - - T_proxy_token &token = tokens_[token_control]; - - *logofs << "Proxy: TOKEN! Token class [" - << DumpToken(token.type) << "] has now " - << token.bytes << " bytes accumulated and " - << token.remaining << " tokens remaining.\n" - << logofs_flush; - #endif - } - - statistics -> updateSplitToken(tokens_[token_split].bytes); - - if (tokens_[token_split].bytes > tokens_[token_split].size) - { - if (addTokenCodes(tokens_[token_split]) < 0) - { - return -1; - } - - #if defined(TEST) || defined(INFO) || defined(TOKEN) - - T_proxy_token &token = tokens_[token_split]; - - *logofs << "Proxy: TOKEN! Token class [" - << DumpToken(token.type) << "] has now " - << token.bytes << " bytes accumulated and " - << token.remaining << " tokens remaining.\n" - << logofs_flush; - #endif - } - } - - statistics -> updateDataToken(tokens_[token_data].bytes); - - if (tokens_[token_data].bytes > tokens_[token_data].size) - { - if (addTokenCodes(tokens_[token_data]) < 0) - { - return -1; - } - - #if defined(TEST) || defined(INFO) || defined(TOKEN) - - T_proxy_token &token = tokens_[token_data]; - - *logofs << "Proxy: TOKEN! Token class [" - << DumpToken(token.type) << "] has now " - << token.bytes << " bytes accumulated and " - << token.remaining << " tokens remaining.\n" - << logofs_flush; - #endif - } - } - else - { - if (addTokenCodes(tokens_[token_control]) < 0) - { - return -1; - } - - // - // Reset all counters on a ping. - // - - tokens_[token_control].bytes = 0; - tokens_[token_split].bytes = 0; - tokens_[token_data].bytes = 0; - - #if defined(TEST) || defined(INFO) || defined(TOKEN) - - T_proxy_token &token = tokens_[token_control]; - - *logofs << "Proxy: TOKEN! Token class [" - << DumpToken(token.type) << "] has now " - << token.bytes << " bytes accumulated and " - << token.remaining << " tokens remaining.\n" - << logofs_flush; - #endif - } - - // - // Check if we have entered in - // congestion state. - // - - if (congestion_ == 0 && - tokens_[token_control].remaining <= 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Entering congestion with " - << tokens_[token_control].remaining - << " tokens remaining.\n" << logofs_flush; - #endif - - congestion_ = 1; - } - - statistics -> updateCongestion(tokens_[token_control].remaining, - tokens_[token_control].limit); - - return 1; -} - -int Proxy::handleTokenFromProxy(T_proxy_token &token, int count) -{ - #if defined(TEST) || defined(INFO) || defined(TOKEN) - *logofs << "Proxy: TOKEN! Received token [" - << DumpToken(token.type) << "] request at " - << strMsTimestamp() << " with count " - << count << ".\n" << logofs_flush; - #endif - - // - // Since ProtoStep7 (#issue 108) with no limitations - // concerning invalid token requests at this point - // - - // - // Add our token reply. - // - - if (handleControl(token.reply, count) < 0) - { - return -1; - } - - return 1; -} - -int Proxy::handleTokenReplyFromProxy(T_proxy_token &token, int count) -{ - #if defined(TEST) || defined(INFO) || defined(TOKEN) - *logofs << "Proxy: TOKEN! Received token [" - << DumpToken(token.type) << "] reply at " - << strMsTimestamp() << " with count " << count - << ".\n" << logofs_flush; - #endif - - // - // Since ProtoStep7 (#issue 108) with no limitations - // concerning invalid token requests at this point - // - - // - // Increment the available tokens. - // - - token.remaining += count; - - if (token.remaining > token.limit) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Token overflow handling messages.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Token overflow handling messages.\n"; - - HandleCleanup(); - } - - #if defined(TEST) || defined(INFO) || defined(TOKEN) - *logofs << "Proxy: TOKEN! Token class [" - << DumpToken(token.type) << "] has now " << token.bytes - << " bytes accumulated and " << token.remaining - << " tokens remaining.\n" << logofs_flush; - #endif - - // - // Check if we can jump out of the - // congestion state. - // - - if (congestion_ == 1 && - tokens_[token_control].remaining > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Exiting congestion with " - << tokens_[token_control].remaining - << " tokens remaining.\n" << logofs_flush; - #endif - - congestion_ = 0; - } - - statistics -> updateCongestion(tokens_[token_control].remaining, - tokens_[token_control].limit); - - return 1; -} - -void Proxy::handleFailOnSave(const char *fullName, const char *failContext) const -{ - #ifdef WARNING - *logofs << "Proxy: WARNING! Error saving stores to cache file " - << "in context [" << failContext << "].\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Error saving stores to cache file " - << "in context [" << failContext << "].\n"; - - #ifdef WARNING - *logofs << "Proxy: WARNING! Removing invalid cache '" - << fullName << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Removing invalid cache '" - << fullName << "'.\n"; - - unlink(fullName); -} - -void Proxy::handleFailOnLoad(const char *fullName, const char *failContext) const -{ - #ifdef WARNING - *logofs << "Proxy: WARNING! Error loading stores from cache file " - << "in context [" << failContext << "].\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Error loading stores from cache file " - << "in context [" << failContext << "].\n"; - - #ifdef WARNING - *logofs << "Proxy: WARNING! Removing invalid cache '" - << fullName << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Removing invalid cache '" - << fullName << "'.\n"; - - unlink(fullName); -} - -int Proxy::handleSaveVersion(unsigned char *buffer, int &major, - int &minor, int &patch) const -{ - // Since ProtoStep8 (#issue 108) - major = 3; - minor = 0; - patch = 0; - - *(buffer + 0) = major; - *(buffer + 1) = minor; - - PutUINT(patch, buffer + 2, storeBigEndian()); - - return 1; -} - -int Proxy::handleLoadVersion(const unsigned char *buffer, int &major, - int &minor, int &patch) const -{ - major = *(buffer + 0); - minor = *(buffer + 1); - - patch = GetUINT(buffer + 2, storeBigEndian()); - - // - // Force the proxy to discard the - // incompatible caches. - // - - // Since ProtoStep8 (#issue 108) - if (major < 3) - { - return -1; - } - - return 1; -} - -char *Proxy::handleSaveAllStores(const char *savePath, bool & isTooSmall) const -{ - isTooSmall = false; - - int cumulativeSize = MessageStore::getCumulativeTotalStorageSize(); - - if (cumulativeSize < control -> PersistentCacheThreshold) - { - #ifdef TEST - *logofs << "Proxy: Cache not saved as size is " - << cumulativeSize << " with threshold set to " - << control -> PersistentCacheThreshold - << ".\n" << logofs_flush; - #endif - - // - // Cumulative store size is smaller than threshold - // so the indicator is set to true - // - - isTooSmall = true; - - return NULL; - } - else if (savePath == NULL) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! No name provided for save path.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": No name provided for save path.\n"; - - return NULL; - } - - #ifdef TEST - *logofs << "Proxy: Going to save content of message stores.\n" - << logofs_flush; - #endif - - // - // Our parent process is likely going to terminate. - // Until we finish saving cache we must ignore its - // SIGIPE. - // - - DisableSignals(); - - ofstream *cachefs = NULL; - - md5_state_t *md5StateStream = NULL; - md5_byte_t *md5DigestStream = NULL; - - md5_state_t *md5StateClient = NULL; - md5_byte_t *md5DigestClient = NULL; - - char md5String[MD5_LENGTH * 2 + 2]; - - char fullName[strlen(savePath) + MD5_LENGTH * 2 + 4]; - - // - // Prepare the template for the temporary file - // - - const char* const uniqueTemplate = "XXXXXX"; - char tempName[strlen(savePath) + strlen("/") + 4 + strlen(uniqueTemplate) + 1]; - - snprintf(tempName, sizeof tempName, "%s/%s%s", - savePath, - control -> ProxyMode == proxy_client ? - "Z-C-" : - "Z-S-", - uniqueTemplate); - - #ifdef TEST - *logofs << "Proxy: Generating temporary file with template '" - << tempName << "'.\n" << logofs_flush; - #endif - - // - // Change the mask to make the file only - // readable by the user, then restore the - // old mask. - // - - mode_t fileMode = umask(0077); - - // - // Generate a unique temporary filename from tempName - // and then create and open the file - // - - int fdTemp = mkstemp(tempName); - if (fdTemp == -1) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Can't create temporary file in '" - << savePath << "'. Cause = " << strerror(errno) << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't create temporary file in '" - << savePath << "'. Cause = " << strerror(errno) << ".\n"; - - umask(fileMode); - - EnableSignals(); - - return NULL; - } - - #ifdef TEST - *logofs << "Proxy: Saving cache to file '" - << tempName << "'.\n" << logofs_flush; - #endif - - // - // Create and open the output stream for the new temporary - // file - // - - cachefs = new (std::nothrow) ofstream(tempName, ios::out | ios::binary); - if ((cachefs == NULL) || cachefs->fail()) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Can't create stream for temporary file '" - << tempName << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't create stream for temporary file '" - << tempName << "'.\n"; - - close(fdTemp); - unlink(tempName); - - umask(fileMode); - - EnableSignals(); - - return NULL; - } - - // - // Close the file descriptor returned by mkstemp - // and restore the old mask - // - - close(fdTemp); - umask(fileMode); - - md5StateStream = new md5_state_t(); - md5DigestStream = new md5_byte_t[MD5_LENGTH]; - - md5_init(md5StateStream); - - // - // First write the proxy version. - // - - unsigned char version[4]; - - int major; - int minor; - int patch; - - handleSaveVersion(version, major, minor, patch); - - #ifdef TEST - *logofs << "Proxy: Saving cache using version '" - << major << "." << minor << "." << patch - << "'.\n" << logofs_flush; - #endif - - if (PutData(cachefs, version, 4) < 0) - { - handleFailOnSave(tempName, "A"); - - delete cachefs; - - delete md5StateStream; - delete [] md5DigestStream; - - EnableSignals(); - - return NULL; - } - - // - // Make space for the calculated MD5 so we - // can later rewind the file and write it - // at this position. - // - - if (PutData(cachefs, md5DigestStream, MD5_LENGTH) < 0) - { - handleFailOnSave(tempName, "B"); - - delete cachefs; - - delete md5StateStream; - delete [] md5DigestStream; - - EnableSignals(); - - return NULL; - } - - md5StateClient = new md5_state_t(); - md5DigestClient = new md5_byte_t[MD5_LENGTH]; - - md5_init(md5StateClient); - - #ifdef DUMP - - ofstream *cacheDump = NULL; - - ofstream *tempfs = (ofstream*) logofs; - - char cacheDumpName[DEFAULT_STRING_LENGTH]; - - if (control -> ProxyMode == proxy_client) - { - snprintf(cacheDumpName, DEFAULT_STRING_LENGTH - 1, - "%s/client-cache-dump", control -> TempPath); - } - else - { - snprintf(cacheDumpName, DEFAULT_STRING_LENGTH - 1, - "%s/server-cache-dump", control -> TempPath); - } - - *(cacheDumpName + DEFAULT_STRING_LENGTH - 1) = '\0'; - - fileMode = umask(0077); - - cacheDump = new ofstream(cacheDumpName, ios::out); - - umask(fileMode); - - logofs = cacheDump; - - #endif - - // - // Use the virtual method of the concrete proxy class. - // - - int allSaved = handleSaveAllStores(cachefs, md5StateStream, md5StateClient); - - #ifdef DUMP - - logofs = tempfs; - - delete cacheDump; - - #endif - - if (allSaved == -1) - { - handleFailOnSave(tempName, "C"); - - delete cachefs; - - delete md5StateStream; - delete [] md5DigestStream; - - delete md5StateClient; - delete [] md5DigestClient; - - EnableSignals(); - - return NULL; - } - - md5_finish(md5StateClient, md5DigestClient); - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - sprintf(md5String + (i * 2), "%02X", md5DigestClient[i]); - } - - strcpy(fullName, (control -> ProxyMode == proxy_client) ? "C-" : "S-"); - - strcat(fullName, md5String); - - md5_append(md5StateStream, (const md5_byte_t *) fullName, strlen(fullName)); - md5_finish(md5StateStream, md5DigestStream); - - // - // Go to the beginning of file plus - // the integer where we wrote our - // proxy version. - // - - cachefs -> seekp(4); - - if (PutData(cachefs, md5DigestStream, MD5_LENGTH) < 0) - { - handleFailOnSave(tempName, "D"); - - delete cachefs; - - delete md5StateStream; - delete [] md5DigestStream; - - delete md5StateClient; - delete [] md5DigestClient; - - EnableSignals(); - - return NULL; - } - - delete cachefs; - - // - // Copy the resulting cache name without - // the path so that we can return it to - // the caller. - // - - char *cacheName = new char[MD5_LENGTH * 2 + 4]; - - strcpy(cacheName, fullName); - - // - // Add the path to the full name and move - // the cache into the path. - // - - strcpy(fullName, savePath); - strcat(fullName, (control -> ProxyMode == proxy_client) ? "/C-" : "/S-"); - strcat(fullName, md5String); - - #ifdef TEST - *logofs << "Proxy: Renaming cache file from '" - << tempName << "' to '" << fullName - << "'.\n" << logofs_flush; - #endif - - rename(tempName, fullName); - - delete md5StateStream; - delete [] md5DigestStream; - - delete md5StateClient; - delete [] md5DigestClient; - - // - // Restore the original handlers. - // - - EnableSignals(); - - #ifdef TEST - *logofs << "Proxy: Successfully saved cache file '" - << cacheName << "'.\n" << logofs_flush; - #endif - - // - // This must be enabled only for test - // because it requires that client and - // server reside on the same machine. - // - - if (control -> PersistentCacheCheckOnShutdown == 1 && - control -> ProxyMode == proxy_server) - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: MATCH! Checking if the file '" - << fullName << "' matches a client cache.\n" - << logofs_flush; - #endif - - strcpy(fullName, savePath); - strcat(fullName, "/C-"); - strcat(fullName, md5String); - - struct stat fileStat; - - if (stat(fullName, &fileStat) != 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Can't find a client cache " - << "with name '" << fullName << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't find a client cache " - << "with name '" << fullName << "'.\n"; - - HandleShutdown(); - } - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: MATCH! Client cache '" << fullName - << "' matches the local cache.\n" - << logofs_flush; - #endif - } - - return cacheName; -} - -const char *Proxy::handleLoadAllStores(const char *loadPath, const char *loadName) const -{ - #ifdef TEST - *logofs << "Proxy: Going to load content of message stores.\n" - << logofs_flush; - #endif - - // - // Until we finish loading cache we - // must at least ignore any SIGIPE. - // - - DisableSignals(); - - if (loadPath == NULL || loadName == NULL) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! No path or no file name provided for cache to restore.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": No path or no file name provided for cache to restore.\n"; - - EnableSignals(); - - return NULL; - } - else if (strlen(loadName) != MD5_LENGTH * 2 + 2) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Bad file name provided for cache to restore.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Bad file name provided for cache to restore.\n"; - - EnableSignals(); - - return NULL; - } - - istream *cachefs = NULL; - char md5String[(MD5_LENGTH * 2) + 2]; - md5_byte_t md5FromFile[MD5_LENGTH]; - - char *cacheName = new char[strlen(loadPath) + strlen(loadName) + 3]; - - strcpy(cacheName, loadPath); - strcat(cacheName, "/"); - strcat(cacheName, loadName); - - #ifdef TEST - *logofs << "Proxy: Name of cache file is '" - << cacheName << "'.\n" << logofs_flush; - #endif - - cachefs = new ifstream(cacheName, ios::in | ios::binary); - - unsigned char version[4]; - - if (cachefs == NULL || GetData(cachefs, version, 4) < 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Can't read cache file '" - << cacheName << "'.\n" << logofs_flush;; - #endif - - handleFailOnLoad(cacheName, "A"); - - delete cachefs; - - delete [] cacheName; - - EnableSignals(); - - return NULL; - } - - int major; - int minor; - int patch; - - if (handleLoadVersion(version, major, minor, patch) < 0) - { - #ifdef PANIC - *logofs << "Proxy: WARNING! Incompatible version '" - << major << "." << minor << "." << patch - << "' in cache file '" << cacheName - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Incompatible version '" - << major << "." << minor << "." << patch - << "' in cache file '" << cacheName - << "'.\n" << logofs_flush; - - if (control -> ProxyMode == proxy_server) - { - handleFailOnLoad(cacheName, "B"); - } - else - { - // - // Simply remove the cache file. - // - - unlink(cacheName); - } - - delete cachefs; - - delete [] cacheName; - - EnableSignals(); - - return NULL; - } - - #ifdef TEST - *logofs << "Proxy: Reading from cache file version '" - << major << "." << minor << "." << patch - << "'.\n" << logofs_flush; - #endif - - if (GetData(cachefs, md5FromFile, MD5_LENGTH) < 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! No checksum in cache file '" - << loadName << "'.\n" << logofs_flush; - #endif - - handleFailOnLoad(cacheName, "C"); - - delete cachefs; - - delete [] cacheName; - - EnableSignals(); - - return NULL; - } - - md5_state_t *md5StateStream = NULL; - md5_byte_t *md5DigestStream = NULL; - - md5StateStream = new md5_state_t(); - md5DigestStream = new md5_byte_t[MD5_LENGTH]; - - md5_init(md5StateStream); - - // - // Use the virtual method of the proxy class. - // - - if (handleLoadAllStores(cachefs, md5StateStream) < 0) - { - handleFailOnLoad(cacheName, "D"); - - delete cachefs; - - delete md5StateStream; - delete [] md5DigestStream; - - delete [] cacheName; - - EnableSignals(); - - return NULL; - } - - md5_append(md5StateStream, (const md5_byte_t *) loadName, strlen(loadName)); - md5_finish(md5StateStream, md5DigestStream); - - for (int i = 0; i < MD5_LENGTH; i++) - { - if (md5DigestStream[i] != md5FromFile[i]) - { - #ifdef PANIC - - *logofs << "Proxy: PANIC! Bad checksum for cache file '" - << cacheName << "'.\n" << logofs_flush; - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - sprintf(md5String + (i * 2), "%02X", md5FromFile[i]); - } - - *logofs << "Proxy: PANIC! Saved checksum is '" - << md5String << "'.\n" << logofs_flush; - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - sprintf(md5String + (i * 2),"%02X", md5DigestStream[i]); - } - - *logofs << "Proxy: PANIC! Calculated checksum is '" - << md5String << "'.\n" << logofs_flush; - - #endif - - handleFailOnLoad(cacheName, "E"); - - delete cachefs; - - delete md5StateStream; - delete [] md5DigestStream; - - delete [] cacheName; - - EnableSignals(); - - return NULL; - } - } - - delete cachefs; - - delete md5StateStream; - delete [] md5DigestStream; - - delete [] cacheName; - - // - // Restore the original handlers. - // - - EnableSignals(); - - #ifdef TEST - *logofs << "Proxy: Successfully loaded cache file '" - << loadName << "'.\n" << logofs_flush; - #endif - - // - // Return the string provided by caller. - // - - return loadName; -} - -int Proxy::allocateChannelMap(int fd) -{ - // - // We assume that the fd is lower than - // the maximum allowed number. This is - // checked at the time the connection - // is accepted. - // - - if (fd < 0 || fd >= CONNECTIONS_LIMIT) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Internal error allocating " - << "new channel with FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Internal error allocating " - << "new channel with FD#" << fd_ << ".\n"; - - HandleCleanup(); - } - - for (int channelId = 0; - channelId < CONNECTIONS_LIMIT; - channelId++) - { - if (checkLocalChannelMap(channelId) == 1 && - fdMap_[channelId] == -1) - { - fdMap_[channelId] = fd; - channelMap_[fd] = channelId; - - #ifdef TEST - *logofs << "Proxy: Allocated new channel ID#" - << channelId << " with FD#" << fd << ".\n" - << logofs_flush; - #endif - - return channelId; - } - } - - // - // No available channel is remaining. - // - - #ifdef TEST - *logofs << "Proxy: WARNING! Can't allocate a new channel " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - return -1; -} - -int Proxy::checkChannelMap(int channelId) -{ - // - // To be acceptable, the channel id must - // be an id that is not possible to use - // to allocate channels at this side. - // - - if (checkLocalChannelMap(channelId) == 1) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Can't open a new channel " - << "with invalid ID#" << channelId << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't open a new channel " - << "with invalid ID#" << channelId << ".\n"; - - return -1; - } - else if (channels_[channelId] != NULL) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Can't open a new channel " - << "over an existing ID#" << channelId - << " with FD#" << getFd(channelId) - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't open a new channel " - << "over an existing ID#" << channelId - << " with FD#" << getFd(channelId) - << ".\n"; - - return -1; - } - - return 1; -} - -int Proxy::assignChannelMap(int channelId, int fd) -{ - // - // We assume that the fd is lower than - // the maximum allowed number. This is - // checked at the time the connection - // is accepted. - // - - if (channelId < 0 || channelId >= CONNECTIONS_LIMIT || - fd < 0 || fd >= CONNECTIONS_LIMIT) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Internal error assigning " - << "new channel with FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Internal error assigning " - << "new channel with FD#" << fd_ << ".\n"; - - HandleCleanup(); - } - - fdMap_[channelId] = fd; - channelMap_[fd] = channelId; - - return 1; -} - -void Proxy::cleanupChannelMap(int channelId) -{ - int fd = fdMap_[channelId]; - - if (fd != -1) - { - fdMap_[channelId] = -1; - channelMap_[fd] = -1; - } -} - -int Proxy::addControlCodes(T_proxy_code code, int data) -{ - // - // Flush the encode buffer plus all the outstanding - // control codes if there is not enough space for - // the new control message. We need to ensure that - // there are further bytes available, in the case - // we will need to add more token control messages. - // - - if (controlLength_ + 3 > CONTROL_CODES_THRESHOLD) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! Flushing control messages " - << "while sending code '" << DumpControl(code) - << "'.\n" << logofs_flush; - #endif - - if (handleFlush() < 0) - { - return -1; - } - } - - controlCodes_[controlLength_++] = 0; - controlCodes_[controlLength_++] = (unsigned char) code; - controlCodes_[controlLength_++] = (unsigned char) (data == -1 ? 0 : data); - - // - // Account for the control frame. - // - - statistics -> addFrameOut(); - - return 1; -} - -void Proxy::setSplitTimeout(int channelId) -{ - int needed = channels_[channelId] -> needSplit(); - - if (needed != isTimestamp(timeouts_.splitTs)) - { - if (needed == 1) - { - #if defined(TEST) || defined(INFO) || defined(SPLIT) - *logofs << "Proxy: SPLIT! Allocating split timestamp at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - timeouts_.splitTs = getTimestamp(); - } - else - { - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL && - channels_[channelId] -> needSplit() == 1) - { - #ifdef TEST - *logofs << "Proxy: SPLIT! Channel for FD#" - << getFd(channelId) << " still needs splits.\n" - << logofs_flush; - #endif - - return; - } - } - - #if defined(TEST) || defined(INFO) || defined(SPLIT) - *logofs << "Proxy: SPLIT! Resetting split timestamp at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - timeouts_.splitTs = nullTimestamp(); - } - } -} - -void Proxy::setMotionTimeout(int channelId) -{ - int needed = channels_[channelId] -> needMotion(); - - if (needed != isTimestamp(timeouts_.motionTs)) - { - if (channels_[channelId] -> needMotion() == 1) - { - #if defined(TEST) || defined(INFO) || defined(SPLIT) - *logofs << "Proxy: Allocating motion timestamp at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - timeouts_.motionTs = getTimestamp(); - } - else - { - T_list &channelList = activeChannels_.getList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL && - channels_[channelId] -> needMotion() == 1) - { - #ifdef TEST - *logofs << "Proxy: SPLIT! Channel for FD#" - << getFd(channelId) << " still needs motions.\n" - << logofs_flush; - #endif - - return; - } - } - - #if defined(TEST) || defined(INFO) || defined(SPLIT) - *logofs << "Proxy: Resetting motion timestamp at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - timeouts_.motionTs = nullTimestamp(); - } - } -} - -void Proxy::increaseChannels(int channelId) -{ - #ifdef TEST - *logofs << "Proxy: Adding channel " << channelId - << " to the list of active channels.\n" - << logofs_flush; - #endif - - activeChannels_.add(channelId); - - #ifdef TEST - *logofs << "Proxy: There are " << activeChannels_.getSize() - << " allocated channels for proxy FD#" << fd_ - << ".\n" << logofs_flush; - #endif -} - -void Proxy::decreaseChannels(int channelId) -{ - #ifdef TEST - *logofs << "Proxy: Removing channel " << channelId - << " from the list of active channels.\n" - << logofs_flush; - #endif - - activeChannels_.remove(channelId); - - #ifdef TEST - *logofs << "Proxy: There are " << activeChannels_.getSize() - << " allocated channels for proxy FD#" << fd_ - << ".\n" << logofs_flush; - #endif -} - -int Proxy::allocateTransport(int channelFd, int channelId) -{ - if (transports_[channelId] == NULL) - { - transports_[channelId] = new Transport(channelFd); - - if (transports_[channelId] == NULL) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Can't allocate transport for " - << "channel id " << channelId << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate transport for " - << "channel id " << channelId << ".\n"; - - return -1; - } - } - else if (transports_[channelId] -> - getType() != transport_agent) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Transport for channel id " - << channelId << " should be null.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Transport for channel id " - << channelId << " should be null.\n"; - - return -1; - } - - return 1; -} - -int Proxy::deallocateTransport(int channelId) -{ - // - // Transport for the agent connection - // is passed from the outside when - // creating the channel. - // - - if (transports_[channelId] -> - getType() != transport_agent) - { - delete transports_[channelId]; - } - - transports_[channelId] = NULL; - - return 1; -} - -int Proxy::handleNewGenericConnection(int clientFd, T_channel_type type, const char *label) -{ - int channelId = allocateChannelMap(clientFd); - - if (channelId == -1) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Maximum number of available " - << "channels exceeded.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Maximum number of available " - << "channels exceeded.\n"; - - return -1; - } - - #ifdef TEST - *logofs << "Proxy: Channel for " << label << " descriptor " - << "FD#" << clientFd << " mapped to ID#" - << channelId << ".\n" - << logofs_flush; - #endif - - // - // Turn queuing off for path server-to-proxy. - // - - SetNoDelay(clientFd, 1); - - if (allocateTransport(clientFd, channelId) < 0) - { - return -1; - } - - switch (type) - { - case channel_cups: - { - channels_[channelId] = new CupsChannel(transports_[channelId], compressor_); - - break; - } - case channel_smb: - { - channels_[channelId] = new SmbChannel(transports_[channelId], compressor_); - - break; - } - case channel_media: - { - channels_[channelId] = new MediaChannel(transports_[channelId], compressor_); - - break; - } - case channel_http: - { - channels_[channelId] = new HttpChannel(transports_[channelId], compressor_); - - break; - } - case channel_font: - { - channels_[channelId] = new FontChannel(transports_[channelId], compressor_); - - break; - } - default: - { - channels_[channelId] = new SlaveChannel(transports_[channelId], compressor_); - - break; - } - } - - if (channels_[channelId] == NULL) - { - deallocateTransport(channelId); - - return -1; - } - - #ifdef TEST - *logofs << "Proxy: Accepted new connection to " - << label << " server.\n" << logofs_flush; - #endif - - cerr << "Info" << ": Accepted new connection to " - << label << " server.\n"; - - increaseChannels(channelId); - - switch (type) - { - case channel_cups: - { - if (handleControl(code_new_cups_connection, channelId) < 0) - { - return -1; - } - - break; - } - case channel_smb: - { - if (handleControl(code_new_smb_connection, channelId) < 0) - { - return -1; - } - - break; - } - case channel_media: - { - if (handleControl(code_new_media_connection, channelId) < 0) - { - return -1; - } - - break; - } - case channel_http: - { - if (handleControl(code_new_http_connection, channelId) < 0) - { - return -1; - } - - break; - } - case channel_font: - { - if (handleControl(code_new_font_connection, channelId) < 0) - { - return -1; - } - - break; - } - default: - { - if (handleControl(code_new_slave_connection, channelId) < 0) - { - return -1; - } - - break; - } - } - - channels_[channelId] -> handleConfiguration(); - - return 1; -} - -int Proxy::handleNewSlaveConnection(int clientFd) -{ - // Since ProtoStep7 (#issue 108) - return handleNewGenericConnection(clientFd, channel_slave, "slave"); -} - - - -int Proxy::handleNewGenericConnectionFromProxy(int channelId, T_channel_type type, - ChannelEndPoint &endPoint, const char *label) -{ - char *unixPath, *host; - long port; - - if (endPoint.getUnixPath(&unixPath)) { - return handleNewGenericConnectionFromProxyUnix(channelId, type, unixPath, label); - } - - if (endPoint.getTCPHostAndPort(&host, &port)) { - return handleNewGenericConnectionFromProxyTCP(channelId, type, host, port, label); - } - - #ifdef WARNING - *logofs << "Proxy: WARNING! Refusing attempted connection " - << "to " << label << " server.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Refusing attempted connection " - << "to " << label << " server.\n"; - - return -1; -} - -int Proxy::handleNewGenericConnectionFromProxyTCP(int channelId, T_channel_type type, - const char *hostname, long port, const char *label) - -{ - if (port <= 0) - { - // - // This happens when user has disabled - // forwarding of the specific service. - // - - #ifdef WARNING - *logofs << "Proxy: WARNING! Refusing attempted connection " - << "to " << label << " server.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Refusing attempted connection " - << "to " << label << " server.\n"; - - return -1; - } - - const char *serverHost = hostname; - int serverAddrFamily = AF_INET; - sockaddr *serverAddr = NULL; - unsigned int serverAddrLength = 0; - - #ifdef TEST - *logofs << "Proxy: Connecting to " << label - << " server '" << serverHost << "' on TCP port '" - << port << "'.\n" << logofs_flush; - #endif - - int serverIPAddr = GetHostAddress(serverHost); - - if (serverIPAddr == 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Unknown " << label - << " server host '" << serverHost << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Unknown " << label - << " server host '" << serverHost - << "'.\n"; - - return -1; - } - - sockaddr_in *serverAddrTCP = new sockaddr_in; - - serverAddrTCP -> sin_family = AF_INET; - serverAddrTCP -> sin_port = htons(port); - serverAddrTCP -> sin_addr.s_addr = serverIPAddr; - - serverAddr = (sockaddr *) serverAddrTCP; - serverAddrLength = sizeof(sockaddr_in); - - // - // Connect to the requested server. - // - - int serverFd = socket(serverAddrFamily, SOCK_STREAM, PF_UNSPEC); - - if (serverFd < 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Call to socket failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to socket failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - delete serverAddrTCP; - - return -1; - } - else if (connect(serverFd, serverAddr, serverAddrLength) < 0) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! Connection to " << label - << " server '" << serverHost << ":" << port - << "' failed with error '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Connection to " << label - << " server '" << serverHost << ":" << port - << "' failed with error '" << ESTR() << "'.\n"; - - close(serverFd); - - delete serverAddrTCP; - - return -1; - } - - delete serverAddrTCP; - - if (handlePostConnectionFromProxy(channelId, serverFd, type, label) < 0) - { - return -1; - } - - #ifdef TEST - *logofs << "Proxy: Forwarded new connection to " - << label << " server on port '" << port - << "'.\n" << logofs_flush; - #endif - - cerr << "Info" << ": Forwarded new connection to " - << label << " server on port '" << port - << "'.\n"; - - return 1; -} - -int Proxy::handleNewGenericConnectionFromProxyUnix(int channelId, T_channel_type type, - const char *path, const char *label) -{ - if (path == NULL || *path == '\0' ) - { - // - // This happens when user has disabled - // forwarding of the specific service. - // - - #ifdef WARNING - *logofs << "Proxy: WARNING! Refusing attempted connection " - << "to " << label << " server.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Refusing attempted connection " - << "to " << label << " server.\n"; - - return -1; - } - - sockaddr_un serverAddrUnix; - - unsigned int serverAddrLength = sizeof(sockaddr_un); - - int serverAddrFamily = AF_UNIX; - - serverAddrUnix.sun_family = AF_UNIX; - - const int serverAddrNameLength = 108; - - strncpy(serverAddrUnix.sun_path, path, serverAddrNameLength); - - *(serverAddrUnix.sun_path + serverAddrNameLength - 1) = '\0'; - - #ifdef TEST - *logofs << "Proxy: Connecting to " << label << " server " - << "on Unix port '" << path << "'.\n" << logofs_flush; - #endif - - // - // Connect to the requested server. - // - - int serverFd = socket(serverAddrFamily, SOCK_STREAM, PF_UNSPEC); - - if (serverFd < 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! Call to socket failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to socket failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - return -1; - } - else if (connect(serverFd, (sockaddr *) &serverAddrUnix, serverAddrLength) < 0) - { - #ifdef WARNING - *logofs << "Proxy: WARNING! Connection to " << label - << " server on Unix port '" << path << "' failed " - << "with error " << EGET() << ", '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Connection to " << label - << " server on Unix port '" << path << "' failed " - << "with error " << EGET() << ", '" << ESTR() << "'.\n"; - - close(serverFd); - - return -1; - } - - if (handlePostConnectionFromProxy(channelId, serverFd, type, label) < 0) - { - return -1; - } - - #ifdef TEST - *logofs << "Proxy: Forwarded new connection to " - << label << " server on Unix port '" << path - << "'.\n" << logofs_flush; - #endif - - cerr << "Info" << ": Forwarded new connection to " - << label << " server on Unix port '" << path - << "'.\n"; - - return 1; -} - -int Proxy::handleNewSlaveConnectionFromProxy(int channelId) -{ - - cerr << "Info" << ": New slave connection on " - << "channel ID#" << channelId << "\n"; - - char *nx_slave_cmd = getenv("NX_SLAVE_CMD"); - if (nx_slave_cmd == NULL) { - return -1; - } - - int spair[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, spair) == -1) { - perror("socketpair"); - return -1; - } - - int serverFd = spair[0]; - int clientFd = spair[1]; - - if (handlePostConnectionFromProxy(channelId, serverFd, channel_slave, "slave") < 0) - { - close(serverFd); - close(clientFd); - return -1; - } - - - int pid = fork(); - if (pid == 0) - { - - if (dup2(clientFd, 0) == -1) - { - perror("dup2"); - exit(1); - } - - if (dup2(clientFd, 1) == -1) - { - perror("dup2"); - exit(1); - } - - close(serverFd); - close(clientFd); - - /* Close FDs used by NX, QVD #1208 */ - for (int fd = 3; fd < 256; fd++) { - close(fd); - } - - char *const argv[2] = {nx_slave_cmd, NULL}; - - if (execv(nx_slave_cmd, argv) == -1) - { - perror("execv"); - } - exit(1); - - } - else if (pid == -1) - { - // TODO Test this! - perror("fork"); - close(serverFd); - close(clientFd); - return -1; - } - - close(clientFd); - slavePidMap_[channelId] = pid; - - cerr << "Info" << ": slave channel ID#" << channelId << " handler has PID " << pid << endl; - - return 1; -} - -void Proxy::checkSlaves() -{ - for (int channelId = 0; channelId 1 && HandleChild(pid)) - { - slavePidMap_[channelId] = nothing; - cerr << "Info:" << " Handled death of slave with pid " << pid << endl; - } - } -} - -int Proxy::handlePostConnectionFromProxy(int channelId, int serverFd, - T_channel_type type, const char *label) -{ - // - // Turn queuing off for path proxy-to-server. - // - - SetNoDelay(serverFd, 1); - - assignChannelMap(channelId, serverFd); - - #ifdef TEST - *logofs << "Proxy: Descriptor FD#" << serverFd - << " mapped to channel ID#" << channelId << ".\n" - << logofs_flush; - #endif - - if (allocateTransport(serverFd, channelId) < 0) - { - return -1; - } - - switch (type) - { - case channel_cups: - { - channels_[channelId] = new CupsChannel(transports_[channelId], compressor_); - break; - } - case channel_smb: - { - channels_[channelId] = new SmbChannel(transports_[channelId], compressor_); - - break; - } - case channel_media: - { - channels_[channelId] = new MediaChannel(transports_[channelId], compressor_); - - break; - } - case channel_http: - { - channels_[channelId] = new HttpChannel(transports_[channelId], compressor_); - - break; - } - case channel_font: - { - channels_[channelId] = new FontChannel(transports_[channelId], compressor_); - - break; - } - default: - { - channels_[channelId] = new SlaveChannel(transports_[channelId], compressor_); - - break; - } - } - - if (channels_[channelId] == NULL) - { - deallocateTransport(channelId); - - return -1; - } - - increaseChannels(channelId); - - channels_[channelId] -> handleConfiguration(); - - return 1; -} diff --git a/nxcomp/Proxy.h b/nxcomp/Proxy.h deleted file mode 100644 index ea60c827a..000000000 --- a/nxcomp/Proxy.h +++ /dev/null @@ -1,1276 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Proxy_H -#define Proxy_H - -#include - -#ifdef _AIX -#include -#endif - -#include "Misc.h" -#include "Timestamp.h" - -#include "List.h" -#include "Channel.h" -#include "Transport.h" -#include "EncodeBuffer.h" -#include "ProxyReadBuffer.h" -#include "ChannelEndPoint.h" - -// -// Forward declaration as we -// need a pointer. -// - -class Agent; - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Log the important tracepoints related -// to writing packets to the peer proxy. -// - -#undef FLUSH - -// -// Codes used for control messages in -// proxy-to-proxy protocol. -// -// The following codes are currently -// unused. -// -// code_alert_reply, -// code_reset_request, -// code_reset_reply, -// code_load_reply, -// code_save_reply, -// code_shutdown_reply, -// code_configuration_request, -// code_configuration_reply. -// -// These are for compatibility with -// old versions. -// -// code_sync_request, -// code_sync_reply, -// -// The code_new_aux_connection should not -// be used anymore. Auxiliary X connections -// are treated as normal X channels since -// version 1.5.0. -// - -typedef enum -{ - code_new_x_connection, - code_new_cups_connection, - code_new_aux_connection, - code_new_smb_connection, - code_new_media_connection, - code_switch_connection, - code_drop_connection, - code_finish_connection, - code_begin_congestion, - code_end_congestion, - code_alert_request, - code_alert_reply, - code_reset_request, - code_reset_reply, - code_load_request, - code_load_reply, - code_save_request, - code_save_reply, - code_shutdown_request, - code_shutdown_reply, - code_control_token_request, - code_control_token_reply, - code_configuration_request, - code_configuration_reply, - code_statistics_request, - code_statistics_reply, - code_new_http_connection, - code_sync_request, - code_sync_reply, - code_new_font_connection, - code_new_slave_connection, - code_finish_listeners, - code_split_token_request, - code_split_token_reply, - code_data_token_request, - code_data_token_reply, - code_last_tag - -} T_proxy_code; - -typedef enum -{ - operation_in_negotiation, - operation_in_messages, - operation_in_configuration, - operation_in_statistics, - operation_last_tag - -} T_proxy_operation; - -typedef enum -{ - frame_ping, - frame_data, - -} T_frame_type; - -typedef enum -{ - token_control, - token_split, - token_data - -} T_token_type; - -typedef enum -{ - load_if_any, - load_if_first - -} T_load_type; - -class Proxy -{ - public: - - // - // Maximum number of supported channels. - // - - static const int CONNECTIONS_LIMIT = 256; - - // - // Numboer of token types. - // - - static const int TOKEN_TYPES = 3; - - // - // Lenght of buffer we use to add our - // control messages plus the length of - // the data frame. - // - - static const int CONTROL_CODES_LENGTH = ENCODE_BUFFER_PREFIX_SIZE - 5; - - static const int CONTROL_CODES_THRESHOLD = CONTROL_CODES_LENGTH - 9; - - Proxy(int fd); - - virtual ~Proxy(); - - // - // Inform the proxy that the negotiation phase is - // completed and that it can start handling binary - // messages. - // - - int setOperational(); - - int getOperational() - { - return (operation_ != operation_in_negotiation); - } - - int setReadDescriptors(fd_set *fdSet, int &fdMax, T_timestamp &tsMax); - - int setWriteDescriptors(fd_set *fdSet, int &fdMax, T_timestamp &tsMax); - - // - // Perform the operation on the proxy - // link or its own channels. - // - - int handleRead(int &resultFds, fd_set &fdSet); - - int handleFlush(int &resultFds, fd_set &fdSet); - - int handleRead(); - - int handleRead(int fd, const char *data = NULL, int size = 0); - - int handleEvents(); - - int handleFlush(); - - int handleFlush(int fd); - - int handlePing(); - - int handleFinish(); - - int handleShutdown(); - - int handleStatistics(int type, ostream *statofs); - - int handleAlert(int alert); - - int handleRotate() - { - activeChannels_.rotate(); - - return 1; - } - - int handleChannelConfiguration(); - - int handleSocketConfiguration(); - - int handleLinkConfiguration(); - - int handleCacheConfiguration(); - - // - // These must be called just after initialization to - // tell to the proxy where the network connections - // have to be forwarded. - // - - virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, - sockaddr * xServerAddr, unsigned int xServerAddrLength) = 0; - - virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort, - ChannelEndPoint &smbServerPort, - ChannelEndPoint &mediaServerPort, - ChannelEndPoint &httpServerPort, - const char *fontServerPort) = 0; - - // - // Create new tunneled channels. - // - - virtual int handleNewConnection(T_channel_type type, int clientFd) = 0; - - virtual int handleNewConnectionFromProxy(T_channel_type type, int channelId) = 0; - - virtual int handleNewAgentConnection(Agent *agent) = 0; - - virtual int handleNewXConnection(int clientFd) = 0; - - virtual int handleNewXConnectionFromProxy(int channelId) = 0; - - int handleNewGenericConnection(int clientFd, T_channel_type type, const char *label); - - int handleNewGenericConnectionFromProxy(int channelId, T_channel_type type, - ChannelEndPoint &endpoint, const char *label); - - int handleNewGenericConnectionFromProxyUnix(int channelId, T_channel_type type, - const char *path, const char *label); - - int handleNewGenericConnectionFromProxyTCP(int channelId, T_channel_type type, - const char *hostname, long port, const char *label); - - int handleNewSlaveConnection(int clientFd); - - int handleNewSlaveConnectionFromProxy(int channelId); - - void checkSlaves(); - - // - // Force closure of channels. - // - - int handleCloseConnection(int clientFd); - - int handleCloseAllXConnections(); - - int handleCloseAllListeners(); - - // - // Called when the loop has replaced - // or closed a previous alert. - // - - void handleResetAlert(); - - // - // Handle the persistent cache. - // - - virtual int handleLoad(T_load_type type) = 0; - - virtual int handleSave() = 0; - - protected: - - // - // Timeout related data: - // - // flush - // split - // motion - // - // Timeouts in milliseconds after which the - // proxy will have to perform the operation. - // - // readTs, writeTs - // - // Timestamp of last packet received or sent - // to remote proxy. Used to detect lost con- - // nection. - // - // loopTs - // - // Timestamp of last loop completed by the - // proxy - // - // pingTs - // - // Timestamp of last ping request sent to the - // remote peer. - // - // alertTs - // - // Timestamp of last 'no data received' alert - // dialog shown to the user. - // - // loadTs - // - // Were message stores populated from data on - // disk. - // - // splitTs - // motionTs - // - // Timestamps of the last operation of this - // kind handled by the proxy. - // - - typedef struct - { - int split; - int motion; - - T_timestamp readTs; - T_timestamp writeTs; - - T_timestamp loopTs; - T_timestamp pingTs; - T_timestamp alertTs; - T_timestamp loadTs; - - T_timestamp splitTs; - T_timestamp motionTs; - - } T_proxy_timeouts; - - // - // Bytes accumulated so far while waiting - // to send the next token, number of tokens - // remaining for each token type and other - // token related information. - // - - typedef struct - { - int size; - int limit; - - int bytes; - int remaining; - - T_proxy_code request; - T_proxy_code reply; - - T_token_type type; - - } T_proxy_token; - - int handlePostConnectionFromProxy(int channelId, int serverFd, - T_channel_type type, const char *label); - - int handleDrain(); - - int handleFrame(T_frame_type type); - - int handleFinish(int channelId); - - int handleDrop(int channelId); - - int handleFinishFromProxy(int channelId); - - int handleDropFromProxy(int channelId); - - int handleStatisticsFromProxy(int type); - - int handleStatisticsFromProxy(const unsigned char *message, unsigned int length); - - int handleNegotiation(const unsigned char *message, unsigned int length); - - int handleNegotiationFromProxy(const unsigned char *message, unsigned int length); - - int handleToken(T_frame_type type); - - int handleTokenFromProxy(T_proxy_token &token, int count); - - int handleTokenReplyFromProxy(T_proxy_token &token, int count); - - int handleSyncFromProxy(int channelId); - - int handleSwitch(int channelId); - - int handleControl(T_proxy_code code, int data = -1); - - int handleControlFromProxy(const unsigned char *message); - - // - // Interleave reads of the X server - // events while writing data to the - // remote proxy. - // - - virtual int handleAsyncEvents() = 0; - - // - // Timer related functions. - // - - protected: - - void setTimer(int value) - { - SetTimer(value); - } - - void resetTimer() - { - ResetTimer(); - - timer_ = 0; - } - - public: - - void handleTimer() - { - timer_ = 1; - } - - int getTimer() - { - return timer_; - } - - // - // Can the channel consume data and the - // proxy produce more output? - // - - int canRead(int fd) const - { - return (isTimeToRead() == 1 && - isTimeToRead(getChannel(fd)) == 1); - } - - // - // Can the proxy read more data from its - // peer? - // - - int canRead() const - { - return (transport_ -> readable() != 0); - } - - int canFlush() const - { - return (encodeBuffer_.getLength() + - controlLength_ + transport_ -> length() + - transport_ -> flushable() > 0); - } - - int needFlush(int channelId) const - { - return (outputChannel_ == channelId && - encodeBuffer_.getLength() > 0); - } - - int needFlush() const - { - return (encodeBuffer_.getLength() > 0); - } - - int shouldFlush() const - { - if ((int) ((encodeBuffer_.getLength() + - controlLength_) / statistics -> - getStreamRatio()) >= control -> TokenSize) - { - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "Proxy: FLUSH! Requesting a flush with " - << (encodeBuffer_.getLength() + controlLength_) - << " bytes and stream ratio " << (double) statistics -> - getStreamRatio() << ".\n" << logofs_flush; - #endif - - return 1; - } - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "Proxy: Not requesting a flush with " - << (encodeBuffer_.getLength() + controlLength_) - << " bytes and stream ratio " << (double) statistics -> - getStreamRatio() << ".\n" << logofs_flush; - #endif - - return 0; - } - - int needDrain() const - { - return (congestion_ == 1 || transport_ -> length() > - control -> TransportProxyBufferThreshold); - } - - int getFd() const - { - return fd_; - } - - int getFlushable(int fd) const - { - if (fd == fd_) - { - return (encodeBuffer_.getLength() + controlLength_ + - transport_ -> flushable()); - } - - return 0; - } - - int getSplitSize() - { - return (clientStore_ != NULL ? clientStore_ -> - getSplitTotalSize() : 0); - } - - int getSplitStorageSize() - { - return (clientStore_ != NULL ? clientStore_ -> - getSplitTotalStorageSize() : 0); - } - - // - // Returns the number of active channels - // that currently managed by this proxy. - // - - int getChannels(T_channel_type type = channel_none); - - // - // If descriptor corresponds to a valid - // channel, returns the type of traffic - // carried by it. - // - - T_channel_type getType(int fd); - - // - // Given a channel type, returns the - // literal name. - // - - const char *getTypeName(T_channel_type type); - - // - // Get a convenient name for 'localhost'. - // - - const char *getComputerName(); - - // - // Set if we have initiated the shutdown - // procedure and if the shutdown request - // has been received from the remote. - // - - int getFinish() const - { - return finish_; - } - - int getShutdown() const - { - return shutdown_; - } - - // - // Interfaces to the transport buffers. - // - - int getLength(int fd) const - { - if (fd == fd_) - { - return transport_ -> length(); - } - - int channelId = getChannel(fd); - - if (channelId < 0 || channels_[channelId] == NULL) - { - return 0; - } - - return transports_[channelId] -> length(); - } - - int getPending(int fd) const - { - if (fd == fd_) - { - return transport_ -> pending(); - } - - int channelId = getChannel(fd); - - if (channelId < 0 || channels_[channelId] == NULL) - { - return 0; - } - - return transports_[channelId] -> pending(); - } - - // - // Check if the proxy or the given channel - // has data in the buffer because of a - // blocking write. - // - - int getBlocked(int fd) const - { - if (fd == fd_) - { - return transport_ -> blocked(); - } - - int channelId = getChannel(fd); - - if (channelId < 0 || channels_[channelId] == NULL) - { - return 0; - } - - return transports_[channelId] -> blocked(); - } - - // - // Check if the proxy or the given channel has - // data to read. - // - - int getReadable(int fd) const - { - if (fd == fd_) - { - return transport_ -> readable(); - } - - int channelId = getChannel(fd); - - if (channelId < 0 || channels_[channelId] == NULL) - { - return 0; - } - - return transports_[channelId] -> readable(); - } - - // - // Return a vale between 0 and 9 in the case - // of the proxy descriptor. - // - - int getCongestion(int fd) const - { - if (fd == fd_) - { - return (agent_ != nothing && congestions_[agent_] == 1 ? 9 : - (int) statistics -> getCongestionInFrame()); - } - - int channelId = getChannel(fd); - - if (channelId < 0 || channels_[channelId] == NULL) - { - return 0; - } - - return channels_[channelId] -> getCongestion(); - } - - // - // Let the statistics class get info - // from the message stores. - // - - const ClientStore * const getClientStore() const - { - return clientStore_; - } - - const ServerStore * const getServerStore() const - { - return serverStore_; - } - - // - // These can be called asynchronously by - // channels during their read or write - // loop. - // - - int handleAsyncRead(int fd) - { - return handleRead(fd); - } - - int handleAsyncCongestion(int fd) - { - int channelId = getChannel(fd); - - return handleControl(code_begin_congestion, channelId); - } - - int handleAsyncDecongestion(int fd) - { - int channelId = getChannel(fd); - - return handleControl(code_end_congestion, channelId); - } - - int handleAsyncSplit(int fd, Split *split) - { - return channels_[getChannel(fd)] -> - handleSplitEvent(encodeBuffer_, split); - } - - int handleAsyncPriority() - { - if (control -> FlushPriority == 1) - { - return handleFlush(); - } - - return 0; - } - - int canAsyncFlush() const - { - return shouldFlush(); - } - - int handleAsyncFlush() - { - return handleFlush(); - } - - int handleAsyncSwitch(int fd) - { - return handleSwitch(getChannel(fd)); - } - - int handleAsyncKeeperCallback() - { - KeeperCallback(); - - return 1; - } - - // - // Internal interfaces used to verify the - // availability of channels and the proxy - // link. - // - - protected: - - int isTimeToRead() const - { - if (congestion_ == 0 && transport_ -> - blocked() == 0) - { - return 1; - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Can't read from channels " - << "with congestion " << congestion_ - << " and blocked " << transport_ -> - blocked() << ".\n" << logofs_flush; - #endif - - return 0; - } - } - - int isTimeToRead(int channelId) const - { - if (channelId >= 0 && channelId < CONNECTIONS_LIMIT && - channels_[channelId] != NULL && - congestions_[channelId] == 0) - { - if (channels_[channelId] -> getType() == channel_x11 || - tokens_[token_data].remaining > 0 || - channels_[channelId] -> - getFinish() == 1) - { - return 1; - } - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: Can't read from generic " - << "descriptor FD#" << getFd(channelId) - << " channel ID#" << channelId << " with " - << tokens_[token_data].remaining - << " data tokens remaining.\n" - << logofs_flush; - #endif - - return 0; - } - - #if defined(TEST) || defined(INFO) - - if (channelId < 0 || channelId >= CONNECTIONS_LIMIT || - channels_[channelId] == NULL) - { - *logofs << "Proxy: WARNING! No valid channel for ID#" - << channelId << ".\n" << logofs_flush; - } - else if (channels_[channelId] -> getFinish()) - { - *logofs << "Proxy: Can't read from finishing " - << "descriptor FD#" << getFd(channelId) - << " channel ID#" << channelId << ".\n" - << logofs_flush; - } - else if (congestions_[channelId] == 1) - { - *logofs << "Proxy: Can't read from congested " - << "descriptor FD#" << getFd(channelId) - << " channel ID#" << channelId << ".\n" - << logofs_flush; - } - - #endif - - return 0; - } - - // - // Handle the flush and split timeouts. - // All these functions should round up - // to the value of the latency timeout - // to save a further loop. - // - - protected: - - int isTimeToSplit() const - { - if (isTimestamp(timeouts_.splitTs) && - getTimeToNextSplit() <= control -> - LatencyTimeout) - { - if (tokens_[token_split].remaining > 0) - { - return 1; - } - - #if defined(TEST) || defined(INFO) - *logofs << "Proxy: WARNING! Can't encode splits " - << "with " << tokens_[token_split].remaining - << " split tokens remaining.\n" - << logofs_flush; - #endif - } - - return 0; - } - - int isTimeToMotion() const - { - return (isTimestamp(timeouts_.motionTs) && - getTimeToNextMotion() <= control -> - LatencyTimeout); - } - - int getTimeToNextSplit() const - { - #if defined(TEST) || defined(INFO) || defined(FLUSH) - - if (isTimestamp(timeouts_.splitTs) == 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! No split timeout was set " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": No split timeout was set " - << "for proxy FD#" << fd_ << ".\n"; - - HandleCleanup(); - } - - #endif - - int diffTs = timeouts_.split - - diffTimestamp(timeouts_.splitTs, - getTimestamp()); - - return (diffTs > 0 ? diffTs : 0); - } - - int getTimeToNextMotion() const - { - #if defined(TEST) || defined(INFO) || defined(FLUSH) - - if (isTimestamp(timeouts_.motionTs) == 0) - { - #ifdef PANIC - *logofs << "Proxy: PANIC! No motion timeout was set " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": No motion timeout was set " - << "for proxy FD#" << fd_ << ".\n"; - - HandleCleanup(); - } - - #endif - - int diffTs = timeouts_.motion - - diffTimestamp(timeouts_.motionTs, - getTimestamp()); - - return (diffTs > 0 ? diffTs : 0); - } - - protected: - - // - // Implement persistence of cache on disk. - // - - virtual int handleLoadFromProxy() = 0; - virtual int handleSaveFromProxy() = 0; - - int handleLoadStores(); - int handleSaveStores(); - - char *handleSaveAllStores(const char *savePath, bool & isTooSmall) const; - - virtual int handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient) const = 0; - - int handleSaveVersion(unsigned char *buffer, int &major, int &minor, int &patch) const; - - void handleFailOnSave(const char *fullName, const char *failContext) const; - - const char *handleLoadAllStores(const char *loadPath, const char *loadName) const; - - virtual int handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const = 0; - - int handleLoadVersion(const unsigned char *buffer, int &major, int &minor, int &patch) const; - - void handleFailOnLoad(const char *fullName, const char *failContext) const; - - // - // Prepare for a new persistent cache. - // - - int handleResetPersistentCache(); - - // - // Reset the stores in the case of a - // failure loading the cache. - // - - int handleResetStores(); - - // - // Reset the transport buffer and the - // other counters. - // - - void handleResetFlush(); - - // - // Utility functions used to map file - // descriptors to channel ids. - // - - protected: - - int allocateChannelMap(int fd); - int checkChannelMap(int channelId); - int assignChannelMap(int channelId, int fd); - - void cleanupChannelMap(int channelId); - - virtual int checkLocalChannelMap(int channelId) = 0; - - int addControlCodes(T_proxy_code code, int data); - int addTokenCodes(T_proxy_token &token); - - int getFd(int channelId) const - { - if (channelId >= 0 && channelId < CONNECTIONS_LIMIT) - { - return fdMap_[channelId]; - } - - return -1; - } - - int getChannel(int fd) const - { - if (fd >= 0 && fd < CONNECTIONS_LIMIT) - { - return channelMap_[fd]; - } - - return -1; - } - - protected: - - void setSplitTimeout(int channelId); - void setMotionTimeout(int channelId); - - void increaseChannels(int channelId); - void decreaseChannels(int channelId); - - int allocateTransport(int channelFd, int channelId); - int deallocateTransport(int channelId); - - // - // The proxy has its own transport. - // - - ProxyTransport *transport_; - - // - // The static compressor is shared among - // channels and all the message stores. - // - - StaticCompressor *compressor_; - - // - // Map NX specific opcodes. - // - - OpcodeStore *opcodeStore_; - - // - // Stores are shared between channels. - // - - ClientStore *clientStore_; - ServerStore *serverStore_; - - // - // Client and server caches are shared - // between channels. - // - - ClientCache *clientCache_; - ServerCache *serverCache_; - - // - // The proxy's file descriptor. - // - - int fd_; - - // - // Channels currently selected for I/O - // operations. - // - - int inputChannel_; - int outputChannel_; - - // - // List of active channels. - // - - List activeChannels_; - - // - // Used to read data sent from peer proxy. - // - - ProxyReadBuffer readBuffer_; - - // - // Used to send data to peer proxy. - // - - EncodeBuffer encodeBuffer_; - - // - // Control messages' array. - // - - int controlLength_; - - unsigned char controlCodes_[CONTROL_CODES_LENGTH]; - - // - // Table of channel classes taking - // care of open X connections. - // - - Channel *channels_[CONNECTIONS_LIMIT]; - - // - // Table of open sockets. - // - - Transport *transports_[CONNECTIONS_LIMIT]; - - // - // Timeout related data. - // - - T_proxy_timeouts timeouts_; - - // - // Proxy can be decoding messages, - // handling a link reconfiguration, - // or decoding statistics. - // - - int operation_; - - // - // True if we are currently draining - // the proxy link. - // - - int draining_; - - // - // Force flush because of prioritized - // control messages to send. - // - - int priority_; - - // - // Set if we have initiated the close - // down procedure. - // - - int finish_; - - // - // Remote peer requested the shutdown. - // - - int shutdown_; - - // - // We are in the middle of a network - // congestion in the path to remote - // proxy. - // - - int congestion_; - - // - // Channels at the remote end that - // are not consuming their data. - // - - int congestions_[CONNECTIONS_LIMIT]; - - // - // Is the timer expired? - // - - int timer_; - - // - // Did the proxy request an alert? - // - - int alert_; - - // - // The channel id of the agent. - // - - int agent_; - - // - // Token related data. - // - - T_proxy_token tokens_[TOKEN_TYPES]; - - // - // Pointer to stream descriptor where - // proxy is producing statistics. - // - - ostream *currentStatistics_; - - private: - - // - // Map channel ids to file descriptors. - // - - int channelMap_[CONNECTIONS_LIMIT]; - int fdMap_[CONNECTIONS_LIMIT]; - int slavePidMap_[CONNECTIONS_LIMIT]; -}; - -#endif /* Proxy_H */ diff --git a/nxcomp/ProxyReadBuffer.cpp b/nxcomp/ProxyReadBuffer.cpp deleted file mode 100644 index 0427bb76c..000000000 --- a/nxcomp/ProxyReadBuffer.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ProxyReadBuffer.h" - -#include "Transport.h" - -// -// Set the verbosity level. You also -// need to define DUMP in Misc.cpp -// if DUMP is defined here. -// - -#define WARNING -#define PANIC -#undef TEST -#undef DEBUG -#undef DUMP - -unsigned int ProxyReadBuffer::suggestedLength(unsigned int pendingLength) -{ - // - // Always read all the data that - // is available. - // - - int readable = transport_ -> readable(); - - unsigned int readLength = (readable == -1 ? 0 : (unsigned int) readable); - - if (readLength < pendingLength) - { - readLength = pendingLength; - } - - // - // Even if the readable data is not - // enough to make a complete message, - // resize the buffer to accommodate - // it all. - // - - if (pendingLength < remaining_) - { - readLength = remaining_; - } - - return readLength; -} - -int ProxyReadBuffer::locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength) -{ - unsigned int lengthLength = 0; - const unsigned char *nextSrc = start; - unsigned char next; - - dataLength = 0; - - #ifdef TEST - *logofs << "ProxyReadBuffer: Locating message for FD#" - << transport_ -> fd() << " with " << end - start - << " bytes.\n" << logofs_flush; - #endif - - // - // Use something like the following if - // you are looking for errors. - // - - #ifdef DUMP - if (control -> ProxyMode == proxy_server && start < end && - transport_ -> fd() == 6 || transport_ -> fd() == 11) - { - *logofs << "ProxyReadBuffer: Partial checksums are:\n"; - - DumpBlockChecksums(start, end - start, 256); - - *logofs << logofs_flush; - } - #endif - - do - { - if (nextSrc >= end) - { - remaining_ = 1; - - #ifdef TEST - *logofs << "ProxyReadBuffer: No message was located " - << "with remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - next = *nextSrc++; - - dataLength <<= 7; - dataLength |= (unsigned int) (next & 0x7f); - - lengthLength++; - } - while (next & 0x80); - - unsigned int totalLength; - - if (dataLength == 0) - { - trailerLength = 0; - controlLength = 3; - totalLength = controlLength; - } - else - { - trailerLength = lengthLength; - controlLength = 0; - totalLength = dataLength + trailerLength; - } - - if (start + totalLength > end) - { - // - // When having to decompress a ZLIB stream, - // a single byte can be enough to complete - // the frame. - // - - if (control -> RemoteStreamCompression == 0) - { - remaining_ = totalLength - (end - start); - } - else - { - remaining_ = 1; - } - - #ifdef TEST - *logofs << "ProxyReadBuffer: No message was located " - << "with remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - else - { - #ifdef DUMP - *logofs << "ProxyReadBuffer: Received " << totalLength << " bytes of data " - << "with checksum "; - - DumpChecksum(start, totalLength); - - *logofs << " on proxy FD#" << transport_ -> fd() << ".\n" << logofs_flush; - #endif - - #if defined(TEST) || defined(INFO) - *logofs << "ProxyReadBuffer: Produced plain input for " << dataLength - << "+" << trailerLength << "+" << controlLength << " bytes out of " - << totalLength << " bytes.\n" << logofs_flush; - #endif - - #ifdef DUMP - *logofs << "ProxyReadBuffer: Partial checksums are:\n"; - - DumpBlockChecksums(start, totalLength, 256); - - *logofs << logofs_flush; - #endif - - remaining_ = 0; - - #ifdef TEST - *logofs << "ProxyReadBuffer: Located message with " - << "remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 1; - } -} diff --git a/nxcomp/ProxyReadBuffer.h b/nxcomp/ProxyReadBuffer.h deleted file mode 100644 index 68e9e95fa..000000000 --- a/nxcomp/ProxyReadBuffer.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ProxyReadBuffer_H -#define ProxyReadBuffer_H - -#include "ReadBuffer.h" -#include "Control.h" - -class ProxyReadBuffer : public ReadBuffer -{ - public: - - ProxyReadBuffer(Transport *transport) - - : ReadBuffer(transport) - { - } - - virtual ~ProxyReadBuffer() - { - } - - protected: - - virtual unsigned int suggestedLength(unsigned int pendingLength); - - virtual int locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength); -}; - -#endif /* ProxyReadBuffer_H */ diff --git a/nxcomp/PutImage.cpp b/nxcomp/PutImage.cpp deleted file mode 100644 index 7b9a3ae5d..000000000 --- a/nxcomp/PutImage.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PutImage.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -PutImageStore::PutImageStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = PUTIMAGE_ENABLE_CACHE; - enableData = PUTIMAGE_ENABLE_DATA; - - // Since ProtoStep7 (#issue 108) - enableCompress = PUTIMAGE_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = PUTIMAGE_DATA_LIMIT; - dataOffset = PUTIMAGE_DATA_OFFSET; - - cacheSlots = PUTIMAGE_CACHE_SLOTS; - cacheThreshold = PUTIMAGE_CACHE_THRESHOLD; - cacheLowerThreshold = PUTIMAGE_CACHE_LOWER_THRESHOLD; - - // Since ProtoStep8 (#issue 108) - enableSplit = PUTIMAGE_ENABLE_SPLIT_IF_PROTO_STEP_8; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -PutImageStore::~PutImageStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int PutImageStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; - #endif - - encodeBuffer.encodeValue(GetUINT(buffer + 2, bigEndian), 16, 8); - - encodeBuffer.encodeValue((unsigned int) buffer[1], 2); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> drawableCache); - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> gcCache); - - unsigned int width = GetUINT(buffer + 12, bigEndian); - encodeBuffer.encodeCachedValue(width, 16, - clientCache -> putImageWidthCache, 8); - - unsigned int height = GetUINT(buffer + 14, bigEndian); - encodeBuffer.encodeCachedValue(height, 16, - clientCache -> putImageHeightCache, 8); - - unsigned int x = GetUINT(buffer + 16, bigEndian); - int xDiff = x - clientCache -> putImageLastX; - clientCache -> putImageLastX = x; - encodeBuffer.encodeCachedValue(xDiff, 16, - clientCache -> putImageXCache, 8); - - unsigned int y = GetUINT(buffer + 18, bigEndian); - int yDiff = y - clientCache -> putImageLastY; - clientCache -> putImageLastY = y; - encodeBuffer.encodeCachedValue(yDiff, 16, - clientCache -> putImageYCache, 8); - - encodeBuffer.encodeCachedValue(buffer[20], 8, - clientCache -> putImageLeftPadCache); - - encodeBuffer.encodeCachedValue(buffer[21], 8, - clientCache -> depthCache); - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int PutImageStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; - #endif - - unsigned int value; - unsigned char cValue; - - decodeBuffer.decodeValue(value, 16, 8); - - size = (value << 2); - - buffer = writeBuffer -> addMessage(size); - - decodeBuffer.decodeValue(value, 2); - buffer[1] = (unsigned char) value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - PutULONG(value, buffer + 4, bigEndian); - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - PutULONG(value, buffer + 8, bigEndian); - - unsigned int width; - decodeBuffer.decodeCachedValue(width, 16, - clientCache -> putImageWidthCache, 8); - PutUINT(width, buffer + 12, bigEndian); - - unsigned int height; - decodeBuffer.decodeCachedValue(height, 16, - clientCache -> putImageHeightCache, 8); - PutUINT(height, buffer + 14, bigEndian); - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageXCache, 8); - clientCache -> putImageLastX += value; - clientCache -> putImageLastX &= 0xffff; - PutUINT(clientCache -> putImageLastX, buffer + 16, bigEndian); - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageYCache, 8); - clientCache -> putImageLastY += value; - clientCache -> putImageLastY &= 0xffff; - PutUINT(clientCache -> putImageLastY, buffer + 18, bigEndian); - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> putImageLeftPadCache); - buffer[20] = cValue; - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - buffer[21] = cValue; - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int PutImageStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PutImageMessage *putImage = (PutImageMessage *) message; - - // - // Here is the fingerprint. - // - - putImage -> format = *(buffer + 1); - putImage -> depth = *(buffer + 21); - putImage -> left_pad = *(buffer + 20); - - putImage -> width = GetUINT(buffer + 12, bigEndian); - putImage -> height = GetUINT(buffer + 14, bigEndian); - putImage -> pos_x = GetUINT(buffer + 16, bigEndian); - putImage -> pos_y = GetUINT(buffer + 18, bigEndian); - - putImage -> drawable = GetULONG(buffer + 4, bigEndian); - putImage -> gcontext = GetULONG(buffer + 8, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PutImageStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PutImageMessage *putImage = (PutImageMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = putImage -> format; - - PutULONG(putImage -> drawable, buffer + 4, bigEndian); - PutULONG(putImage -> gcontext, buffer + 8, bigEndian); - - PutUINT(putImage -> width, buffer + 12, bigEndian); - PutUINT(putImage -> height, buffer + 14, bigEndian); - PutUINT(putImage -> pos_x, buffer + 16, bigEndian); - PutUINT(putImage -> pos_y, buffer + 18, bigEndian); - - *(buffer + 20) = (unsigned char) putImage -> left_pad; - *(buffer + 21) = (unsigned char) putImage -> depth; - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PutImageStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PutImageMessage *putImage = (PutImageMessage *) message; - - *logofs << name() << ": Identity format " << (unsigned) putImage -> format - << ", depth " << (unsigned) putImage -> depth << ", left_pad " - << (unsigned) putImage -> left_pad << ", width " << putImage -> width - << ", height " << putImage -> height << ", pos_x " << putImage -> pos_x - << ", pos_y " << putImage -> pos_y << ", drawable " << putImage -> drawable - << ", gcontext " << putImage -> gcontext << ", size " << putImage -> size_ - << ".\n" << logofs_flush; - - #endif -} - -void PutImageStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Fields format, width, height, left_pad, depth. - // - - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 12, 4); - md5_append(md5_state_, buffer + 20, 2); -} - -void PutImageStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - // - // Encode the variant part. - // - - PutImageMessage *putImage = (PutImageMessage *) message; - PutImageMessage *cachedPutImage = (PutImageMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putImage -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(putImage -> drawable, clientCache -> drawableCache); - - cachedPutImage -> drawable = putImage -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putImage -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(putImage -> gcontext, clientCache -> gcCache); - - cachedPutImage -> gcontext = putImage -> gcontext; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putImage -> pos_x - << " as " << "pos_x" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_x = putImage -> pos_x - cachedPutImage -> pos_x; - - encodeBuffer.encodeCachedValue(diff_x, 16, - clientCache -> putImageXCache, 8); - - cachedPutImage -> pos_x = putImage -> pos_x; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putImage -> pos_y - << " as " << "pos_y" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_y = putImage -> pos_y - cachedPutImage -> pos_y; - - encodeBuffer.encodeCachedValue(diff_y, 16, - clientCache -> putImageYCache, 8); - - cachedPutImage -> pos_y = putImage -> pos_y; -} - -void PutImageStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - // - // Decode the variant part. - // - - PutImageMessage *putImage = (PutImageMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - putImage -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putImage -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - putImage -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putImage -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageXCache, 8); - - putImage -> pos_x += value; - putImage -> pos_x &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putImage -> pos_x - << " as pos_x field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageYCache, 8); - - putImage -> pos_y += value; - putImage -> pos_y &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putImage -> pos_y - << " as pos_y field.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/PutImage.h b/nxcomp/PutImage.h deleted file mode 100644 index 93dde9dfb..000000000 --- a/nxcomp/PutImage.h +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PutImage_H -#define PutImage_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define PUTIMAGE_ENABLE_CACHE 1 -#define PUTIMAGE_ENABLE_DATA 1 - -#define PUTIMAGE_DATA_LIMIT 262144 - 24 -#define PUTIMAGE_DATA_OFFSET 24 - -#define PUTIMAGE_CACHE_SLOTS 6000 -#define PUTIMAGE_CACHE_THRESHOLD 70 -#define PUTIMAGE_CACHE_LOWER_THRESHOLD 50 - -#define PUTIMAGE_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -#define PUTIMAGE_CACHE_THRESHOLD_IF_PACKED 10 -#define PUTIMAGE_CACHE_LOWER_THRESHOLD_IF_PACKED 5 - -#define PUTIMAGE_CACHE_THRESHOLD_IF_SHADOW 97 -#define PUTIMAGE_CACHE_LOWER_THRESHOLD_IF_SHADOW 90 - -#define PUTIMAGE_ENABLE_SPLIT_IF_PROTO_STEP_8 0 - -// -// The message class. -// - -class PutImageMessage : public Message -{ - friend class PutImageStore; - - public: - - PutImageMessage() - { - } - - ~PutImageMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char format; - unsigned char depth; - unsigned char left_pad; - unsigned short width; - unsigned short height; - unsigned int drawable; - unsigned int gcontext; - unsigned short pos_x; - unsigned short pos_y; -}; - -class PutImageStore : public MessageStore -{ - public: - - PutImageStore(StaticCompressor *compressor); - - virtual ~PutImageStore(); - - virtual const char *name() const - { - return "PutImage"; - } - - virtual unsigned char opcode() const - { - return X_PutImage; - } - - virtual unsigned int storage() const - { - return sizeof(PutImageMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new PutImageMessage(); - } - - virtual Message *create(const Message &message) const - { - return new PutImageMessage((const PutImageMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (PutImageMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PutImage_H */ diff --git a/nxcomp/PutPackedImage.cpp b/nxcomp/PutPackedImage.cpp deleted file mode 100644 index 66506ebbe..000000000 --- a/nxcomp/PutPackedImage.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "PutPackedImage.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -PutPackedImageStore::PutPackedImageStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = PUTPACKEDIMAGE_ENABLE_CACHE; - enableData = PUTPACKEDIMAGE_ENABLE_DATA; - enableCompress = PUTPACKEDIMAGE_ENABLE_COMPRESS; - - dataLimit = PUTPACKEDIMAGE_DATA_LIMIT; - dataOffset = PUTPACKEDIMAGE_DATA_OFFSET; - - cacheSlots = PUTPACKEDIMAGE_CACHE_SLOTS; - cacheThreshold = PUTPACKEDIMAGE_CACHE_THRESHOLD; - cacheLowerThreshold = PUTPACKEDIMAGE_CACHE_LOWER_THRESHOLD; - - // Since ProtoStep8 (#issue 108) - enableSplit = PUTPACKEDIMAGE_ENABLE_SPLIT_IF_PROTO_STEP_8; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -PutPackedImageStore::~PutPackedImageStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int PutPackedImageStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; - #endif - - // Client. - encodeBuffer.encodeCachedValue(*(buffer + 1), 8, - clientCache -> resourceCache); - - // Size. - encodeBuffer.encodeValue(GetUINT(buffer + 2, bigEndian), 16, 10); - - // Drawable. - encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> drawableCache); - // GC. - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> gcCache); - // Method. - encodeBuffer.encodeCachedValue(*(buffer + 12), 8, - clientCache -> methodCache); - // Format. - encodeBuffer.encodeValue(*(buffer + 13), 2); - - // SrcDepth. - encodeBuffer.encodeCachedValue(*(buffer + 14), 8, - clientCache -> depthCache); - // DstDepth. - encodeBuffer.encodeCachedValue(*(buffer + 15), 8, - clientCache -> depthCache); - // SrcLength. - encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 24, - clientCache -> putPackedImageSrcLengthCache); - // DstLength. - encodeBuffer.encodeCachedValue(GetULONG(buffer + 20, bigEndian), 24, - clientCache -> putPackedImageDstLengthCache); - // SrcX. - unsigned int x = GetUINT(buffer + 24, bigEndian); - int xDiff = x - clientCache -> putImageLastX; - clientCache -> putImageLastX = x; - encodeBuffer.encodeCachedValue(xDiff, 16, - clientCache -> putImageXCache, 8); - // SrcY. - unsigned int y = GetUINT(buffer + 26, bigEndian); - int yDiff = y - clientCache -> putImageLastY; - clientCache -> putImageLastY = y; - encodeBuffer.encodeCachedValue(yDiff, 16, - clientCache -> putImageYCache, 8); - // SrcWidth. - encodeBuffer.encodeCachedValue(GetUINT(buffer + 28, bigEndian), 16, - clientCache -> putImageWidthCache, 8); - // SrcHeight. - encodeBuffer.encodeCachedValue(GetUINT(buffer + 30, bigEndian), 16, - clientCache -> putImageHeightCache, 8); - // DstX. - x = GetUINT(buffer + 32, bigEndian); - xDiff = x - clientCache -> putImageLastX; - clientCache -> putImageLastX = x; - encodeBuffer.encodeCachedValue(xDiff, 16, - clientCache -> putImageXCache, 8); - // DstY. - y = GetUINT(buffer + 34, bigEndian); - yDiff = y - clientCache -> putImageLastY; - clientCache -> putImageLastY = y; - encodeBuffer.encodeCachedValue(yDiff, 16, - clientCache -> putImageYCache, 8); - // DstWidth. - encodeBuffer.encodeCachedValue(GetUINT(buffer + 36, bigEndian), 16, - clientCache -> putImageWidthCache, 8); - // DstHeight. - encodeBuffer.encodeCachedValue(GetUINT(buffer + 38, bigEndian), 16, - clientCache -> putImageHeightCache, 8); - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int PutPackedImageStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; - #endif - - unsigned int value; - unsigned char cValue; - - // Client. - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> resourceCache); - - // Size. - decodeBuffer.decodeValue(size, 16, 10); - - size <<= 2; - - buffer = writeBuffer -> addMessage(size); - - *(buffer + 1) = cValue; - - // Drawable. - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - PutULONG(value, buffer + 4, bigEndian); - - // GC. - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - PutULONG(value, buffer + 8, bigEndian); - - // Method. - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> methodCache); - *(buffer + 12) = cValue; - - // Format. - decodeBuffer.decodeValue(value, 2); - *(buffer + 13) = value; - - // SrcDepth. - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - *(buffer + 14) = cValue; - - // DstDepth. - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - *(buffer + 15) = cValue; - - // SrcLength. - decodeBuffer.decodeCachedValue(value, 24, - clientCache -> putPackedImageSrcLengthCache); - PutULONG(value, buffer + 16, bigEndian); - - // DstLength. - decodeBuffer.decodeCachedValue(value, 24, - clientCache -> putPackedImageDstLengthCache); - PutULONG(value, buffer + 20, bigEndian); - - // SrcX. - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageXCache, 8); - clientCache -> putImageLastX += value; - clientCache -> putImageLastX &= 0xffff; - PutUINT(clientCache -> putImageLastX, buffer + 24, bigEndian); - - // SrcY. - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageYCache, 8); - clientCache -> putImageLastY += value; - clientCache -> putImageLastY &= 0xffff; - PutUINT(clientCache -> putImageLastY, buffer + 26, bigEndian); - - // SrcWidth. - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageWidthCache, 8); - PutUINT(value, buffer + 28, bigEndian); - - // SrcHeight. - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageHeightCache, 8); - PutUINT(value, buffer + 30, bigEndian); - - // DstX. - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageXCache, 8); - clientCache -> putImageLastX += value; - clientCache -> putImageLastX &= 0xffff; - PutUINT(clientCache -> putImageLastX, buffer + 32, bigEndian); - - // DstY. - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageYCache, 8); - clientCache -> putImageLastY += value; - clientCache -> putImageLastY &= 0xffff; - PutUINT(clientCache -> putImageLastY, buffer + 34, bigEndian); - - // DstWidth. - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageWidthCache, 8); - PutUINT(value, buffer + 36, bigEndian); - - // DstHeight. - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageHeightCache, 8); - PutUINT(value, buffer + 38, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int PutPackedImageStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; - - // - // Here is the fingerprint. - // - - putPackedImage -> client = *(buffer + 1); - - putPackedImage -> drawable = GetULONG(buffer + 4, bigEndian); - putPackedImage -> gcontext = GetULONG(buffer + 8, bigEndian); - - putPackedImage -> method = *(buffer + 12); - - putPackedImage -> format = *(buffer + 13); - putPackedImage -> src_depth = *(buffer + 14); - putPackedImage -> dst_depth = *(buffer + 15); - - putPackedImage -> src_length = GetULONG(buffer + 16, bigEndian); - putPackedImage -> dst_length = GetULONG(buffer + 20, bigEndian); - - putPackedImage -> src_x = GetUINT(buffer + 24, bigEndian); - putPackedImage -> src_y = GetUINT(buffer + 26, bigEndian); - putPackedImage -> src_width = GetUINT(buffer + 28, bigEndian); - putPackedImage -> src_height = GetUINT(buffer + 30, bigEndian); - - putPackedImage -> dst_x = GetUINT(buffer + 32, bigEndian); - putPackedImage -> dst_y = GetUINT(buffer + 34, bigEndian); - putPackedImage -> dst_width = GetUINT(buffer + 36, bigEndian); - putPackedImage -> dst_height = GetUINT(buffer + 38, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int PutPackedImageStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = putPackedImage -> client; - - PutULONG(putPackedImage -> drawable, buffer + 4, bigEndian); - PutULONG(putPackedImage -> gcontext, buffer + 8, bigEndian); - - *(buffer + 12) = putPackedImage -> method; - - *(buffer + 13) = putPackedImage -> format; - *(buffer + 14) = putPackedImage -> src_depth; - *(buffer + 15) = putPackedImage -> dst_depth; - - PutULONG(putPackedImage -> src_length, buffer + 16, bigEndian); - PutULONG(putPackedImage -> dst_length, buffer + 20, bigEndian); - - PutUINT(putPackedImage -> src_x, buffer + 24, bigEndian); - PutUINT(putPackedImage -> src_y, buffer + 26, bigEndian); - PutUINT(putPackedImage -> src_width, buffer + 28, bigEndian); - PutUINT(putPackedImage -> src_height, buffer + 30, bigEndian); - - PutUINT(putPackedImage -> dst_x, buffer + 32, bigEndian); - PutUINT(putPackedImage -> dst_y, buffer + 34, bigEndian); - PutUINT(putPackedImage -> dst_width, buffer + 36, bigEndian); - PutUINT(putPackedImage -> dst_height, buffer + 38, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void PutPackedImageStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; - - *logofs << name() << ": Identity format " - - << "drawable " << putPackedImage -> drawable << ", " - << "gcontext " << putPackedImage -> gcontext << ", " - - << "format " << (unsigned int) putPackedImage -> format << ", " - << "method " << (unsigned int) putPackedImage -> method << ", " - - << "src_depth " << (unsigned int) putPackedImage -> src_depth << ", " - << "dst_depth " << (unsigned int) putPackedImage -> dst_depth << ", " - - << "src_length " << putPackedImage -> src_length << ", " - << "dst_length " << putPackedImage -> dst_length << ", " - - << "src_x " << putPackedImage -> src_x << ", " - << "src_y " << putPackedImage -> src_y << ", " - << "src_width " << putPackedImage -> src_width << ", " - << "src_height " << putPackedImage -> src_height << ", " - - << "dst_x " << putPackedImage -> dst_x << ", " - << "dst_y " << putPackedImage -> dst_y << ", " - << "dst_width " << putPackedImage -> dst_width << ", " - << "dst_height " << putPackedImage -> dst_height << ", " - - << "size " << putPackedImage -> size_ << ".\n" - << logofs_flush; - - #endif -} - -void PutPackedImageStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Fields method, format, src_depth, dst_depth, - // src_length, dst_length, src_x, src_y, src_width, - // src_height. - // - // - // TODO: We should better investigate the effect of - // having fields src_x and src_y in identity instead - // of keeping them in differences. - // - - md5_append(md5_state_, buffer + 12, 20); -} - -void PutPackedImageStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - // - // Encode the variant part. - // - - PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; - PutPackedImageMessage *cachedPutPackedImage = (PutPackedImageMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " - << (unsigned int) putPackedImage -> client - << " as client field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(putPackedImage -> client, 8, - clientCache -> resourceCache); - - cachedPutPackedImage -> client = putPackedImage -> client; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putPackedImage -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(putPackedImage -> drawable, clientCache -> drawableCache); - - cachedPutPackedImage -> drawable = putPackedImage -> drawable; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putPackedImage -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(putPackedImage -> gcontext, clientCache -> gcCache); - - cachedPutPackedImage -> gcontext = putPackedImage -> gcontext; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putPackedImage -> dst_x - << " as " << "dst_x" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_x = putPackedImage -> dst_x - cachedPutPackedImage -> dst_x; - - encodeBuffer.encodeCachedValue(diff_x, 16, - clientCache -> putImageXCache, 8); - - cachedPutPackedImage -> dst_x = putPackedImage -> dst_x; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putPackedImage -> dst_y - << " as " << "dst_y" << " field.\n" << logofs_flush; - #endif - - unsigned short int diff_y = putPackedImage -> dst_y - cachedPutPackedImage -> dst_y; - - encodeBuffer.encodeCachedValue(diff_y, 16, - clientCache -> putImageYCache, 8); - - cachedPutPackedImage -> dst_y = putPackedImage -> dst_y; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putPackedImage -> dst_width - << " as " << "dst_width" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(putPackedImage -> dst_width, 16, - clientCache -> putImageWidthCache, 8); - - cachedPutPackedImage -> dst_width = putPackedImage -> dst_width; - - #ifdef TEST - *logofs << name() << ": Encoding value " << putPackedImage -> dst_height - << " as " << "dst_height" << " field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(putPackedImage -> dst_height, 16, - clientCache -> putImageHeightCache, 8); - - cachedPutPackedImage -> dst_height = putPackedImage -> dst_height; -} - -void PutPackedImageStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - // - // Decode the variant part. - // - - PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeCachedValue(putPackedImage -> client, 8, - clientCache -> resourceCache); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " - << (unsigned int) putPackedImage -> client - << " as client field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); - - putPackedImage -> drawable = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putPackedImage -> drawable - << " as drawable field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - putPackedImage -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putPackedImage -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageXCache, 8); - - putPackedImage -> dst_x += value; - putPackedImage -> dst_x &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putPackedImage -> dst_x - << " as dst_x field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageYCache, 8); - - putPackedImage -> dst_y += value; - putPackedImage -> dst_y &= 0xffff; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putPackedImage -> dst_y - << " as dst_y field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageWidthCache, 8); - - putPackedImage -> dst_width = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putPackedImage -> dst_width - << " as dst_width field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> putImageHeightCache, 8); - - putPackedImage -> dst_height = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << putPackedImage -> dst_height - << " as dst_height field.\n" << logofs_flush; - #endif -} - diff --git a/nxcomp/PutPackedImage.h b/nxcomp/PutPackedImage.h deleted file mode 100644 index d28ad39eb..000000000 --- a/nxcomp/PutPackedImage.h +++ /dev/null @@ -1,218 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef PutPackedImage_H -#define PutPackedImage_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define PUTPACKEDIMAGE_ENABLE_CACHE 1 -#define PUTPACKEDIMAGE_ENABLE_DATA 1 -#define PUTPACKEDIMAGE_ENABLE_COMPRESS 0 - -// -// We can't exceed lenght of 262144 bytes. -// - -#define PUTPACKEDIMAGE_DATA_LIMIT 262144 - 40 -#define PUTPACKEDIMAGE_DATA_OFFSET 40 - -#define PUTPACKEDIMAGE_CACHE_SLOTS 6000 -#define PUTPACKEDIMAGE_CACHE_THRESHOLD 70 -#define PUTPACKEDIMAGE_CACHE_LOWER_THRESHOLD 50 - -#define PUTPACKEDIMAGE_CACHE_THRESHOLD_IF_PACKED_SHADOW 97 -#define PUTPACKEDIMAGE_CACHE_LOWER_THRESHOLD_IF_PACKED_SHADOW 90 - -#define PUTPACKEDIMAGE_ENABLE_SPLIT_IF_PROTO_STEP_8 0 - -// -// The message class. -// - -class PutPackedImageMessage : public Message -{ - friend class PutPackedImageStore; - - public: - - PutPackedImageMessage() - { - } - - ~PutPackedImageMessage() - { - } - - // - // Here are the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char client; - - unsigned int drawable; - unsigned int gcontext; - - unsigned char format; - unsigned char method; - - unsigned char src_depth; - unsigned char dst_depth; - - unsigned int src_length; - unsigned int dst_length; - - short int src_x; - short int src_y; - unsigned short src_width; - unsigned short src_height; - - short int dst_x; - short int dst_y; - unsigned short dst_width; - unsigned short dst_height; -}; - -class PutPackedImageStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - PutPackedImageStore(StaticCompressor *compressor); - - virtual ~PutPackedImageStore(); - - virtual const char *name() const - { - return "PutPackedImage"; - } - - virtual unsigned char opcode() const - { - return X_NXPutPackedImage; - } - - virtual unsigned int storage() const - { - return sizeof(PutPackedImageMessage); - } - - // - // Very special of this class. - // - - int getPackedSize(const int position) const - { - PutPackedImageMessage *message = (PutPackedImageMessage *) (*messages_)[position]; - - if (message == NULL) - { - return 0; - } - - return dataOffset + message -> src_length; - } - - int getUnpackedSize(const int position) const - { - PutPackedImageMessage *message = (PutPackedImageMessage *) (*messages_)[position]; - - if (message == NULL) - { - return 0; - } - - return dataOffset + message -> dst_length; - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new PutPackedImageMessage(); - } - - virtual Message *create(const Message &message) const - { - return new PutPackedImageMessage((const PutPackedImageMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (PutPackedImageMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* PutPackedImage_H */ diff --git a/nxcomp/QueryFontReply.cpp b/nxcomp/QueryFontReply.cpp deleted file mode 100644 index ffd5eaee9..000000000 --- a/nxcomp/QueryFontReply.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "QueryFontReply.h" - -#include "ServerCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -QueryFontReplyStore::QueryFontReplyStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = QUERYFONTREPLY_ENABLE_CACHE; - enableData = QUERYFONTREPLY_ENABLE_DATA; - enableSplit = QUERYFONTREPLY_ENABLE_SPLIT; - - // Since ProtoStep7 (#issue 108) - enableCompress = QUERYFONTREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = QUERYFONTREPLY_DATA_LIMIT; - dataOffset = QUERYFONTREPLY_DATA_OFFSET; - - cacheSlots = QUERYFONTREPLY_CACHE_SLOTS; - cacheThreshold = QUERYFONTREPLY_CACHE_THRESHOLD; - cacheLowerThreshold = QUERYFONTREPLY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -QueryFontReplyStore::~QueryFontReplyStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int QueryFontReplyStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Clear the padding bytes. - // - - unsigned char *pad = (unsigned char *) buffer; - - if (size >= 24) - { - PutULONG(0, pad + 20, bigEndian); - } - - if (size >= 40) - { - PutULONG(0, pad + 36, bigEndian); - } - - // - // TODO: This doesn't work. Probably these - // padding bytes are not padding anymore. - // This is to be investigated. - // - // pad += 60; - // - // while (pad + 16 <= (buffer + size)) - // { - // PutULONG(0, pad + 12, bigEndian); - // - // pad += 16; - // } - // - - #ifdef DEBUG - *logofs << name() << ": Cleaned padding bytes of " - << "message at " << message << ".\n" - << logofs_flush; - #endif - - return 1; -} - -int QueryFontReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - return 1; -} - -void QueryFontReplyStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - QueryFontReplyMessage *queryFontReply = (QueryFontReplyMessage *) message; - - *logofs << name() << ": Identity size " << queryFontReply -> size_ << ".\n"; - - #endif -} - -void QueryFontReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} diff --git a/nxcomp/QueryFontReply.h b/nxcomp/QueryFontReply.h deleted file mode 100644 index e12fe4e4b..000000000 --- a/nxcomp/QueryFontReply.h +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef QueryFontReply_H -#define QueryFontReply_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// -#define QUERYFONTREPLY_ENABLE_CACHE 1 -#define QUERYFONTREPLY_ENABLE_DATA 1 -#define QUERYFONTREPLY_ENABLE_SPLIT 0 - -#define QUERYFONTREPLY_DATA_LIMIT 1048576 - 32 -#define QUERYFONTREPLY_DATA_OFFSET 8 - -#define QUERYFONTREPLY_CACHE_SLOTS 200 -#define QUERYFONTREPLY_CACHE_THRESHOLD 20 -#define QUERYFONTREPLY_CACHE_LOWER_THRESHOLD 5 - -#define QUERYFONTREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -// -// The message class. -// - -class QueryFontReplyMessage : public Message -{ - friend class QueryFontReplyStore; - - public: - - QueryFontReplyMessage() - { - } - - ~QueryFontReplyMessage() - { - } -}; - -class QueryFontReplyStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - QueryFontReplyStore(StaticCompressor *compressor); - - virtual ~QueryFontReplyStore(); - - virtual const char *name() const - { - return "QueryFontReply"; - } - - virtual unsigned char opcode() const - { - return X_QueryFont; - } - - virtual unsigned int storage() const - { - return sizeof(QueryFontReplyMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new QueryFontReplyMessage(); - } - - virtual Message *create(const Message &message) const - { - return new QueryFontReplyMessage((const QueryFontReplyMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (QueryFontReplyMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* QueryFontReply_H */ diff --git a/nxcomp/ReadBuffer.cpp b/nxcomp/ReadBuffer.cpp deleted file mode 100644 index 1e2326cee..000000000 --- a/nxcomp/ReadBuffer.cpp +++ /dev/null @@ -1,635 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ReadBuffer.h" - -#include "Transport.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -ReadBuffer::ReadBuffer(Transport *transport) - - : transport_(transport) -{ - // - // The read buffer will grow until - // reaching the maximum buffer size - // and then will remain stable at - // that size. - // - - initialReadSize_ = READ_BUFFER_DEFAULT_SIZE; - maximumBufferSize_ = READ_BUFFER_DEFAULT_SIZE; - - size_ = 0; - buffer_ = NULL; - - owner_ = 1; - length_ = 0; - start_ = 0; - - remaining_ = 0; -} - -ReadBuffer::~ReadBuffer() -{ - if (owner_ == 1) - { - delete [] buffer_; - } -} - -void ReadBuffer::readMessage(const unsigned char *message, unsigned int length) -{ - // - // To be here we must be the real owner - // of the buffer and there must not be - // pending bytes in the transport. - // - - #ifdef TEST - - if (owner_ == 0) - { - *logofs << "ReadBuffer: PANIC! Class for FD#" - << transport_ -> fd() << " doesn't " - << "appear to be the owner of the buffer " - << "while borrowing from the caller.\n" - << logofs_flush; - - HandleCleanup(); - } - - #endif - - // - // Be sure that any outstanding data from - // the transport is appended to our own - // byffer. - // - - if (transport_ -> pending() != 0) - { - #ifdef WARNING - *logofs << "ReadBuffer: WARNING! Class for FD#" - << transport_ -> fd() << " has pending " - << "data in the transport while " - << "borrowing from the caller.\n" - << logofs_flush; - #endif - - readMessage(); - - if (owner_ == 0) - { - convertBuffer(); - } - } - - // - // Can't borrow the buffer if there is data - // from a partial message. In this case add - // the new data to the end of our buffer. - // - - if (length_ == 0) - { - #ifdef TEST - *logofs << "ReadBuffer: Borrowing " << length - << " bytes from the caller for FD#" - << transport_ -> fd() << " with " - << length_ << " bytes in the buffer.\n" - << logofs_flush; - #endif - - delete [] buffer_; - - buffer_ = (unsigned char *) message; - size_ = length; - - length_ = length; - - owner_ = 0; - start_ = 0; - } - else - { - #ifdef TEST - *logofs << "ReadBuffer: Appending " << length - << " bytes from the caller for FD#" - << transport_ -> fd() << " with " - << length_ << " bytes in the buffer.\n" - << logofs_flush; - #endif - - appendBuffer(message, length); - } -} - -int ReadBuffer::readMessage() -{ - int pendingLength = transport_ -> pending(); - - if (pendingLength > 0) - { - // - // Can't move the data in the borrowed buffer, - // so use the tansport buffer only if we don't - // have any partial message. This can happen - // with the proxy where we need to deflate the - // stream. - // - - if (length_ == 0) - { - unsigned char *newBuffer; - - length_ = transport_ -> getPending(newBuffer); - - if (newBuffer == NULL) - { - #ifdef PANIC - *logofs << "ReadBuffer: PANIC! Failed to borrow " - << length_ << " bytes of memory for buffer " - << "in context [A].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to borrow memory for " - << "read buffer in context [A].\n"; - - HandleCleanup(); - } - - delete [] buffer_; - - buffer_ = newBuffer; - size_ = length_; - - owner_ = 0; - start_ = 0; - - #ifdef TEST - *logofs << "ReadBuffer: Borrowed " << length_ - << " pending bytes for FD#" << transport_ -> - fd() << ".\n" << logofs_flush; - #endif - - return length_; - } - #ifdef TEST - else - { - *logofs << "ReadBuffer: WARNING! Cannot borrow " - << pendingLength << " bytes for FD#" - << transport_ -> fd() << " with " - << length_ << " bytes in the buffer.\n" - << logofs_flush; - } - #endif - } - - unsigned int readLength = suggestedLength(pendingLength); - - #ifdef DEBUG - *logofs << "ReadBuffer: Requested " << readLength - << " bytes for FD#" << transport_ -> fd() - << " with readable " << transport_ -> readable() - << " remaining " << remaining_ << " pending " - << transport_ -> pending() << ".\n" - << logofs_flush; - #endif - - if (readLength < initialReadSize_) - { - readLength = initialReadSize_; - } - - #ifdef DEBUG - *logofs << "ReadBuffer: Buffer size is " << size_ - << " length " << length_ << " and start " - << start_ << ".\n" << logofs_flush; - #endif - - // - // We can't use the transport buffer - // to read our own data in it. - // - - #ifdef TEST - - if (owner_ == 0) - { - *logofs << "ReadBuffer: PANIC! Class for FD#" - << transport_ -> fd() << " doesn't " - << "appear to be the owner of the buffer " - << "while reading.\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - // - // Be sure that we have enough space - // to store all the requested data. - // - - if (buffer_ == NULL || length_ + readLength > size_) - { - unsigned int newSize = length_ + readLength; - - #ifdef TEST - *logofs << "ReadBuffer: Resizing buffer for FD#" - << transport_ -> fd() << " in read from " - << size_ << " to " << newSize << " bytes.\n" - << logofs_flush; - #endif - - unsigned char *newBuffer = allocateBuffer(newSize); - - memcpy(newBuffer, buffer_ + start_, length_); - - delete [] buffer_; - - buffer_ = newBuffer; - size_ = newSize; - - transport_ -> pendingReset(); - - owner_ = 1; - } - else if (start_ != 0 && length_ != 0) - { - // - // If any bytes are left due to a partial - // message, shift them to the beginning - // of the buffer. - // - - #ifdef TEST - *logofs << "ReadBuffer: Moving " << length_ - << " bytes of data " << "at beginning of " - << "the buffer for FD#" << transport_ -> fd() - << ".\n" << logofs_flush; - #endif - - memmove(buffer_, buffer_ + start_, length_); - } - - start_ = 0; - - #ifdef DEBUG - *logofs << "ReadBuffer: Buffer size is now " << size_ - << " length is " << length_ << " and start is " - << start_ << ".\n" << logofs_flush; - #endif - - unsigned char *readData = buffer_ + length_; - - #ifdef DEBUG - *logofs << "ReadBuffer: Going to read " << readLength - << " bytes from FD#" << transport_ -> fd() << ".\n" - << logofs_flush; - #endif - - int bytesRead = transport_ -> read(readData, readLength); - - if (bytesRead > 0) - { - #ifdef TEST - *logofs << "ReadBuffer: Read " << bytesRead - << " bytes from FD#" << transport_ -> fd() - << ".\n" << logofs_flush; - #endif - - length_ += bytesRead; - } - else if (bytesRead < 0) - { - // - // Check if there is more data pending than the - // size of the provided buffer. After reading - // the requested amount, in fact, the transport - // may have decompressed the data and produced - // more input. This trick allows us to always - // borrow the buffer from the transport, even - // when the partial read would have prevented - // that. - // - - if (transport_ -> pending() > 0) - { - #ifdef TEST - *logofs << "ReadBuffer: WARNING! Trying to read some " - << "more with " << transport_ -> pending() - << " bytes pending for FD#" << transport_ -> - fd() << ".\n" << logofs_flush; - #endif - - return readMessage(); - } - - #ifdef TEST - *logofs << "ReadBuffer: Error detected reading " - << "from FD#" << transport_ -> fd() - << ".\n" << logofs_flush; - #endif - - return -1; - } - #ifdef TEST - else - { - *logofs << "ReadBuffer: No data read from FD#" - << transport_ -> fd() << " with remaining " - << remaining_ << ".\n" << logofs_flush; - } - #endif - - return bytesRead; -} - -const unsigned char *ReadBuffer::getMessage(unsigned int &controlLength, - unsigned int &dataLength) -{ - #ifdef TEST - - if (transport_ -> pending() > 0) - { - *logofs << "ReadBuffer: PANIC! The transport " - << "appears to have data pending.\n" - << logofs_flush; - - HandleCleanup(); - } - - #endif - - if (length_ == 0) - { - #ifdef DEBUG - *logofs << "ReadBuffer: No message can be located " - << "for FD#" << transport_ -> fd() << ".\n" - << logofs_flush; - #endif - - if (owner_ == 0) - { - buffer_ = NULL; - size_ = 0; - - transport_ -> pendingReset(); - - owner_ = 1; - start_ = 0; - } - - return NULL; - } - - unsigned int trailerLength; - - #ifdef DEBUG - *logofs << "ReadBuffer: Going to locate message with " - << "start at " << start_ << " and length " - << length_ << " for FD#" << transport_ -> fd() - << ".\n" << logofs_flush; - #endif - - int located = locateMessage(buffer_ + start_, buffer_ + start_ + length_, - controlLength, dataLength, trailerLength); - - if (located == 0) - { - // - // No more complete messages are in - // the buffer. - // - - #ifdef DEBUG - *logofs << "ReadBuffer: No message was located " - << "for FD#" << transport_ -> fd() - << ".\n" << logofs_flush; - #endif - - if (owner_ == 0) - { - // - // Must move the remaining bytes in - // our own buffer. - // - - convertBuffer(); - } - - return NULL; - } - else - { - const unsigned char *result = buffer_ + start_; - - if (dataLength > 0) - { - // - // Message contains data, so go to the - // first byte of payload. - // - - result += trailerLength; - - start_ += (dataLength + trailerLength); - length_ -= (dataLength + trailerLength); - } - else - { - // - // It is a control message. - // - - start_ += (controlLength + trailerLength); - length_ -= (controlLength + trailerLength); - } - - #ifdef DEBUG - *logofs << "ReadBuffer: Located message for FD#" - << transport_ -> fd() << " with control length " - << controlLength << " and data length " - << dataLength << ".\n" << logofs_flush; - #endif - - remaining_ = 0; - - return result; - } -} - -int ReadBuffer::setSize(int initialReadSize, int maximumBufferSize) -{ - initialReadSize_ = initialReadSize; - maximumBufferSize_ = maximumBufferSize; - - #ifdef TEST - *logofs << "ReadBuffer: WARNING! Set buffer parameters to " - << initialReadSize_ << "/" << maximumBufferSize_ - << " for object at "<< this << ".\n" - << logofs_flush; - #endif - - return 1; -} - -void ReadBuffer::fullReset() -{ - #ifdef TEST - - if (owner_ == 0) - { - *logofs << "ReadBuffer: PANIC! Class for FD#" - << transport_ -> fd() << " doesn't " - << "appear to be the owner of the buffer " - << "in reset.\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - if (length_ == 0 && size_ > maximumBufferSize_) - { - #ifdef TEST - *logofs << "ReadBuffer: Resizing buffer for FD#" - << transport_ -> fd() << " in reset from " - << size_ << " to " << maximumBufferSize_ - << " bytes.\n" << logofs_flush; - #endif - - delete [] buffer_; - - int newSize = maximumBufferSize_; - - unsigned char *newBuffer = allocateBuffer(newSize); - - buffer_ = newBuffer; - size_ = newSize; - - transport_ -> pendingReset(); - - owner_ = 1; - start_ = 0; - } -} - -unsigned char *ReadBuffer::allocateBuffer(unsigned int newSize) -{ - unsigned char *newBuffer = new unsigned char[newSize]; - - if (newBuffer == NULL) - { - #ifdef PANIC - *logofs << "ReadBuffer: PANIC! Can't allocate " - << newSize << " bytes of memory for buffer " - << "in context [B].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "read buffer in context [B].\n"; - - HandleCleanup(); - } - - #ifdef VALGRIND - - memset(newBuffer, '\0', newSize); - - #endif - - return newBuffer; -} - -void ReadBuffer::appendBuffer(const unsigned char *message, unsigned int length) -{ - if (start_ + length_ + length > size_) - { - unsigned int newSize = length_ + length + initialReadSize_; - - #ifdef TEST - *logofs << "ReadBuffer: WARNING! Resizing buffer " - << "for FD#" << transport_ -> fd() - << " from " << size_ << " to " << newSize - << " bytes.\n" << logofs_flush; - #endif - - unsigned char *newBuffer = allocateBuffer(newSize); - - memcpy(newBuffer, buffer_ + start_, length_); - - delete [] buffer_; - - buffer_ = newBuffer; - size_ = newSize; - - start_ = 0; - } - - memcpy(buffer_ + start_ + length_, message, length); - - length_ += length; - - transport_ -> pendingReset(); - - owner_ = 1; -} - -void ReadBuffer::convertBuffer() -{ - unsigned int newSize = length_ + initialReadSize_; - - #ifdef TEST - *logofs << "ReadBuffer: WARNING! Converting " - << length_ << " bytes to own buffer " - << "for FD#" << transport_ -> fd() - << " with new size " << newSize - << " bytes.\n" << logofs_flush; - #endif - - unsigned char *newBuffer = allocateBuffer(newSize); - - memcpy(newBuffer, buffer_ + start_, length_); - - buffer_ = newBuffer; - size_ = newSize; - - transport_ -> pendingReset(); - - owner_ = 1; - start_ = 0; -} diff --git a/nxcomp/ReadBuffer.h b/nxcomp/ReadBuffer.h deleted file mode 100644 index a12bcc9b3..000000000 --- a/nxcomp/ReadBuffer.h +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ReadBuffer_H -#define ReadBuffer_H - -#include "Misc.h" -#include "Timestamp.h" -#include "Transport.h" - -#define READ_BUFFER_DEFAULT_SIZE 8192 - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -class ReadBuffer -{ - public: - - ReadBuffer(Transport *transport); - - virtual ~ReadBuffer(); - - int readMessage(); - - void readMessage(const unsigned char *message, unsigned int length); - - const unsigned char *getMessage(unsigned int &dataLength) - { - unsigned int controlLength; - - return getMessage(controlLength, dataLength); - } - - const unsigned char *getMessage(unsigned int &controlLength, unsigned int &dataLength); - - unsigned int getLength() const - { - return length_; - } - - unsigned int getRemaining() const - { - return remaining_; - } - - int setSize(int initialReadSize, int initialbufferSize); - - void fullReset(); - - // - // Check if there is a complete - // message in the buffer. - // - - int checkMessage() - { - if (length_ == 0) - { - return 0; - } - else - { - unsigned int controlLength; - unsigned int dataLength; - unsigned int trailerLength; - - return (locateMessage(buffer_ + start_, buffer_ + start_ + length_, - controlLength, dataLength, trailerLength)); - } - } - - protected: - - virtual unsigned int suggestedLength(unsigned int pendingLength) = 0; - - virtual int locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength) = 0; - - unsigned char *allocateBuffer(unsigned int newSize); - - void appendBuffer(const unsigned char *message, unsigned int length); - - void convertBuffer(); - - Transport *transport_; - - unsigned char *buffer_; - - unsigned int length_; - unsigned int size_; - unsigned int start_; - unsigned int remaining_; - - int owner_; - - unsigned int initialReadSize_; - unsigned int maximumBufferSize_; -}; - -#endif /* ReadBuffer_H */ diff --git a/nxcomp/RenderAddGlyphs.cpp b/nxcomp/RenderAddGlyphs.cpp deleted file mode 100644 index ed0864b93..000000000 --- a/nxcomp/RenderAddGlyphs.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderAddGlyphs.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 4, bigEndian), 29, - clientCache -> renderGlyphSetCache); - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 8, bigEndian), 32, - clientCache -> renderNumGlyphsCache, 8); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeCachedValue(value, 29, - clientCache -> renderGlyphSetCache); - - PutULONG(value, buffer + 4, bigEndian); - - decodeBuffer.decodeCachedValue(value, 32, - clientCache -> renderNumGlyphsCache, 8); - - PutULONG(value, buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - encodeCharData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - decodeCharData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.add_glyphs.type = *(buffer + 1); - - renderExtension -> data.add_glyphs.set_id = GetULONG(buffer + 4, bigEndian); - renderExtension -> data.add_glyphs.num_elm = GetULONG(buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.add_glyphs.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.add_glyphs.type; - - PutULONG(renderExtension -> data.add_glyphs.set_id, buffer + 4, bigEndian); - PutULONG(renderExtension -> data.add_glyphs.num_elm, buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.add_glyphs.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - md5_append(md5_state, buffer + 1, 3); - md5_append(md5_state, buffer + 8, 4); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(renderExtension -> data.add_glyphs.set_id, 29, - clientCache -> renderGlyphSetCache); - - cachedRenderExtension -> data.add_glyphs.set_id = - renderExtension -> data.add_glyphs.set_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.add_glyphs.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(renderExtension -> data.add_glyphs.set_id, 29, - clientCache -> renderGlyphSetCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.add_glyphs.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderAddGlyphs.h b/nxcomp/RenderAddGlyphs.h deleted file mode 100644 index d3c8cd158..000000000 --- a/nxcomp/RenderAddGlyphs.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderAddGlyphs_H -#define RenderAddGlyphs_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderAddGlyphs" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderAddGlyphsStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 12 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderAddGlyphs_H */ diff --git a/nxcomp/RenderChangePicture.cpp b/nxcomp/RenderChangePicture.cpp deleted file mode 100644 index 2abb97493..000000000 --- a/nxcomp/RenderChangePicture.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderChangePicture.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> renderSrcPictureCache); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeXidValue(value, clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - #ifdef DEBUG - - if (size == MESSAGE_OFFSET + 4) - { - *logofs << name() << ": Mask is " << GetULONG(buffer + 8, bigEndian) - << " value is " << GetULONG(buffer + 12, bigEndian) - << ".\n" << logofs_flush; - } - else - { - *logofs << name() << ": WARNING! Unexpected size. Mask is " - << GetULONG(buffer + 8, bigEndian) << ".\n" - << logofs_flush; - } - - #endif - - encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.change_picture.type = *(buffer + 1); - - renderExtension -> data.change_picture.src_id = GetULONG(buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.change_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.change_picture.type; - - PutULONG(renderExtension -> data.change_picture.src_id, buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.change_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - md5_append(md5_state, buffer + 1, 3); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(renderExtension -> data.change_picture.src_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.change_picture.src_id = - renderExtension -> data.change_picture.src_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.change_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.change_picture.src_id, - clientCache -> renderSrcPictureCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.change_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderChangePicture.h b/nxcomp/RenderChangePicture.h deleted file mode 100644 index 4bab1ef98..000000000 --- a/nxcomp/RenderChangePicture.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderChangePicture_H -#define RenderChangePicture_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderChangePicture" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderChangePictureStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 8 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderChangePicture_H */ diff --git a/nxcomp/RenderComposite.cpp b/nxcomp/RenderComposite.cpp deleted file mode 100644 index e8603a7da..000000000 --- a/nxcomp/RenderComposite.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderComposite.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> renderSrcPictureCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), - clientCache -> renderMaskPictureCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 16, bigEndian), - clientCache -> renderDstPictureCache); - - // - // Src X and Y. - // - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 20, bigEndian), - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 22, bigEndian), - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - // - // Mask X and Y. - // - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 24, bigEndian), - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 26, bigEndian), - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - // - // Dst X and Y. - // - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 28, bigEndian), - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 30, bigEndian), - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - // - // Width and height. - // - - encodeBuffer.encodeCachedValue(GetUINT(buffer + 32, bigEndian), 16, - clientCache -> renderWidthCache, 11); - - encodeBuffer.encodeCachedValue(GetUINT(buffer + 34, bigEndian), 16, - clientCache -> renderHeightCache, 11); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - decodeBuffer.decodeXidValue(value, clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 8, bigEndian); - - decodeBuffer.decodeXidValue(value, clientCache -> renderMaskPictureCache); - - PutULONG(value, buffer + 12, bigEndian); - - decodeBuffer.decodeXidValue(value, clientCache -> renderDstPictureCache); - - PutULONG(value, buffer + 16, bigEndian); - - // - // Src X and Y. - // - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - PutUINT(clientCache -> renderLastX, buffer + 20, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - PutUINT(clientCache -> renderLastY, buffer + 22, bigEndian); - - // - // Mask X and Y. - // - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - PutUINT(clientCache -> renderLastX, buffer + 24, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - PutUINT(clientCache -> renderLastY, buffer + 26, bigEndian); - - // - // Dst X and Y. - // - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - PutUINT(clientCache -> renderLastX, buffer + 28, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - PutUINT(clientCache -> renderLastY, buffer + 30, bigEndian); - - // - // Width and height. - // - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> renderWidthCache, 11); - - PutUINT(value, buffer + 32, bigEndian); - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> renderHeightCache, 11); - - PutUINT(value, buffer + 34, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.composite.type = *(buffer + 1); - renderExtension -> data.composite.op = *(buffer + 4); - - renderExtension -> data.composite.src_id = GetULONG(buffer + 8, bigEndian); - renderExtension -> data.composite.msk_id = GetULONG(buffer + 12, bigEndian); - renderExtension -> data.composite.dst_id = GetULONG(buffer + 16, bigEndian); - - renderExtension -> data.composite.src_x = GetUINT(buffer + 20, bigEndian); - renderExtension -> data.composite.src_y = GetUINT(buffer + 22, bigEndian); - - renderExtension -> data.composite.msk_x = GetUINT(buffer + 24, bigEndian); - renderExtension -> data.composite.msk_y = GetUINT(buffer + 26, bigEndian); - - renderExtension -> data.composite.dst_x = GetUINT(buffer + 28, bigEndian); - renderExtension -> data.composite.dst_y = GetUINT(buffer + 30, bigEndian); - - renderExtension -> data.composite.width = GetUINT(buffer + 32, bigEndian); - renderExtension -> data.composite.height = GetUINT(buffer + 34, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.composite.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.composite.type; - *(buffer + 4) = renderExtension -> data.composite.op; - - PutULONG(renderExtension -> data.composite.src_id, buffer + 8, bigEndian); - PutULONG(renderExtension -> data.composite.msk_id, buffer + 12, bigEndian); - PutULONG(renderExtension -> data.composite.dst_id, buffer + 16, bigEndian); - - PutUINT(renderExtension -> data.composite.src_x, buffer + 20, bigEndian); - PutUINT(renderExtension -> data.composite.src_y, buffer + 22, bigEndian); - - PutUINT(renderExtension -> data.composite.msk_x, buffer + 24, bigEndian); - PutUINT(renderExtension -> data.composite.msk_y, buffer + 26, bigEndian); - - PutUINT(renderExtension -> data.composite.dst_x, buffer + 28, bigEndian); - PutUINT(renderExtension -> data.composite.dst_y, buffer + 30, bigEndian); - - PutUINT(renderExtension -> data.composite.width, buffer + 32, bigEndian); - PutUINT(renderExtension -> data.composite.height, buffer + 34, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.composite.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - // - // Include the minor opcode and size in the - // identity, plus the operator, the x and y - // of the source and mask and the width and - // height of the destination. - // - - md5_append(md5_state, buffer + 1, 4); - md5_append(md5_state, buffer + 20, 8); - md5_append(md5_state, buffer + 32, 4); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Source " << renderExtension -> data.composite.src_id - << " mask " << renderExtension -> data.composite.msk_id - << " destination " << renderExtension -> data.composite.msk_id - << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(renderExtension -> data.composite.src_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.composite.src_id = - renderExtension -> data.composite.src_id; - - encodeBuffer.encodeXidValue(renderExtension -> data.composite.msk_id, - clientCache -> renderMaskPictureCache); - - cachedRenderExtension -> data.composite.msk_id = - renderExtension -> data.composite.msk_id; - - encodeBuffer.encodeXidValue(renderExtension -> data.composite.dst_id, - clientCache -> renderDstPictureCache); - - cachedRenderExtension -> data.composite.dst_id = - renderExtension -> data.composite.dst_id; - - // - // Dst X and Y. - // - - unsigned int value; - unsigned int previous; - - value = renderExtension -> data.composite.dst_x; - previous = cachedRenderExtension -> data.composite.dst_x; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderXCache, 11); - - cachedRenderExtension -> data.composite.dst_x = value; - - value = renderExtension -> data.composite.dst_y; - previous = cachedRenderExtension -> data.composite.dst_y; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderYCache, 11); - - cachedRenderExtension -> data.composite.dst_y = value; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.composite.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.composite.src_id, - clientCache -> renderSrcPictureCache); - - decodeBuffer.decodeXidValue(renderExtension -> data.composite.msk_id, - clientCache -> renderMaskPictureCache); - - decodeBuffer.decodeXidValue(renderExtension -> data.composite.dst_id, - clientCache -> renderDstPictureCache); - - // - // Dst X and Y. - // - - unsigned int value; - unsigned int previous; - - previous = renderExtension -> data.composite.dst_x; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderXCache, 11); - - renderExtension -> data.composite.dst_x = value; - - previous = renderExtension -> data.composite.dst_y; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderYCache, 11); - - renderExtension -> data.composite.dst_y = value; - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.composite.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderComposite.h b/nxcomp/RenderComposite.h deleted file mode 100644 index aafa1e776..000000000 --- a/nxcomp/RenderComposite.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderComposite_H -#define RenderComposite_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderComposite" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderCompositeStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 36 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 0 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 0 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderComposite_H */ diff --git a/nxcomp/RenderCompositeGlyphs.cpp b/nxcomp/RenderCompositeGlyphs.cpp deleted file mode 100644 index 74b3ec779..000000000 --- a/nxcomp/RenderCompositeGlyphs.cpp +++ /dev/null @@ -1,625 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderCompositeGlyphs.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding value " - << ((size - MESSAGE_OFFSET) >> 2) << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << size - << ".\n" << logofs_flush; - #endif - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> renderSrcPictureCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), - clientCache -> renderDstPictureCache); - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 32, - clientCache -> renderFormatCache); - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 20, bigEndian), 29, - clientCache -> renderGlyphSetCache); - - unsigned int src_x = GetUINT(buffer + 24, bigEndian); - unsigned int src_y = GetUINT(buffer + 26, bigEndian); - - // Since ProtoStep8 (#issue 108) - encodeBuffer.encodeDiffCachedValue(src_x, - clientCache -> renderGlyphX, 16, - clientCache -> renderGlyphXCache, 11); - - encodeBuffer.encodeDiffCachedValue(src_y, - clientCache -> renderGlyphY, 16, - clientCache -> renderGlyphYCache, 11); - - #ifdef TEST - *logofs << name() << ": Encoded source X " - << GetUINT(buffer + 24, bigEndian) << " source Y " - << GetUINT(buffer + 26, bigEndian) << ".\n" - << logofs_flush; - #endif - - // - // Bytes from 28 to 36 contain in the order: - // - // 1 byte for the length of the first string. - // 3 bytes of padding. - // 2 bytes for the X offset. - // 2 bytes for the Y offset. - // - // Encode these bytes differentially to match - // all the strings that have equal glyphs. - // - // Only manage the first string of glyphs. The - // others strings should match, if they contain - // the same glyphs, since the offset are rela- - // tive to the first offset coordinates. - // - - // Since ProtoStep8 (#issue 108) - if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - unsigned int numGlyphs = *(buffer + 28); - - encodeBuffer.encodeCachedValue(numGlyphs, 8, - clientCache -> renderNumGlyphsCache); - - unsigned int offset_x = GetUINT(buffer + 32, bigEndian); - unsigned int offset_y = GetUINT(buffer + 34, bigEndian); - - if (offset_x == src_x && offset_y == src_y) - { - encodeBuffer.encodeBoolValue(0); - - #ifdef TEST - *logofs << name() << ": Matched offset X " - << GetUINT(buffer + 32, bigEndian) << " offset Y " - << GetUINT(buffer + 34, bigEndian) << ".\n" - << logofs_flush; - #endif - } - else - { - encodeBuffer.encodeBoolValue(1); - - encodeBuffer.encodeDiffCachedValue(offset_x, - clientCache -> renderGlyphX, 16, - clientCache -> renderGlyphXCache, 11); - - encodeBuffer.encodeDiffCachedValue(offset_y, - clientCache -> renderGlyphY, 16, - clientCache -> renderGlyphYCache, 11); - - #ifdef TEST - *logofs << name() << ": Missed offset X " - << GetUINT(buffer + 32, bigEndian) << " offset Y " - << GetUINT(buffer + 34, bigEndian) << ".\n" - << logofs_flush; - #endif - } - } - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - decodeBuffer.decodeXidValue(value, - clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 8, bigEndian); - - decodeBuffer.decodeXidValue(value, - clientCache -> renderDstPictureCache); - - PutULONG(value, buffer + 12, bigEndian); - - decodeBuffer.decodeCachedValue(value, 32, - clientCache -> renderFormatCache); - - PutULONG(value, buffer + 16, bigEndian); - - decodeBuffer.decodeCachedValue(value, 29, - clientCache -> renderGlyphSetCache); - - PutULONG(value, buffer + 20, bigEndian); - - unsigned int src_x; - unsigned int src_y; - - // Since ProtoStep8 (#issue 108) - decodeBuffer.decodeDiffCachedValue(src_x, - clientCache -> renderGlyphX, 16, - clientCache -> renderGlyphXCache, 11); - - decodeBuffer.decodeDiffCachedValue(src_y, - clientCache -> renderGlyphY, 16, - clientCache -> renderGlyphYCache, 11); - - PutUINT(src_x, buffer + 24, bigEndian); - PutUINT(src_y, buffer + 26, bigEndian); - - // Since ProtoStep8 (#issue 108) - if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - decodeBuffer.decodeCachedValue(value, 8, - clientCache -> renderNumGlyphsCache); - - *(buffer + 28) = value; - - decodeBuffer.decodeBoolValue(value); - - if (value == 0) - { - PutUINT(src_x, buffer + 32, bigEndian); - PutUINT(src_y, buffer + 34, bigEndian); - } - else - { - decodeBuffer.decodeDiffCachedValue(src_x, - clientCache -> renderGlyphX, 16, - clientCache -> renderGlyphXCache, 11); - - PutUINT(src_x, buffer + 32, bigEndian); - - decodeBuffer.decodeDiffCachedValue(src_y, - clientCache -> renderGlyphY, 16, - clientCache -> renderGlyphYCache, 11); - - PutUINT(src_y, buffer + 34, bigEndian); - } - } - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - // Since ProtoStep8 (#issue 108) - if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - encodeCharData(encodeBuffer, buffer, MESSAGE_OFFSET_IF_PROTO_STEP_8, - size, bigEndian, channelCache); - } - else if (size > MESSAGE_OFFSET) - { - encodeCharData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - } - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of text data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - // Since ProtoStep8 (#issue 108) - if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - decodeCharData(decodeBuffer, buffer, MESSAGE_OFFSET_IF_PROTO_STEP_8, - size, bigEndian, channelCache); - } - else if (size > MESSAGE_OFFSET) - { - decodeCharData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - } - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.composite_glyphs.type = *(buffer + 1); - renderExtension -> data.composite_glyphs.op = *(buffer + 4); - - renderExtension -> data.composite_glyphs.src_id = GetULONG(buffer + 8, bigEndian); - renderExtension -> data.composite_glyphs.dst_id = GetULONG(buffer + 12, bigEndian); - - renderExtension -> data.composite_glyphs.format = GetULONG(buffer + 16, bigEndian); - renderExtension -> data.composite_glyphs.set_id = GetULONG(buffer + 20, bigEndian); - - renderExtension -> data.composite_glyphs.src_x = GetUINT(buffer + 24, bigEndian); - renderExtension -> data.composite_glyphs.src_y = GetUINT(buffer + 26, bigEndian); - - // Since ProtoStep8 (#issue 108) - if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - renderExtension -> data.composite_glyphs.num_elm = *(buffer + 28); - - renderExtension -> data.composite_glyphs.offset_x = GetUINT(buffer + 32, bigEndian); - renderExtension -> data.composite_glyphs.offset_y = GetUINT(buffer + 34, bigEndian); - } - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.composite_glyphs.type - << " size is " << renderExtension -> size_ << " identity size " - << renderExtension -> i_size_ << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.composite_glyphs.type; - *(buffer + 4) = renderExtension -> data.composite_glyphs.op; - - PutULONG(renderExtension -> data.composite_glyphs.src_id, buffer + 8, bigEndian); - PutULONG(renderExtension -> data.composite_glyphs.dst_id, buffer + 12, bigEndian); - - PutULONG(renderExtension -> data.composite_glyphs.format, buffer + 16, bigEndian); - PutULONG(renderExtension -> data.composite_glyphs.set_id, buffer + 20, bigEndian); - - PutUINT(renderExtension -> data.composite_glyphs.src_x, buffer + 24, bigEndian); - PutUINT(renderExtension -> data.composite_glyphs.src_y, buffer + 26, bigEndian); - - // Since ProtoStep8 (#issue 108) - if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - *(buffer + 28) = renderExtension -> data.composite_glyphs.num_elm; - - PutUINT(renderExtension -> data.composite_glyphs.offset_x, buffer + 32, bigEndian); - PutUINT(renderExtension -> data.composite_glyphs.offset_y, buffer + 34, bigEndian); - } - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.composite_glyphs.type - << " size is " << renderExtension -> size_ << " identity size " - << renderExtension -> i_size_ << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - // - // Include minor opcode, size and - // the composite operator in the - // identity. - // - - md5_append(md5_state, buffer + 1, 4); - - // - // Include the format. - // - - md5_append(md5_state, buffer + 16, 4); - - // - // Also include the length of the - // first string. - // - - // Since ProtoStep8 (#issue 108) - if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - md5_append(md5_state, buffer + 28, 1); - } -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(renderExtension -> data.composite_glyphs.src_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.composite_glyphs.src_id = - renderExtension -> data.composite_glyphs.src_id; - - encodeBuffer.encodeXidValue(renderExtension -> data.composite_glyphs.dst_id, - clientCache -> renderDstPictureCache); - - cachedRenderExtension -> data.composite_glyphs.dst_id = - renderExtension -> data.composite_glyphs.dst_id; - - encodeBuffer.encodeCachedValue(renderExtension -> data.composite_glyphs.set_id, 29, - clientCache -> renderGlyphSetCache); - - cachedRenderExtension -> data.composite_glyphs.set_id = - renderExtension -> data.composite_glyphs.set_id; - - // - // Src X and Y. - // - // The source X and Y coordinates are - // encoded as differerences in respect - // to the cached message. - // - - unsigned int value; - unsigned int previous; - - // Since ProtoStep8 (#issue 108) - value = renderExtension -> data.composite_glyphs.src_x; - previous = cachedRenderExtension -> data.composite_glyphs.src_x; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderGlyphXCache, 11); - - cachedRenderExtension -> data.composite_glyphs.src_x = value; - - value = renderExtension -> data.composite_glyphs.src_y; - previous = cachedRenderExtension -> data.composite_glyphs.src_y; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderGlyphYCache, 11); - - cachedRenderExtension -> data.composite_glyphs.src_y = value; - - #ifdef TEST - *logofs << name() << ": Encoded source X " - << renderExtension -> data.composite_glyphs.src_x << " source Y " - << renderExtension -> data.composite_glyphs.src_y << ".\n" - << logofs_flush; - #endif - - // Since ProtoStep8 (#issue 108) - if (renderExtension -> size_ >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - // - // Offset X and Y. - // - - if (renderExtension -> data.composite_glyphs.offset_x == - renderExtension -> data.composite_glyphs.src_x && - renderExtension -> data.composite_glyphs.offset_y == - renderExtension -> data.composite_glyphs.src_y) - { - encodeBuffer.encodeBoolValue(0); - - cachedRenderExtension -> data.composite_glyphs.offset_x = - renderExtension -> data.composite_glyphs.offset_x; - - cachedRenderExtension -> data.composite_glyphs.offset_y = - renderExtension -> data.composite_glyphs.offset_y; - - #ifdef TEST - *logofs << name() << ": Matched offset X " - << renderExtension -> data.composite_glyphs.offset_x << " offset Y " - << renderExtension -> data.composite_glyphs.offset_y << ".\n" - << logofs_flush; - #endif - } - else - { - encodeBuffer.encodeBoolValue(1); - - value = renderExtension -> data.composite_glyphs.offset_x; - previous = cachedRenderExtension -> data.composite_glyphs.offset_x; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderGlyphXCache, 11); - - cachedRenderExtension -> data.composite_glyphs.offset_x = value; - - value = renderExtension -> data.composite_glyphs.offset_y; - previous = cachedRenderExtension -> data.composite_glyphs.offset_y; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderGlyphYCache, 11); - - cachedRenderExtension -> data.composite_glyphs.offset_y = value; - - #ifdef TEST - *logofs << name() << ": Missed offset X " - << renderExtension -> data.composite_glyphs.offset_x << " offset Y " - << renderExtension -> data.composite_glyphs.offset_y << ".\n" - << logofs_flush; - #endif - } - } - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.composite_glyphs.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.composite_glyphs.src_id, - clientCache -> renderSrcPictureCache); - - decodeBuffer.decodeXidValue(renderExtension -> data.composite_glyphs.dst_id, - clientCache -> renderDstPictureCache); - - decodeBuffer.decodeCachedValue(renderExtension -> data.composite_glyphs.set_id, 29, - clientCache -> renderGlyphSetCache); - - // - // Src X and Y. - // - - unsigned int value; - unsigned int previous; - - // Since ProtoStep8 (#issue 108) - previous = renderExtension -> data.composite_glyphs.src_x; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderGlyphXCache, 11); - - renderExtension -> data.composite_glyphs.src_x = value; - - previous = renderExtension -> data.composite_glyphs.src_y; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderGlyphYCache, 11); - - renderExtension -> data.composite_glyphs.src_y = value; - - // Since ProtoStep8 (#issue 108) - if (renderExtension -> size_ >= MESSAGE_OFFSET_IF_PROTO_STEP_8) - { - // - // Offset X and Y. - // - - decodeBuffer.decodeBoolValue(value); - - if (value == 0) - { - renderExtension -> data.composite_glyphs.offset_x = - renderExtension -> data.composite_glyphs.src_x; - - renderExtension -> data.composite_glyphs.offset_y = - renderExtension -> data.composite_glyphs.src_y; - } - else - { - previous = renderExtension -> data.composite_glyphs.offset_x; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderGlyphXCache, 11); - - renderExtension -> data.composite_glyphs.offset_x = value; - - previous = renderExtension -> data.composite_glyphs.offset_y; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderGlyphYCache, 11); - - renderExtension -> data.composite_glyphs.offset_y = value; - } - } - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.composite_glyphs.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderCompositeGlyphs.h b/nxcomp/RenderCompositeGlyphs.h deleted file mode 100644 index 1062ee781..000000000 --- a/nxcomp/RenderCompositeGlyphs.h +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderCompositeGlyphs_H -#define RenderCompositeGlyphs_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderCompositeGlyphs" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderCompositeGlyphsStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 28 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Encode the first 8 bytes of the -// data differentially in newer -// protocol versions. -// - -#undef MESSAGE_OFFSET_IF_PROTO_STEP_8 -#define MESSAGE_OFFSET_IF_PROTO_STEP_8 36 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - // Since ProtoStep8 (#issue 108) - unsigned int offset = MESSAGE_OFFSET_IF_PROTO_STEP_8; - - return (size >= offset ? offset : size); - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderCompositeGlyphs_H */ diff --git a/nxcomp/RenderCreateGlyphSet.cpp b/nxcomp/RenderCreateGlyphSet.cpp deleted file mode 100644 index 3e7a71721..000000000 --- a/nxcomp/RenderCreateGlyphSet.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderCreateGlyphSet.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeNewXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> renderGlyphSetCache, - clientCache -> renderFreeGlyphSetCache); - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 8, bigEndian), 32, - clientCache -> renderFormatCache); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeNewXidValue(value, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> renderGlyphSetCache, - clientCache -> renderFreeGlyphSetCache); - - PutULONG(value, buffer + 4, bigEndian); - - decodeBuffer.decodeCachedValue(value, 32, - clientCache -> renderFormatCache); - - PutULONG(value, buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.create_set.type = *(buffer + 1); - - renderExtension -> data.create_set.set_id = GetULONG(buffer + 4, bigEndian); - renderExtension -> data.create_set.format = GetULONG(buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.create_set.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.create_set.type; - - PutULONG(renderExtension -> data.create_set.set_id, buffer + 4, bigEndian); - PutULONG(renderExtension -> data.create_set.format, buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.create_set.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - md5_append(md5_state, buffer + 1, 3); - md5_append(md5_state, buffer + 8, 4); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeNewXidValue(renderExtension -> data.create_set.set_id, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> renderGlyphSetCache, - clientCache -> renderFreeGlyphSetCache); - - cachedRenderExtension -> data.create_set.set_id = - renderExtension -> data.create_set.set_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.create_set.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeNewXidValue(renderExtension -> data.create_set.set_id, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> renderGlyphSetCache, - clientCache -> renderFreeGlyphSetCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.create_set.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderCreateGlyphSet.h b/nxcomp/RenderCreateGlyphSet.h deleted file mode 100644 index 10f5d6699..000000000 --- a/nxcomp/RenderCreateGlyphSet.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderCreateGlyphSet_H -#define RenderCreateGlyphSet_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderCreateGlyphSet" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderCreateGlyphSetStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 12 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 0 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 0 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderCreateGlyphSet_H */ diff --git a/nxcomp/RenderCreatePicture.cpp b/nxcomp/RenderCreatePicture.cpp deleted file mode 100644 index 2fd736cbb..000000000 --- a/nxcomp/RenderCreatePicture.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderCreatePicture.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeNewXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> renderSrcPictureCache, - clientCache -> renderFreePictureCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> drawableCache); - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 12, bigEndian), 32, - clientCache -> renderFormatCache); - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 32, - clientCache -> renderValueMaskCache); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeNewXidValue(value, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> renderSrcPictureCache, - clientCache -> renderFreePictureCache); - - PutULONG(value, buffer + 4, bigEndian); - - decodeBuffer.decodeXidValue(value, - clientCache -> drawableCache); - - PutULONG(value, buffer + 8, bigEndian); - - decodeBuffer.decodeCachedValue(value, 32, - clientCache -> renderFormatCache); - - PutULONG(value, buffer + 12, bigEndian); - - decodeBuffer.decodeCachedValue(value, 32, - clientCache -> renderValueMaskCache); - - PutULONG(value, buffer + 16, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.create_picture.type = *(buffer + 1); - - renderExtension -> data.create_picture.src_id = GetULONG(buffer + 4, bigEndian); - renderExtension -> data.create_picture.dst_id = GetULONG(buffer + 8, bigEndian); - - renderExtension -> data.create_picture.format = GetULONG(buffer + 12, bigEndian); - renderExtension -> data.create_picture.mask = GetULONG(buffer + 16, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.create_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.create_picture.type; - - PutULONG(renderExtension -> data.create_picture.src_id, buffer + 4, bigEndian); - PutULONG(renderExtension -> data.create_picture.dst_id, buffer + 8, bigEndian); - - PutULONG(renderExtension -> data.create_picture.format, buffer + 12, bigEndian); - PutULONG(renderExtension -> data.create_picture.mask, buffer + 16, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.create_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - md5_append(md5_state, buffer + 1, 3); - md5_append(md5_state, buffer + 12, 8); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding new id value " - << renderExtension -> data.create_picture.src_id - << ".\n"; - #endif - - encodeBuffer.encodeNewXidValue(renderExtension -> data.create_picture.src_id, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> renderSrcPictureCache, - clientCache -> renderFreePictureCache); - - cachedRenderExtension -> data.create_picture.src_id = - renderExtension -> data.create_picture.src_id; - - encodeBuffer.encodeXidValue(renderExtension -> data.create_picture.dst_id, - clientCache -> drawableCache); - - cachedRenderExtension -> data.create_picture.dst_id = - renderExtension -> data.create_picture.dst_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.create_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeNewXidValue(renderExtension -> data.create_picture.src_id, - clientCache -> lastId, clientCache -> lastIdCache, - clientCache -> renderSrcPictureCache, - clientCache -> renderFreePictureCache); - - decodeBuffer.decodeXidValue(renderExtension -> data.create_picture.dst_id, - clientCache -> drawableCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.create_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderCreatePicture.h b/nxcomp/RenderCreatePicture.h deleted file mode 100644 index ae2f583a0..000000000 --- a/nxcomp/RenderCreatePicture.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderCreatePicture_H -#define RenderCreatePicture_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderCreatePicture" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderCreatePictureStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 20 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderCreatePicture_H */ diff --git a/nxcomp/RenderExtension.cpp b/nxcomp/RenderExtension.cpp deleted file mode 100644 index bd2285e82..000000000 --- a/nxcomp/RenderExtension.cpp +++ /dev/null @@ -1,423 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "NXrender.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -#include "RenderExtension.h" - -#include "RenderGenericRequest.h" -#include "RenderCreatePicture.h" -#include "RenderChangePicture.h" -#include "RenderFreePicture.h" -#include "RenderPictureClip.h" -#include "RenderPictureTransform.h" -#include "RenderPictureFilter.h" -#include "RenderCreateGlyphSet.h" -#include "RenderFreeGlyphSet.h" -#include "RenderAddGlyphs.h" -#include "RenderComposite.h" -#include "RenderCompositeGlyphs.h" -#include "RenderFillRectangles.h" -#include "RenderTrapezoids.h" -#include "RenderTriangles.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Constructor and destructor. -// - -RenderExtensionStore::RenderExtensionStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = RENDEREXTENSION_ENABLE_CACHE; - enableData = RENDEREXTENSION_ENABLE_DATA; - enableSplit = RENDEREXTENSION_ENABLE_SPLIT; - enableCompress = RENDEREXTENSION_ENABLE_COMPRESS; - - generic_ = new RenderGenericRequestStore(); - - for (int i = 0; i < RENDEREXTENSION_MINOR_OPCODE_LIMIT; i++) - { - minors_[i] = generic_; - } - - minors_[X_RenderChangePicture] = new RenderChangePictureStore(); - minors_[X_RenderFillRectangles] = new RenderFillRectanglesStore(); - minors_[X_RenderAddGlyphs] = new RenderAddGlyphsStore(); - - // Since ProtoStep7 (#issue 108) - minors_[X_RenderCreatePicture] = new RenderCreatePictureStore(); - minors_[X_RenderFreePicture] = new RenderFreePictureStore(); - minors_[X_RenderSetPictureClipRectangles] = new RenderPictureClipStore(); - minors_[X_RenderCreateGlyphSet] = new RenderCreateGlyphSetStore(); - minors_[X_RenderComposite] = new RenderCompositeStore(); - minors_[X_RenderCompositeGlyphs8] = new RenderCompositeGlyphsStore(); - minors_[X_RenderCompositeGlyphs16] = new RenderCompositeGlyphsStore(); - minors_[X_RenderCompositeGlyphs32] = new RenderCompositeGlyphsStore(); - - minors_[X_RenderSetPictureTransform] = new RenderPictureTransformStore(); - minors_[X_RenderSetPictureFilter] = new RenderPictureFilterStore(); - minors_[X_RenderFreeGlyphSet] = new RenderFreeGlyphSetStore(); - minors_[X_RenderTrapezoids] = new RenderTrapezoidsStore(); - minors_[X_RenderTriangles] = new RenderTrianglesStore(); - - dataLimit = RENDEREXTENSION_DATA_LIMIT; - dataOffset = RENDEREXTENSION_DATA_OFFSET; - - // Since ProtoStep7 (#issue 108) - cacheSlots = RENDEREXTENSION_CACHE_SLOTS_IF_PROTO_STEP_7; - - cacheThreshold = RENDEREXTENSION_CACHE_THRESHOLD; - cacheLowerThreshold = RENDEREXTENSION_CACHE_LOWER_THRESHOLD; - - opcode_ = X_NXInternalRenderExtension; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -RenderExtensionStore::~RenderExtensionStore() -{ - for (int i = 0; i < RENDEREXTENSION_MINOR_OPCODE_LIMIT; i++) - { - if (minors_[i] != generic_) - { - delete minors_[i]; - } - } - - delete generic_; - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -int RenderExtensionStore::validateMessage(const unsigned char *buffer, int size) -{ - #ifdef TEST - *logofs << name() << ": Encoding message OPCODE#" - << (unsigned) *buffer << " MINOR#" << (unsigned) - *(buffer + 1) << " with size " << size - << ".\n" << logofs_flush; - #endif - - return (size >= control -> MinimumMessageSize && - size <= control -> MaximumMessageSize); -} - -// -// Here are the methods to handle the messages' content. -// - -int RenderExtensionStore::identitySize(const unsigned char *buffer, unsigned int size) -{ - return minors_[*(buffer + 1)] -> identitySize(buffer, size); -} - -int RenderExtensionStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - encodeBuffer.encodeOpcodeValue(*(buffer + 1), - ((ClientCache *) channelCache) -> renderOpcodeCache); - - minors_[*(buffer + 1)] -> encodeMessage(encodeBuffer, buffer, size, - bigEndian, channelCache); - - return 1; -} - -int RenderExtensionStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - unsigned char type; - - decodeBuffer.decodeOpcodeValue(type, - ((ClientCache *) channelCache) -> renderOpcodeCache); - - minors_[type] -> decodeMessage(decodeBuffer, buffer, size, type, - bigEndian, writeBuffer, channelCache); - - return 1; -} - -int RenderExtensionStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - return minors_[*(buffer + 1)] -> parseIdentity(message, buffer, size, bigEndian); -} - -int RenderExtensionStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - return minors_[((RenderExtensionMessage *) message) -> data.any.type] -> - unparseIdentity(message, buffer, size, bigEndian); -} - -void RenderExtensionStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - minors_[*(buffer + 1)] -> identityChecksum(message, buffer, size, md5_state_, bigEndian); -} - -void RenderExtensionStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - minors_[((RenderExtensionMessage *) message) -> data.any.type] -> - updateIdentity(encodeBuffer, message, cachedMessage, channelCache); -} - -void RenderExtensionStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - minors_[((RenderExtensionMessage *) message) -> data.any.type] -> - updateIdentity(decodeBuffer, message, channelCache); -} - -void RenderExtensionStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - #ifdef WARNING - *logofs << name() << ": WARNING! Dump of identity not implemented.\n" - << logofs_flush; - #endif - - #endif -} - -// -// TODO: The following encoding and decoding functions -// could be generalized further, for example by passing -// the pointer to the data cache, the number of caches -// made available by the caller and the first cache to -// iterate through. -// - -void RenderMinorExtensionStore::encodeLongData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeLongData(buffer + offset, size - offset); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - offset - << " bytes of long data.\n" << logofs_flush; - #endif -} - -void RenderMinorExtensionStore::encodeIntData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeIntData(buffer + offset, size - offset); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - offset - << " bytes of int data.\n" << logofs_flush; - #endif -} - -void RenderMinorExtensionStore::encodeCharData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(buffer + offset, size - offset); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - offset - << " bytes of text data.\n" << logofs_flush; - #endif -} - -void RenderMinorExtensionStore::decodeLongData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeLongData(buffer + offset, size - offset); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - offset - << " bytes of long data.\n" << logofs_flush; - #endif -} - -void RenderMinorExtensionStore::decodeIntData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeIntData(buffer + offset, size - offset); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - offset - << " bytes of int data.\n" << logofs_flush; - #endif -} - -void RenderMinorExtensionStore::decodeCharData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(buffer + offset, size - offset); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - offset - << " bytes of text data.\n" << logofs_flush; - #endif -} - -void RenderMinorExtensionStore::parseIntData(const Message *message, const unsigned char *buffer, - unsigned int offset, unsigned int size, - int bigEndian) const -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_); - - for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2) - { - #ifdef DEBUG - *logofs << name() << ": Parsing int with i = " << i << " c = " - << c << ".\n" << logofs_flush; - #endif - - renderExtension -> data.any.short_data[c] = GetUINT(buffer + i, bigEndian); - - if (++c == 16) c = 0; - } -} - -void RenderMinorExtensionStore::unparseIntData(const Message *message, unsigned char *buffer, - unsigned int offset, unsigned int size, - int bigEndian) const -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_); - - for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2) - { - #ifdef DEBUG - *logofs << name() << ": Unparsing int with i = " << i << " c = " - << c << ".\n" << logofs_flush; - #endif - - PutUINT(renderExtension -> data.any.short_data[c], buffer + i, bigEndian); - - if (++c == 16) c = 0; - } -} - -void RenderMinorExtensionStore::updateIntData(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, unsigned int offset, - unsigned int size, ChannelCache *channelCache) const -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_); - - for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2) - { - #ifdef DEBUG - *logofs << name() << ": Encoding int update with i = " << i - << " c = " << c << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(renderExtension -> data.any.short_data[c], 16, - *clientCache -> renderDataCache[c]); - - cachedRenderExtension -> data.any.short_data[c] = - renderExtension -> data.any.short_data[c]; - - if (++c == 16) c = 0; - } -} - -void RenderMinorExtensionStore::updateIntData(DecodeBuffer &decodeBuffer, const Message *message, - unsigned int offset, unsigned int size, - ChannelCache *channelCache) const -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_); - - unsigned int value; - - for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2) - { - #ifdef DEBUG - *logofs << name() << ": Decoding int update with i = " << i - << " c = " << c << ".\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache -> renderDataCache[c]); - - renderExtension -> data.any.short_data[c] = value; - - if (++c == 16) c = 0; - } -} diff --git a/nxcomp/RenderExtension.h b/nxcomp/RenderExtension.h deleted file mode 100644 index aa9db1b55..000000000 --- a/nxcomp/RenderExtension.h +++ /dev/null @@ -1,504 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderExtension_H -#define RenderExtension_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Compression of data part is not enabled as -// most messages of this type are smaller than -// the current data size compression threshold. -// - -#define RENDEREXTENSION_ENABLE_CACHE 1 -#define RENDEREXTENSION_ENABLE_DATA 0 -#define RENDEREXTENSION_ENABLE_SPLIT 0 -#define RENDEREXTENSION_ENABLE_COMPRESS 0 - -#define RENDEREXTENSION_DATA_LIMIT 6144 -#define RENDEREXTENSION_DATA_OFFSET 36 - -#define RENDEREXTENSION_CACHE_THRESHOLD 20 -#define RENDEREXTENSION_CACHE_LOWER_THRESHOLD 10 - -#define RENDEREXTENSION_CACHE_SLOTS_IF_PROTO_STEP_7 8000 - -// -// Used to build the table of minor opcodes. -// - -#define RENDEREXTENSION_MINOR_OPCODE_LIMIT 256 - -// -// The message class. -// - -class RenderMinorExtensionStore; - -class RenderExtensionMessage : public Message -{ - friend class RenderExtensionStore; - friend class RenderMinorExtensionStore; - - friend class RenderGenericRequestStore; - friend class RenderCreatePictureStore; - friend class RenderChangePictureStore; - friend class RenderFreePictureStore; - friend class RenderPictureClipStore; - friend class RenderPictureTransformStore; - friend class RenderPictureFilterStore; - friend class RenderCreateGlyphSetStore; - friend class RenderFreeGlyphSetStore; - friend class RenderAddGlyphsStore; - friend class RenderCompositeStore; - friend class RenderCompositeGlyphsStore; - friend class RenderFillRectanglesStore; - friend class RenderTrapezoidsStore; - friend class RenderTrianglesStore; - - public: - - RenderExtensionMessage() - { - } - - ~RenderExtensionMessage() - { - } - - // - // We consider for this message a data offset of 36, - // that is size of the biggest among all requests of - // this extension. The most common requests have a - // specific differential encoding, others are simply - // encoded through an array of int or char caches. - // - - private: - - union - { - struct - { - unsigned char type; - - unsigned char char_data[32]; - unsigned short short_data[16]; - unsigned short long_data[8]; - } - any; - - struct - { - unsigned char type; - - unsigned int src_id; - unsigned int dst_id; - - unsigned int format; - unsigned int mask; - } - create_picture; - - struct - { - unsigned char type; - - unsigned int src_id; - } - change_picture; - - struct - { - unsigned char type; - - unsigned int src_id; - } - free_picture; - - struct - { - unsigned char type; - - unsigned int src_id; - - unsigned short src_x; - unsigned short src_y; - } - picture_clip; - - struct - { - unsigned char type; - - unsigned int src_id; - } - picture_transform; - - struct - { - unsigned char type; - - unsigned int src_id; - unsigned int num_elm; - } - picture_filter; - - struct - { - unsigned char type; - - unsigned int set_id; - unsigned int format; - } - create_set; - - struct - { - unsigned char type; - - unsigned int set_id; - } - free_set; - - struct - { - unsigned char type; - - unsigned int set_id; - unsigned int num_elm; - } - add_glyphs; - - struct - { - unsigned char type; - - unsigned char op; - - unsigned int src_id; - unsigned int msk_id; - unsigned int dst_id; - - unsigned short src_x; - unsigned short src_y; - - unsigned short msk_x; - unsigned short msk_y; - - unsigned short dst_x; - unsigned short dst_y; - - unsigned short width; - unsigned short height; - } - composite; - - struct - { - unsigned char type; - - unsigned char op; - - unsigned char num_elm; - - unsigned int src_id; - unsigned int dst_id; - - unsigned int format; - unsigned int set_id; - - unsigned short src_x; - unsigned short src_y; - - unsigned short offset_x; - unsigned short offset_y; - } - composite_glyphs; - - struct - { - unsigned char type; - - unsigned char op; - - unsigned int dst_id; - } - fill_rectangles; - - struct - { - unsigned char type; - - unsigned char op; - - unsigned int src_id; - unsigned int dst_id; - - unsigned int format; - - unsigned short src_x; - unsigned short src_y; - } - trapezoids; - - struct - { - unsigned char type; - - unsigned char op; - - unsigned int src_id; - unsigned int dst_id; - - unsigned int format; - - unsigned short src_x; - unsigned short src_y; - } - triangles; - - struct - { - unsigned char type; - - unsigned char op; - - unsigned char num_elm; - - unsigned int src_id; - unsigned int dst_id; - - unsigned int format; - unsigned int set_id; - - unsigned short src_x; - unsigned short src_y; - - unsigned short delta_x; - unsigned short delta_y; - } - composite_glyphs_compat; - - } - data; -}; - -class RenderExtensionStore : public MessageStore -{ - public: - - RenderExtensionStore(StaticCompressor *compressor); - - virtual ~RenderExtensionStore(); - - virtual const char *name() const - { - return "RenderExtension"; - } - - virtual unsigned char opcode() const - { - return opcode_; - } - - virtual unsigned int storage() const - { - return sizeof(RenderExtensionMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new RenderExtensionMessage(); - } - - virtual Message *create(const Message &message) const - { - return new RenderExtensionMessage((const RenderExtensionMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (RenderExtensionMessage *) message; - } - - // - // Determine if the message must be stored - // in the cache. - // - - virtual int validateMessage(const unsigned char *buffer, int size); - - // - // Since protocol step 5 these methods are - // specialized in their minor opcode stores. - // - - virtual int identitySize(const unsigned char *buffer, unsigned int size); - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; - - private: - - unsigned char opcode_; - - // - // Keep pointers to specialized classes. - // - - RenderMinorExtensionStore *minors_[RENDEREXTENSION_MINOR_OPCODE_LIMIT]; - - RenderMinorExtensionStore *generic_; -}; - -class RenderMinorExtensionStore : public MinorMessageStore -{ - public: - - virtual const char *name() const = 0; - - virtual int identitySize(const unsigned char *buffer, unsigned int size) = 0; - - virtual int encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const = 0; - - virtual int decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, unsigned char type, int bigEndian, - WriteBuffer *writeBuffer, ChannelCache *channelCache) const = 0; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const = 0; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const = 0; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const = 0; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const = 0; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, md5_state_t *md5_state, - int bigEndian) const = 0; - - // - // Internal encode and decode utilities. - // - - protected: - - void encodeLongData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - void encodeIntData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - void encodeCharData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - void decodeLongData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - void decodeIntData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - void decodeCharData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int offset, unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - /* - * The following methods are only used in the - * encoding of the generic render request. To - * be removed in future. - */ - - void parseIntData(const Message *message, const unsigned char *buffer, - unsigned int offset, unsigned int size, - int bigEndian) const; - - void unparseIntData(const Message *message, unsigned char *buffer, - unsigned int offset, unsigned int size, - int bigEndian) const; - - void updateIntData(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, unsigned int offset, - unsigned int size, ChannelCache *channelCache) const; - - void updateIntData(DecodeBuffer &decodeBuffer, const Message *message, - unsigned int offset, unsigned int size, - ChannelCache *channelCache) const; -}; - -#endif /* RenderExtension_H */ diff --git a/nxcomp/RenderFillRectangles.cpp b/nxcomp/RenderFillRectangles.cpp deleted file mode 100644 index a6f2c0e0d..000000000 --- a/nxcomp/RenderFillRectangles.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderFillRectangles.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - // - // The color structure (4 components, 2 bytes - // each) is included in the data part, so that - // it gets into the checksum. The rectangles - // are in the format x, y, width, height with - // 2 bytes per each field, so each request is - // at least 12 + 8 + 8 = 28 bytes long. - // - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> renderSrcPictureCache); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - decodeBuffer.decodeXidValue(value, clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - encodeIntData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - decodeIntData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.fill_rectangles.type = *(buffer + 1); - renderExtension -> data.fill_rectangles.op = *(buffer + 4); - - renderExtension -> data.fill_rectangles.dst_id = GetULONG(buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.fill_rectangles.type << " size is " - << renderExtension -> size_ << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.fill_rectangles.type; - *(buffer + 4) = renderExtension -> data.fill_rectangles.op; - - PutULONG(renderExtension -> data.fill_rectangles.dst_id, buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.fill_rectangles.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - md5_append(md5_state, buffer + 1, 4); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(renderExtension -> data.fill_rectangles.dst_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.fill_rectangles.dst_id = - renderExtension -> data.fill_rectangles.dst_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.fill_rectangles.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.fill_rectangles.dst_id, - clientCache -> renderSrcPictureCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.fill_rectangles.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderFillRectangles.h b/nxcomp/RenderFillRectangles.h deleted file mode 100644 index 9efaeffa8..000000000 --- a/nxcomp/RenderFillRectangles.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderFillRectangles_H -#define RenderFillRectangles_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderFillRectangles" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderFillRectanglesStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 12 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderFillRectangles_H */ diff --git a/nxcomp/RenderFreeGlyphSet.cpp b/nxcomp/RenderFreeGlyphSet.cpp deleted file mode 100644 index cf1261ac0..000000000 --- a/nxcomp/RenderFreeGlyphSet.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderFreeGlyphSet.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeFreeXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> renderFreeGlyphSetCache); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - unsigned int value; - - ClientCache *clientCache = (ClientCache *) channelCache; - - *(buffer + 1) = type; - - decodeBuffer.decodeFreeXidValue(value, - clientCache -> renderFreeGlyphSetCache); - - PutULONG(value, buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.free_set.type = *(buffer + 1); - - renderExtension -> data.free_set.set_id = GetULONG(buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.free_set.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.free_set.type; - - PutULONG(renderExtension -> data.free_set.set_id, buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.free_set.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - md5_append(md5_state, buffer + 1, 3); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeFreeXidValue(renderExtension -> data.free_set.set_id, - clientCache -> renderFreeGlyphSetCache); - - cachedRenderExtension -> data.free_set.set_id = - renderExtension -> data.free_set.set_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.free_set.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeFreeXidValue(renderExtension -> data.free_set.set_id, - clientCache -> renderFreeGlyphSetCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.free_set.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderFreeGlyphSet.h b/nxcomp/RenderFreeGlyphSet.h deleted file mode 100644 index 8817e8d99..000000000 --- a/nxcomp/RenderFreeGlyphSet.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderFreeGlyphSet_H -#define RenderFreeGlyphSet_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderFreeGlyphSet" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderFreeGlyphSetStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 8 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 0 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 0 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderFreeGlyphSet_H */ diff --git a/nxcomp/RenderFreePicture.cpp b/nxcomp/RenderFreePicture.cpp deleted file mode 100644 index 3d468624a..000000000 --- a/nxcomp/RenderFreePicture.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderFreePicture.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeFreeXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> renderFreePictureCache); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - unsigned int value; - - ClientCache *clientCache = (ClientCache *) channelCache; - - *(buffer + 1) = type; - - decodeBuffer.decodeFreeXidValue(value, - clientCache -> renderFreePictureCache); - - PutULONG(value, buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.free_picture.type = *(buffer + 1); - - renderExtension -> data.free_picture.src_id = GetULONG(buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.free_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.free_picture.type; - - PutULONG(renderExtension -> data.free_picture.src_id, buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.free_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - md5_append(md5_state, buffer + 1, 3); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeFreeXidValue(renderExtension -> data.free_picture.src_id, - clientCache -> renderFreePictureCache); - - cachedRenderExtension -> data.free_picture.src_id = - renderExtension -> data.free_picture.src_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.free_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeFreeXidValue(renderExtension -> data.free_picture.src_id, - clientCache -> renderFreePictureCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.free_picture.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderFreePicture.h b/nxcomp/RenderFreePicture.h deleted file mode 100644 index b50191a72..000000000 --- a/nxcomp/RenderFreePicture.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderFreePicture_H -#define RenderFreePicture_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderFreePicture" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderFreePictureStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 8 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 0 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 0 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderFreePicture_H */ diff --git a/nxcomp/RenderGenericRequest.cpp b/nxcomp/RenderGenericRequest.cpp deleted file mode 100644 index fc3210ba2..000000000 --- a/nxcomp/RenderGenericRequest.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "NXrender.h" - -#include "RenderExtension.h" -#include "RenderGenericRequest.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Here are the methods to handle the messages' content. -// - -int RenderGenericRequestStore::encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message.\n" - << logofs_flush; - - unsigned char type = *(buffer + 1); - - #endif - - encodeBuffer.encodeCachedValue(size >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef DEBUG - *logofs << name() << ": Encoding full unhandled message. " - << "Type is " << (unsigned int) type << " size is " - << size << ".\n" << logofs_flush; - #endif - - encodeIntData(encodeBuffer, buffer, 4, size, - bigEndian, clientCache); - - #ifdef DEBUG - *logofs << name() << ": Encoded full message.\n" - << logofs_flush; - #endif - - return 1; -} - -int RenderGenericRequestStore::decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, unsigned char type, int bigEndian, - WriteBuffer *writeBuffer, ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message.\n" - << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - size <<= 2; - - buffer = writeBuffer -> addMessage(size); - - *(buffer + 1) = type; - - #ifdef DEBUG - *logofs << name() << ": Decoding full unhandled message. " - << "Type is " << (unsigned int) type << " size is " - << size << ".\n" << logofs_flush; - #endif - - decodeIntData(decodeBuffer, buffer, 4, size, - bigEndian, clientCache); - - #ifdef DEBUG - *logofs << name() << ": Decoded full message.\n" - << logofs_flush; - #endif - - return 1; -} - -void RenderGenericRequestStore::encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ -} - -void RenderGenericRequestStore::decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ -} - -int RenderGenericRequestStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - #ifdef DEBUG - *logofs << name() << ": Parsing identity for message at " - << this << ".\n" << logofs_flush; - #endif - - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - unsigned char type = *(buffer + 1); - - renderExtension -> data.any.type = type; - - #ifdef DEBUG - *logofs << name() << ": Parsing unhandled identity. " - << "Type is " << (unsigned int) renderExtension -> data.any.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif - - parseIntData(message, buffer, 4, size, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int RenderGenericRequestStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - #ifdef DEBUG - *logofs << name() << ": Unparsing identity for message at " - << this << ".\n" << logofs_flush; - #endif - - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - unsigned char type = renderExtension -> data.any.type; - - *(buffer + 1) = type; - - #ifdef DEBUG - *logofs << name() << ": Unparsing unhandled identity. " - << "Type is " << (unsigned int) renderExtension -> data.any.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif - - unparseIntData(message, buffer, 4, size, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void RenderGenericRequestStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, md5_state_t *md5_state, - int bigEndian) const -{ - // - // Include the minor opcode in the checksum. - // Because the data offset can be beyond the - // real end of the message, we need to include - // the size or we will match any message whose - // size is less or equal to the data offset. - // - - md5_append(md5_state, buffer + 1, 3); -} - -void RenderGenericRequestStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - // - // Encode the variant part. - // - - #ifdef DEBUG - *logofs << name() << ": Updating identity for message at " - << this << ".\n" << logofs_flush; - #endif - - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - #ifdef DEBUG - *logofs << name() << ": Encoding unhandled update. " - << "Type is " << (unsigned int) renderExtension -> data.any.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif - - updateIntData(encodeBuffer, message, cachedMessage, 4, - renderExtension -> size_, channelCache); - - #ifdef DEBUG - *logofs << name() << ": Updated identity for message at " - << this << ".\n" << logofs_flush; - #endif -} - -void RenderGenericRequestStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - #ifdef DEBUG - *logofs << name() << ": Updating identity for message at " - << this << ".\n" << logofs_flush; - #endif - - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - #ifdef DEBUG - *logofs << name() << ": Decoding unhandled update. " - << "Type is " << (unsigned int) renderExtension -> data.any.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif - - updateIntData(decodeBuffer, message, 4, - renderExtension -> size_, channelCache); - - #ifdef DEBUG - *logofs << name() << ": Updated identity for message at " - << this << ".\n" << logofs_flush; - #endif -} diff --git a/nxcomp/RenderGenericRequest.h b/nxcomp/RenderGenericRequest.h deleted file mode 100644 index fdf5ca876..000000000 --- a/nxcomp/RenderGenericRequest.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderGenericRequest_H -#define RenderGenericRequest_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -class RenderGenericRequestStore : public RenderMinorExtensionStore -{ - public: - - virtual const char *name() const - { - return "RenderGenericRequest"; - } - - virtual int identitySize(const unsigned char *buffer, unsigned int size) - { - return RENDEREXTENSION_DATA_OFFSET; - } - - virtual int encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, unsigned char type, int bigEndian, - WriteBuffer *writeBuffer, ChannelCache *channelCache) const; - - virtual void encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual void decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, md5_state_t *md5_state, - int bigEndian) const; -}; - -#endif /* RenderGenericRequest_H */ diff --git a/nxcomp/RenderMinorExtensionHeaders.h b/nxcomp/RenderMinorExtensionHeaders.h deleted file mode 100644 index b7f6efc5a..000000000 --- a/nxcomp/RenderMinorExtensionHeaders.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderMinorExtensionHeaders_H -#define RenderMinorExtensionHeaders_H - -#include "NXrender.h" - -#include "Message.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -#include "RenderExtension.h" - -#endif /* RenderMinorExtensionHeaders_H */ diff --git a/nxcomp/RenderMinorExtensionMethods.h b/nxcomp/RenderMinorExtensionMethods.h deleted file mode 100644 index d272337e0..000000000 --- a/nxcomp/RenderMinorExtensionMethods.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// This file is included multiple times, -// one for each message inheriting the -// parent class. -// - -public: - -#if MESSAGE_HAS_SIZE - -virtual void encodeSize(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - -virtual void decodeSize(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, unsigned char type, int bigEndian, - WriteBuffer *writeBuffer, ChannelCache *channelCache) const; - -#endif - -#if MESSAGE_HAS_DATA - -virtual void encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - -virtual void decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, - unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - -#endif - -virtual int encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - -virtual int decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, unsigned char type, int bigEndian, - WriteBuffer *writeBuffer, ChannelCache *channelCache) const; - -virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - -virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - -virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - -virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - -virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, md5_state_t *md5_state, - int bigEndian) const; diff --git a/nxcomp/RenderMinorExtensionTags.h b/nxcomp/RenderMinorExtensionTags.h deleted file mode 100644 index c24a99638..000000000 --- a/nxcomp/RenderMinorExtensionTags.h +++ /dev/null @@ -1,194 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderMinorExtensionTags_H -#define RenderMinorExtensionTags_H - -// -// Set in the message header file. -// - -#if MESSAGE_HAS_SIZE - -#define MESSAGE_ENCODE_SIZE encodeSize(encodeBuffer, buffer, size, bigEndian, channelCache) -#define MESSAGE_DECODE_SIZE decodeSize(decodeBuffer, buffer, size, type, bigEndian, writeBuffer, channelCache) - -#else - -#define MESSAGE_ENCODE_SIZE -#define MESSAGE_DECODE_SIZE size = MESSAGE_OFFSET; buffer = writeBuffer -> addMessage(size); - -#endif - -#if MESSAGE_HAS_DATA - -#define MESSAGE_ENCODE_DATA encodeData(encodeBuffer, buffer, size, bigEndian, channelCache) -#define MESSAGE_DECODE_DATA decodeData(decodeBuffer, buffer, size, bigEndian, channelCache) - -#else - -#define MESSAGE_ENCODE_DATA -#define MESSAGE_DECODE_DATA - -#endif - -// -// Prologue an epilogue of the message -// handling functions. -// - -#define MESSAGE_BEGIN_ENCODE_SIZE \ -\ -void MESSAGE_STORE::encodeSize(EncodeBuffer &encodeBuffer, const unsigned char *buffer, \ - const unsigned int size, int bigEndian, \ - ChannelCache *channelCache) const \ -{ - -#define MESSAGE_END_ENCODE_SIZE \ -\ -} - -#define MESSAGE_BEGIN_DECODE_SIZE \ -\ -void MESSAGE_STORE::decodeSize(DecodeBuffer &decodeBuffer, unsigned char *&buffer, \ - unsigned int &size, unsigned char type, int bigEndian, \ - WriteBuffer *writeBuffer, ChannelCache *channelCache) const \ -{ - -#define MESSAGE_END_DECODE_SIZE \ -\ -} - -#define MESSAGE_BEGIN_ENCODE_MESSAGE \ -\ -int MESSAGE_STORE::encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, \ - const unsigned int size, int bigEndian, \ - ChannelCache *channelCache) const \ -{ \ - MESSAGE_ENCODE_SIZE; - - -#define MESSAGE_END_ENCODE_MESSAGE \ -\ - MESSAGE_ENCODE_DATA; \ -\ - return 1; \ -} - -#define MESSAGE_BEGIN_DECODE_MESSAGE \ -\ -int MESSAGE_STORE::decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, \ - unsigned int &size, unsigned char type, int bigEndian, \ - WriteBuffer *writeBuffer, ChannelCache *channelCache) const \ -{ \ - MESSAGE_DECODE_SIZE; - - -#define MESSAGE_END_DECODE_MESSAGE \ -\ - MESSAGE_DECODE_DATA; \ -\ - return 1; \ -} - -#define MESSAGE_BEGIN_ENCODE_DATA \ -\ -void MESSAGE_STORE::encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, \ - unsigned int size, int bigEndian, \ - ChannelCache *channelCache) const \ -{ - -#define MESSAGE_END_ENCODE_DATA \ -\ -} - -#define MESSAGE_BEGIN_DECODE_DATA \ -\ -void MESSAGE_STORE::decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, \ - unsigned int size, int bigEndian, \ - ChannelCache *channelCache) const \ -{ - -#define MESSAGE_END_DECODE_DATA \ -\ -} - -#define MESSAGE_BEGIN_PARSE_IDENTITY \ -\ -int MESSAGE_STORE::parseIdentity(Message *message, const unsigned char *buffer, \ - unsigned int size, int bigEndian) const \ -{ - -#define MESSAGE_END_PARSE_IDENTITY \ -\ - return 1; \ -\ -} - -#define MESSAGE_BEGIN_UNPARSE_IDENTITY \ -\ -int MESSAGE_STORE::unparseIdentity(const Message *message, unsigned char *buffer, \ - unsigned int size, int bigEndian) const \ -{ - -#define MESSAGE_END_UNPARSE_IDENTITY \ -\ - return 1; \ -\ -} - -#define MESSAGE_BEGIN_IDENTITY_CHECKSUM \ -\ -void MESSAGE_STORE::identityChecksum(const Message *message, const unsigned char *buffer, \ - unsigned int size, md5_state_t *md5_state, \ - int bigEndian) const \ -{ - -#define MESSAGE_END_IDENTITY_CHECKSUM \ -\ -} - -#define MESSAGE_BEGIN_ENCODE_UPDATE \ -\ -void MESSAGE_STORE::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, \ - const Message *cachedMessage, \ - ChannelCache *channelCache) const \ -{ - -#define MESSAGE_END_ENCODE_UPDATE \ -\ -} - -#define MESSAGE_BEGIN_DECODE_UPDATE \ -\ -void MESSAGE_STORE::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, \ - ChannelCache *channelCache) const \ -{ - -#define MESSAGE_END_DECODE_UPDATE \ -\ -} - -#endif /* RenderMinorExtensionTags_H */ diff --git a/nxcomp/RenderPictureClip.cpp b/nxcomp/RenderPictureClip.cpp deleted file mode 100644 index 32d526c81..000000000 --- a/nxcomp/RenderPictureClip.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderPictureClip.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - // - // The data is constituted by a number of - // rectangles. Each rectangle is in the - // format x, y, width, height with 2 bytes - // per each field, so each request is at - // least 12 + 8 = 20 bytes long. - // - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> renderSrcPictureCache); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 8, bigEndian), - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 10, bigEndian), - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeXidValue(value, - clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 4, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - PutUINT(clientCache -> renderLastX, buffer + 8, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - PutUINT(clientCache -> renderLastY, buffer + 10, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - encodeIntData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - decodeIntData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.picture_clip.type = *(buffer + 1); - - renderExtension -> data.picture_clip.src_id = GetULONG(buffer + 4, bigEndian); - - renderExtension -> data.picture_clip.src_x = GetUINT(buffer + 8, bigEndian); - renderExtension -> data.picture_clip.src_y = GetUINT(buffer + 10, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.picture_clip.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.picture_clip.type; - - PutULONG(renderExtension -> data.picture_clip.src_id, buffer + 4, bigEndian); - - PutUINT(renderExtension -> data.picture_clip.src_x, buffer + 8, bigEndian); - PutUINT(renderExtension -> data.picture_clip.src_y, buffer + 10, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.picture_clip.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - // - // Encode the picture id and the - // source x and y differentially. - // - - md5_append(md5_state, buffer + 1, 3); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(renderExtension -> data.picture_clip.src_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.picture_clip.src_id = - renderExtension -> data.picture_clip.src_id; - - // - // The source x and y coordinates are - // encoded as differerences in respect - // to the previous cached value. - // - - unsigned int value; - unsigned int previous; - - value = renderExtension -> data.picture_clip.src_x; - previous = cachedRenderExtension -> data.picture_clip.src_x; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderXCache, 11); - - cachedRenderExtension -> data.picture_clip.src_x = value; - - value = renderExtension -> data.picture_clip.src_y; - previous = cachedRenderExtension -> data.picture_clip.src_y; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderYCache, 11); - - cachedRenderExtension -> data.picture_clip.src_y = value; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.picture_clip.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.picture_clip.src_id, - clientCache -> renderSrcPictureCache); - - unsigned int value; - unsigned int previous; - - previous = renderExtension -> data.picture_clip.src_x; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderXCache, 11); - - renderExtension -> data.picture_clip.src_x = value; - - previous = renderExtension -> data.picture_clip.src_y; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderYCache, 11); - - renderExtension -> data.picture_clip.src_y = value; - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.picture_clip.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderPictureClip.h b/nxcomp/RenderPictureClip.h deleted file mode 100644 index bd811dfcd..000000000 --- a/nxcomp/RenderPictureClip.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderPictureClip_H -#define RenderPictureClip_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderPictureClip" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderPictureClipStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 12 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderPictureClip_H */ diff --git a/nxcomp/RenderPictureFilter.cpp b/nxcomp/RenderPictureFilter.cpp deleted file mode 100644 index 9598601c2..000000000 --- a/nxcomp/RenderPictureFilter.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderPictureFilter.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding value " - << ((size - MESSAGE_OFFSET) >> 2) << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << size - << ".\n" << logofs_flush; - #endif - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> renderSrcPictureCache); - - encodeBuffer.encodeCachedValue(GetUINT(buffer + 8, bigEndian), 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeXidValue(value, - clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 4, bigEndian); - - decodeBuffer.decodeCachedValue(value, 16, - clientCache -> renderLengthCache, 5); - - PutUINT(value, buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - encodeCharData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - decodeCharData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.picture_filter.type = *(buffer + 1); - - renderExtension -> data.picture_filter.src_id = GetULONG(buffer + 4, bigEndian); - renderExtension -> data.picture_filter.num_elm = GetUINT(buffer + 8, bigEndian); - - // - // Clean the padding bytes. This - // should be the purpose of the - // filter. - // - - #ifdef TEST - *logofs << name() << ": Cleaning " - << RoundUp4(renderExtension -> data.picture_filter.num_elm) - - renderExtension -> data.picture_filter.num_elm << " bytes " - << "at offset " << MESSAGE_OFFSET + renderExtension -> - data.picture_filter.num_elm << " with " << renderExtension -> - data.picture_filter.num_elm << " elements and size " - << renderExtension -> size_ << ".\n" << logofs_flush; - #endif - - if (size >= MESSAGE_OFFSET + renderExtension -> - data.picture_filter.num_elm) - { - unsigned char *next = (unsigned char *) buffer + - MESSAGE_OFFSET + renderExtension -> - data.picture_filter.num_elm; - - while (next < buffer + size) - { - *next++ = '\0'; - } - } - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.picture_filter.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.picture_filter.type; - - PutULONG(renderExtension -> data.picture_filter.src_id, buffer + 4, bigEndian); - PutUINT(renderExtension -> data.picture_filter.num_elm, buffer + 8, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.picture_filter.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - // - // Include the length of the filter name - // in the checksum. - // - - md5_append(md5_state, buffer + 1, 3); - md5_append(md5_state, buffer + 8, 2); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(renderExtension -> data.picture_filter.src_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.picture_filter.src_id = - renderExtension -> data.picture_filter.src_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.picture_filter.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.picture_filter.src_id, - clientCache -> renderSrcPictureCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.picture_filter.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderPictureFilter.h b/nxcomp/RenderPictureFilter.h deleted file mode 100644 index a3e37538b..000000000 --- a/nxcomp/RenderPictureFilter.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderPictureFilter_H -#define RenderPictureFilter_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderPictureFilter" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderPictureFilterStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 12 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderPictureFilter_H */ diff --git a/nxcomp/RenderPictureTransform.cpp b/nxcomp/RenderPictureTransform.cpp deleted file mode 100644 index 053748bd3..000000000 --- a/nxcomp/RenderPictureTransform.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderPictureTransform.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - // - // Size is always 44. The identity size - // is set to 8, so we encode the 36 bytes - // of the transformation matrix as our - // data. - // -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - size = MESSAGE_OFFSET + 36; - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), - clientCache -> renderSrcPictureCache); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeXidValue(value, - clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.picture_transform.type = *(buffer + 1); - - renderExtension -> data.picture_transform.src_id = GetULONG(buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.picture_transform.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.picture_transform.type; - - PutULONG(renderExtension -> data.picture_transform.src_id, buffer + 4, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.picture_transform.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - md5_append(md5_state, buffer + 1, 3); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(renderExtension -> data.picture_transform.src_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.picture_transform.src_id = - renderExtension -> data.picture_transform.src_id; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.picture_transform.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.picture_transform.src_id, - clientCache -> renderSrcPictureCache); - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.picture_transform.type - << " size is " << renderExtension -> size_ << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderPictureTransform.h b/nxcomp/RenderPictureTransform.h deleted file mode 100644 index 649cd05d3..000000000 --- a/nxcomp/RenderPictureTransform.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderPictureTransform_H -#define RenderPictureTransform_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderPictureTransform" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderPictureTransformStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 8 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return MESSAGE_OFFSET; - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderPictureTransform_H */ diff --git a/nxcomp/RenderTrapezoids.cpp b/nxcomp/RenderTrapezoids.cpp deleted file mode 100644 index 85f4cad05..000000000 --- a/nxcomp/RenderTrapezoids.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderTrapezoids.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - // - // The trapezoid data is made up of a structure - // containing a top and bottom coordinate in 4 - // bytes format, plus two lines, each represent- - // ed as four points in 4 bytes format. Thus - // each trapezoid is 4 * 2 + (4 * 4) * 2 = 40 - // bytes. Bytes are all padded to an long int, - // so we don't need to clean the message. - // - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding value " - << ((size - MESSAGE_OFFSET) >> 2) << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << size - << ".\n" << logofs_flush; - #endif - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> renderSrcPictureCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), - clientCache -> renderDstPictureCache); - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 32, - clientCache -> renderFormatCache); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 20, bigEndian), - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 22, bigEndian), - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - decodeBuffer.decodeXidValue(value, - clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 8, bigEndian); - - decodeBuffer.decodeXidValue(value, - clientCache -> renderDstPictureCache); - - PutULONG(value, buffer + 12, bigEndian); - - decodeBuffer.decodeCachedValue(value, 32, - clientCache -> renderFormatCache); - - PutULONG(value, buffer + 16, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - PutUINT(clientCache -> renderLastX, buffer + 20, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - PutUINT(clientCache -> renderLastY, buffer + 22, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - if (size > MESSAGE_OFFSET) - { - encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - } - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of text data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - if (size > MESSAGE_OFFSET) - { - decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - } - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.trapezoids.type = *(buffer + 1); - renderExtension -> data.trapezoids.op = *(buffer + 4); - - renderExtension -> data.trapezoids.src_id = GetULONG(buffer + 8, bigEndian); - renderExtension -> data.trapezoids.dst_id = GetULONG(buffer + 12, bigEndian); - - renderExtension -> data.trapezoids.format = GetULONG(buffer + 16, bigEndian); - - renderExtension -> data.trapezoids.src_x = GetUINT(buffer + 20, bigEndian); - renderExtension -> data.trapezoids.src_y = GetUINT(buffer + 22, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.trapezoids.type - << " size is " << renderExtension -> size_ << " identity size " - << renderExtension -> i_size_ << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.trapezoids.type; - *(buffer + 4) = renderExtension -> data.trapezoids.op; - - PutULONG(renderExtension -> data.trapezoids.src_id, buffer + 8, bigEndian); - PutULONG(renderExtension -> data.trapezoids.dst_id, buffer + 12, bigEndian); - - PutULONG(renderExtension -> data.trapezoids.format, buffer + 16, bigEndian); - - PutUINT(renderExtension -> data.trapezoids.src_x, buffer + 20, bigEndian); - PutUINT(renderExtension -> data.trapezoids.src_y, buffer + 22, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.trapezoids.type - << " size is " << renderExtension -> size_ << " identity size " - << renderExtension -> i_size_ << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - // - // Include minor opcode, size and the - // operator in the identity. - // - - md5_append(md5_state, buffer + 1, 4); - - // - // Also include the format but not the - // x and y source. - // - - md5_append(md5_state, buffer + 16, 4); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(renderExtension -> data.trapezoids.src_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.trapezoids.src_id = - renderExtension -> data.trapezoids.src_id; - - encodeBuffer.encodeXidValue(renderExtension -> data.trapezoids.dst_id, - clientCache -> renderDstPictureCache); - - cachedRenderExtension -> data.trapezoids.dst_id = - renderExtension -> data.trapezoids.dst_id; - - // - // The source x and y coordinates are - // encoded as differerences in respect - // to the previous cached value. - // - - unsigned int value; - unsigned int previous; - - value = renderExtension -> data.trapezoids.src_x; - previous = cachedRenderExtension -> data.trapezoids.src_x; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderXCache, 11); - - cachedRenderExtension -> data.trapezoids.src_x = value; - - value = renderExtension -> data.trapezoids.src_y; - previous = cachedRenderExtension -> data.trapezoids.src_y; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderYCache, 11); - - cachedRenderExtension -> data.trapezoids.src_y = value; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.trapezoids.type - << " size is " << renderExtension -> size_ << " source x " - << renderExtension -> data.trapezoids.src_x << " y " - << renderExtension -> data.trapezoids.src_y << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.trapezoids.src_id, - clientCache -> renderSrcPictureCache); - - decodeBuffer.decodeXidValue(renderExtension -> data.trapezoids.dst_id, - clientCache -> renderDstPictureCache); - - unsigned int value; - unsigned int previous; - - previous = renderExtension -> data.trapezoids.src_x; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderXCache, 11); - - renderExtension -> data.trapezoids.src_x = value; - - previous = renderExtension -> data.trapezoids.src_y; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderYCache, 11); - - renderExtension -> data.trapezoids.src_y = value; - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.trapezoids.type - << " size is " << renderExtension -> size_ << " source x " - << renderExtension -> data.trapezoids.src_x << " y " - << renderExtension -> data.trapezoids.src_y << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderTrapezoids.h b/nxcomp/RenderTrapezoids.h deleted file mode 100644 index faf524c76..000000000 --- a/nxcomp/RenderTrapezoids.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderTrapezoids_H -#define RenderTrapezoids_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderTrapezoids" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderTrapezoidsStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 24 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return (size >= MESSAGE_OFFSET ? MESSAGE_OFFSET : size); - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderTrapezoids_H */ diff --git a/nxcomp/RenderTriangles.cpp b/nxcomp/RenderTriangles.cpp deleted file mode 100644 index 746a8e278..000000000 --- a/nxcomp/RenderTriangles.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -// -// Include the template for -// this message class. -// - -#include "RenderTriangles.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#include MESSAGE_TAGS - -// -// Message handling methods. -// - -MESSAGE_BEGIN_ENCODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding value " - << ((size - MESSAGE_OFFSET) >> 2) << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, - clientCache -> renderLengthCache, 5); - - #ifdef TEST - *logofs << name() << ": Encoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_SIZE - -MESSAGE_BEGIN_DECODE_SIZE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(size, 16, - clientCache -> renderLengthCache, 5); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << size - << ".\n" << logofs_flush; - #endif - - size = MESSAGE_OFFSET + (size << 2); - - buffer = writeBuffer -> addMessage(size); - - #ifdef TEST - *logofs << name() << ": Decoded size with value " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_SIZE - -MESSAGE_BEGIN_ENCODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), - clientCache -> renderSrcPictureCache); - - encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), - clientCache -> renderDstPictureCache); - - encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 32, - clientCache -> renderFormatCache); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 20, bigEndian), - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 22, bigEndian), - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - #ifdef TEST - *logofs << name() << ": Encoded message. Type is " - << (unsigned int) *(buffer + 1) << " size is " - << size << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_MESSAGE - -MESSAGE_BEGIN_DECODE_MESSAGE -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - *(buffer + 1) = type; - - decodeBuffer.decodeCachedValue(*(buffer + 4), 8, - clientCache -> renderOpCache); - - decodeBuffer.decodeXidValue(value, - clientCache -> renderSrcPictureCache); - - PutULONG(value, buffer + 8, bigEndian); - - decodeBuffer.decodeXidValue(value, - clientCache -> renderDstPictureCache); - - PutULONG(value, buffer + 12, bigEndian); - - decodeBuffer.decodeCachedValue(value, 32, - clientCache -> renderFormatCache); - - PutULONG(value, buffer + 16, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastX, 16, - clientCache -> renderXCache, 11); - - PutUINT(clientCache -> renderLastX, buffer + 20, bigEndian); - - decodeBuffer.decodeDiffCachedValue(value, - clientCache -> renderLastY, 16, - clientCache -> renderYCache, 11); - - PutUINT(clientCache -> renderLastY, buffer + 22, bigEndian); - - #ifdef TEST - *logofs << name() << ": Decoded message. Type is " - << (unsigned int) type << " size is " << size - << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_MESSAGE - -MESSAGE_BEGIN_ENCODE_DATA -{ - if (size > MESSAGE_OFFSET) - { - encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - } - - #ifdef TEST - *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET - << " bytes of text data.\n" << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_DATA - -MESSAGE_BEGIN_DECODE_DATA -{ - if (size > MESSAGE_OFFSET) - { - decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, - size, bigEndian, channelCache); - } - - #ifdef TEST - *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET - << " bytes of data.\n" << logofs_flush; - #endif -} -MESSAGE_END_DECODE_DATA - -MESSAGE_BEGIN_PARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - renderExtension -> data.triangles.type = *(buffer + 1); - renderExtension -> data.triangles.op = *(buffer + 4); - - renderExtension -> data.triangles.src_id = GetULONG(buffer + 8, bigEndian); - renderExtension -> data.triangles.dst_id = GetULONG(buffer + 12, bigEndian); - - renderExtension -> data.triangles.format = GetULONG(buffer + 16, bigEndian); - - renderExtension -> data.triangles.src_x = GetUINT(buffer + 20, bigEndian); - renderExtension -> data.triangles.src_y = GetUINT(buffer + 22, bigEndian); - - #ifdef TEST - *logofs << name() << ": Parsed identity. Type is " - << (unsigned int) renderExtension -> data.triangles.type - << " size is " << renderExtension -> size_ << " identity size " - << renderExtension -> i_size_ << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_PARSE_IDENTITY - -MESSAGE_BEGIN_UNPARSE_IDENTITY -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - *(buffer + 1) = renderExtension -> data.triangles.type; - *(buffer + 4) = renderExtension -> data.triangles.op; - - PutULONG(renderExtension -> data.triangles.src_id, buffer + 8, bigEndian); - PutULONG(renderExtension -> data.triangles.dst_id, buffer + 12, bigEndian); - - PutULONG(renderExtension -> data.triangles.format, buffer + 16, bigEndian); - - PutUINT(renderExtension -> data.triangles.src_x, buffer + 20, bigEndian); - PutUINT(renderExtension -> data.triangles.src_y, buffer + 22, bigEndian); - - #ifdef TEST - *logofs << name() << ": Unparsed identity. Type is " - << (unsigned int) renderExtension -> data.triangles.type - << " size is " << renderExtension -> size_ << " identity size " - << renderExtension -> i_size_ << ".\n" << logofs_flush; - #endif -} -MESSAGE_END_UNPARSE_IDENTITY - -MESSAGE_BEGIN_IDENTITY_CHECKSUM -{ - // - // Include minor opcode, size and the - // operator in the identity. - // - - md5_append(md5_state, buffer + 1, 4); - - // - // Also include the format but not the - // x and y source. - // - - md5_append(md5_state, buffer + 16, 4); -} -MESSAGE_END_IDENTITY_CHECKSUM - -MESSAGE_BEGIN_ENCODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeXidValue(renderExtension -> data.triangles.src_id, - clientCache -> renderSrcPictureCache); - - cachedRenderExtension -> data.triangles.src_id = - renderExtension -> data.triangles.src_id; - - encodeBuffer.encodeXidValue(renderExtension -> data.triangles.dst_id, - clientCache -> renderDstPictureCache); - - cachedRenderExtension -> data.triangles.dst_id = - renderExtension -> data.triangles.dst_id; - - // - // The source x and y coordinates are - // encoded as differerences in respect - // to the previous cached value. - // - - unsigned int value; - unsigned int previous; - - value = renderExtension -> data.triangles.src_x; - previous = cachedRenderExtension -> data.triangles.src_x; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderXCache, 11); - - cachedRenderExtension -> data.triangles.src_x = value; - - value = renderExtension -> data.triangles.src_y; - previous = cachedRenderExtension -> data.triangles.src_y; - - encodeBuffer.encodeDiffCachedValue(value, previous, 16, - clientCache -> renderYCache, 11); - - cachedRenderExtension -> data.triangles.src_y = value; - - #ifdef TEST - *logofs << name() << ": Encoded update. Type is " - << (unsigned int) renderExtension -> data.triangles.type - << " size is " << renderExtension -> size_ << " source x " - << renderExtension -> data.triangles.src_x << " y " - << renderExtension -> data.triangles.src_y << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_ENCODE_UPDATE - -MESSAGE_BEGIN_DECODE_UPDATE -{ - RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeXidValue(renderExtension -> data.triangles.src_id, - clientCache -> renderSrcPictureCache); - - decodeBuffer.decodeXidValue(renderExtension -> data.triangles.dst_id, - clientCache -> renderDstPictureCache); - - unsigned int value; - unsigned int previous; - - previous = renderExtension -> data.triangles.src_x; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderXCache, 11); - - renderExtension -> data.triangles.src_x = value; - - previous = renderExtension -> data.triangles.src_y; - - decodeBuffer.decodeDiffCachedValue(value, previous, 16, - clientCache -> renderYCache, 11); - - renderExtension -> data.triangles.src_y = value; - - #ifdef TEST - *logofs << name() << ": Decoded update. Type is " - << (unsigned int) renderExtension -> data.triangles.type - << " size is " << renderExtension -> size_ << " source x " - << renderExtension -> data.triangles.src_x << " y " - << renderExtension -> data.triangles.src_y << ".\n" - << logofs_flush; - #endif -} -MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/RenderTriangles.h b/nxcomp/RenderTriangles.h deleted file mode 100644 index d73efb7b8..000000000 --- a/nxcomp/RenderTriangles.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef RenderTriangles_H -#define RenderTriangles_H - -// -// Define the characteristics -// of this message class here. -// - -#undef MESSAGE_NAME -#define MESSAGE_NAME "RenderTriangles" - -#undef MESSAGE_STORE -#define MESSAGE_STORE RenderTrianglesStore - -#undef MESSAGE_CLASS -#define MESSAGE_CLASS RenderMinorExtensionStore - -#undef MESSAGE_METHODS -#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" - -#undef MESSAGE_HEADERS -#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" - -#undef MESSAGE_TAGS -#define MESSAGE_TAGS "RenderMinorExtensionTags.h" - -#undef MESSAGE_OFFSET -#define MESSAGE_OFFSET 24 - -#undef MESSAGE_HAS_SIZE -#define MESSAGE_HAS_SIZE 1 - -#undef MESSAGE_HAS_DATA -#define MESSAGE_HAS_DATA 1 - -#undef MESSAGE_HAS_FILTER -#define MESSAGE_HAS_FILTER 0 - -// -// Declare the message class. -// - -#include MESSAGE_HEADERS - -class MESSAGE_STORE : public MESSAGE_CLASS -{ - public: - - virtual const char *name() const - { - return MESSAGE_NAME; - } - - virtual int identitySize(const unsigned char *buffer, - unsigned int size) - { - return (size >= MESSAGE_OFFSET ? MESSAGE_OFFSET : size); - } - - #include MESSAGE_METHODS -}; - -#endif /* RenderTriangles_H */ diff --git a/nxcomp/Rgb.cpp b/nxcomp/Rgb.cpp deleted file mode 100644 index 8946a9fc8..000000000 --- a/nxcomp/Rgb.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Rgb.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -int UnpackRgb(T_geometry *geometry, unsigned char method, unsigned char *src_data, - int src_size, int dst_bpp, int dst_width, int dst_height, - unsigned char *dst_data, int dst_size) -{ - if (*src_data == 0) - { - if (dst_size != src_size - 1) - { - #ifdef TEST - *logofs << "UnpackRgb: PANIC! Invalid destination size " - << dst_size << " with source " << src_size - << ".\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef TEST - *logofs << "UnpackRgb: Expanding " << src_size - 1 - << " bytes of plain RGB data.\n" << logofs_flush; - #endif - - memcpy(dst_data, src_data + 1, src_size - 1); - - return 1; - } - - unsigned int check_size = dst_size; - - int result = ZDecompress(&unpackStream, dst_data, &check_size, - src_data + 1, src_size - 1); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "UnpackRgb: PANIC! Failure decompressing RGB data. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decompressing RGB data. " - << "Error is '" << zError(result) << "'.\n"; - - return -1; - } - else if (check_size != (unsigned int) dst_size) - { - #ifdef PANIC - *logofs << "UnpackRgb: PANIC! Size mismatch in RGB data. " - << "Resulting size is " << check_size << " with " - << "expected size " << dst_size << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Size mismatch in RGB data. " - << "Resulting size is " << check_size << " with " - << "expected size " << dst_size << ".\n"; - - return -1; - } - - #ifdef TEST - *logofs << "UnpackRgb: Decompressed " << src_size - 1 - << " bytes to " << dst_size << " bytes of RGB data.\n" - << logofs_flush; - #endif - - return 1; -} diff --git a/nxcomp/Rgb.h b/nxcomp/Rgb.h deleted file mode 100644 index ec088dd1b..000000000 --- a/nxcomp/Rgb.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Rgb_H -#define Rgb_H - -#include "Unpack.h" - -int UnpackRgb(T_geometry *geometry, unsigned char method, - unsigned char *src_data, int src_size, int dst_bpp, - int dst_width, int dst_height, unsigned char *dst_data, - int dst_size); - -#endif /* Rgb_H */ diff --git a/nxcomp/Rle.cpp b/nxcomp/Rle.cpp deleted file mode 100644 index 92fc7785a..000000000 --- a/nxcomp/Rle.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Rle.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -int UnpackRle(T_geometry *geometry, unsigned char method, unsigned char *src_data, - int src_size, int dst_bpp, int dst_width, int dst_height, - unsigned char *dst_data, int dst_size) -{ - if (*src_data == 0) - { - if (dst_size != src_size - 1) - { - #ifdef TEST - *logofs << "UnpackRle: PANIC! Invalid destination size " - << dst_size << " with source " << src_size - << ".\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef TEST - *logofs << "UnpackRle: Expanding " << src_size - 1 - << " bytes of plain RLE data.\n" << logofs_flush; - #endif - - memcpy(dst_data, src_data + 1, src_size - 1); - - return 1; - } - - unsigned int check_size = dst_size; - - int result = ZDecompress(&unpackStream, dst_data, &check_size, - src_data + 1, src_size - 1); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "UnpackRle: PANIC! Failure decompressing RLE data. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decompressing RLE data. " - << "Error is '" << zError(result) << "'.\n"; - - return -1; - } - else if (check_size != (unsigned int) dst_size) - { - #ifdef PANIC - *logofs << "UnpackRle: PANIC! Size mismatch in RLE data. " - << "Resulting size is " << check_size << " with " - << "expected size " << dst_size << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Size mismatch in RLE data. " - << "Resulting size is " << check_size << " with " - << "expected size " << dst_size << ".\n"; - - return -1; - } - - #ifdef TEST - *logofs << "UnpackRle: Decompressed " << src_size - 1 - << " bytes to " << dst_size << " bytes of RLE data.\n" - << logofs_flush; - #endif - - return 1; -} diff --git a/nxcomp/Rle.h b/nxcomp/Rle.h deleted file mode 100644 index cc5dab0e8..000000000 --- a/nxcomp/Rle.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Rle_H -#define Rle_H - -#include "Unpack.h" - -int UnpackRle(T_geometry *geometry, unsigned char method, - unsigned char *src_data, int src_size, int dst_bpp, - int dst_width, int dst_height, unsigned char *dst_data, - int dst_size); - -#endif /* Rle_H */ diff --git a/nxcomp/SendEvent.cpp b/nxcomp/SendEvent.cpp deleted file mode 100644 index 8658c1835..000000000 --- a/nxcomp/SendEvent.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "SendEvent.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "IntCache.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int SendEventStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SendEventMessage *sendEvent = (SendEventMessage *) message; - - // - // Here is the fingerprint. - // - - sendEvent -> propagate = *(buffer + 1); - - sendEvent -> window = GetULONG(buffer + 4, bigEndian); - sendEvent -> mask = GetULONG(buffer + 8, bigEndian); - - sendEvent -> code = *(buffer + 12); - sendEvent -> byte_data = *(buffer + 13); - - sendEvent -> sequence = GetUINT(buffer + 14, bigEndian); - - sendEvent -> int_data = GetULONG(buffer + 16, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int SendEventStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SendEventMessage *sendEvent = (SendEventMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = sendEvent -> propagate; - - PutULONG(sendEvent -> window, buffer + 4, bigEndian); - PutULONG(sendEvent -> mask, buffer + 8, bigEndian); - - *(buffer + 12) = sendEvent -> code; - *(buffer + 13) = sendEvent -> byte_data; - - PutUINT(sendEvent -> sequence, buffer + 14, bigEndian); - - PutULONG(sendEvent -> int_data, buffer + 16, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void SendEventStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - SendEventMessage *sendEvent = (SendEventMessage *) message; - - *logofs << name() << ": Identity propagate " << (unsigned int) sendEvent -> propagate - << ", window " << sendEvent -> window << ", mask " << sendEvent -> mask - << ", code " << (unsigned int) sendEvent -> code << ", byte_data " - << (unsigned int) sendEvent -> byte_data << ", sequence " - << sendEvent -> sequence << ", int_data " << sendEvent -> int_data - << ", size " << sendEvent -> size_ << ".\n" << logofs_flush; - - #endif -} - -void SendEventStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ -} - -void SendEventStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - SendEventMessage *sendEvent = (SendEventMessage *) message; - SendEventMessage *cachedSendEvent = (SendEventMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << (unsigned int) sendEvent -> propagate - << " as propagate field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeBoolValue(sendEvent -> propagate); - - cachedSendEvent -> propagate = sendEvent -> propagate; - - #ifdef TEST - *logofs << name() << ": Encoding value " << sendEvent -> window - << " as window field.\n" << logofs_flush; - #endif - - if (sendEvent -> window == 0 || sendEvent -> window == 1) - { - encodeBuffer.encodeBoolValue(1); - - encodeBuffer.encodeBoolValue(sendEvent -> window); - } - else - { - encodeBuffer.encodeBoolValue(0); - - encodeBuffer.encodeXidValue(sendEvent -> window, clientCache -> windowCache); - } - - cachedSendEvent -> window = sendEvent -> window; - - #ifdef TEST - *logofs << name() << ": Encoding value " << sendEvent -> mask - << " as mask field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(sendEvent -> mask, 32, - clientCache -> sendEventMaskCache); - - cachedSendEvent -> mask = sendEvent -> mask; - - #ifdef TEST - *logofs << name() << ": Encoding value " << sendEvent -> code - << " as code field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(sendEvent -> code, 8, - clientCache -> sendEventCodeCache); - - cachedSendEvent -> code = sendEvent -> code; - - #ifdef TEST - *logofs << name() << ": Encoding value " << sendEvent -> byte_data - << " as byte_data field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(sendEvent -> byte_data, 8, - clientCache -> sendEventByteDataCache); - - cachedSendEvent -> byte_data = sendEvent -> byte_data; - - #ifdef TEST - *logofs << name() << ": Encoding value " << sendEvent -> sequence - << " as sequence field.\n" << logofs_flush; - #endif - - unsigned int diffSeq = sendEvent -> sequence - - clientCache -> sendEventLastSequence; - - clientCache -> sendEventLastSequence = sendEvent -> sequence; - - encodeBuffer.encodeValue(diffSeq, 16, 4); - - cachedSendEvent -> sequence = sendEvent -> sequence; - - #ifdef TEST - *logofs << name() << ": Encoding value " << sendEvent -> int_data - << " as int_data field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(sendEvent -> int_data, 32, - clientCache -> sendEventIntDataCache); - - cachedSendEvent -> int_data = sendEvent -> int_data; -} - -void SendEventStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - SendEventMessage *sendEvent = (SendEventMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeBoolValue(value); - - sendEvent -> propagate = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << (unsigned int) sendEvent -> propagate - << " as propagate field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeBoolValue(value); - - if (value) - { - decodeBuffer.decodeBoolValue(value); - } - else - { - decodeBuffer.decodeXidValue(value, clientCache -> windowCache); - } - - sendEvent -> window = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << sendEvent -> window - << " as window field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(sendEvent -> mask, 32, - clientCache -> sendEventMaskCache); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << sendEvent -> mask - << " as mask field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(sendEvent -> code, 8, - clientCache -> sendEventCodeCache); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << sendEvent -> code - << " as code field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(sendEvent -> byte_data, 8, - clientCache -> sendEventByteDataCache); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << sendEvent -> byte_data - << " as byte_data field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeValue(value, 16, 4); - - clientCache -> sendEventLastSequence += value; - clientCache -> sendEventLastSequence &= 0xffff; - - sendEvent -> sequence = clientCache -> sendEventLastSequence; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << sendEvent -> sequence - << " as sequence field.\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(sendEvent -> int_data, 32, - clientCache -> sendEventIntDataCache); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << sendEvent -> int_data - << " as int_data field.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/SendEvent.h b/nxcomp/SendEvent.h deleted file mode 100644 index a8841a706..000000000 --- a/nxcomp/SendEvent.h +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef SendEvent_H -#define SendEvent_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define SENDEVENT_ENABLE_CACHE 1 -#define SENDEVENT_ENABLE_DATA 0 -#define SENDEVENT_ENABLE_SPLIT 0 -#define SENDEVENT_ENABLE_COMPRESS 0 - -#define SENDEVENT_DATA_LIMIT 24 -#define SENDEVENT_DATA_OFFSET 20 - -#define SENDEVENT_CACHE_SLOTS 2000 -#define SENDEVENT_CACHE_THRESHOLD 2 -#define SENDEVENT_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class SendEventMessage : public Message -{ - friend class SendEventStore; - - public: - - SendEventMessage() - { - } - - ~SendEventMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char propagate; - unsigned int window; - unsigned int mask; - - // - // These are part of the event data. - // - - unsigned char code; - unsigned char byte_data; - unsigned short sequence; - unsigned int int_data; -}; - -class SendEventStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - SendEventStore() : MessageStore() - { - enableCache = SENDEVENT_ENABLE_CACHE; - enableData = SENDEVENT_ENABLE_DATA; - enableSplit = SENDEVENT_ENABLE_SPLIT; - enableCompress = SENDEVENT_ENABLE_COMPRESS; - - dataLimit = SENDEVENT_DATA_LIMIT; - dataOffset = SENDEVENT_DATA_OFFSET; - - cacheSlots = SENDEVENT_CACHE_SLOTS; - cacheThreshold = SENDEVENT_CACHE_THRESHOLD; - cacheLowerThreshold = SENDEVENT_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~SendEventStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "SendEvent"; - } - - virtual unsigned char opcode() const - { - return X_SendEvent; - } - - virtual unsigned int storage() const - { - return sizeof(SendEventMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new SendEventMessage(); - } - - virtual Message *create(const Message &message) const - { - return new SendEventMessage((const SendEventMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (SendEventMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* SendEvent_H */ diff --git a/nxcomp/SequenceQueue.cpp b/nxcomp/SequenceQueue.cpp deleted file mode 100644 index 3114bfcd0..000000000 --- a/nxcomp/SequenceQueue.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "SequenceQueue.h" - -static const unsigned int INITIAL_SIZE_ = 16; -static const unsigned int GROWTH_INCREMENT = 16; - -SequenceQueue::SequenceQueue() - - : queue_(new RequestSequence[INITIAL_SIZE_]), size_(INITIAL_SIZE_), - length_(0), start_(0), end_(0) -{ -} - -SequenceQueue::~SequenceQueue() -{ - delete [] queue_; -} - -void SequenceQueue::push(unsigned short int sequence, unsigned char opcode, - unsigned int data1, unsigned int data2, - unsigned int data3) -{ - if (length_ == 0) - { - start_ = end_ = 0; - - queue_[0].opcode = opcode; - queue_[0].sequence = sequence; - - queue_[0].data1 = data1; - queue_[0].data2 = data2; - queue_[0].data3 = data3; - - length_ = 1; - - return; - } - - if (length_ == size_) - { - size_ += GROWTH_INCREMENT; - - RequestSequence *newQueue = new RequestSequence[size_]; - - for (int i = start_; (unsigned int) i < length_; i++) - { - newQueue[i - start_] = queue_[i]; - } - - for (int i1 = 0; (unsigned int) i1 < start_; i1++) - { - newQueue[i1 + length_ - start_] = queue_[i1]; - } - - delete [] queue_; - - queue_ = newQueue; - - start_ = 0; - - end_ = length_ - 1; - } - - end_++; - - if (end_ == size_) - { - end_ = 0; - } - - queue_[end_].opcode = opcode; - queue_[end_].sequence = sequence; - - queue_[end_].data1 = data1; - queue_[end_].data2 = data2; - queue_[end_].data3 = data3; - - length_++; -} - -int SequenceQueue::peek(unsigned short int &sequence, - unsigned char &opcode) -{ - if (length_ == 0) - { - return 0; - } - else - { - opcode = queue_[start_].opcode; - sequence = queue_[start_].sequence; - - return 1; - } -} - -int SequenceQueue::peek(unsigned short int &sequence, unsigned char &opcode, - unsigned int &data1, unsigned int &data2, - unsigned int &data3) -{ - if (length_ == 0) - { - return 0; - } - else - { - opcode = queue_[start_].opcode; - sequence = queue_[start_].sequence; - - data1 = queue_[start_].data1; - data2 = queue_[start_].data2; - data3 = queue_[start_].data3; - - return 1; - } -} - -int SequenceQueue::pop(unsigned short int &sequence, unsigned char &opcode, - unsigned int &data1, unsigned int &data2, - unsigned int &data3) -{ - if (length_ == 0) - { - return 0; - } - else - { - opcode = queue_[start_].opcode; - sequence = queue_[start_].sequence; - - data1 = queue_[start_].data1; - data2 = queue_[start_].data2; - data3 = queue_[start_].data3; - - start_++; - - if (start_ == size_) - { - start_ = 0; - } - - length_--; - - return 1; - } -} diff --git a/nxcomp/SequenceQueue.h b/nxcomp/SequenceQueue.h deleted file mode 100644 index 2a72bc3fe..000000000 --- a/nxcomp/SequenceQueue.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef SequenceQueue_H -#define SequenceQueue_H - -// -// List of outstanding request messages which -// are waiting for a reply. This class is used -// in X client and server channels to correlate -// the replies sequence numbers to the original -// request type. -// - -class SequenceQueue -{ - public: - - SequenceQueue(); - - virtual ~SequenceQueue(); - - void push(unsigned short int sequence, unsigned char opcode, - unsigned int data1 = 0, unsigned int data2 = 0, - unsigned int data3 = 0); - - int peek(unsigned short int &sequence, unsigned char &opcode); - - int peek(unsigned short int &sequence, unsigned char &opcode, - unsigned int &data1, unsigned int &data2, - unsigned int &data3); - - int pop(unsigned short int &sequence, unsigned char &opcode, - unsigned int &data1, unsigned int &data2, - unsigned int &data3); - - int pop(unsigned short int &sequence, unsigned char &opcode) - { - unsigned int data1, data2, data3; - - return pop(sequence, opcode, data1, data2, data3); - } - - int length() - { - return length_; - } - - private: - - struct RequestSequence - { - unsigned short int sequence; - unsigned char opcode; - unsigned int data1; - unsigned int data2; - unsigned int data3; - }; - - RequestSequence *queue_; - - unsigned int size_; - unsigned int length_; - - unsigned int start_; - unsigned int end_; -}; - -#endif /* SequenceQueue_H */ diff --git a/nxcomp/ServerCache.cpp b/nxcomp/ServerCache.cpp deleted file mode 100644 index 00693d2af..000000000 --- a/nxcomp/ServerCache.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ServerCache.h" - -// -// Some global caches used to store information -// common to all X connections. -// - -BlockCache ServerCache::lastInitReply; -BlockCache ServerCache::lastKeymap; -unsigned char ServerCache::getKeyboardMappingLastKeysymsPerKeycode = 0; -BlockCache ServerCache::getKeyboardMappingLastMap; -BlockCache ServerCache::getModifierMappingLastMap; -BlockCache ServerCache::xResources; -BlockCacheSet ServerCache::queryFontFontCache(16); - -ServerCache::ServerCache() : - - replySequenceCache(6), eventSequenceCache(6), - lastTimestamp(0), visualCache(8), colormapCache(8), - - errorMinorCache(8), - - colormapNotifyWindowCache(8), colormapNotifyColormapCache(8), - - createNotifyWindowCache(8), createNotifyLastWindow(0), - - exposeWindowCache(12), - - focusInWindowCache(8), - - keyPressLastKey(0), - - mapNotifyEventCache(8), mapNotifyWindowCache(8), - - motionNotifyTimestampCache(8), motionNotifyLastRootX(0), - motionNotifyLastRootY(0), motionNotifyRootXCache(8), - motionNotifyRootYCache(8), motionNotifyEventXCache(8), - motionNotifyEventYCache(8), motionNotifyStateCache(8), - - noExposeDrawableCache(8), noExposeMinorCache(8), - - propertyNotifyWindowCache(8), propertyNotifyAtomCache(8), - - reparentNotifyWindowCache(8), - - selectionClearWindowCache(8), selectionClearAtomCache(8), - - visibilityNotifyWindowCache(8), - - getGeometryRootCache(8), - - getInputFocusWindowCache(8), - - getKeyboardMappingKeysymCache(8), - - getPropertyTypeCache(8), - - getSelectionOwnerCache(8), - - getWindowAttributesClassCache(8), getWindowAttributesPlanesCache(8), - getWindowAttributesPixelCache(8), getWindowAttributesAllEventsCache(8), - getWindowAttributesYourEventsCache(8), - getWindowAttributesDontPropagateCache(8), - - queryPointerRootCache(8), queryPointerChildCache(8), - - translateCoordsChildCache(8), translateCoordsXCache(8), - translateCoordsYCache(8), - - queryTreeWindowCache(8) - -{ - unsigned int i; - - for (i = 0; i < 3; i++) - { - configureNotifyWindowCache[i] = new IntCache(8); - } - - for (i = 0; i < 5; i++) - { - configureNotifyGeomCache[i] = new IntCache(8); - } - - for (i = 0; i < 5; i++) - { - exposeGeomCache[i] = new IntCache(8); - } - - for (i = 0; i < 3; i++) - { - motionNotifyWindowCache[i] = new IntCache(8); - } - - for (i = 0; i < 5; i++) - { - getGeometryGeomCache[i] = new IntCache(8); - } - - for (i = 0; i < 23; i++) - { - keyPressCache[i] = 0; - } - - for (i = 0; i < 6; i++) - { - queryFontCharInfoCache[i] = new IntCache(8); - queryFontLastCharInfo[i] = 0; - } - - for (i = 0; i < 12; i++) - { - genericReplyIntCache[i] = new IntCache(8); - } - - for (i = 0; i < 14; i++) - { - genericEventIntCache[i] = new IntCache(8); - } -} - - -ServerCache::~ServerCache() -{ - unsigned int i; - - for (i = 0; i < 3; i++) - { - delete configureNotifyWindowCache[i]; - } - - for (i = 0; i < 5; i++) - { - delete configureNotifyGeomCache[i]; - } - - for (i = 0; i < 5; i++) - { - delete exposeGeomCache[i]; - } - - for (i = 0; i < 3; i++) - { - delete motionNotifyWindowCache[i]; - } - - for (i = 0; i < 5; i++) - { - delete getGeometryGeomCache[i]; - } - - for (i = 0; i < 6; i++) - { - delete queryFontCharInfoCache[i]; - } - - for (i = 0; i < 12; i++) - { - delete genericReplyIntCache[i]; - } - - for (i = 0; i < 14; i++) - { - delete genericEventIntCache[i]; - } -} diff --git a/nxcomp/ServerCache.h b/nxcomp/ServerCache.h deleted file mode 100644 index c6e2b81b6..000000000 --- a/nxcomp/ServerCache.h +++ /dev/null @@ -1,303 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ServerCache_H -#define ServerCache_H - -#include "Misc.h" - -#include "IntCache.h" -#include "CharCache.h" -#include "OpcodeCache.h" -#include "BlockCache.h" -#include "BlockCacheSet.h" - -#include "ChannelCache.h" - -class ServerCache : public ChannelCache -{ - public: - - ServerCache(); - - ~ServerCache(); - - // - // Opcode prediction caches. - // - - OpcodeCache opcodeCache; - - // - // General-purpose caches. - // - - IntCache replySequenceCache; - IntCache eventSequenceCache; - unsigned int lastTimestamp; - CharCache depthCache; - IntCache visualCache; - IntCache colormapCache; - CharCache resourceCache; - - // - // X connection startup. - // - - static BlockCache lastInitReply; - - // - // X errors. - // - - CharCache errorCodeCache; - IntCache errorMinorCache; - CharCache errorMajorCache; - - // - // ButtonPress and ButtonRelease events. - // - - CharCache buttonCache; - - // - // ColormapNotify event. - // - - IntCache colormapNotifyWindowCache; - IntCache colormapNotifyColormapCache; - - // - // ConfigureNotify event. - // - - IntCache *configureNotifyWindowCache[3]; - IntCache *configureNotifyGeomCache[5]; - - // - // CreateNotify event. - // - - IntCache createNotifyWindowCache; - unsigned int createNotifyLastWindow; - - // - // Expose event. - // - - IntCache exposeWindowCache; - IntCache *exposeGeomCache[5]; - - // - // FocusIn event (also used for FocusOut). - // - - IntCache focusInWindowCache; - - // - // KeymapNotify event. - // - - static BlockCache lastKeymap; - - // - // KeyPress event. - // - - unsigned char keyPressLastKey; - unsigned char keyPressCache[23]; - - // - // MapNotify event (also used for UnmapNotify). - // - - IntCache mapNotifyEventCache; - IntCache mapNotifyWindowCache; - - // - // MotionNotify event (also used for KeyPress, - // KeyRelease, ButtonPress, ButtonRelease, - // EnterNotify, and LeaveNotify events and - // QueryPointer reply). - // - - IntCache motionNotifyTimestampCache; - unsigned int motionNotifyLastRootX; - unsigned int motionNotifyLastRootY; - IntCache motionNotifyRootXCache; - IntCache motionNotifyRootYCache; - IntCache motionNotifyEventXCache; - IntCache motionNotifyEventYCache; - IntCache motionNotifyStateCache; - IntCache *motionNotifyWindowCache[3]; - - // - // NoExpose event. - // - - IntCache noExposeDrawableCache; - IntCache noExposeMinorCache; - CharCache noExposeMajorCache; - - // - // PropertyNotify event. - // - - IntCache propertyNotifyWindowCache; - IntCache propertyNotifyAtomCache; - - // - // ReparentNotify event. - // - - IntCache reparentNotifyWindowCache; - - // - // SelectionClear event. - // - - IntCache selectionClearWindowCache; - IntCache selectionClearAtomCache; - - // - // VisibilityNotify event. - // - - IntCache visibilityNotifyWindowCache; - - // - // GetGeometry reply. - // - - IntCache getGeometryRootCache; - IntCache *getGeometryGeomCache[5]; - - // - // GetInputFocus reply. - // - - IntCache getInputFocusWindowCache; - - // - // GetKeyboardMapping reply. - // - - static unsigned char getKeyboardMappingLastKeysymsPerKeycode; - static BlockCache getKeyboardMappingLastMap; - IntCache getKeyboardMappingKeysymCache; - CharCache getKeyboardMappingLastByteCache; - - // - // GetModifierMapping reply. - // - - static BlockCache getModifierMappingLastMap; - - // - // GetProperty reply. - // - - CharCache getPropertyFormatCache; - IntCache getPropertyTypeCache; - static BlockCache xResources; - - // - // GetSelection reply. - // - - IntCache getSelectionOwnerCache; - - // - // GetWindowAttributes reply. - // - - IntCache getWindowAttributesClassCache; - CharCache getWindowAttributesBitGravityCache; - CharCache getWindowAttributesWinGravityCache; - IntCache getWindowAttributesPlanesCache; - IntCache getWindowAttributesPixelCache; - IntCache getWindowAttributesAllEventsCache; - IntCache getWindowAttributesYourEventsCache; - IntCache getWindowAttributesDontPropagateCache; - - // - // QueryColors reply. - // - - BlockCache queryColorsLastReply; - - // - // QueryFont reply. - // - - static BlockCacheSet queryFontFontCache; - IntCache *queryFontCharInfoCache[6]; - unsigned int queryFontLastCharInfo[6]; - - // - // QueryPointer reply. - // - - IntCache queryPointerRootCache; - IntCache queryPointerChildCache; - - // - // TranslateCoords reply. - // - - IntCache translateCoordsChildCache; - IntCache translateCoordsXCache; - IntCache translateCoordsYCache; - - // - // QueryTree reply. - // - - IntCache queryTreeWindowCache; - - // - // Generic reply. Use short data - // in protocol versions >= 3. - // - - CharCache genericReplyCharCache; - IntCache *genericReplyIntCache[12]; - - // - // Generic event. Only in protocol - // versions >= 3. - // - - CharCache genericEventCharCache; - IntCache *genericEventIntCache[14]; - - // - // Used in the abort split events. - // - - OpcodeCache abortOpcodeCache; -}; - -#endif /* ServerCache_H */ diff --git a/nxcomp/ServerChannel.cpp b/nxcomp/ServerChannel.cpp deleted file mode 100644 index eff24e90e..000000000 --- a/nxcomp/ServerChannel.cpp +++ /dev/null @@ -1,7942 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#ifndef ANDROID -#include -#endif - -#include -#include - -#include "NXproto.h" -#include "NXalert.h" -#include "NXpack.h" -#include "NXmitshm.h" - -#include "ServerChannel.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "StaticCompressor.h" - -#include "Statistics.h" -#include "Proxy.h" - -#include "Auth.h" -#include "Unpack.h" - -// -// Available unpack methods. -// - -#include "Alpha.h" -#include "Colormap.h" -#include "Bitmap.h" -#include "Jpeg.h" -#include "Pgn.h" -#include "Rgb.h" -#include "Rle.h" - -extern Proxy *proxy; - -// -// Set the verbosity level. You also -// need to define OPCODES in Misc.cpp -// if you want literals instead of -// opcodes' numbers. -// - -#define PANIC -#define WARNING -#undef OPCODES -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Log the important tracepoints related -// to writing packets to the peer proxy. -// - -#undef FLUSH - -// -// Log the operations related to splits. -// - -#undef SPLIT - -// -// Define this to log when a channel -// is created or destroyed. -// - -#undef REFERENCES - -// -// Define this to exit and suspend the -// session after a given number of X -// messages decoded by the proxy. -// - -#undef SUSPEND - -// -// Define these to hide the server extensions. -// - -#define HIDE_MIT_SHM_EXTENSION -#define HIDE_BIG_REQUESTS_EXTENSION -#define HIDE_XFree86_Bigfont_EXTENSION -#undef HIDE_SHAPE_EXTENSION -#undef HIDE_XKEYBOARD_EXTENSION - -// -// Known reasons of connection failures. -// - -#define INVALID_COOKIE_DATA "Invalid MIT-MAGIC-COOKIE-1 key" -#define INVALID_COOKIE_SIZE ((int) sizeof(INVALID_COOKIE_DATA) - 1) - -#define NO_AUTH_PROTO_DATA "No protocol specified" -#define NO_AUTH_PROTO_SIZE ((int) sizeof(NO_AUTH_PROTO_DATA) - 1) - -// -// Here are the static members. -// - -#ifdef REFERENCES - -int ServerChannel::references_ = 0; - -#endif - -ServerChannel::ServerChannel(Transport *transport, StaticCompressor *compressor) - - : Channel(transport, compressor), readBuffer_(transport_, this) -{ - // - // Sequence number of the next message - // being encoded or decoded. - // - - clientSequence_ = 0; - serverSequence_ = 0; - - // - // Save the last motion event and flush - // it only when the timeout expires. - // - - lastMotion_[0] = '\0'; - - // - // Clear the queue of sequence numbers - // of split commits. Used to mask the - // errors. - // - - initCommitQueue(); - - // - // Do we enable or not sending of expose - // events to the X client. - // - - enableExpose_ = 1; - enableGraphicsExpose_ = 1; - enableNoExpose_ = 1; - - // - // Track data of image currently being - // decompressed. - // - - imageState_ = NULL; - - // - // Track MIT-SHM resources. - // - - shmemState_ = NULL; - - // - // Store the unpack state for each agent - // resource. - // - - for (int i = 0; i < CONNECTIONS_LIMIT; i++) - { - unpackState_[i] = NULL; - } - - // - // Data about the split parameters requested - // by the encoding side. - // - - splitState_.resource = nothing; - splitState_.current = 0; - splitState_.save = 1; - splitState_.load = 1; - splitState_.commit = 0; - - // - // It will be eventually set by - // the server proxy. - // - - fontPort_ = -1; - - #ifdef REFERENCES - *logofs << "ServerChannel: Created new object at " - << this << " for FD#" << fd_ << " out of " - << ++references_ << " allocated channels.\n" - << logofs_flush; - #endif -} - -ServerChannel::~ServerChannel() -{ - #ifdef TEST - *logofs << "ServerChannel: Freeing image state information.\n" - << logofs_flush; - #endif - - handleImageStateRemove(); - - #ifdef TEST - *logofs << "ServerChannel: Freeing shared memory information.\n" - << logofs_flush; - #endif - - handleShmemStateRemove(); - - #ifdef TEST - *logofs << "ServerChannel: Freeing unpack state information.\n" - << logofs_flush; - #endif - - for (int i = 0; i < CONNECTIONS_LIMIT; i++) - { - handleUnpackStateRemove(i); - } - - #ifdef TEST - *logofs << "ServerChannel: Freeing channel caches.\n" - << logofs_flush; - #endif - - #ifdef REFERENCES - *logofs << "ServerChannel: Deleted object at " - << this << " for FD#" << fd_ << " out of " - << --references_ << " allocated channels.\n" - << logofs_flush; - #endif -} - -// -// Beginning of handleRead(). -// - -int ServerChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, - unsigned int length) -{ - #ifdef DEBUG - *logofs << "handleRead: Called for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - // - // Pointer to located message and - // its size in bytes. - // - - const unsigned char *inputMessage; - unsigned int inputLength; - - // - // Set when message is found in - // cache. - // - - int hit; - - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: Trying to read from FD#" - << fd_ << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - int result = readBuffer_.readMessage(); - - #if defined(DEBUG) || defined(INFO) - *logofs << "handleRead: Read result on FD#" << fd_ - << " is " << result << ".\n" - << logofs_flush; - #endif - - if (result < 0) - { - // - // Let the proxy close the channel. - // - - return -1; - } - else if (result == 0) - { - #if defined(TEST) || defined(INFO) - - // - // This can happen because we have the descriptor - // selected in the read set but we already read - // the data asynchronously, while decoding data - // read from the proxy. - // - - *logofs << "handleRead: WARNING! No data read from FD#" - << fd_ << " while encoding messages.\n" - << logofs_flush; - - #endif - - return 0; - } - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "handleRead: Encoding messages for FD#" << fd_ - << " with " << readBuffer_.getLength() << " bytes " - << "in the buffer.\n" << logofs_flush; - #endif - - // - // Extract any complete message which - // is available in the buffer. - // - - if (proxy -> handleAsyncSwitch(fd_) < 0) - { - return -1; - } - - while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) - { - hit = 0; - - if (firstReply_) - { - // - // Handle the X server's authorization reply. - // - - if (handleAuthorization(inputMessage, inputLength) < 0) - { - return -1; - } - - imageByteOrder_ = inputMessage[30]; - bitmapBitOrder_ = inputMessage[31]; - scanlineUnit_ = inputMessage[32]; - scanlinePad_ = inputMessage[33]; - - encodeBuffer.encodeValue((unsigned int) inputMessage[0], 8); - encodeBuffer.encodeValue((unsigned int) inputMessage[1], 8); - encodeBuffer.encodeValue(GetUINT(inputMessage + 2, bigEndian_), 16); - encodeBuffer.encodeValue(GetUINT(inputMessage + 4, bigEndian_), 16); - encodeBuffer.encodeValue(GetUINT(inputMessage + 6, bigEndian_), 16); - - if (ServerCache::lastInitReply.compare(inputLength - 8, inputMessage + 8)) - { - encodeBuffer.encodeBoolValue(1); - } - else - { - encodeBuffer.encodeBoolValue(0); - - for (unsigned int i = 8; i < inputLength; i++) - { - encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8); - } - } - - firstReply_ = 0; - - #if defined(TEST) || defined(OPCODES) - - int bits = encodeBuffer.diffBits(); - - *logofs << "handleRead: Handled first reply. " << inputLength - << " bytes in, " << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - - #endif - - priority_++; - - } - else - { - // - // NX client needs this line to consider - // the initialization phase successfully - // completed. - // - - if (firstClient_ == -1) - { - cerr << "Info" << ": Established X server connection.\n" ; - - firstClient_ = fd_; - } - - // - // Check if this is a reply. - // - - if (*inputMessage == X_Reply) - { - int bits = 0; - - unsigned char inputOpcode = *inputMessage; - - unsigned short int requestSequenceNum; - unsigned char requestOpcode; - unsigned int requestData[3]; - - unsigned int sequenceNum = GetUINT(inputMessage + 2, bigEndian_); - - #ifdef SUSPEND - - if (sequenceNum >= 1000) - { - cerr << "Warning" << ": Exiting to test the resilience of the agent.\n"; - - sleep(2); - - HandleAbort(); - } - - #endif - - // - // We managed all the events and errors caused - // by the previous requests. We can now reset - // the queue of split commits. - // - - clearCommitQueue(); - - // - // Encode opcode and difference between - // current sequence and the last one. - // - - encodeBuffer.encodeOpcodeValue(inputOpcode, serverCache_ -> opcodeCache); - - unsigned int sequenceDiff = sequenceNum - serverSequence_; - - serverSequence_ = sequenceNum; - - #ifdef DEBUG - *logofs << "handleRead: Last server sequence number for FD#" - << fd_ << " is " << serverSequence_ << " with " - << "difference " << sequenceDiff << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(sequenceDiff, 16, - serverCache_ -> replySequenceCache, 7); - - // - // Now handle the data part. - // - - if (sequenceQueue_.peek(requestSequenceNum, requestOpcode) && - requestSequenceNum == sequenceNum) - { - // - // We've found the request that generated this reply. - // It is possible to compress the reply based on the - // specific request type. - // - - sequenceQueue_.pop(requestSequenceNum, requestOpcode, - requestData[0], requestData[1], requestData[2]); - - // - // If differential compression is disabled - // then use the most simple encoding. - // - - if (control -> LocalDeltaCompression == 0) - { - int result = handleFastReadReply(encodeBuffer, requestOpcode, - inputMessage, inputLength); - if (result < 0) - { - return -1; - } - else if (result > 0) - { - continue; - } - } - - switch (requestOpcode) - { - case X_AllocColor: - { - const unsigned char *nextSrc = inputMessage + 8; - for (unsigned int i = 0; i < 3; i++) - { - unsigned int colorValue = GetUINT(nextSrc, bigEndian_); - nextSrc += 2; - if (colorValue == requestData[i]) - encodeBuffer.encodeBoolValue(1); - else - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeValue(colorValue - colorValue, 16, 6); - } - } - unsigned int pixel = GetULONG(inputMessage + 16, bigEndian_); - encodeBuffer.encodeValue(pixel, 32, 9); - - priority_++; - } - break; - case X_GetAtomName: - { - unsigned int nameLength = GetUINT(inputMessage + 8, bigEndian_); - encodeBuffer.encodeValue(nameLength, 16, 6); - const unsigned char *nextSrc = inputMessage + 32; - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, nameLength); - - priority_++; - } - break; - case X_GetGeometry: - { - // - // TODO: This obtains a satisfactory 10:1, but - // could be cached to leverage the big amount - // of such requests issued by QT clients. - // - - encodeBuffer.encodeCachedValue(inputMessage[1], 8, - serverCache_ -> depthCache); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> getGeometryRootCache, 9); - const unsigned char *nextSrc = inputMessage + 12; - for (unsigned int i = 0; i < 5; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *serverCache_ -> getGeometryGeomCache[i], 8); - nextSrc += 2; - } - - priority_++; - } - break; - case X_GetInputFocus: - { - // - // Is it a real X_GetInputFocus or a - // masqueraded reply? - // - - if (requestData[0] == X_GetInputFocus) - { - encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> getInputFocusWindowCache); - - priority_++; - } - else - { - // - // TODO: We are not setting priority in case - // of replies other than real X_GetInputFocus - // or X_NXGetUnpackParameters. We should check - // once again that this is OK. - // - - #ifdef TEST - *logofs << "handleRead: Received tainted X_GetInputFocus reply " - << "for request OPCODE#" << requestData[0] << " with " - << "sequence " << sequenceNum << ".\n" - << logofs_flush; - #endif - - // - // Don't encode any data in case of sync - // messages or any other reply for which - // opcode is enough. - // - - if (requestData[0] == opcodeStore_ -> getUnpackParameters) - { - for (int i = 0; i < PACK_METHOD_LIMIT; i++) - { - encodeBuffer.encodeBoolValue(control -> LocalUnpackMethods[i]); - } - - priority_++; - } - else if (requestData[0] == opcodeStore_ -> getShmemParameters) - { - if (handleShmemReply(encodeBuffer, requestOpcode, requestData[1], - inputMessage, inputLength) < 0) - { - return -1; - } - - priority_++; - } - else if (requestData[0] == opcodeStore_ -> getFontParameters) - { - if (handleFontReply(encodeBuffer, requestOpcode, - inputMessage, inputLength) < 0) - { - return -1; - } - } - - // - // Account this data to the original opcode. - // - - requestOpcode = requestData[0]; - } - } - break; - case X_GetKeyboardMapping: - { - unsigned int keysymsPerKeycode = (unsigned int) inputMessage[1]; - if (ServerCache::getKeyboardMappingLastMap.compare(inputLength - 32, - inputMessage + 32) && (keysymsPerKeycode == - ServerCache::getKeyboardMappingLastKeysymsPerKeycode)) - { - encodeBuffer.encodeBoolValue(1); - - priority_++; - - break; - } - ServerCache::getKeyboardMappingLastKeysymsPerKeycode = keysymsPerKeycode; - encodeBuffer.encodeBoolValue(0); - unsigned int numKeycodes = - (((inputLength - 32) / keysymsPerKeycode) >> 2); - encodeBuffer.encodeValue(numKeycodes, 8); - encodeBuffer.encodeValue(keysymsPerKeycode, 8, 4); - const unsigned char *nextSrc = inputMessage + 32; - unsigned char previous = 0; - for (unsigned int count = numKeycodes * keysymsPerKeycode; - count; --count) - { - unsigned int keysym = GetULONG(nextSrc, bigEndian_); - nextSrc += 4; - if (keysym == NoSymbol) - encodeBuffer.encodeBoolValue(1); - else - { - encodeBuffer.encodeBoolValue(0); - unsigned int first3Bytes = (keysym >> 8); - encodeBuffer.encodeCachedValue(first3Bytes, 24, - serverCache_ -> getKeyboardMappingKeysymCache, 9); - unsigned char lastByte = (unsigned char) (keysym & 0xff); - encodeBuffer.encodeCachedValue(lastByte - previous, 8, - serverCache_ -> getKeyboardMappingLastByteCache, 5); - previous = lastByte; - } - } - - priority_++; - } - break; - case X_GetModifierMapping: - { - encodeBuffer.encodeValue((unsigned int) inputMessage[1], 8); - const unsigned char *nextDest = inputMessage + 32; - if (ServerCache::getModifierMappingLastMap.compare(inputLength - 32, - nextDest)) - { - encodeBuffer.encodeBoolValue(1); - - priority_++; - - break; - } - encodeBuffer.encodeBoolValue(0); - for (unsigned int count = inputLength - 32; count; count--) - { - unsigned char next = *nextDest++; - if (next == 0) - encodeBuffer.encodeBoolValue(1); - else - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeValue(next, 8); - } - } - - priority_++; - } - break; - case X_GetProperty: - { - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_GetProperty); - - hit = handleEncode(encodeBuffer, serverCache_, messageStore, - requestOpcode, inputMessage, inputLength); - - priority_++; - } - break; - case X_GetSelectionOwner: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> getSelectionOwnerCache, 9); - priority_++; - } - break; - case X_GetWindowAttributes: - { - encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> visualCache); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 12, bigEndian_), - 16, serverCache_ -> getWindowAttributesClassCache, 3); - encodeBuffer.encodeCachedValue(inputMessage[14], 8, - serverCache_ -> getWindowAttributesBitGravityCache); - encodeBuffer.encodeCachedValue(inputMessage[15], 8, - serverCache_ -> getWindowAttributesWinGravityCache); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), - 32, serverCache_ -> getWindowAttributesPlanesCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 20, bigEndian_), - 32, serverCache_ -> getWindowAttributesPixelCache, 9); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[24]); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[25]); - encodeBuffer.encodeValue((unsigned int) inputMessage[26], 2); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[27]); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 28, bigEndian_), - 29, serverCache_ -> colormapCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 32, bigEndian_), - 32, serverCache_ -> getWindowAttributesAllEventsCache); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 36, bigEndian_), - 32, serverCache_ -> getWindowAttributesYourEventsCache); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 40, bigEndian_), - 16, serverCache_ -> getWindowAttributesDontPropagateCache); - - priority_++; - } - break; - case X_GrabKeyboard: - case X_GrabPointer: - { - encodeBuffer.encodeValue((unsigned int) inputMessage[1], 3); - - priority_++; - } - break; - case X_InternAtom: - { - encodeBuffer.encodeValue(GetULONG(inputMessage + 8, bigEndian_), 29, 9); - - priority_++; - } - break; - case X_ListExtensions: - { - encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8); - unsigned int numExtensions = (unsigned int) inputMessage[1]; - encodeBuffer.encodeValue(numExtensions, 8); - const unsigned char *nextSrc = inputMessage + 32; - - for (; numExtensions; numExtensions--) - { - unsigned int length = (unsigned int) (*nextSrc++); - - encodeBuffer.encodeValue(length, 8); - - #ifdef HIDE_MIT_SHM_EXTENSION - - if (!strncmp((char *) nextSrc, "MIT-SHM", 7)) - { - #ifdef TEST - *logofs << "handleRead: Hiding MIT-SHM extension in reply.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) nextSrc, "NO-MIT-", 7); - } - - #endif - - #ifdef HIDE_BIG_REQUESTS_EXTENSION - - if (!strncmp((char *) nextSrc, "BIG-REQUESTS", 12)) - { - #ifdef TEST - *logofs << "handleRead: Hiding BIG-REQUESTS extension in reply.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) nextSrc, "NO-BIG-REQUE", 12); - } - - #endif - - #ifdef HIDE_XKEYBOARD_EXTENSION - - if (!strncmp((char *) nextSrc, "XKEYBOARD", 9)) - { - #ifdef TEST - *logofs << "handleRead: Hiding XKEYBOARD extension in reply.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) nextSrc, "NO-XKEYBO", 9); - } - - #endif - - #ifdef HIDE_XFree86_Bigfont_EXTENSION - - if (!strncmp((char *) nextSrc, "XFree86-Bigfont", 15)) - { - #ifdef TEST - *logofs << "handleRead: Hiding XFree86-Bigfont extension in reply.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) nextSrc, "NO-XFree86-Bigf", 15); - } - - #endif - - #ifdef HIDE_SHAPE_EXTENSION - - if (!strncmp((char *) nextSrc, "SHAPE", 5)) - { - #ifdef TEST - *logofs << "handleRead: Hiding SHAPE extension in reply.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) nextSrc, "NO-SH", 5); - } - - #endif - - // - // Check if user disabled RENDER extension. - // - - if (control -> HideRender == 1 && - !strncmp((char *) nextSrc, "RENDER", 6)) - { - #ifdef TEST - *logofs << "handleRead: Hiding RENDER extension in reply.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) nextSrc, "NO-REN", 6); - } - - for (; length; length--) - { - encodeBuffer.encodeValue((unsigned int) (*nextSrc++), 8); - } - } - - priority_++; - } - break; - case X_ListFonts: - { - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_ListFonts); - - if (handleEncodeCached(encodeBuffer, serverCache_, messageStore, - inputMessage, inputLength)) - { - priority_++; - - hit = 1; - - break; - } - - encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8); - unsigned int numFonts = GetUINT(inputMessage + 8, bigEndian_); - encodeBuffer.encodeValue(numFonts, 16, 6); - - // Differential encoding. - encodeBuffer.encodeBoolValue(1); - - const unsigned char* nextSrc = inputMessage + 32; - for (; numFonts; numFonts--) - { - unsigned int length = (unsigned int) (*nextSrc++); - encodeBuffer.encodeValue(length, 8); - - // Since ProtoStep7 (#issue 108) - encodeBuffer.encodeTextData(nextSrc, length); - - nextSrc += length; - } - - priority_++; - } - break; - case X_LookupColor: - case X_AllocNamedColor: - { - const unsigned char *nextSrc = inputMessage + 8; - if (requestOpcode == X_AllocNamedColor) - { - encodeBuffer.encodeValue(GetULONG(nextSrc, bigEndian_), 32, 9); - nextSrc += 4; - } - unsigned int count = 3; - do - { - unsigned int exactColor = GetUINT(nextSrc, bigEndian_); - encodeBuffer.encodeValue(exactColor, 16, 9); - unsigned int visualColor = GetUINT(nextSrc + 6, bigEndian_) - - exactColor; - encodeBuffer.encodeValue(visualColor, 16, 5); - nextSrc += 2; - } - while (--count); - - priority_++; - } - break; - case X_QueryBestSize: - { - encodeBuffer.encodeValue(GetUINT(inputMessage + 8, bigEndian_), 16, 8); - encodeBuffer.encodeValue(GetUINT(inputMessage + 10, bigEndian_), 16, 8); - - priority_++; - } - break; - case X_QueryColors: - { - // Differential encoding. - encodeBuffer.encodeBoolValue(1); - - unsigned int numColors = ((inputLength - 32) >> 3); - const unsigned char *nextSrc = inputMessage + 40; - unsigned char *nextDest = (unsigned char *) inputMessage + 38; - for (unsigned int c = 1; c < numColors; c++) - { - for (unsigned int i = 0; i < 6; i++) - *nextDest++ = *nextSrc++; - nextSrc += 2; - } - unsigned int colorsLength = numColors * 6; - if (serverCache_ -> queryColorsLastReply.compare(colorsLength, - inputMessage + 32)) - encodeBuffer.encodeBoolValue(1); - else - { - const unsigned char *nextSrc = inputMessage + 32; - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeValue(numColors, 16, 5); - for (numColors *= 3; numColors; numColors--) - { - encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16); - nextSrc += 2; - } - } - - priority_++; - } - break; - case X_QueryExtension: - { - if (requestData[0] == X_QueryExtension) - { - // - // Value in requestData[0] will be nonzero - // if the request is for an extension that - // we should hide to the X client. - // - - if (requestData[1]) - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeValue(0, 8); - } - else - { - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[8]); - encodeBuffer.encodeValue((unsigned int) inputMessage[9], 8); - } - - encodeBuffer.encodeValue((unsigned int) inputMessage[10], 8); - encodeBuffer.encodeValue((unsigned int) inputMessage[11], 8); - - if (requestData[2] == X_NXInternalShapeExtension) - { - opcodeStore_ -> shapeExtension = inputMessage[9]; - - #ifdef TEST - *logofs << "handleRead: Shape extension opcode for FD#" << fd_ - << " is " << (unsigned int) opcodeStore_ -> shapeExtension - << ".\n" << logofs_flush; - #endif - } - else if (requestData[2] == X_NXInternalRenderExtension) - { - opcodeStore_ -> renderExtension = inputMessage[9]; - - #ifdef TEST - *logofs << "handleRead: Render extension opcode for FD#" << fd_ - << " is " << (unsigned int) opcodeStore_ -> renderExtension - << ".\n" << logofs_flush; - #endif - } - - priority_++; - } - else - { - #ifdef TEST - *logofs << "handleRead: Received tainted X_QueryExtension reply " - << "for request OPCODE#" << requestData[0] << " with " - << "sequence " << sequenceNum << ".\n" - << logofs_flush; - #endif - - if (requestData[0] == opcodeStore_ -> getShmemParameters) - { - if (handleShmemReply(encodeBuffer, requestOpcode, requestData[1], - inputMessage, inputLength) < 0) - { - return -1; - } - - priority_++; - } - // - // Account this data to the original opcode. - // - - requestOpcode = requestData[0]; - } - } - break; - case X_QueryFont: - { - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_QueryFont); - - if (handleEncodeCached(encodeBuffer, serverCache_, messageStore, - inputMessage, inputLength)) - { - priority_++; - - hit = 1; - - break; - } - - // Differential encoding. - encodeBuffer.encodeBoolValue(1); - - unsigned int numProperties = GetUINT(inputMessage + 46, bigEndian_); - unsigned int numCharInfos = GetULONG(inputMessage + 56, bigEndian_); - encodeBuffer.encodeValue(numProperties, 16, 8); - encodeBuffer.encodeValue(numCharInfos, 32, 10); - handleEncodeCharInfo(inputMessage + 8, encodeBuffer); - handleEncodeCharInfo(inputMessage + 24, encodeBuffer); - encodeBuffer.encodeValue(GetUINT(inputMessage + 40, bigEndian_), 16, 9); - encodeBuffer.encodeValue(GetUINT(inputMessage + 42, bigEndian_), 16, 9); - encodeBuffer.encodeValue(GetUINT(inputMessage + 44, bigEndian_), 16, 9); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[48]); - encodeBuffer.encodeValue((unsigned int) inputMessage[49], 8); - encodeBuffer.encodeValue((unsigned int) inputMessage[50], 8); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[51]); - encodeBuffer.encodeValue(GetUINT(inputMessage + 52, bigEndian_), 16, 9); - encodeBuffer.encodeValue(GetUINT(inputMessage + 54, bigEndian_), 16, 9); - const unsigned char *nextSrc = inputMessage + 60; - unsigned int index; - - int end = 0; - - if (ServerCache::queryFontFontCache.lookup(numProperties * 8 + - numCharInfos * 12, nextSrc, index)) - { - encodeBuffer.encodeBoolValue(1); - encodeBuffer.encodeValue(index, 4); - - end = 1; - } - - if (end == 0) - { - encodeBuffer.encodeBoolValue(0); - for (; numProperties; numProperties--) - { - encodeBuffer.encodeValue(GetULONG(nextSrc, bigEndian_), 32, 9); - encodeBuffer.encodeValue(GetULONG(nextSrc + 4, bigEndian_), 32, 9); - nextSrc += 8; - } - for (; numCharInfos; numCharInfos--) - { - handleEncodeCharInfo(nextSrc, encodeBuffer); - - nextSrc += 12; - } - } - - priority_++; - } - break; - case X_QueryPointer: - { - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> queryPointerRootCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), - 29, serverCache_ -> queryPointerChildCache, 9); - unsigned int rootX = GetUINT(inputMessage + 16, bigEndian_); - unsigned int rootY = GetUINT(inputMessage + 18, bigEndian_); - unsigned int eventX = GetUINT(inputMessage + 20, bigEndian_); - unsigned int eventY = GetUINT(inputMessage + 22, bigEndian_); - eventX -= rootX; - eventY -= rootY; - encodeBuffer.encodeCachedValue( - rootX - serverCache_ -> motionNotifyLastRootX, 16, - serverCache_ -> motionNotifyRootXCache, 8); - serverCache_ -> motionNotifyLastRootX = rootX; - encodeBuffer.encodeCachedValue( - rootY - serverCache_ -> motionNotifyLastRootY, 16, - serverCache_ -> motionNotifyRootYCache, 8); - serverCache_ -> motionNotifyLastRootY = rootY; - encodeBuffer.encodeCachedValue(eventX, 16, - serverCache_ -> motionNotifyEventXCache, 8); - encodeBuffer.encodeCachedValue(eventY, 16, - serverCache_ -> motionNotifyEventYCache, 8); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 24, bigEndian_), - 16, serverCache_ -> motionNotifyStateCache); - priority_++; - } - break; - case X_QueryTree: - { - // - // This was very inefficient. In practice - // it just copied data on the output. Now - // it obtains an average 7:1 compression - // and could optionally be cached. - // - - unsigned int children = GetUINT(inputMessage + 16, bigEndian_); - - encodeBuffer.encodeValue(children, 16, 8); - - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, - serverCache_ -> queryTreeWindowCache); - - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 29, - serverCache_ -> queryTreeWindowCache); - - const unsigned char *next = inputMessage + 32; - - for (unsigned int i = 0; i < children; i++) - { - encodeBuffer.encodeCachedValue(GetULONG(next + (i * 4), bigEndian_), 29, - serverCache_ -> queryTreeWindowCache); - } - - priority_++; - } - break; - case X_TranslateCoords: - { - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> translateCoordsChildCache, 9); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 12, bigEndian_), - 16, serverCache_ -> translateCoordsXCache, 8); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 14, bigEndian_), - 16, serverCache_ -> translateCoordsYCache, 8); - priority_++; - } - break; - case X_GetImage: - { - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_GetImage); - - if (handleEncodeCached(encodeBuffer, serverCache_, messageStore, - inputMessage, inputLength)) - { - priority_++; - - hit = 1; - - break; - } - - // Depth. - encodeBuffer.encodeCachedValue(inputMessage[1], 8, - serverCache_ -> depthCache); - // Reply length. - encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 9); - - // Visual. - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, - serverCache_ -> visualCache); - - // Since ProtoStep8 (#issue 108) - handleCopy(encodeBuffer, requestOpcode, messageStore -> - dataOffset, inputMessage, inputLength); - - priority_++; - } - break; - case X_GetPointerMapping: - { - encodeBuffer.encodeValue(inputMessage[1], 8, 4); - encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 4); - for (unsigned int i = 32; i < inputLength; i++) - encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8, 4); - - priority_++; - } - break; - case X_GetKeyboardControl: - { - encodeBuffer.encodeValue(inputMessage[1], 8, 2); - encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8); - for (unsigned int i = 8; i < inputLength; i++) - encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8, 4); - - priority_++; - } - break; - default: - { - #ifdef PANIC - *logofs << "ServerChannel: PANIC! No matching request with " - << "OPCODE#" << (unsigned int) requestOpcode - << " for reply with sequence number " - << requestSequenceNum << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": No matching request with OPCODE#" - << (unsigned int) requestOpcode << " for reply with " - << "sequence number " << requestSequenceNum << ".\n"; - - return -1; - } - } - - bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - - const char *cacheString = (hit ? "cached " : ""); - - *logofs << "handleRead: Handled " << cacheString << "reply to OPCODE#" - << (unsigned int) requestOpcode << " (" << DumpOpcode(requestOpcode) - << ") for FD#" << fd_ << " sequence " << serverSequence_ - << ". " << inputLength << " bytes in, " << bits << " bits (" - << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; - - #endif - - } // End of if (sequenceQueue_.peek(requestSequenceNum, requestOpcode) && ... - else - { - // - // We didn't push the request opcode. - // Check if fast encoding is required. - // - - requestOpcode = X_Reply; - - if (control -> LocalDeltaCompression == 0) - { - int result = handleFastReadReply(encodeBuffer, requestOpcode, - inputMessage, inputLength); - if (result < 0) - { - return -1; - } - else if (result > 0) - { - continue; - } - } - - // - // Group all replies whose opcode was not - // pushed in sequence number queue under - // the category 'generic reply'. - // - - #ifdef DEBUG - *logofs << "handleRead: Identified generic reply.\n" - << logofs_flush; - #endif - - MessageStore *messageStore = serverStore_ -> - getReplyStore(X_NXInternalGenericReply); - - hit = handleEncode(encodeBuffer, serverCache_, messageStore, - requestOpcode, inputMessage, inputLength); - - priority_++; - - bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - - const char *cacheString = (hit ? "cached " : ""); - - *logofs << "handleRead: Handled " << cacheString << "generic reply " - << "OPCODE#" << X_NXInternalGenericReply << " for FD#" << fd_ - << " sequence " << serverSequence_ << ". " << inputLength - << " bytes in, " << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - - #endif - } - - if (hit) - { - statistics -> addCachedReply(requestOpcode); - } - - statistics -> addReplyBits(requestOpcode, inputLength << 3, bits); - - } // End of if (inputMessage[0] == 1) ... - else - { - // - // Event or error. - // - - unsigned char inputOpcode = *inputMessage; - - unsigned int inputSequence = GetUINT(inputMessage + 2, bigEndian_); - - // - // Check if this is an event which we can discard. - // - - if ((inputOpcode == Expose && enableExpose_ == 0) || - (inputOpcode == GraphicsExpose && enableGraphicsExpose_ == 0) || - (inputOpcode == NoExpose && enableNoExpose_ == 0)) - { - continue; - } - else if (shmemState_ != NULL && shmemState_ -> enabled == 1 && - inputOpcode == shmemState_ -> event && - checkShmemEvent(inputOpcode, inputSequence, - inputMessage) > 0) - { - continue; - } - else if (inputOpcode == MotionNotify) - { - // - // Save the motion event and send when another - // event or error is received or the motion ti- - // meout is elapsed. If a previous motion event - // was already saved, we replace it with the - // new one and don't reset the timeout, so we - // still have a motion event every given ms. - // - - memcpy(lastMotion_, inputMessage, 32); - - #ifdef TEST - *logofs << "handleRead: Saved suppressed motion event for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - continue; - } - else if (inputOpcode == X_Error) - { - // - // Check if this is an error that matches a - // sequence number for which we are expecting - // a reply. - // - - unsigned short int errorSequenceNum; - unsigned char errorOpcode; - - if (sequenceQueue_.peek(errorSequenceNum, errorOpcode) && - ((unsigned int) errorSequenceNum == inputSequence)) - { - sequenceQueue_.pop(errorSequenceNum, errorOpcode); - } - - // - // Check if error is due to an image commit - // generated at the end of a split. - // - - if (checkCommitError(*(inputMessage + 1), inputSequence, inputMessage) > 0) - { - #ifdef TEST - *logofs << "handleRead: Skipping error on image commit for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - continue; - } - - // - // Check if it's an error generated by a request - // concerning shared memory support. - // - - else if (shmemState_ != NULL && (shmemState_ -> sequence == - inputSequence || (shmemState_ -> enabled == 1 && - (shmemState_ -> opcode == *(inputMessage + 10) || - shmemState_ -> error == *(inputMessage + 1)))) && - checkShmemError(*(inputMessage + 1), inputSequence, - inputMessage) > 0) - { - #ifdef TEST - *logofs << "handleRead: Skipping error on shmem operation for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - continue; - } - } - // - // Check if user pressed the CTRL+ALT+SHIFT+ESC key - // sequence because was unable to kill the session - // through the normal procedure. - // - - if (inputOpcode == KeyPress) - { - if (checkKeyboardEvent(inputOpcode, inputSequence, inputMessage) == 1) - { - #ifdef TEST - *logofs << "handleRead: Removing the key sequence from the " - << "event stream for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - continue; - } - } - - // - // We are going to handle an event or error - // that's not a mouse motion. Prepend any - // saved motion to it. - // - - if (lastMotion_[0] != '\0') - { - if (handleMotion(encodeBuffer) < 0) - { - #ifdef PANIC - *logofs << "handleRead: PANIC! Can't encode motion event for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't encode motion event for FD#" - << fd_ << ".\n"; - - return -1; - } - } - - // - // Encode opcode and difference between - // current sequence and the last one. - // - - encodeBuffer.encodeOpcodeValue(inputOpcode, serverCache_ -> opcodeCache); - - unsigned int sequenceDiff = inputSequence - serverSequence_; - - serverSequence_ = inputSequence; - - #ifdef DEBUG - *logofs << "handleRead: Last server sequence number for FD#" - << fd_ << " is " << serverSequence_ << " with " - << "difference " << sequenceDiff << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(sequenceDiff, 16, - serverCache_ -> eventSequenceCache, 7); - - // - // If differential compression is disabled - // then use the most simple encoding. - // - - if (control -> LocalDeltaCompression == 0) - { - int result = handleFastReadEvent(encodeBuffer, inputOpcode, - inputMessage, inputLength); - if (result < 0) - { - return -1; - } - else if (result > 0) - { - continue; - } - } - - switch (inputOpcode) - { - case X_Error: - { - // - // Set the priority flag in the case of - // a X protocol error. This may restart - // the client if it was waiting for the - // reply. - // - - priority_++; - - unsigned char errorCode = *(inputMessage + 1); - - encodeBuffer.encodeCachedValue(errorCode, 8, - serverCache_ -> errorCodeCache); - - if (errorCode != 11 && errorCode != 8 && - errorCode != 15 && errorCode != 1) - { - encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 16); - } - - if (errorCode >= 18) - { - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, - serverCache_ -> errorMinorCache); - } - - encodeBuffer.encodeCachedValue(inputMessage[10], 8, - serverCache_ -> errorMajorCache); - - if (errorCode >= 18) - { - const unsigned char *nextSrc = inputMessage + 11; - for (unsigned int i = 11; i < 32; i++) - encodeBuffer.encodeValue(*nextSrc++, 8); - } - } - break; - case ButtonPress: - case ButtonRelease: - case KeyPress: - case KeyRelease: - case MotionNotify: - case EnterNotify: - case LeaveNotify: - { - // - // Set the priority in the case this is - // an event that the remote side may - // care to receive as soon as possible. - // - - switch (inputOpcode) - { - case ButtonPress: - case ButtonRelease: - case KeyPress: - case KeyRelease: - { - priority_++; - } - } - - unsigned char detail = inputMessage[1]; - if (*inputMessage == MotionNotify) - encodeBuffer.encodeBoolValue((unsigned int) detail); - else if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify)) - encodeBuffer.encodeValue((unsigned int) detail, 3); - else if (*inputMessage == KeyRelease) - { - if (detail == serverCache_ -> keyPressLastKey) - encodeBuffer.encodeBoolValue(1); - else - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeValue((unsigned int) detail, 8); - } - } - else if ((*inputMessage == ButtonPress) || (*inputMessage == ButtonRelease)) - encodeBuffer.encodeCachedValue(detail, 8, - serverCache_ -> buttonCache); - else - encodeBuffer.encodeValue((unsigned int) detail, 8); - unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_); - unsigned int timestampDiff = - timestamp - serverCache_ -> lastTimestamp; - serverCache_ -> lastTimestamp = timestamp; - encodeBuffer.encodeCachedValue(timestampDiff, 32, - serverCache_ -> motionNotifyTimestampCache, 9); - int skipRest = 0; - if (*inputMessage == KeyRelease) - { - skipRest = 1; - for (unsigned int i = 8; i < 31; i++) - { - if (inputMessage[i] != serverCache_ -> keyPressCache[i - 8]) - { - skipRest = 0; - break; - } - } - encodeBuffer.encodeBoolValue(skipRest); - } - - if (!skipRest) - { - const unsigned char *nextSrc = inputMessage + 8; - for (unsigned int i = 0; i < 3; i++) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29, - *serverCache_ -> motionNotifyWindowCache[i], 6); - nextSrc += 4; - } - unsigned int rootX = GetUINT(inputMessage + 20, bigEndian_); - unsigned int rootY = GetUINT(inputMessage + 22, bigEndian_); - unsigned int eventX = GetUINT(inputMessage + 24, bigEndian_); - unsigned int eventY = GetUINT(inputMessage + 26, bigEndian_); - eventX -= rootX; - eventY -= rootY; - encodeBuffer.encodeCachedValue(rootX - - serverCache_ -> motionNotifyLastRootX, 16, - serverCache_ -> motionNotifyRootXCache, 6); - serverCache_ -> motionNotifyLastRootX = rootX; - encodeBuffer.encodeCachedValue(rootY - - serverCache_ -> motionNotifyLastRootY, 16, - serverCache_ -> motionNotifyRootYCache, 6); - serverCache_ -> motionNotifyLastRootY = rootY; - encodeBuffer.encodeCachedValue(eventX, 16, - serverCache_ -> motionNotifyEventXCache, 6); - encodeBuffer.encodeCachedValue(eventY, 16, - serverCache_ -> motionNotifyEventYCache, 6); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 28, bigEndian_), - 16, serverCache_ -> motionNotifyStateCache); - if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify)) - encodeBuffer.encodeValue((unsigned int) inputMessage[30], 2); - else - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[30]); - if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify)) - encodeBuffer.encodeValue((unsigned int) inputMessage[31], 2); - else if (*inputMessage == KeyPress) - { - serverCache_ -> keyPressLastKey = detail; - for (unsigned int i = 8; i < 31; i++) - { - serverCache_ -> keyPressCache[i - 8] = inputMessage[i]; - } - } - } - } - break; - case ColormapNotify: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, serverCache_ -> colormapNotifyWindowCache, 8); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> colormapNotifyColormapCache, 8); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[12]); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[13]); - } - break; - case ConfigureNotify: - { - const unsigned char *nextSrc = inputMessage + 4; - for (unsigned int i = 0; i < 3; i++) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29, - *serverCache_ -> configureNotifyWindowCache[i], 9); - nextSrc += 4; - } - for (unsigned int j = 0; j < 5; j++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *serverCache_ -> configureNotifyGeomCache[j], 8); - nextSrc += 2; - } - encodeBuffer.encodeBoolValue(*nextSrc); - } - break; - case CreateNotify: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, serverCache_ -> createNotifyWindowCache, 9); - unsigned int window = GetULONG(inputMessage + 8, bigEndian_); - encodeBuffer.encodeValue(window - - serverCache_ -> createNotifyLastWindow, 29, 5); - serverCache_ -> createNotifyLastWindow = window; - const unsigned char* nextSrc = inputMessage + 12; - for (unsigned int i = 0; i < 5; i++) - { - encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16, 9); - nextSrc += 2; - } - encodeBuffer.encodeBoolValue(*nextSrc); - } - break; - case Expose: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, - serverCache_ -> exposeWindowCache, 9); - const unsigned char *nextSrc = inputMessage + 8; - for (unsigned int i = 0; i < 5; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, - *serverCache_ -> exposeGeomCache[i], 6); - nextSrc += 2; - } - } - break; - case FocusIn: - case FocusOut: - { - encodeBuffer.encodeValue((unsigned int) inputMessage[1], 3); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, serverCache_ -> focusInWindowCache, 9); - encodeBuffer.encodeValue((unsigned int) inputMessage[8], 2); - } - break; - case KeymapNotify: - { - if (ServerCache::lastKeymap.compare(31, inputMessage + 1)) - encodeBuffer.encodeBoolValue(1); - else - { - encodeBuffer.encodeBoolValue(0); - const unsigned char *nextSrc = inputMessage + 1; - for (unsigned int i = 1; i < 32; i++) - encodeBuffer.encodeValue((unsigned int) *nextSrc++, 8); - } - } - break; - case MapNotify: - case UnmapNotify: - case DestroyNotify: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, serverCache_ -> mapNotifyEventCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> mapNotifyWindowCache, 9); - if ((*inputMessage == MapNotify) || (*inputMessage == UnmapNotify)) - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[12]); - } - break; - case NoExpose: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, serverCache_ -> noExposeDrawableCache, 9); - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, - serverCache_ -> noExposeMinorCache); - encodeBuffer.encodeCachedValue(inputMessage[10], 8, - serverCache_ -> noExposeMajorCache); - } - break; - case PropertyNotify: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, serverCache_ -> propertyNotifyWindowCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> propertyNotifyAtomCache, 9); - unsigned int timestamp = GetULONG(inputMessage + 12, bigEndian_); - unsigned int timestampDiff = - timestamp - serverCache_ -> lastTimestamp; - serverCache_ -> lastTimestamp = timestamp; - encodeBuffer.encodeValue(timestampDiff, 32, 9); - encodeBuffer.encodeBoolValue((unsigned int) inputMessage[16]); - } - break; - case ReparentNotify: - { - const unsigned char* nextSrc = inputMessage + 4; - for (unsigned int i = 0; i < 3; i++) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), - 29, serverCache_ -> reparentNotifyWindowCache, 9); - nextSrc += 4; - } - encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16, 6); - encodeBuffer.encodeValue(GetUINT(nextSrc + 2, bigEndian_), 16, 6); - encodeBuffer.encodeBoolValue((unsigned int)inputMessage[20]); - } - break; - case SelectionClear: - { - unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_); - unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp; - serverCache_ -> lastTimestamp = timestamp; - encodeBuffer.encodeValue(timestampDiff, 32, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> selectionClearWindowCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), - 29, serverCache_ -> selectionClearAtomCache, 9); - } - break; - case SelectionRequest: - { - unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_); - unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp; - serverCache_ -> lastTimestamp = timestamp; - encodeBuffer.encodeValue(timestampDiff, 32, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), - 29, serverCache_ -> selectionClearWindowCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), - 29, serverCache_ -> selectionClearWindowCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), - 29, serverCache_ -> selectionClearAtomCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 20, bigEndian_), - 29, serverCache_ -> selectionClearAtomCache, 9); - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 24, bigEndian_), - 29, serverCache_ -> selectionClearAtomCache, 9); - } - break; - case VisibilityNotify: - { - encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), - 29, serverCache_ -> visibilityNotifyWindowCache, 9); - encodeBuffer.encodeValue((unsigned int) inputMessage[8], 2); - } - break; - default: - { - #ifdef TEST - *logofs << "handleRead: Using generic event compression " - << "for OPCODE#" << (unsigned int) inputOpcode - << ".\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(*(inputMessage + 1), 8, - serverCache_ -> genericEventCharCache); - - for (unsigned int i = 0; i < 14; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(inputMessage + i * 2 + 4, bigEndian_), - 16, *serverCache_ -> genericEventIntCache[i]); - } - } - - } // switch (inputOpcode)... - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - - if (*inputMessage == X_Error) - { - unsigned char code = *(inputMessage + 1); - - *logofs << "handleRead: Handled error ERR_CODE#" - << (unsigned int) code << " for FD#" << fd_; - - *logofs << " RES_ID#" << GetULONG(inputMessage + 4, bigEndian_); - - *logofs << " MIN_OP#" << GetUINT(inputMessage + 8, bigEndian_); - - *logofs << " MAJ_OP#" << (unsigned int) *(inputMessage + 10); - - *logofs << " sequence " << inputSequence << ". " << inputLength - << " bytes in, " << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - } - else - { - *logofs << "handleRead: Handled event OPCODE#" - << (unsigned int) *inputMessage << " for FD#" << fd_ - << " sequence " << inputSequence << ". " << inputLength - << " bytes in, " << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - } - - #endif - - statistics -> addEventBits(*inputMessage, inputLength << 3, bits); - - } // End of if (inputMessage[0] == X_Reply) ... else ... - - } // End of if (firstReply_) ... else ... - - } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != 0) ... - - // - // Check if we need to flush because of - // prioritized data. - // - - if (priority_ > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: WARNING! Requesting flush " - << "because of " << priority_ << " prioritized " - << "messages for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - if (proxy -> handleAsyncPriority() < 0) - { - return -1; - } - - // - // Reset the priority flag. - // - - priority_ = 0; - } - - // - // Flush if we produced enough data. - // - - if (proxy -> canAsyncFlush() == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleRead: WARNING! Requesting flush " - << "because of token length exceeded.\n" - << logofs_flush; - #endif - - if (proxy -> handleAsyncFlush() < 0) - { - return -1; - } - } - - #if defined(TEST) || defined(INFO) - - if (transport_ -> pending() != 0 || - readBuffer_.checkMessage() != 0) - { - *logofs << "handleRead: PANIC! Buffer for X descriptor FD#" - << fd_ << " has " << transport_ -> pending() - << " bytes to read.\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - // - // Reset the read buffer. - // - - readBuffer_.fullReset(); - - return 1; -} - -// -// End of handleRead(). -// - -// -// Beginning of handleWrite(). -// - -int ServerChannel::handleWrite(const unsigned char *message, unsigned int length) -{ - #ifdef TEST - *logofs << "handleWrite: Called for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - // - // Create the buffer from which to - // decode messages. - // - - DecodeBuffer decodeBuffer(message, length); - - #if defined(TEST) || defined(INFO) || defined(FLUSH) - *logofs << "handleWrite: Decoding messages for FD#" << fd_ - << " with " << length << " bytes in the buffer.\n" - << logofs_flush; - #endif - - if (firstRequest_) - { - // - // Need to add the length of the first request - // because it was not present in the previous - // versions. Length of the first request was - // assumed to be the same as the encode buffer - // but this may be not the case if a different - // encoding is used. - // - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeValue(length, 8); - - unsigned int nextByte; - unsigned char *outputMessage = writeBuffer_.addMessage(length); - unsigned char *nextDest = outputMessage; - - for (unsigned int i = 0; i < length; i++) - { - decodeBuffer.decodeValue(nextByte, 8); - - *nextDest++ = (unsigned char) nextByte; - } - - if (*outputMessage == 0x42) - { - setBigEndian(1); - } - else - { - setBigEndian(0); - } - - #ifdef TEST - *logofs << "handleWrite: First request detected.\n" << logofs_flush; - #endif - - // - // Handle the fake authorization cookie. - // - - if (handleAuthorization(outputMessage) < 0) - { - return -1; - } - - firstRequest_ = 0; - - } // End of if (firstRequest_) - - // - // This was previously in a 'else' block. - // Due to the way the first request was - // handled, we could not decode multiple - // messages in the first frame. - // - - { // Start of the decoding block. - - unsigned char outputOpcode; - - unsigned char *outputMessage; - unsigned int outputLength; - - // - // Set when message is found in cache. - // - - int hit; - - while (decodeBuffer.decodeOpcodeValue(outputOpcode, clientCache_ -> opcodeCache, 1)) - { - hit = 0; - - // - // Splits are sent by client proxy outside the - // normal read loop. As we 'insert' splits in - // the real client-server X protocol, we must - // avoid to increment the sequence number or - // our clients would get confused. - // - - if (outputOpcode != opcodeStore_ -> splitData) - { - clientSequence_++; - clientSequence_ &= 0xffff; - - #ifdef DEBUG - *logofs << "handleWrite: Last client sequence number for FD#" - << fd_ << " is " << clientSequence_ << ".\n" - << logofs_flush; - #endif - } - else - { - // - // It's a split, not a normal - // burst of proxy data. - // - - handleSplit(decodeBuffer); - - continue; - } - - #ifdef SUSPEND - - if (clientSequence_ == 1000) - { - cerr << "Warning" << ": Exiting to test the resilience of the agent.\n"; - - sleep(2); - - HandleAbort(); - } - - #endif - - // - // Is differential encoding disabled? - // - - if (control -> RemoteDeltaCompression == 0) - { - int result = handleFastWriteRequest(decodeBuffer, outputOpcode, - outputMessage, outputLength); - if (result < 0) - { - return -1; - } - else if (result > 0) - { - continue; - } - } - - // - // General-purpose temp variables for - // decoding ints and chars. - // - - unsigned int value; - unsigned char cValue; - - #ifdef DEBUG - *logofs << "handleWrite: Going to handle request OPCODE#" - << (unsigned int) outputOpcode << " (" << DumpOpcode(outputOpcode) - << ") for FD#" << fd_ << " sequence " << clientSequence_ - << ".\n" << logofs_flush; - #endif - - switch (outputOpcode) - { - case X_AllocColor: - { - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> colormapCache); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned char *nextDest = outputMessage + 8; - unsigned int colorData[3]; - - for (unsigned int i = 0; i < 3; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *(clientCache_ -> allocColorRGBCache[i]), 4); - PutUINT(value, nextDest, bigEndian_); - colorData[i] = value; - nextDest += 2; - } - - sequenceQueue_.push(clientSequence_, outputOpcode, - colorData[0], colorData[1], colorData[2]); - } - break; - case X_ReparentWindow: - { - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeValue(value, 16, 11); - PutUINT(value, outputMessage + 12, bigEndian_); - decodeBuffer.decodeValue(value, 16, 11); - PutUINT(value, outputMessage + 14, bigEndian_); - } - break; - case X_ChangeProperty: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ChangeProperty); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - unsigned char format; - decodeBuffer.decodeCachedValue(format, 8, - clientCache_ -> changePropertyFormatCache); - unsigned int dataLength; - decodeBuffer.decodeValue(dataLength, 32, 6); - outputLength = 24 + RoundUp4(dataLength * (format >> 3)); - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 2); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> changePropertyPropertyCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> changePropertyTypeCache, 9); - PutULONG(value, outputMessage + 12, bigEndian_); - outputMessage[16] = format; - PutULONG(dataLength, outputMessage + 20, bigEndian_); - unsigned char *nextDest = outputMessage + 24; - - if (format == 8) - { - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, dataLength); - } - else if (format == 32) - { - for (unsigned int i = 0; i < dataLength; i++) - { - decodeBuffer.decodeCachedValue(value, 32, - clientCache_ -> changePropertyData32Cache); - - PutULONG(value, nextDest, bigEndian_); - - nextDest += 4; - } - } - else - { - for (unsigned int i = 0; i < dataLength; i++) - { - decodeBuffer.decodeValue(value, 16); - - PutUINT(value, nextDest, bigEndian_); - - nextDest += 2; - } - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_SendEvent: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_SendEvent); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 44; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeBoolValue(value); - *(outputMessage + 1) = value; - decodeBuffer.decodeBoolValue(value); - if (value) - { - decodeBuffer.decodeBoolValue(value); - } - else - { - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - } - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 32, - clientCache_ -> sendEventMaskCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(*(outputMessage + 12), 8, - clientCache_ -> sendEventCodeCache); - decodeBuffer.decodeCachedValue(*(outputMessage + 13), 8, - clientCache_ -> sendEventByteDataCache); - decodeBuffer.decodeValue(value, 16, 4); - clientCache_ -> sendEventLastSequence += value; - clientCache_ -> sendEventLastSequence &= 0xffff; - PutUINT(clientCache_ -> sendEventLastSequence, outputMessage + 14, bigEndian_); - decodeBuffer.decodeCachedValue(value, 32, - clientCache_ -> sendEventIntDataCache); - PutULONG(value, outputMessage + 16, bigEndian_); - - for (unsigned int i = 20; i < 44; i++) - { - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache_ -> sendEventEventCache); - *(outputMessage + i) = cValue; - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_ChangeWindowAttributes: - { - unsigned int numAttrs; - decodeBuffer.decodeValue(numAttrs, 4); - outputLength = 12 + (numAttrs << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned int bitmask; - decodeBuffer.decodeCachedValue(bitmask, 15, - clientCache_ -> createWindowBitmaskCache); - PutULONG(bitmask, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - unsigned int mask = 0x1; - for (unsigned int i = 0; i < 15; i++) - { - if (bitmask & mask) - { - decodeBuffer.decodeCachedValue(value, 32, - *clientCache_ -> createWindowAttrCache[i]); - PutULONG(value, nextDest, bigEndian_); - nextDest += 4; - } - mask <<= 1; - } - } - break; - case X_ClearArea: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ClearArea); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeBoolValue(value); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned char *nextDest = outputMessage + 8; - for (unsigned int i = 0; i < 4; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> clearAreaGeomCache[i], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_CloseFont: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 29, 5); - clientCache_ -> lastFont += value; - clientCache_ -> lastFont &= 0x1fffffff; - PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_); - } - break; - case X_ConfigureWindow: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ConfigureWindow); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 12; - outputMessage = writeBuffer_.addMessage(outputLength); - writeBuffer_.registerPointer(&outputMessage); - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned int bitmask; - decodeBuffer.decodeCachedValue(bitmask, 7, - clientCache_ -> configureWindowBitmaskCache); - PutUINT(bitmask, outputMessage + 8, bigEndian_); - unsigned int mask = 0x1; - for (unsigned int i = 0; i < 7; i++) - { - if (bitmask & mask) - { - unsigned char* nextDest = writeBuffer_.addMessage(4); - outputLength += 4; - decodeBuffer.decodeCachedValue(value, CONFIGUREWINDOW_FIELD_WIDTH[i], - *clientCache_ -> configureWindowAttrCache[i], 8); - PutULONG(value, nextDest, bigEndian_); - nextDest += 4; - } - mask <<= 1; - } - writeBuffer_.unregisterPointer(); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_ConvertSelection: - { - outputLength = 24; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> convertSelectionRequestorCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned char* nextDest = outputMessage + 8; - for (unsigned int i = 0; i < 3; i++) - { - decodeBuffer.decodeCachedValue(value, 29, - *(clientCache_ -> convertSelectionAtomCache[i]), 9); - PutULONG(value, nextDest, bigEndian_); - nextDest += 4; - } - decodeBuffer.decodeValue(value, 32, 4); - clientCache_ -> convertSelectionLastTimestamp += value; - PutULONG(clientCache_ -> convertSelectionLastTimestamp, - nextDest, bigEndian_); - } - break; - case X_CopyArea: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_CopyArea); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 28; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 12, bigEndian_); - unsigned char *nextDest = outputMessage + 16; - for (unsigned int i = 0; i < 6; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> copyAreaGeomCache[i], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_CopyGC: - { - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 23, - clientCache_ -> createGCBitmaskCache); - PutULONG(value, outputMessage + 12, bigEndian_); - } - break; - case X_CopyPlane: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 12, bigEndian_); - unsigned char *nextDest = outputMessage + 16; - for (unsigned int i = 0; i < 6; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> copyPlaneGeomCache[i], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - decodeBuffer.decodeCachedValue(value, 32, - clientCache_ -> copyPlaneBitPlaneCache, 10); - PutULONG(value, outputMessage + 28, bigEndian_); - } - break; - case X_CreateGC: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_CreateGC); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - writeBuffer_.registerPointer(&outputMessage); - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeNewXidValue(value, clientCache_ -> lastId, - clientCache_ -> lastIdCache, clientCache_ -> gcCache, - clientCache_ -> freeGCCache); - - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned int offset = 8; - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + offset, bigEndian_); - offset += 4; - unsigned int bitmask; - decodeBuffer.decodeCachedValue(bitmask, 23, - clientCache_ -> createGCBitmaskCache); - PutULONG(bitmask, outputMessage + offset, bigEndian_); - unsigned int mask = 0x1; - for (unsigned int i = 0; i < 23; i++) - { - if (bitmask & mask) - { - unsigned char* nextDest = writeBuffer_.addMessage(4); - outputLength += 4; - unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i]; - if (fieldWidth <= 4) - decodeBuffer.decodeValue(value, fieldWidth); - else - decodeBuffer.decodeCachedValue(value, fieldWidth, - *clientCache_ -> createGCAttrCache[i]); - PutULONG(value, nextDest, bigEndian_); - } - mask <<= 1; - } - writeBuffer_.unregisterPointer(); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_ChangeGC: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ChangeGC); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 12; - outputMessage = writeBuffer_.addMessage(outputLength); - writeBuffer_.registerPointer(&outputMessage); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned int offset = 8; - unsigned int bitmask; - decodeBuffer.decodeCachedValue(bitmask, 23, - clientCache_ -> createGCBitmaskCache); - PutULONG(bitmask, outputMessage + offset, bigEndian_); - unsigned int mask = 0x1; - for (unsigned int i = 0; i < 23; i++) - { - if (bitmask & mask) - { - unsigned char* nextDest = writeBuffer_.addMessage(4); - outputLength += 4; - unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i]; - if (fieldWidth <= 4) - decodeBuffer.decodeValue(value, fieldWidth); - else - decodeBuffer.decodeCachedValue(value, fieldWidth, - *clientCache_ -> createGCAttrCache[i]); - PutULONG(value, nextDest, bigEndian_); - } - mask <<= 1; - } - writeBuffer_.unregisterPointer(); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_CreatePixmap: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_CreatePixmap); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - } - break; - case X_CreateWindow: - { - outputLength = 32; - outputMessage = writeBuffer_.addMessage(outputLength); - writeBuffer_.registerPointer(&outputMessage); - decodeBuffer.decodeCachedValue(cValue, 8, clientCache_ -> depthCache); - outputMessage[1] = cValue; - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 8, bigEndian_); - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeNewXidValue(value, clientCache_ -> lastId, - clientCache_ -> lastIdCache, clientCache_ -> windowCache, - clientCache_ -> freeWindowCache); - - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - unsigned int i; - for (i = 0; i < 6; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> createWindowGeomCache[i], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> visualCache); - PutULONG(value, outputMessage + 24, bigEndian_); - unsigned int bitmask; - decodeBuffer.decodeCachedValue(bitmask, 15, - clientCache_ -> createWindowBitmaskCache); - PutULONG(bitmask, outputMessage + 28, bigEndian_); - unsigned int mask = 0x1; - for (i = 0; i < 15; i++) - { - if (bitmask & mask) - { - nextDest = writeBuffer_.addMessage(4); - outputLength += 4; - decodeBuffer.decodeCachedValue(value, 32, - *clientCache_ -> createWindowAttrCache[i]); - PutULONG(value, nextDest, bigEndian_); - } - mask <<= 1; - } - writeBuffer_.unregisterPointer(); - } - break; - case X_DeleteProperty: - { - outputLength = 12; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeValue(value, 29, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - } - break; - case X_FillPoly: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_FillPoly); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - unsigned int numPoints; - - // Since ProtoStep10 (#issue 108) - decodeBuffer.decodeCachedValue(numPoints, 16, - clientCache_ -> fillPolyNumPointsCache, 4); - - outputLength = 16 + (numPoints << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeValue(value, 2); - outputMessage[12] = (unsigned char) value; - unsigned int relativeCoordMode; - decodeBuffer.decodeBoolValue(relativeCoordMode); - outputMessage[13] = (unsigned char) relativeCoordMode; - unsigned char *nextDest = outputMessage + 16; - unsigned int pointIndex = 0; - for (unsigned int i = 0; i < numPoints; i++) - { - if (relativeCoordMode) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> fillPolyXRelCache[pointIndex], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> fillPolyYRelCache[pointIndex], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - else - { - unsigned int x, y; - decodeBuffer.decodeBoolValue(value); - if (value) - { - decodeBuffer.decodeValue(value, 3); - x = clientCache_ -> fillPolyRecentX[value]; - y = clientCache_ -> fillPolyRecentY[value]; - } - else - { - decodeBuffer.decodeCachedValue(x, 16, - *clientCache_ -> fillPolyXAbsCache[pointIndex], 8); - decodeBuffer.decodeCachedValue(y, 16, - *clientCache_ -> fillPolyYAbsCache[pointIndex], 8); - clientCache_ -> fillPolyRecentX[clientCache_ -> fillPolyIndex] = x; - clientCache_ -> fillPolyRecentY[clientCache_ -> fillPolyIndex] = y; - clientCache_ -> fillPolyIndex++; - if (clientCache_ -> fillPolyIndex == 8) - clientCache_ -> fillPolyIndex = 0; - } - PutUINT(x, nextDest, bigEndian_); - nextDest += 2; - PutUINT(y, nextDest, bigEndian_); - nextDest += 2; - } - - if (++pointIndex == 10) pointIndex = 0; - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_FreeColors: - { - unsigned int numPixels; - decodeBuffer.decodeValue(numPixels, 16, 4); - outputLength = 12 + (numPixels << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> colormapCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeValue(value, 32, 4); - PutULONG(value, outputMessage + 8, bigEndian_); - unsigned char* nextDest = outputMessage + 12; - while (numPixels) - { - decodeBuffer.decodeValue(value, 32, 8); - PutULONG(value, nextDest, bigEndian_); - nextDest += 4; - numPixels--; - } - } - break; - case X_FreeCursor: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> cursorCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - } - break; - case X_FreeGC: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeGCCache); - - PutULONG(value, outputMessage + 4, bigEndian_); - } - break; - case X_FreePixmap: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeDrawableCache); - - PutULONG(value, outputMessage + 4, bigEndian_); - } - break; - case X_GetAtomName: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 29, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_GetGeometry: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_GetInputFocus: - { - outputLength = 4; - outputMessage = writeBuffer_.addMessage(outputLength); - - sequenceQueue_.push(clientSequence_, outputOpcode, outputOpcode); - } - break; - case X_GetModifierMapping: - { - outputLength = 4; - outputMessage = writeBuffer_.addMessage(outputLength); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_GetKeyboardMapping: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 8); - outputMessage[4] = value; - decodeBuffer.decodeValue(value, 8); - outputMessage[5] = value; - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_GetProperty: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_GetProperty); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - // - // Save a reference to identify the reply. - // - - unsigned int property = GetULONG(outputMessage + 8, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode, property); - - break; - } - - outputLength = 24; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeBoolValue(value); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned int property; - decodeBuffer.decodeValue(property, 29, 9); - PutULONG(property, outputMessage + 8, bigEndian_); - decodeBuffer.decodeValue(value, 29, 9); - PutULONG(value, outputMessage + 12, bigEndian_); - decodeBuffer.decodeValue(value, 32, 2); - PutULONG(value, outputMessage + 16, bigEndian_); - decodeBuffer.decodeValue(value, 32, 8); - PutULONG(value, outputMessage + 20, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode, property); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_GetSelectionOwner: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> getSelectionOwnerSelectionCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_GrabButton: - case X_GrabPointer: - { - outputLength = 24; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeBoolValue(value); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> grabButtonEventMaskCache); - PutUINT(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeBoolValue(value); - outputMessage[10] = (unsigned char) value; - decodeBuffer.decodeBoolValue(value); - outputMessage[11] = (unsigned char) value; - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> grabButtonConfineCache, 9); - PutULONG(value, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> cursorCache, 9); - PutULONG(value, outputMessage + 16, bigEndian_); - if (outputOpcode == X_GrabButton) - { - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache_ -> grabButtonButtonCache); - outputMessage[20] = cValue; - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> grabButtonModifierCache); - PutUINT(value, outputMessage + 22, bigEndian_); - } - else - { - decodeBuffer.decodeValue(value, 32, 4); - clientCache_ -> grabKeyboardLastTimestamp += value; - PutULONG(clientCache_ -> grabKeyboardLastTimestamp, - outputMessage + 20, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - } - break; - case X_GrabKeyboard: - { - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeBoolValue(value); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeValue(value, 32, 4); - clientCache_ -> grabKeyboardLastTimestamp += value; - PutULONG(clientCache_ -> grabKeyboardLastTimestamp, outputMessage + 8, - bigEndian_); - decodeBuffer.decodeBoolValue(value); - outputMessage[12] = (unsigned char) value; - decodeBuffer.decodeBoolValue(value); - outputMessage[13] = (unsigned char) value; - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_GrabServer: - case X_UngrabServer: - case X_NoOperation: - { - #ifdef DEBUG - *logofs << "handleWrite: Managing (probably tainted) X_NoOperation request for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - outputLength = 4; - outputMessage = writeBuffer_.addMessage(outputLength); - } - break; - case X_PolyText8: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyText8); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> polyTextCacheX); - clientCache_ -> polyTextLastX += value; - clientCache_ -> polyTextLastX &= 0xffff; - PutUINT(clientCache_ -> polyTextLastX, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> polyTextCacheY); - clientCache_ -> polyTextLastY += value; - clientCache_ -> polyTextLastY &= 0xffff; - PutUINT(clientCache_ -> polyTextLastY, outputMessage + 14, bigEndian_); - unsigned int addedLength = 0; - writeBuffer_.registerPointer(&outputMessage); - for (;;) - { - decodeBuffer.decodeBoolValue(value); - if (!value) - break; - unsigned int textLength; - decodeBuffer.decodeValue(textLength, 8); - if (textLength == 255) - { - addedLength += 5; - unsigned char *nextSegment = writeBuffer_.addMessage(5); - *nextSegment = (unsigned char) textLength; - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> polyTextFontCache); - PutULONG(value, nextSegment + 1, 1); - } - else - { - addedLength += (textLength + 2); - unsigned char *nextSegment = - writeBuffer_.addMessage(textLength + 2); - *nextSegment = (unsigned char) textLength; - unsigned char *nextDest = nextSegment + 1; - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache_ -> polyTextDeltaCache); - *nextDest++ = cValue; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, textLength); - - nextDest += textLength; - } - } - outputLength += addedLength; - unsigned int mod4 = (addedLength & 0x3); - if (mod4) - { - unsigned int extra = 4 - mod4; - unsigned char *nextDest = writeBuffer_.addMessage(extra); - for (unsigned int i = 0; i < extra; i++) - *nextDest++ = 0; - outputLength += extra; - } - writeBuffer_.unregisterPointer(); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_PolyText16: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyText16); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> polyTextCacheX); - clientCache_ -> polyTextLastX += value; - clientCache_ -> polyTextLastX &= 0xffff; - PutUINT(clientCache_ -> polyTextLastX, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> polyTextCacheY); - clientCache_ -> polyTextLastY += value; - clientCache_ -> polyTextLastY &= 0xffff; - PutUINT(clientCache_ -> polyTextLastY, outputMessage + 14, bigEndian_); - unsigned int addedLength = 0; - writeBuffer_.registerPointer(&outputMessage); - for (;;) - { - decodeBuffer.decodeBoolValue(value); - if (!value) - break; - unsigned int textLength; - decodeBuffer.decodeValue(textLength, 8); - if (textLength == 255) - { - addedLength += 5; - unsigned char *nextSegment = writeBuffer_.addMessage(5); - *nextSegment = (unsigned char) textLength; - decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> polyTextFontCache); - PutULONG(value, nextSegment + 1, 1); - } - else - { - addedLength += (textLength * 2 + 2); - unsigned char *nextSegment = - writeBuffer_.addMessage(textLength * 2 + 2); - *nextSegment = (unsigned char) textLength; - unsigned char *nextDest = nextSegment + 1; - decodeBuffer.decodeCachedValue(cValue, 8, clientCache_ -> polyTextDeltaCache); - *nextDest++ = cValue; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, textLength * 2); - - nextDest += textLength * 2; - } - } - outputLength += addedLength; - - unsigned int mod4 = (addedLength & 0x3); - if (mod4) - { - unsigned int extra = 4 - mod4; - unsigned char *nextDest = writeBuffer_.addMessage(extra); - for (unsigned int i = 0; i < extra; i++) - *nextDest++ = 0; - outputLength += extra; - } - writeBuffer_.unregisterPointer(); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_ImageText8: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ImageText8); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - unsigned int textLength; - decodeBuffer.decodeCachedValue(textLength, 8, - clientCache_ -> imageTextLengthCache, 4); - outputLength = 16 + RoundUp4(textLength); - outputMessage = writeBuffer_.addMessage(outputLength); - outputMessage[1] = (unsigned char) textLength; - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> imageTextCacheX); - clientCache_ -> imageTextLastX += value; - clientCache_ -> imageTextLastX &= 0xffff; - PutUINT(clientCache_ -> imageTextLastX, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> imageTextCacheY); - clientCache_ -> imageTextLastY += value; - clientCache_ -> imageTextLastY &= 0xffff; - PutUINT(clientCache_ -> imageTextLastY, outputMessage + 14, bigEndian_); - unsigned char *nextDest = outputMessage + 16; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, textLength); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_ImageText16: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_ImageText16); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - unsigned int textLength; - decodeBuffer.decodeCachedValue(textLength, 8, - clientCache_ -> imageTextLengthCache, 4); - outputLength = 16 + RoundUp4(textLength * 2); - outputMessage = writeBuffer_.addMessage(outputLength); - outputMessage[1] = (unsigned char) textLength; - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> imageTextCacheX); - clientCache_ -> imageTextLastX += value; - clientCache_ -> imageTextLastX &= 0xffff; - PutUINT(clientCache_ -> imageTextLastX, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> imageTextCacheY); - clientCache_ -> imageTextLastY += value; - clientCache_ -> imageTextLastY &= 0xffff; - PutUINT(clientCache_ -> imageTextLastY, outputMessage + 14, bigEndian_); - unsigned char *nextDest = outputMessage + 16; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, textLength * 2); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_InternAtom: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_InternAtom); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - sequenceQueue_.push(clientSequence_, outputOpcode); - - break; - } - - unsigned int nameLength; - decodeBuffer.decodeValue(nameLength, 16, 6); - outputLength = RoundUp4(nameLength) + 8; - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(nameLength, outputMessage + 4, bigEndian_); - decodeBuffer.decodeBoolValue(value); - outputMessage[1] = (unsigned char) value; - unsigned char *nextDest = outputMessage + 8; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, nameLength); - - sequenceQueue_.push(clientSequence_, outputOpcode); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_ListExtensions: - { - outputLength = 4; - outputMessage = writeBuffer_.addMessage(outputLength); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_ListFonts: - { - unsigned int textLength; - decodeBuffer.decodeValue(textLength, 16, 6); - outputLength = 8 + RoundUp4(textLength); - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(textLength, outputMessage + 6, bigEndian_); - decodeBuffer.decodeValue(value, 16, 6); - PutUINT(value, outputMessage + 4, bigEndian_); - unsigned char* nextDest = outputMessage + 8; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, textLength); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_LookupColor: - case X_AllocNamedColor: - { - unsigned int textLength; - decodeBuffer.decodeValue(textLength, 16, 6); - outputLength = 12 + RoundUp4(textLength); - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> colormapCache); - PutULONG(value, outputMessage + 4, bigEndian_); - PutUINT(textLength, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, textLength); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_MapWindow: - case X_UnmapWindow: - case X_MapSubwindows: - case X_GetWindowAttributes: - case X_DestroyWindow: - case X_DestroySubwindows: - case X_QueryPointer: - case X_QueryTree: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - - if (outputOpcode == X_DestroyWindow) // Since ProtoStep7 (#issue 108) - { - decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeWindowCache); - } - else - { - decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); - } - - PutULONG(value, outputMessage + 4, bigEndian_); - if (outputOpcode == X_QueryPointer || - outputOpcode == X_GetWindowAttributes || - outputOpcode == X_QueryTree) - { - sequenceQueue_.push(clientSequence_, outputOpcode); - } - } - break; - case X_OpenFont: - { - unsigned int nameLength; - decodeBuffer.decodeValue(nameLength, 16, 7); - outputLength = RoundUp4(12 + nameLength); - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(nameLength, outputMessage + 8, bigEndian_); - decodeBuffer.decodeValue(value, 29, 5); - clientCache_ -> lastFont += value; - clientCache_ -> lastFont &= 0x1fffffff; - PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeTextData(nextDest, nameLength); - } - break; - case X_PolyFillRectangle: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyFillRectangle); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 12; - outputMessage = writeBuffer_.addMessage(outputLength); - writeBuffer_.registerPointer(&outputMessage); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0, lastWidth = 0, lastHeight = 0; - unsigned int numRectangles = 0; - - for (;;) - { - outputLength += 8; - writeBuffer_.addMessage(8); - unsigned char *nextDest = outputMessage + 12 + - (numRectangles << 3); - numRectangles++; - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillRectangleCacheX[index], 8); - value += lastX; - PutUINT(value, nextDest, bigEndian_); - lastX = value; - nextDest += 2; - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillRectangleCacheY[index], 8); - value += lastY; - PutUINT(value, nextDest, bigEndian_); - lastY = value; - nextDest += 2; - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillRectangleCacheWidth[index], 8); - value += lastWidth; - PutUINT(value, nextDest, bigEndian_); - lastWidth = value; - nextDest += 2; - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillRectangleCacheHeight[index], 8); - value += lastHeight; - PutUINT(value, nextDest, bigEndian_); - lastHeight = value; - nextDest += 2; - - if (++index == 4) index = 0; - - decodeBuffer.decodeBoolValue(value); - - if (!value) break; - } - writeBuffer_.unregisterPointer(); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_PolyFillArc: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyFillArc); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 12; - outputMessage = writeBuffer_.addMessage(outputLength); - writeBuffer_.registerPointer(&outputMessage); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0, - lastWidth = 0, lastHeight = 0, - lastAngle1 = 0, lastAngle2 = 0; - - unsigned int numArcs = 0; - - for (;;) - { - outputLength += 12; - writeBuffer_.addMessage(12); - - unsigned char *nextDest = outputMessage + 12 + - (numArcs * 12); - numArcs++; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillArcCacheX[index], 8); - value += lastX; - PutUINT(value, nextDest, bigEndian_); - lastX = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillArcCacheY[index], 8); - value += lastY; - PutUINT(value, nextDest, bigEndian_); - lastY = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillArcCacheWidth[index], 8); - value += lastWidth; - PutUINT(value, nextDest, bigEndian_); - lastWidth = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillArcCacheHeight[index], 8); - value += lastHeight; - PutUINT(value, nextDest, bigEndian_); - lastHeight = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillArcCacheAngle1[index], 8); - value += lastAngle1; - PutUINT(value, nextDest, bigEndian_); - lastAngle1 = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyFillArcCacheAngle2[index], 8); - value += lastAngle2; - PutUINT(value, nextDest, bigEndian_); - lastAngle2 = value; - nextDest += 2; - - if (++index == 2) index = 0; - - decodeBuffer.decodeBoolValue(value); - - if (!value) break; - } - writeBuffer_.unregisterPointer(); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_PolyArc: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyArc); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - outputLength = 12; - outputMessage = writeBuffer_.addMessage(outputLength); - writeBuffer_.registerPointer(&outputMessage); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0, - lastWidth = 0, lastHeight = 0, - lastAngle1 = 0, lastAngle2 = 0; - - unsigned int numArcs = 0; - - for (;;) - { - outputLength += 12; - writeBuffer_.addMessage(12); - - unsigned char *nextDest = outputMessage + 12 + - (numArcs * 12); - numArcs++; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyArcCacheX[index], 8); - value += lastX; - PutUINT(value, nextDest, bigEndian_); - lastX = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyArcCacheY[index], 8); - value += lastY; - PutUINT(value, nextDest, bigEndian_); - lastY = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyArcCacheWidth[index], 8); - value += lastWidth; - PutUINT(value, nextDest, bigEndian_); - lastWidth = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyArcCacheHeight[index], 8); - value += lastHeight; - PutUINT(value, nextDest, bigEndian_); - lastHeight = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyArcCacheAngle1[index], 8); - value += lastAngle1; - PutUINT(value, nextDest, bigEndian_); - lastAngle1 = value; - nextDest += 2; - - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyArcCacheAngle2[index], 8); - value += lastAngle2; - PutUINT(value, nextDest, bigEndian_); - lastAngle2 = value; - nextDest += 2; - - if (++index == 2) index = 0; - - decodeBuffer.decodeBoolValue(value); - - if (!value) break; - } - writeBuffer_.unregisterPointer(); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_PolyPoint: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyPoint); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - unsigned int numPoints; - decodeBuffer.decodeValue(numPoints, 16, 4); - outputLength = (numPoints << 2) + 12; - outputMessage = writeBuffer_.addMessage(outputLength); - unsigned int relativeCoordMode; - decodeBuffer.decodeBoolValue(relativeCoordMode); - outputMessage[1] = (unsigned char) relativeCoordMode; - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0; - - for (unsigned int i = 0; i < numPoints; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyPointCacheX[index], 8); - lastX += value; - PutUINT(lastX, nextDest, bigEndian_); - nextDest += 2; - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyPointCacheY[index], 8); - lastY += value; - PutUINT(lastY, nextDest, bigEndian_); - nextDest += 2; - - if (++index == 2) index = 0; - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_PolyLine: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolyLine); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - unsigned int numPoints; - decodeBuffer.decodeValue(numPoints, 16, 4); - outputLength = (numPoints << 2) + 12; - outputMessage = writeBuffer_.addMessage(outputLength); - unsigned int relativeCoordMode; - decodeBuffer.decodeBoolValue(relativeCoordMode); - outputMessage[1] = (unsigned char) relativeCoordMode; - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - - unsigned int index = 0; - unsigned int lastX = 0, lastY = 0; - - for (unsigned int i = 0; i < numPoints; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyLineCacheX[index], 8); - lastX += value; - PutUINT(lastX, nextDest, bigEndian_); - nextDest += 2; - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyLineCacheY[index], 8); - lastY += value; - PutUINT(lastY, nextDest, bigEndian_); - nextDest += 2; - - if (++index == 2) index = 0; - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_PolyRectangle: - { - unsigned int numRectangles; - decodeBuffer.decodeValue(numRectangles, 16, 3); - outputLength = (numRectangles << 3) + 12; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - for (unsigned int i = 0; i < numRectangles; i++) - for (unsigned int k = 0; k < 4; k++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> polyRectangleGeomCache[k], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - } - break; - case X_PolySegment: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PolySegment); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - unsigned int numSegments; - decodeBuffer.decodeValue(numSegments, 16, 4); - outputLength = (numSegments << 3) + 12; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - - for (numSegments *= 2; numSegments; numSegments--) - { - unsigned int index; - decodeBuffer.decodeBoolValue(index); - unsigned int x; - decodeBuffer.decodeCachedValue(x, 16, - clientCache_ -> polySegmentCacheX, 6); - x += clientCache_ -> polySegmentLastX[index]; - PutUINT(x, nextDest, bigEndian_); - nextDest += 2; - - unsigned int y; - decodeBuffer.decodeCachedValue(y, 16, - clientCache_ -> polySegmentCacheY, 6); - y += clientCache_ -> polySegmentLastY[index]; - PutUINT(y, nextDest, bigEndian_); - nextDest += 2; - - clientCache_ -> polySegmentLastX[clientCache_ -> polySegmentCacheIndex] = x; - clientCache_ -> polySegmentLastY[clientCache_ -> polySegmentCacheIndex] = y; - - if (clientCache_ -> polySegmentCacheIndex == 1) - clientCache_ -> polySegmentCacheIndex = 0; - else - clientCache_ -> polySegmentCacheIndex = 1; - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_PutImage: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_PutImage); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - - if (outputOpcode == X_PutImage) - { - handleImage(outputOpcode, outputMessage, outputLength); - } - } - break; - case X_QueryBestSize: - { - outputLength = 12; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 2); - outputMessage[1] = (unsigned char)value; - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeValue(value, 16, 8); - PutUINT(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeValue(value, 16, 8); - PutUINT(value, outputMessage + 10, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_QueryColors: - { - // Differential or plain data compression? - decodeBuffer.decodeBoolValue(value); - - if (value) - { - unsigned int numColors; - decodeBuffer.decodeValue(numColors, 16, 5); - outputLength = (numColors << 2) + 8; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> colormapCache); - PutULONG(value, outputMessage + 4, bigEndian_); - unsigned char *nextDest = outputMessage + 8; - unsigned int predictedPixel = clientCache_ -> queryColorsLastPixel; - for (unsigned int i = 0; i < numColors; i++) - { - unsigned int pixel; - decodeBuffer.decodeBoolValue(value); - if (value) - pixel = predictedPixel; - else - decodeBuffer.decodeValue(pixel, 32, 9); - PutULONG(pixel, nextDest, bigEndian_); - if (i == 0) - clientCache_ -> queryColorsLastPixel = pixel; - predictedPixel = pixel + 1; - nextDest += 4; - } - } - else - { - // Request length. - unsigned int requestLength; - decodeBuffer.decodeValue(requestLength, 16, 10); - outputLength = (requestLength << 2); - outputMessage = writeBuffer_.addMessage(outputLength); - - const unsigned char *compressedData = NULL; - unsigned int compressedDataSize = 0; - - int decompressed = handleDecompress(decodeBuffer, outputOpcode, 4, - outputMessage, outputLength, compressedData, - compressedDataSize); - if (decompressed < 0) - { - return -1; - } - } - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_QueryExtension: - { - unsigned int nameLength; - decodeBuffer.decodeValue(nameLength, 16, 6); - outputLength = 8 + RoundUp4(nameLength); - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(nameLength, outputMessage + 4, bigEndian_); - unsigned char *nextDest = outputMessage + 8; - for (unsigned int i = 0; i < nameLength; i++) - { - decodeBuffer.decodeValue(value, 8); - *nextDest++ = (unsigned char) value; - } - - unsigned int hide = 0; - - #ifdef HIDE_MIT_SHM_EXTENSION - - if (!strncmp((char *) outputMessage + 8, "MIT-SHM", 7)) - { - #ifdef TEST - *logofs << "handleWrite: Going to hide MIT-SHM extension in reply.\n" - << logofs_flush; - #endif - - hide = 1; - } - - #endif - - #ifdef HIDE_BIG_REQUESTS_EXTENSION - - if (!strncmp((char *) outputMessage + 8, "BIG-REQUESTS", 12)) - { - #ifdef TEST - *logofs << "handleWrite: Going to hide BIG-REQUESTS extension in reply.\n" - << logofs_flush; - #endif - - hide = 1; - } - - #endif - - #ifdef HIDE_XKEYBOARD_EXTENSION - - else if (!strncmp((char *) outputMessage + 8, "XKEYBOARD", 9)) - { - #ifdef TEST - *logofs << "handleWrite: Going to hide XKEYBOARD extension in reply.\n" - << logofs_flush; - #endif - - hide = 1; - } - - #endif - - #ifdef HIDE_XFree86_Bigfont_EXTENSION - - else if (!strncmp((char *) outputMessage + 8, "XFree86-Bigfont", 15)) - { - #ifdef TEST - *logofs << "handleWrite: Going to hide XFree86-Bigfont extension in reply.\n" - << logofs_flush; - #endif - - hide = 1; - } - - #endif - - // - // This is if you want to experiment disabling SHAPE extensions. - // - - #ifdef HIDE_SHAPE_EXTENSION - - if (!strncmp((char *) outputMessage + 8, "SHAPE", 5)) - { - #ifdef DEBUG - *logofs << "handleWrite: Going to hide SHAPE extension in reply.\n" - << logofs_flush; - #endif - - hide = 1; - } - - #endif - - // - // Check if user disabled RENDER extension. - // - - if (control -> HideRender == 1 && - strncmp((char *) outputMessage + 8, "RENDER", 6) == 0) - { - #ifdef TEST - *logofs << "handleWrite: Going to hide RENDER extension in reply.\n" - << logofs_flush; - #endif - - hide = 1; - } - - unsigned int extension = 0; - - if (strncmp((char *) outputMessage + 8, "SHAPE", 5) == 0) - { - extension = X_NXInternalShapeExtension; - } - else if (strncmp((char *) outputMessage + 8, "RENDER", 6) == 0) - { - extension = X_NXInternalRenderExtension; - } - - sequenceQueue_.push(clientSequence_, outputOpcode, - outputOpcode, hide, extension); - } - break; - case X_QueryFont: - { - outputLength = 8; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 29, 5); - clientCache_ -> lastFont += value; - clientCache_ -> lastFont &= 0x1fffffff; - PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_SetClipRectangles: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_SetClipRectangles); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - break; - } - - unsigned int numRectangles; - - // Since ProtoStep9 (#issue 108) - decodeBuffer.decodeValue(numRectangles, 15, 4); - - outputLength = (numRectangles << 3) + 12; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeValue(value, 2); - outputMessage[1] = (unsigned char) value; - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> setClipRectanglesXCache, 8); - PutUINT(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> setClipRectanglesYCache, 8); - PutUINT(value, outputMessage + 10, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - for (unsigned int i = 0; i < numRectangles; i++) - { - for (unsigned int k = 0; k < 4; k++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache_ -> setClipRectanglesGeomCache[k], 8); - PutUINT(value, nextDest, bigEndian_); - nextDest += 2; - } - } - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_SetDashes: - { - unsigned int numDashes; - decodeBuffer.decodeCachedValue(numDashes, 16, - clientCache_ -> setDashesLengthCache, 5); - outputLength = 12 + RoundUp4(numDashes); - outputMessage = writeBuffer_.addMessage(outputLength); - PutUINT(numDashes, outputMessage + 10, bigEndian_); - decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> setDashesOffsetCache, 5); - PutUINT(value, outputMessage + 8, bigEndian_); - unsigned char *nextDest = outputMessage + 12; - for (unsigned int i = 0; i < numDashes; i++) - { - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache_ -> setDashesDashCache_[i & 1], 5); - *nextDest++ = cValue; - } - } - break; - case X_SetSelectionOwner: - { - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> setSelectionOwnerCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> getSelectionOwnerSelectionCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 32, - clientCache_ -> setSelectionOwnerTimestampCache, 9); - PutULONG(value, outputMessage + 12, bigEndian_); - } - break; - case X_TranslateCoords: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_TranslateCoords); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - sequenceQueue_.push(clientSequence_, outputOpcode); - - break; - } - - outputLength = 16; - outputMessage = writeBuffer_.addMessage(outputLength); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> translateCoordsSrcCache, 9); - PutULONG(value, outputMessage + 4, bigEndian_); - decodeBuffer.decodeCachedValue(value, 29, - clientCache_ -> translateCoordsDstCache, 9); - PutULONG(value, outputMessage + 8, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> translateCoordsXCache, 8); - PutUINT(value, outputMessage + 12, bigEndian_); - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> translateCoordsYCache, 8); - PutUINT(value, outputMessage + 14, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_GetImage: - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_GetImage); - - if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, - outputMessage, outputLength)) - { - sequenceQueue_.push(clientSequence_, outputOpcode); - - break; - } - - outputLength = 20; - outputMessage = writeBuffer_.addMessage(outputLength); - // Format. - unsigned int format; - decodeBuffer.decodeValue(format, 2); - outputMessage[1] = (unsigned char) format; - // Drawable. - decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); - PutULONG(value, outputMessage + 4, bigEndian_); - // X. - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> putImageXCache, 8); - clientCache_ -> putImageLastX += value; - clientCache_ -> putImageLastX &= 0xffff; - PutUINT(clientCache_ -> putImageLastX, outputMessage + 8, bigEndian_); - // Y. - decodeBuffer.decodeCachedValue(value, 16, - clientCache_ -> putImageYCache, 8); - clientCache_ -> putImageLastY += value; - clientCache_ -> putImageLastY &= 0xffff; - PutUINT(clientCache_ -> putImageLastY, outputMessage + 10, bigEndian_); - // Width. - unsigned int width; - decodeBuffer.decodeCachedValue(width, 16, - clientCache_ -> putImageWidthCache, 8); - PutUINT(width, outputMessage + 12, bigEndian_); - // Height. - unsigned int height; - decodeBuffer.decodeCachedValue(height, 16, - clientCache_ -> putImageHeightCache, 8); - PutUINT(height, outputMessage + 14, bigEndian_); - // Plane mask. - decodeBuffer.decodeCachedValue(value, 32, - clientCache_ -> getImagePlaneMaskCache, 5); - PutULONG(value, outputMessage + 16, bigEndian_); - - sequenceQueue_.push(clientSequence_, outputOpcode); - - handleSave(messageStore, outputMessage, outputLength); - } - break; - case X_GetPointerMapping: - { - outputLength = 4; - outputMessage = writeBuffer_.addMessage(outputLength); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - case X_GetKeyboardControl: - { - outputLength = 4; - outputMessage = writeBuffer_.addMessage(outputLength); - - sequenceQueue_.push(clientSequence_, outputOpcode); - } - break; - default: - { - if (outputOpcode == opcodeStore_ -> renderExtension) - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXInternalRenderExtension); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> shapeExtension) - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXInternalShapeExtension); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> putPackedImage) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoding packed image request for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXPutPackedImage); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - - if (outputOpcode == opcodeStore_ -> putPackedImage) - { - handleImage(outputOpcode, outputMessage, outputLength); - } - } - else if (outputOpcode == opcodeStore_ -> setUnpackColormap) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoding set unpack colormap request " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXSetUnpackColormap); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - // - // Message could have been split. - // - - if (outputOpcode == opcodeStore_ -> setUnpackColormap) - { - handleColormap(outputOpcode, outputMessage, outputLength); - } - } - else if (outputOpcode == opcodeStore_ -> setUnpackAlpha) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoding unpack alpha request for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXSetUnpackAlpha); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - // - // Message could have been split. - // - - if (outputOpcode == opcodeStore_ -> setUnpackAlpha) - { - handleAlpha(outputOpcode, outputMessage, outputLength); - } - } - else if (outputOpcode == opcodeStore_ -> setUnpackGeometry) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoding set unpack geometry request " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXSetUnpackGeometry); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - - handleGeometry(outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> startSplit) - { - handleStartSplitRequest(decodeBuffer, outputOpcode, - outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> endSplit) - { - handleEndSplitRequest(decodeBuffer, outputOpcode, - outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> commitSplit) - { - int result = handleCommitSplitRequest(decodeBuffer, outputOpcode, - outputMessage, outputLength); - - // - // Check if message has been successfully - // extracted from the split store. In this - // case post-process it in the usual way. - // - - if (result > 0) - { - if (outputOpcode == opcodeStore_ -> putPackedImage || - outputOpcode == X_PutImage) - { - handleImage(outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> setUnpackColormap) - { - handleColormap(outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> setUnpackAlpha) - { - handleAlpha(outputOpcode, outputMessage, outputLength); - } - } - else if (result < 0) - { - return -1; - } - } - else if (outputOpcode == opcodeStore_ -> abortSplit) - { - handleAbortSplitRequest(decodeBuffer, outputOpcode, - outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> finishSplit) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoding finish split request " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache_ -> resourceCache); - - handleNullRequest(outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> freeSplit) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoding free split request " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache_ -> resourceCache); - - handleNullRequest(outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> freeUnpack) - { - #ifdef DEBUG - *logofs << "handleWrite: Decoding free unpack request " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache_ -> resourceCache); - - #ifdef DEBUG - *logofs << "handleWrite: Freeing unpack state for resource " - << (unsigned int) cValue << ".\n" << logofs_flush; - #endif - - handleUnpackStateRemove(cValue); - - handleNullRequest(outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> setExposeParameters) - { - // - // Send expose events according to agent's wish. - // - - decodeBuffer.decodeBoolValue(enableExpose_); - decodeBuffer.decodeBoolValue(enableGraphicsExpose_); - decodeBuffer.decodeBoolValue(enableNoExpose_); - - handleNullRequest(outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> getUnpackParameters) - { - // - // Client proxy needs the list of supported - // unpack methods. We would need an encode - // buffer, but this is in proxy, not here in - // channel. - // - - #ifdef TEST - *logofs << "handleWrite: Sending X_GetInputFocus request for FD#" - << fd_ << " due to OPCODE#" << (unsigned int) outputOpcode - << ".\n" << logofs_flush; - #endif - - outputOpcode = X_GetInputFocus; - - outputLength = 4; - outputMessage = writeBuffer_.addMessage(outputLength); - - sequenceQueue_.push(clientSequence_, outputOpcode, - opcodeStore_ -> getUnpackParameters); - } - else if (outputOpcode == opcodeStore_ -> getControlParameters || - outputOpcode == opcodeStore_ -> getCleanupParameters || - outputOpcode == opcodeStore_ -> getImageParameters) - { - handleNullRequest(outputOpcode, outputMessage, outputLength); - } - else if (outputOpcode == opcodeStore_ -> getShmemParameters) - { - if (handleShmemRequest(decodeBuffer, outputOpcode, - outputMessage, outputLength) < 0) - { - return -1; - } - } - else if (outputOpcode == opcodeStore_ -> setCacheParameters) - { - if (handleCacheRequest(decodeBuffer, outputOpcode, - outputMessage, outputLength) < 0) - { - return -1; - } - } - else if (outputOpcode == opcodeStore_ -> getFontParameters) - { - if (handleFontRequest(decodeBuffer, outputOpcode, - outputMessage, outputLength) < 0) - { - return -1; - } - } - else - { - MessageStore *messageStore = clientStore_ -> - getRequestStore(X_NXInternalGenericRequest); - - hit = handleDecode(decodeBuffer, clientCache_, messageStore, - outputOpcode, outputMessage, outputLength); - } - } - } // End of switch on opcode. - - // - // TODO: at the moment the variable hit was being set - // but not used, so to avoid the corresponding warning - // this logging block has been added. - // This code will probably be optimized away when none - // of the defines is set, but if there is no additional - // use for the hit variable in the future, then maybe - // it could be removed completely. - // - - if (hit) - { - #if defined(TEST) || defined(OPCODES) - *logofs << "handleWrite: Cached flag enabled in handled request.\n" - << logofs_flush; - #endif - } - - // - // A packed image request can generate more than just - // a single X_PutImage. Write buffer is handled inside - // handleUnpack(). Cannot simply assume that the final - // opcode and size must be put at the buffer offset as - // as buffer could have been grown or could have been - // replaced by a scratch buffer. The same is true in - // the case of a shared memory image. - // - - if (outputOpcode != 0) - { - // - // Commit opcode and size to the buffer. - // - - *outputMessage = (unsigned char) outputOpcode; - - PutUINT(outputLength >> 2, outputMessage + 2, bigEndian_); - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleWrite: Handled request OPCODE#" - << (unsigned int) outputOpcode << " (" - << DumpOpcode(outputOpcode) << ") for FD#" - << fd_ << " sequence " << clientSequence_ - << ". " << outputLength << " bytes out.\n" - << logofs_flush; - #endif - } - #if defined(TEST) || defined(OPCODES) - else - { - // - // In case of shared memory images the log doesn't - // reflect the actual opcode of the request that is - // going to be written. It would be possible to find - // the opcode of the original request received from - // the remote proxy in member imageState_ -> opcode, - // but we have probably already deleted the struct. - // - - *logofs << "handleWrite: Handled image request for FD#" - << fd_ << " new sequence " << clientSequence_ - << ". " << outputLength << " bytes out.\n" - << logofs_flush; - } - #endif - - // - // Check if we produced enough data. We need to - // decode all the proxy messages or the decode - // buffer will be left in an inconsistent state, - // so we just update the finish flag in case of - // failure. - // - - handleFlush(flush_if_needed); - - } // End of while (decodeBuffer.decodeOpcodeValue(outputOpcode, 8, ... - - } // End of the decoding block. - - // - // Write any remaining data to the X connection. - // - - if (handleFlush(flush_if_any) < 0) - { - return -1; - } - - // - // Reset offset at which we read the - // last event looking for the shared - // memory completion. - // - - if (shmemState_ != NULL) - { - shmemState_ -> checked = 0; - } - - return 1; -} - -// -// End of handleWrite(). -// - -// -// Other members. -// - -int ServerChannel::handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, - T_store_action action, int position, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - // Since ProtoStep7 (#issue 108) - splitState_.current = splitState_.resource; - - handleSplitStoreAlloc(&splitResources_, splitState_.current); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Message OPCODE#" - << (unsigned int) store -> opcode() << " of size " << size - << " [split] with resource " << splitState_.current - << " position " << position << " and action [" - << DumpAction(action) << "] at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - // - // Get the MD5 of the message being - // split. - // - - T_checksum checksum = NULL; - - if (action != IS_HIT) - { - handleSplitChecksum(decodeBuffer, checksum); - } - - // - // The method must abort the connection - // if it can't allocate the split. - // - - Split *splitMessage = clientStore_ -> getSplitStore(splitState_.current) -> - add(store, splitState_.current, position, - action, checksum, buffer, size); - - // - // If the encoding side didn't provide - // a checksum, then don't send the split - // report. - // - - if (checksum == NULL) - { - if (action == IS_HIT) - { - splitMessage -> setState(split_loaded); - } - else - { - splitMessage -> setState(split_missed); - } - - #if defined(TEST) || defined(SPLIT) - - *logofs << "handleSplit: SPLIT! There are " << clientStore_ -> - getSplitTotalSize() << " messages and " << clientStore_ -> - getSplitTotalStorageSize() << " bytes to send in " - << "the split stores.\n" << logofs_flush; - - clientStore_ -> dumpSplitStore(splitState_.current); - - #endif - - return 1; - } - - delete [] checksum; - - // - // Tell the split store if it must use - // the disk cache to retrieve and save - // the message. - // - - splitMessage -> setPolicy(splitState_.load, splitState_.save); - - // - // Try to locate the message on disk. - // - - if (clientStore_ -> getSplitStore(splitState_.current) -> - load(splitMessage) == 1) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Loaded the message " - << "from the image cache.\n" << logofs_flush; - #endif - - splitMessage -> setState(split_loaded); - } - else - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: WARNING! SPLIT! Can't find the message " - << "in the image cache.\n" << logofs_flush; - #endif - - splitMessage -> setState(split_missed); - } - - #if defined(TEST) || defined(SPLIT) - - T_timestamp startTs = getTimestamp(); - - *logofs << "handleSplit: SPLIT! Encoding abort " - << "split events for FD#" << fd_ << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - - if (proxy -> handleAsyncSplit(fd_, splitMessage) < 0) - { - return -1; - } - - // - // Send the encoded data immediately. We - // want the abort split message to reach - // the remote proxy as soon as possible. - // - - if (proxy -> handleAsyncFlush() < 0) - { - return -1; - } - - #if defined(TEST) || defined(SPLIT) - - *logofs << "handleSplit: SPLIT! Spent " - << diffTimestamp(startTs, getTimestamp()) << " Ms " - << "handling abort split events for FD#" << fd_ - << ".\n" << logofs_flush; - - *logofs << "handleSplit: SPLIT! There are " << clientStore_ -> - getSplitTotalSize() << " messages and " << clientStore_ -> - getSplitTotalStorageSize() << " bytes to send in " - << "the split stores.\n" << logofs_flush; - - clientStore_ -> dumpSplitStore(splitState_.current); - - #endif - - return 1; -} - -int ServerChannel::handleSplit(DecodeBuffer &decodeBuffer) -{ - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Going to handle splits " - << "for FD#" << fd_ << " at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - unsigned char resource; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - splitState_.current = resource; - - handleSplitStoreAlloc(&splitResources_, splitState_.current); - - SplitStore *splitStore = clientStore_ -> getSplitStore(splitState_.current); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Handling splits for " - << "resource [" << splitState_.current << "] with " - << splitStore -> getSize() << " elements " - << "in the split store.\n" << logofs_flush; - #endif - - int result = splitStore -> receive(decodeBuffer); - - if (result < 0) - { - #ifdef PANIC - *logofs << "handleSplit: PANIC! Receive of split for FD#" << fd_ - << " failed.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Receive of split for FD#" << fd_ - << " failed.\n"; - - return -1; - } - else if (result == 0) - { - // - // The split is still incomplete. It's time - // to check if we need to start the house- - // keeping process to take care of the image - // cache. - // - - if (proxy -> handleAsyncKeeperCallback() < 0) - { - return -1; - } - } - else - { - // - // Note that we don't need the resource id at the - // X server side and, thus, we don't provide it - // at the time we add split to the split store. - // - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Remote agent should " - << "now commit a new split for resource [" - << splitState_.current << "].\n" - << logofs_flush; - - clientStore_ -> dumpCommitStore(); - - #endif - - if (splitStore -> getSize() == 0) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! Removing split store " - << "for resource [" << splitState_.current - << "] at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - handleSplitStoreRemove(&splitResources_, splitState_.current); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: SPLIT! There are [" << clientStore_ -> - getSplitTotalSize() << "] messages and " << clientStore_ -> - getSplitTotalStorageSize() << " bytes to send in " - << "the split stores.\n" << logofs_flush; - #endif - } - else - { - // - // If the next split is discarded, it can be - // that, since the beginning of the split, we - // have saved the message on the disk, due to - // a more recent split operation. This is also - // the case when we had to discard the message - // because it was locked but, since then, we - // completed the transferral of the split. - // - - Split *splitMessage = splitStore -> getFirstSplit(); - - if (splitMessage -> getAction() == is_discarded && - splitMessage -> getState() == split_missed && - splitStore -> load(splitMessage) == 1) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplit: WARNING! SPLIT! Asynchronously " - << "loaded the message from the image cache.\n" - << logofs_flush; - #endif - - splitMessage -> setState(split_loaded); - - #if defined(TEST) || defined(SPLIT) - - T_timestamp startTs = getTimestamp(); - - *logofs << "handleSplit: WARNING! SPLIT! Asynchronously " - << "encoding abort split events for FD#" << fd_ - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - if (proxy -> handleAsyncSplit(fd_, splitMessage) < 0) - { - return -1; - } - - // - // Send the encoded data immediately. We - // want the abort split message to reach - // the remote proxy as soon as possible. - // - - if (proxy -> handleAsyncFlush() < 0) - { - return -1; - } - - #if defined(TEST) || defined(SPLIT) - - *logofs << "handleSplit: WARNING! SPLIT! Spent " - << diffTimestamp(startTs, getTimestamp()) << " Ms " - << "handling asynchronous abort split events for " - << "FD#" << fd_ << ".\n" << logofs_flush; - - *logofs << "handleSplit: SPLIT! There are " << clientStore_ -> - getSplitTotalSize() << " messages and " << clientStore_ -> - getSplitTotalStorageSize() << " bytes to send in " - << "the split stores.\n" << logofs_flush; - - clientStore_ -> dumpSplitStore(splitState_.current); - - #endif - } - } - } - - return 1; -} - -int ServerChannel::handleSplitEvent(EncodeBuffer &encodeBuffer, Split *splitMessage) -{ - int resource = splitMessage -> getResource(); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Going to send a " - << "split report for resource " << resource - << ".\n" << logofs_flush; - #endif - - // - // This function is called only after the message - // has been searched in the disk cache. We need to - // inform the other side if the data transfer can - // start or it must be aborted to let the local - // side use the copy that was found on the disk. - // - - #if defined(TEST) || defined(INFO) - - if (splitMessage -> getState() != split_loaded && - splitMessage -> getState() != split_missed) - { - *logofs << "handleSplitEvent: PANIC! Can't find the split to be aborted.\n" - << logofs_flush; - - HandleCleanup(); - } - - #endif - - // - // We need to send a boolean telling if the split - // was found or not, followed by the checksum of - // message we are referencing. - // - - T_checksum checksum = splitMessage -> getChecksum(); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Sending split report for " - << "checksum [" << DumpChecksum(checksum) << "].\n" - << logofs_flush; - #endif - - if (proxy -> handleAsyncSwitch(fd_) < 0) - { - return -1; - } - - encodeBuffer.encodeOpcodeValue(opcodeStore_ -> splitEvent, - serverCache_ -> opcodeCache); - - // - // The encoding in older protocol versions - // is different but we will never try to - // send a split report if the remote does - // not support our version. - // - - encodeBuffer.encodeCachedValue(resource, 8, - serverCache_ -> resourceCache); - - if (splitMessage -> getState() == split_loaded) - { - encodeBuffer.encodeBoolValue(1); - - encodeBuffer.encodeOpcodeValue(splitMessage -> getStore() -> opcode(), - serverCache_ -> abortOpcodeCache); - - encodeBuffer.encodeValue(splitMessage -> compressedSize(), 32, 14); - } - else - { - encodeBuffer.encodeBoolValue(0); - } - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - encodeBuffer.encodeValue((unsigned int) checksum[i], 8); - } - - // - // Update statistics for this special opcode. - // - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) || defined(INFO) || defined(SPLIT) - *logofs << "handleSplitEvent: SPLIT! Handled event OPCODE#" - << (unsigned int) opcodeStore_ -> splitEvent << " (" - << DumpOpcode(opcodeStore_ -> splitEvent) << ")" << " for FD#" - << fd_ << " sequence none. 0 bytes in, " << bits << " bits (" - << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; - #endif - - statistics -> addEventBits(opcodeStore_ -> splitEvent, 0, bits); - - return 1; -} - -int ServerChannel::handleAbortSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - unsigned char resource; - - decodeBuffer.decodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Handling abort split " - << "request for FD#" << fd_ << " and resource " - << (unsigned) resource << ".\n" - << logofs_flush; - #endif - - int splits = 0; - - SplitStore *splitStore = clientStore_ -> getSplitStore(resource); - - if (splitStore != NULL) - { - // - // Discard from the memory cache the messages - // that are still incomplete and then get rid - // of the splits in the store. - // - - #if defined(TEST) || defined(SPLIT) - - clientStore_ -> dumpSplitStore(resource); - - #endif - - Split *splitMessage; - - for (;;) - { - splitMessage = splitStore -> getFirstSplit(); - - if (splitMessage == NULL) - { - // - // Check if we had created the store - // but no message was added yet. - // - - #ifdef WARNING - - if (splits == 0) - { - *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The " - << "split store for resource [" << (unsigned int) - resource << "] is unexpectedly empty.\n" - << logofs_flush; - } - - #endif - - break; - } - - // - // Splits already aborted can't be in the - // split store. - // - - #if defined(TEST) || defined(SPLIT) - - if (splitMessage -> getState() == split_aborted) - { - *logofs << "handleAbortSplitRequest: PANIC! SPLIT! Found an " - << "aborted split in store [" << (unsigned int) resource - << "].\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - if (splitMessage -> getAction() == IS_HIT) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Removing the " - << "split from the memory cache.\n" - << logofs_flush; - #endif - - splitMessage -> getStore() -> remove(splitMessage -> getPosition(), - discard_checksum, use_data); - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Removing the " - << "split from the split store.\n" - << logofs_flush; - #endif - - splitMessage = splitStore -> pop(); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleAbortSplitRequest: SPLIT! Freeing up the " - << "aborted split.\n" << logofs_flush; - #endif - - delete splitMessage; - - splits++; - } - } - #ifdef WARNING - else - { - *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The " - << "split store for resource [" << (unsigned int) - resource << "] is already empty.\n" - << logofs_flush; - } - #endif - - handleNullRequest(opcode, buffer, size); - - return (splits > 0); -} - -int ServerChannel::handleCommitSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - // - // Get request type and position of the image - // to commit. - // - - unsigned char request; - - decodeBuffer.decodeOpcodeValue(request, clientCache_ -> opcodeCache); - - unsigned int diffCommit; - - decodeBuffer.decodeValue(diffCommit, 32, 5); - - splitState_.commit += diffCommit; - - unsigned char resource = 0; - unsigned int commit = 1; - - // - // Send the resource id and the commit flag. - // The resource id is ignored at the moment. - // The message will be handled based on the - // resource id that was sent together with - // the original message. - // - - decodeBuffer.decodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - decodeBuffer.decodeBoolValue(commit); - - Split *split = handleSplitCommitRemove(request, resource, splitState_.commit); - - if (split == NULL) - { - return -1; - } - - clientStore_ -> getCommitStore() -> update(split); - - if (commit == 1) - { - #if defined(TEST) || defined(SPLIT) - *logofs << "handleCommitSplitRequest: SPLIT! Handling split commit " - << "for FD#" << fd_ << " with commit " << commit - << " request " << (unsigned) request << " resource " - << (unsigned) resource << " and position " - << splitState_.commit << ".\n" - << logofs_flush; - #endif - - // - // Allocate as many bytes in the write - // buffer as the final length of the - // message in uncompressed form. - // - - size = split -> plainSize(); - - buffer = writeBuffer_.addMessage(size); - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleCommitSplitRequest: SPLIT! Prepared an " - << "outgoing buffer of " << size << " bytes.\n" - << logofs_flush; - #endif - - if (clientStore_ -> getCommitStore() -> expand(split, buffer, size) < 0) - { - writeBuffer_.removeMessage(size); - - commit = 0; - } - } - - // - // Free the split. - // - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleCommitSplitRequest: SPLIT! Freeing up the " - << "committed split.\n" << logofs_flush; - #endif - - delete split; - - // - // Discard the operation and send a null - // message. - // - - if (commit == 0) - { - handleNullRequest(opcode, buffer, size); - } - else - { - // - // Save the sequence number to be able - // to mask any error generated by the - // request. - // - - updateCommitQueue(clientSequence_); - - // - // Now in the write buffer there is - // a copy of this request. - // - - opcode = request; - } - - return commit; -} - -int ServerChannel::handleGeometry(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size) -{ - // - // Replace the old geometry and taint - // the message into a X_NoOperation. - // - - int resource = *(buffer + 1); - - #ifdef TEST - *logofs << "handleGeometry: Setting new unpack geometry " - << "for resource " << resource << ".\n" - << logofs_flush; - #endif - - handleUnpackStateInit(resource); - - handleUnpackAllocGeometry(resource); - - unpackState_[resource] -> geometry -> depth1_bpp = *(buffer + 4); - unpackState_[resource] -> geometry -> depth4_bpp = *(buffer + 5); - unpackState_[resource] -> geometry -> depth8_bpp = *(buffer + 6); - unpackState_[resource] -> geometry -> depth16_bpp = *(buffer + 7); - unpackState_[resource] -> geometry -> depth24_bpp = *(buffer + 8); - unpackState_[resource] -> geometry -> depth32_bpp = *(buffer + 9); - - unpackState_[resource] -> geometry -> red_mask = GetULONG(buffer + 12, bigEndian_); - unpackState_[resource] -> geometry -> green_mask = GetULONG(buffer + 16, bigEndian_); - unpackState_[resource] -> geometry -> blue_mask = GetULONG(buffer + 20, bigEndian_); - - handleCleanAndNullRequest(opcode, buffer, size); - - return 1; -} - -int ServerChannel::handleColormap(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size) -{ - // - // Replace the old colormap and taint - // the message into a X_NoOperation. - // - - int resource = *(buffer + 1); - - #ifdef TEST - *logofs << "handleColormap: Setting new unpack colormap " - << "for resource " << resource << ".\n" - << logofs_flush; - #endif - - handleUnpackStateInit(resource); - - handleUnpackAllocColormap(resource); - - // - // New protocol versions send the alpha - // data in compressed form. - // - - // - // Since ProtoStep7 (#issue 108) - // - - { // An anonymous block is used here to limit the scope of local variables - unsigned int packed = GetULONG(buffer + 8, bigEndian_); - unsigned int unpacked = GetULONG(buffer + 12, bigEndian_); - - validateSize("colormap", packed, unpacked, 16, size); - - if (unpackState_[resource] -> colormap -> entries != unpacked >> 2 && - unpackState_[resource] -> colormap -> data != NULL) - { - #ifdef TEST - *logofs << "handleColormap: Freeing previously allocated " - << "unpack colormap data.\n" << logofs_flush; - #endif - - delete [] unpackState_[resource] -> colormap -> data; - - unpackState_[resource] -> colormap -> data = NULL; - unpackState_[resource] -> colormap -> entries = 0; - } - - #ifdef TEST - *logofs << "handleColormap: Setting " << unpacked - << " bytes of unpack colormap data for resource " - << resource << ".\n" << logofs_flush; - #endif - - if (unpackState_[resource] -> colormap -> data == NULL) - { - unpackState_[resource] -> colormap -> data = - (unsigned int *) new unsigned char[unpacked]; - - if (unpackState_[resource] -> colormap -> data == NULL) - { - #ifdef PANIC - *logofs << "handleColormap: PANIC! Can't allocate " - << unpacked << " entries for unpack colormap data " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - goto handleColormapEnd; - } - - #ifdef DEBUG - *logofs << "handleColormap: Size of new colormap data is " - << unpacked << ".\n" << logofs_flush; - #endif - } - - unsigned int method = *(buffer + 4); - - if (method == PACK_COLORMAP) - { - if (UnpackColormap(method, buffer + 16, packed, - (unsigned char *) unpackState_[resource] -> - colormap -> data, unpacked) < 0) - { - #ifdef PANIC - *logofs << "handleColormap: PANIC! Can't unpack " << packed - << " bytes to " << unpacked << " entries for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - delete [] unpackState_[resource] -> colormap -> data; - - unpackState_[resource] -> colormap -> data = NULL; - unpackState_[resource] -> colormap -> entries = 0; - - goto handleColormapEnd; - } - } - else - { - memcpy((unsigned char *) unpackState_[resource] -> - colormap -> data, buffer + 16, unpacked); - } - - unpackState_[resource] -> colormap -> entries = unpacked >> 2; - - #if defined(DEBUG) && defined(DUMP) - - *logofs << "handleColormap: Dumping colormap entries:\n" - << logofs_flush; - - const unsigned char *p = (const unsigned char *) unpackState_[resource] -> colormap -> data; - - for (unsigned int i = 0; i < unpackState_[resource] -> - colormap -> entries; i++) - { - *logofs << "handleColormap: [" << i << "] [" - << (void *) ((int) p[i]) << "].\n" - << logofs_flush; - } - - #endif - } // end anonymous block - -handleColormapEnd: - - handleCleanAndNullRequest(opcode, buffer, size); - - return 1; -} - -int ServerChannel::handleAlpha(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size) -{ - int resource = *(buffer + 1); - - #ifdef TEST - *logofs << "handleAlpha: Setting new unpack alpha " - << "for resource " << resource << ".\n" - << logofs_flush; - #endif - - handleUnpackStateInit(resource); - - handleUnpackAllocAlpha(resource); - - // - // New protocol versions send the alpha - // data in compressed form. - // - - // - // Since ProtoStep7 (#issue 108) - // - - { // An anonymous block is used here to limit the scope of local variables - unsigned int packed = GetULONG(buffer + 8, bigEndian_); - unsigned int unpacked = GetULONG(buffer + 12, bigEndian_); - - validateSize("alpha", packed, unpacked, 16, size); - - if (unpackState_[resource] -> alpha -> entries != unpacked && - unpackState_[resource] -> alpha -> data != NULL) - { - #ifdef TEST - *logofs << "handleAlpha: Freeing previously allocated " - << "unpack alpha data.\n" << logofs_flush; - #endif - - delete [] unpackState_[resource] -> alpha -> data; - - unpackState_[resource] -> alpha -> data = NULL; - unpackState_[resource] -> alpha -> entries = 0; - } - - #ifdef TEST - *logofs << "handleAlpha: Setting " << unpacked - << " bytes of unpack alpha data for resource " - << resource << ".\n" << logofs_flush; - #endif - - if (unpackState_[resource] -> alpha -> data == NULL) - { - unpackState_[resource] -> alpha -> data = new unsigned char[unpacked]; - - if (unpackState_[resource] -> alpha -> data == NULL) - { - #ifdef PANIC - *logofs << "handleAlpha: PANIC! Can't allocate " - << unpacked << " entries for unpack alpha data " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - goto handleAlphaEnd; - } - - #ifdef DEBUG - *logofs << "handleAlpha: Size of new alpha data is " - << unpacked << ".\n" << logofs_flush; - #endif - } - - unsigned int method = *(buffer + 4); - - if (method == PACK_ALPHA) - { - if (UnpackAlpha(method, buffer + 16, packed, - unpackState_[resource] -> alpha -> - data, unpacked) < 0) - { - #ifdef PANIC - *logofs << "handleAlpha: PANIC! Can't unpack " << packed - << " bytes to " << unpacked << " entries for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - delete [] unpackState_[resource] -> alpha -> data; - - unpackState_[resource] -> alpha -> data = NULL; - unpackState_[resource] -> alpha -> entries = 0; - - goto handleAlphaEnd; - } - } - else - { - memcpy((unsigned char *) unpackState_[resource] -> - alpha -> data, buffer + 16, unpacked); - } - - unpackState_[resource] -> alpha -> entries = unpacked; - - #if defined(DEBUG) && defined(DUMP) - - *logofs << "handleAlpha: Dumping alpha entries:\n" - << logofs_flush; - - const unsigned char *p = unpackState_[resource] -> alpha -> data; - - for (unsigned int i = 0; i < unpackState_[resource] -> - alpha -> entries; i++) - { - *logofs << "handleAlpha: [" << i << "] [" - << (void *) ((int) p[i]) << "].\n" - << logofs_flush; - } - - #endif - } //end anonymous block - -handleAlphaEnd: - - handleCleanAndNullRequest(opcode, buffer, size); - - return 1; -} - -int ServerChannel::handleImage(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size) -{ - int result = 1; - - // - // Save the original opcode together with - // the image state so we can later find if - // this is a plain or a packed image when - // moving data to the shared memory area. - // - - handleImageStateAlloc(opcode); - - if (opcode == opcodeStore_ -> putPackedImage) - { - // - // Unpack the image and put a X_PutImage in a - // new buffer. Save the expected output size, - // so, in the case of a decoding error we can - // still update the statistics. - // - - int length = GetULONG(buffer + 20, bigEndian_); - - #ifdef TEST - *logofs << "handleImage: Sending image for FD#" << fd_ - << " due to OPCODE#" << (unsigned int) opcode << " with " - << GetULONG(buffer + 16, bigEndian_) << " bytes packed " - << "and " << GetULONG(buffer + 20, bigEndian_) - << " bytes unpacked.\n" << logofs_flush; - #endif - - statistics -> addPackedBytesIn(size); - - result = handleUnpack(opcode, buffer, size); - - if (result < 0) - { - // - // Recover from the error. Send a X_NoOperation - // to keep the sequence counter in sync with - // the remote peer. - // - - size = 4; - buffer = writeBuffer_.addMessage(size); - - *buffer = X_NoOperation; - - PutUINT(size >> 2, buffer + 2, bigEndian_); - - #ifdef PANIC - *logofs << "handleImage: PANIC! Sending X_NoOperation for FD#" - << fd_ << " to recover from failed unpack.\n" - << logofs_flush; - #endif - - // - // Set the output length to reflect the amount of - // data that would have been produced by unpacking - // the image. This is advisable to keep the count- - // ers in sync with those at remote proxy. Setting - // the size here doesn't have any effect on the - // size of data sent to the X server as the actual - // size will be taken from the content of the write - // buffer. - // - - size = length; - } - - statistics -> addPackedBytesOut(size); - - // - // Refrain the write loop from putting - // opcode and size in the output buffer. - // - - opcode = 0; - } - - // - // Now image is unpacked as a X_PutImage - // in write buffer. Check if we can send - // the image using the MIT-SHM extension. - // - - if (result > 0) - { - result = handleShmem(opcode, buffer, size); - - // - // We already put opcode and size in - // the resulting buffer. - // - - if (result > 0) - { - opcode = 0; - } - } - - return 1; -} - -int ServerChannel::handleMotion(EncodeBuffer &encodeBuffer) -{ - #if defined(TEST) || defined(INFO) - - if (lastMotion_[0] == '\0') - { - *logofs << "handleMotion: PANIC! No motion events to send " - << "for FD#" << fd_ << ".\n" << logofs_flush; - - HandleCleanup(); - } - - #endif - - #if defined(TEST) || defined(INFO) - *logofs << "handleMotion: Sending motion events for FD#" - << fd_ << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - // - // Replicate code from read loop. When have - // time and wish, try to split everything - // in functions. - // - - if (proxy -> handleAsyncSwitch(fd_) < 0) - { - return -1; - } - - const unsigned char *buffer = lastMotion_; - unsigned char opcode = *lastMotion_; - unsigned int size = 32; - - if (GetUINT(buffer + 2, bigEndian_) < serverSequence_) - { - PutUINT(serverSequence_, (unsigned char *) buffer + 2, bigEndian_); - } - - encodeBuffer.encodeOpcodeValue(opcode, serverCache_ -> opcodeCache); - - unsigned int sequenceNum = GetUINT(buffer + 2, bigEndian_); - - unsigned int sequenceDiff = sequenceNum - serverSequence_; - - serverSequence_ = sequenceNum; - - #ifdef DEBUG - *logofs << "handleMotion: Last server sequence number for FD#" - << fd_ << " is " << serverSequence_ << " with " - << "difference " << sequenceDiff << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(sequenceDiff, 16, - serverCache_ -> eventSequenceCache, 7); - - // - // If we fast encoded the message - // then skip the rest. - // - - if (control -> LocalDeltaCompression == 0) - { - int result = handleFastReadEvent(encodeBuffer, opcode, - buffer, size); - - #ifdef DEBUG - *logofs << "handleMotion: Sent saved motion event for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - lastMotion_[0] = '\0'; - - #ifdef DEBUG - *logofs << "handleMotion: Reset last motion event for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - if (result < 0) - { - return -1; - } - else if (result > 0) - { - return 1; - } - } - - // - // This should be just the part specific - // for motion events but is currently a - // copy-paste of code from the read loop. - // - - unsigned char detail = buffer[1]; - if (*buffer == MotionNotify) - encodeBuffer.encodeBoolValue((unsigned int) detail); - else if ((*buffer == EnterNotify) || (*buffer == LeaveNotify)) - encodeBuffer.encodeValue((unsigned int) detail, 3); - else if (*buffer == KeyRelease) - { - if (detail == serverCache_ -> keyPressLastKey) - encodeBuffer.encodeBoolValue(1); - else - { - encodeBuffer.encodeBoolValue(0); - encodeBuffer.encodeValue((unsigned int) detail, 8); - } - } - else if ((*buffer == ButtonPress) || (*buffer == ButtonRelease)) - encodeBuffer.encodeCachedValue(detail, 8, - serverCache_ -> buttonCache); - else - encodeBuffer.encodeValue((unsigned int) detail, 8); - unsigned int timestamp = GetULONG(buffer + 4, bigEndian_); - unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp; - serverCache_ -> lastTimestamp = timestamp; - encodeBuffer.encodeCachedValue(timestampDiff, 32, - serverCache_ -> motionNotifyTimestampCache, 9); - int skipRest = 0; - if (*buffer == KeyRelease) - { - skipRest = 1; - for (unsigned int i = 8; i < 31; i++) - { - if (buffer[i] != serverCache_ -> keyPressCache[i - 8]) - { - skipRest = 0; - break; - } - } - encodeBuffer.encodeBoolValue(skipRest); - } - if (!skipRest) - { - const unsigned char *nextSrc = buffer + 8; - for (unsigned int i = 0; i < 3; i++) - { - encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29, - *serverCache_ -> motionNotifyWindowCache[i], 6); - nextSrc += 4; - } - unsigned int rootX = GetUINT(buffer + 20, bigEndian_); - unsigned int rootY = GetUINT(buffer + 22, bigEndian_); - unsigned int eventX = GetUINT(buffer + 24, bigEndian_); - unsigned int eventY = GetUINT(buffer + 26, bigEndian_); - eventX -= rootX; - eventY -= rootY; - encodeBuffer.encodeCachedValue(rootX - - serverCache_ -> motionNotifyLastRootX, 16, - serverCache_ -> motionNotifyRootXCache, 6); - serverCache_ -> motionNotifyLastRootX = rootX; - encodeBuffer.encodeCachedValue(rootY - - serverCache_ -> motionNotifyLastRootY, 16, - serverCache_ -> motionNotifyRootYCache, 6); - serverCache_ -> motionNotifyLastRootY = rootY; - encodeBuffer.encodeCachedValue(eventX, 16, - serverCache_ -> motionNotifyEventXCache, 6); - encodeBuffer.encodeCachedValue(eventY, 16, - serverCache_ -> motionNotifyEventYCache, 6); - encodeBuffer.encodeCachedValue(GetUINT(buffer + 28, bigEndian_), - 16, serverCache_ -> motionNotifyStateCache); - if ((*buffer == EnterNotify) || (*buffer == LeaveNotify)) - encodeBuffer.encodeValue((unsigned int) buffer[30], 2); - else - encodeBuffer.encodeBoolValue((unsigned int) buffer[30]); - if ((*buffer == EnterNotify) || (*buffer == LeaveNotify)) - encodeBuffer.encodeValue((unsigned int) buffer[31], 2); - else if (*buffer == KeyPress) - { - serverCache_ -> keyPressLastKey = detail; - for (unsigned int i = 8; i < 31; i++) - { - serverCache_ -> keyPressCache[i - 8] = buffer[i]; - } - } - } - - // - // Print info about achieved compression - // and update the statistics. - // - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleMotion: Handled event OPCODE#" << (unsigned int) buffer[0] - << " for FD#" << fd_ << " sequence " << sequenceNum << ". " - << size << " bytes in, " << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - #endif - - statistics -> addEventBits(*buffer, size << 3, bits); - - #ifdef DEBUG - *logofs << "handleMotion: Sent saved motion event for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - lastMotion_[0] = '\0'; - - #ifdef DEBUG - *logofs << "handleMotion: Reset last motion event for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ServerChannel::handleConfiguration() -{ - #ifdef TEST - *logofs << "ServerChannel: Setting new buffer parameters " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - readBuffer_.setSize(control -> ServerInitialReadSize, - control -> ServerMaximumBufferSize); - - writeBuffer_.setSize(control -> TransportXBufferSize, - control -> TransportXBufferThreshold, - control -> TransportMaximumBufferSize); - - transport_ -> setSize(control -> TransportXBufferSize, - control -> TransportXBufferThreshold, - control -> TransportMaximumBufferSize); - return 1; -} - -int ServerChannel::handleFinish() -{ - #ifdef TEST - *logofs << "ServerChannel: Finishing connection for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - congestion_ = 0; - priority_ = 0; - - finish_ = 1; - - // - // Reset the motion event. - // - - lastMotion_[0] = '\0'; - - transport_ -> fullReset(); - - return 1; -} - -int ServerChannel::handleAsyncEvents() -{ - // - // Encode more events while decoding the - // proxy messages. - // - - if (transport_ -> readable() > 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleAsyncEvents: WARNING! Encoding events " - << "for FD#" << fd_ << " at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - #if defined(TEST) || defined(INFO) - - T_timestamp startTs = getTimestamp(); - - #endif - - if (proxy -> handleAsyncRead(fd_) < 0) - { - return -1; - } - - #if defined(TEST) || defined(INFO) - *logofs << "handleAsyncEvents: Spent " << diffTimestamp(startTs, - getTimestamp()) << " Ms handling events for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - return 1; - } - - return 0; -} - -int ServerChannel::handleUnpack(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size) -{ - int resource = *(buffer + 1); - - #ifdef DEBUG - *logofs << "handleUnpack: Unpacking image for resource " << resource - << " with method " << (unsigned int) *(buffer + 12) - << ".\n" << logofs_flush; - #endif - - handleUnpackStateInit(resource); - - T_geometry *geometryState = unpackState_[resource] -> geometry; - T_colormap *colormapState = unpackState_[resource] -> colormap; - T_alpha *alphaState = unpackState_[resource] -> alpha; - - if (geometryState == NULL) - { - #ifdef PANIC - *logofs << "handleUnpack: PANIC! Missing geometry unpacking " - << "image for resource " << resource << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Missing geometry unpacking " - << "image for resource " << resource << ".\n"; - - return -1; - } - - // - // Get the image data from the buffer. - // - - imageState_ -> drawable = GetULONG(buffer + 4, bigEndian_); - imageState_ -> gcontext = GetULONG(buffer + 8, bigEndian_); - - imageState_ -> method = *(buffer + 12); - - imageState_ -> format = *(buffer + 13); - imageState_ -> srcDepth = *(buffer + 14); - imageState_ -> dstDepth = *(buffer + 15); - - imageState_ -> srcLength = GetULONG(buffer + 16, bigEndian_); - imageState_ -> dstLength = GetULONG(buffer + 20, bigEndian_); - - imageState_ -> srcX = GetUINT(buffer + 24, bigEndian_); - imageState_ -> srcY = GetUINT(buffer + 26, bigEndian_); - imageState_ -> srcWidth = GetUINT(buffer + 28, bigEndian_); - imageState_ -> srcHeight = GetUINT(buffer + 30, bigEndian_); - - imageState_ -> dstX = GetUINT(buffer + 32, bigEndian_); - imageState_ -> dstY = GetUINT(buffer + 34, bigEndian_); - imageState_ -> dstWidth = GetUINT(buffer + 36, bigEndian_); - imageState_ -> dstHeight = GetUINT(buffer + 38, bigEndian_); - - #ifdef TEST - *logofs << "handleUnpack: Source X is " << imageState_ -> srcX - << " Y is " << imageState_ -> srcY << " width is " - << imageState_ -> srcWidth << " height is " - << imageState_ -> srcHeight << ".\n" - << logofs_flush; - #endif - - #ifdef TEST - *logofs << "handleUnpack: Destination X is " << imageState_ -> dstX - << " Y is " << imageState_ -> dstY << " width is " - << imageState_ -> dstWidth << " height is " - << imageState_ -> dstHeight << ".\n" - << logofs_flush; - #endif - - if (imageState_ -> srcX != 0 || imageState_ -> srcY != 0) - { - #ifdef PANIC - *logofs << "handleUnpack: PANIC! Unsupported source coordinates " - << "in unpack request.\n" << logofs_flush; - #endif - - return -1; - } - else if (imageState_ -> method == PACK_COLORMAP_256_COLORS && - (colormapState == NULL || colormapState -> data == NULL)) - { - #ifdef PANIC - *logofs << "handleUnpack: PANIC! Cannot find any unpack colormap.\n" - << logofs_flush; - #endif - - return -1; - } - - // - // Field srcLength carries size of image data in - // packed format. Field dstLength is size of the - // image in the original X bitmap format. - // - - unsigned int srcDataOffset = 40; - - unsigned int srcSize = imageState_ -> srcLength; - - unsigned int removeSize = size; - - unsigned char *srcData = buffer + srcDataOffset; - - // - // Get source and destination bits per pixel. - // - - int srcBitsPerPixel = MethodBitsPerPixel(imageState_ -> method); - - if (srcBitsPerPixel <= 0) - { - #ifdef PANIC - *logofs << "handleUnpack: PANIC! Can't identify source " - << "bits per pixel for method " << (unsigned int) - imageState_ -> method << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify source bits " - << "per pixel for method " << (unsigned int) - imageState_ -> method << ".\n"; - - writeBuffer_.removeMessage(removeSize); - - return -1; - } - - #ifdef TEST - *logofs << "handleUnpack: Source bits per pixel are " - << srcBitsPerPixel << " source data size is " - << srcSize << ".\n" << logofs_flush; - #endif - - int dstBitsPerPixel = UnpackBitsPerPixel(geometryState, imageState_ -> dstDepth); - - if (dstBitsPerPixel <= 0) - { - #ifdef PANIC - *logofs << "handleUnpack: PANIC! Can't identify " - << "destination bits per pixel for depth " - << (unsigned int) imageState_ -> dstDepth - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't identify " - << "destination bits per pixel for depth " - << (unsigned int) imageState_ -> dstDepth - << ".\n"; - - writeBuffer_.removeMessage(removeSize); - - return -1; - } - - // - // Destination is a PutImage request. - // - - unsigned int dstDataOffset = 24; - - // - // Output buffer size must match the number of input - // pixels multiplied by the number of bytes per pixel - // of current geometry. - // - - size = (RoundUp4(imageState_ -> dstWidth * dstBitsPerPixel / 8) * - imageState_ -> dstHeight) + dstDataOffset; - - #ifdef TEST - *logofs << "handleUnpack: Destination bits per pixel are " - << dstBitsPerPixel << " destination data size is " - << size - dstDataOffset << ".\n" << logofs_flush; - #endif - - unsigned int dstSize = size - dstDataOffset; - - imageState_ -> dstLines = imageState_ -> dstHeight; - - unsigned char *dstData; - - // - // Size of the final output buffer had to be stored - // in the offset field of XImage/NXPackedImage. - // - - #ifdef WARNING - - if (dstSize != imageState_ -> dstLength) - { - *logofs << "handleUnpack: WARNING! Destination size mismatch " - << "with reported " << imageState_ -> dstLength - << " and actual " << dstSize << ".\n" - << logofs_flush; - } - - #endif - - // - // The decoding algorithm has put the packed image - // in the plain write buffer. Let's use the scratch - // buffer to uncompress the image. - // - - buffer = writeBuffer_.addScratchMessage(size); - - dstData = buffer + dstDataOffset; - - // - // Unpack image into the buffer. - // - - *buffer = (unsigned char) X_PutImage; - - *(buffer + 1) = imageState_ -> format; - - PutUINT(size >> 2, buffer + 2, bigEndian_); - - PutULONG(imageState_ -> drawable, buffer + 4, bigEndian_); - PutULONG(imageState_ -> gcontext, buffer + 8, bigEndian_); - - PutUINT(imageState_ -> dstWidth, buffer + 12, bigEndian_); - PutUINT(imageState_ -> dstLines, buffer + 14, bigEndian_); - - PutUINT(imageState_ -> dstX, buffer + 16, bigEndian_); - PutUINT(imageState_ -> dstY, buffer + 18, bigEndian_); - - *(buffer + 20) = 0; - *(buffer + 21) = imageState_ -> dstDepth; - - #ifdef TEST - *logofs << "handleUnpack: Write buffer size is " - << writeBuffer_.getLength() << " scratch size is " - << writeBuffer_.getScratchLength() << ".\n" - << logofs_flush; - #endif - - int result = 0; - - switch (imageState_ -> method) - { - case PACK_JPEG_8_COLORS: - case PACK_JPEG_64_COLORS: - case PACK_JPEG_256_COLORS: - case PACK_JPEG_512_COLORS: - case PACK_JPEG_4K_COLORS: - case PACK_JPEG_32K_COLORS: - case PACK_JPEG_64K_COLORS: - case PACK_JPEG_256K_COLORS: - case PACK_JPEG_2M_COLORS: - case PACK_JPEG_16M_COLORS: - { - result = UnpackJpeg(geometryState, imageState_ -> method, srcData, - srcSize, dstBitsPerPixel, imageState_ -> dstWidth, - imageState_ -> dstHeight, dstData, dstSize); - break; - } - case PACK_PNG_8_COLORS: - case PACK_PNG_64_COLORS: - case PACK_PNG_256_COLORS: - case PACK_PNG_512_COLORS: - case PACK_PNG_4K_COLORS: - case PACK_PNG_32K_COLORS: - case PACK_PNG_64K_COLORS: - case PACK_PNG_256K_COLORS: - case PACK_PNG_2M_COLORS: - case PACK_PNG_16M_COLORS: - { - result = UnpackPng(geometryState, imageState_ -> method, srcData, - srcSize, dstBitsPerPixel, imageState_ -> dstWidth, - imageState_ -> dstHeight, dstData, dstSize); - break; - } - case PACK_RGB_16M_COLORS: - { - result = UnpackRgb(geometryState, imageState_ -> method, srcData, - srcSize, dstBitsPerPixel, imageState_ -> dstWidth, - imageState_ -> dstHeight, dstData, dstSize); - break; - } - case PACK_RLE_16M_COLORS: - { - result = UnpackRle(geometryState, imageState_ -> method, srcData, - srcSize, dstBitsPerPixel, imageState_ -> dstWidth, - imageState_ -> dstHeight, dstData, dstSize); - break; - } - case PACK_BITMAP_16M_COLORS: - { - result = UnpackBitmap(geometryState, imageState_ -> method, srcData, - srcSize, dstBitsPerPixel, imageState_ -> dstWidth, - imageState_ -> dstHeight, dstData, dstSize); - break; - } - case PACK_COLORMAP_256_COLORS: - { - result = Unpack8(geometryState, colormapState, srcBitsPerPixel, - imageState_ -> srcWidth, imageState_ -> srcHeight, srcData, - srcSize, dstBitsPerPixel, imageState_ -> dstWidth, - imageState_ -> dstHeight, dstData, dstSize); - - break; - } - default: - { - const T_colormask *colorMask = MethodColorMask(imageState_ -> method); - - switch (imageState_ -> method) - { - case PACK_MASKED_8_COLORS: - case PACK_MASKED_64_COLORS: - case PACK_MASKED_256_COLORS: - { - result = Unpack8(geometryState, colorMask, imageState_ -> srcDepth, - imageState_ -> srcWidth, imageState_ -> srcHeight, - srcData, srcSize, imageState_ -> dstDepth, - imageState_ -> dstWidth, imageState_ -> dstHeight, - dstData, dstSize); - break; - } - case PACK_MASKED_512_COLORS: - case PACK_MASKED_4K_COLORS: - case PACK_MASKED_32K_COLORS: - case PACK_MASKED_64K_COLORS: - { - result = Unpack16(geometryState, colorMask, imageState_ -> srcDepth, - imageState_ -> srcWidth, imageState_ -> srcHeight, - srcData, srcSize, imageState_ -> dstDepth, - imageState_ -> dstWidth, imageState_ -> dstHeight, - dstData, dstSize); - break; - } - case PACK_MASKED_256K_COLORS: - case PACK_MASKED_2M_COLORS: - case PACK_MASKED_16M_COLORS: - { - result = Unpack24(geometryState, colorMask, imageState_ -> srcDepth, - imageState_ -> srcWidth, imageState_ -> srcHeight, - srcData, srcSize, imageState_ -> dstDepth, - imageState_ -> dstWidth, imageState_ -> dstHeight, - dstData, dstSize); - break; - } - default: - { - break; - } - } - } - } - - writeBuffer_.removeMessage(removeSize); - - if (result <= 0) - { - #ifdef PANIC - *logofs << "handleUnpack: PANIC! Failed to unpack image " - << "with method '" << (unsigned int) imageState_ -> method - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Failed to unpack image " - << "with method '" << (unsigned int) imageState_ -> method - << "'.\n"; - - // - // TODO: We should mark the image somehow, - // and force the remote to remove it from - // the cache. - // - - writeBuffer_.removeScratchMessage(); - - return -1; - } - - // - // Alpha channel is used only on some 32 bits pixmaps - // and only if render extension is in use. Presently - // we don't have an efficient way to know in advance - // if mask must be applied or not to the image. If an - // alpha channel is set, the function will check if - // the size of the alpha data matches the size of the - // image. In the worst case we'll create an useless - // alpha plane for a pixmap that doesn't need it. - // - - if (alphaState != NULL && alphaState -> data != NULL && - imageState_ -> dstDepth == 32) - { - UnpackAlpha(alphaState, dstData, dstSize, imageByteOrder_); - } - - return 1; -} - -int ServerChannel::handleAuthorization(unsigned char *buffer) -{ - // - // At the present moment we don't support more than - // a single display for each proxy, so authorization - // data is shared among all the channels. - // - // Use the following code to simulate authentication - // failures on a LSB machine: - // - // memcpy(buffer + 12 + (((buffer[6] + 256 * - // buffer[7]) + 3) & ~3), "1234567890123456", 16); - // - - if (auth == NULL) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleAuthorization: Forwarding the real cookie " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - return 0; - } - else if (auth -> checkCookie(buffer) == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleAuthorization: Matched the fake cookie " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - return 1; - } - else - { - #if defined(TEST) || defined(INFO) - *logofs << "handleAuthorization: WARNING! Failed to match " - << "the fake cookie for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - return -1; - } -} - -int ServerChannel::handleAuthorization(const unsigned char *buffer, int size) -{ - // - // Check the X server's response and, in the case of - // an error, print the textual information reported - // by the server. - // - - if (*buffer != 1) - { - const char *reason = NULL; - - // - // At the moment we don't take into account the end- - // ianess of the reply. This should work in any case - // because we simply try to match a few well-known - // error strings. - // - - if (size >= INVALID_COOKIE_SIZE + 8 && - memcmp(buffer + 8, INVALID_COOKIE_DATA, - INVALID_COOKIE_SIZE) == 0) - { - reason = INVALID_COOKIE_DATA; - } - else if (size >= NO_AUTH_PROTO_SIZE + 8 && - memcmp(buffer + 8, NO_AUTH_PROTO_DATA, - NO_AUTH_PROTO_SIZE) == 0) - { - reason = NO_AUTH_PROTO_DATA; - } - else - { - reason = "Unknown"; - } - - #ifdef WARNING - *logofs << "handleAuthorization: WARNING! X connection failed " - << "with error '" << reason << "' on FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - cerr << "Warning" << ": X connection failed " - << "with error '" << reason << "'.\n"; - } - #if defined(TEST) || defined(INFO) - else - { - *logofs << "handleAuthorization: X connection successful " - << "on FD#" << fd_ << ".\n" << logofs_flush; - } - #endif - - return 1; -} - -// -// Use a simple encoding. Need to handle the image -// requests in the usual way and the X_ListExtensions -// and X_QueryExtension to hide MIT-SHM and RENDER -// in the reply. -// - -int ServerChannel::handleFastWriteRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - // - // All the NX requests are handled in the - // main message loop. - // - - // - // Since ProtoStep7 (#issue 108) - // - // The X_PutImage can be handled here only - // if a split was not requested. - // - - if ((opcode >= X_NXFirstOpcode && opcode <= X_NXLastOpcode) || - (opcode == X_PutImage && splitState_.resource != nothing) || - opcode == X_ListExtensions || - opcode == X_QueryExtension) - { - return 0; - } - - #ifdef DEBUG - *logofs << "handleFastWriteRequest: Decoding raw request OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - buffer = writeBuffer_.addMessage(4); - - #ifndef __sun - - unsigned int *next = (unsigned int *) decodeBuffer.decodeMemory(4); - - *((unsigned int *) buffer) = *next; - - #else /* #ifndef __sun */ - - memcpy(buffer, decodeBuffer.decodeMemory(4), 4); - - #endif /* #ifndef __sun */ - - size = GetUINT(buffer + 2, bigEndian_) << 2; - - if (size < 4) - { - #ifdef WARNING - *logofs << "handleFastWriteRequest: WARNING! Assuming size 4 " - << "for suspicious message of size " << size - << ".\n" << logofs_flush; - #endif - - size = 4; - } - - writeBuffer_.registerPointer(&buffer); - - if (writeBuffer_.getAvailable() < size - 4 || - (int) size >= control -> TransportFlushBufferSize) - { - #ifdef DEBUG - *logofs << "handleFastWriteRequest: Using scratch buffer for OPCODE#" - << (unsigned int) opcode << " with size " << size << " and " - << writeBuffer_.getLength() << " bytes in buffer.\n" - << logofs_flush; - #endif - - // - // The procedure moving data to shared memory - // assumes that the full message is stored in - // the scratch buffer. We can safely let the - // scratch buffer inherit the decode buffer - // at the next offset. - // - - writeBuffer_.removeMessage(4); - - buffer = writeBuffer_.addScratchMessage(((unsigned char *) - decodeBuffer.decodeMemory(size - 4)) - 4, size); - } - else - { - writeBuffer_.addMessage(size - 4); - - #ifndef __sun - - if (size <= 32) - { - next = (unsigned int *) decodeBuffer.decodeMemory(size - 4); - - for (unsigned int i = 4; i < size; i += sizeof(unsigned int)) - { - *((unsigned int *) (buffer + i)) = *next++; - } - } - else - { - memcpy(buffer + 4, decodeBuffer.decodeMemory(size - 4), size - 4); - } - - #else /* #ifndef __sun */ - - memcpy(buffer + 4, decodeBuffer.decodeMemory(size - 4), size - 4); - - #endif /* #ifndef __sun */ - } - - // - // Opcode could have been tainted by the client - // proxy. Replace the original opcode with the - // one sent in the decode buffer. - // - - *buffer = opcode; - - writeBuffer_.unregisterPointer(); - - if (opcode == X_PutImage) - { - handleImage(opcode, buffer, size); - } - - #if defined(TEST) || defined(OPCODES) - - if (opcode != 0) - { - *logofs << "handleFastWriteRequest: Handled request " - << "OPCODE#" << (unsigned int) opcode << " (" - << DumpOpcode(opcode) << ") for FD#" << fd_ - << " sequence " << clientSequence_ << ". " - << size << " bytes out.\n" << logofs_flush; - } - else - { - *logofs << "handleFastWriteRequest: Handled image or " - << "other request for FD#" << fd_ - << " sequence " << clientSequence_ << ". " - << size << " bytes out.\n" << logofs_flush; - } - - #endif - - handleFlush(flush_if_needed); - - return 1; -} - -// -// Use the simplest encoding except for replies that -// need to be managed some way. -// - -int ServerChannel::handleFastReadReply(EncodeBuffer &encodeBuffer, const unsigned char &opcode, - const unsigned char *&buffer, const unsigned int &size) -{ - // - // If we pushed a X_GetInputFocus in the sequence - // queue this means that the original message was - // a NX request for which we have to provide a NX - // reply. - // - - if ((opcode >= X_NXFirstOpcode && - opcode <= X_NXLastOpcode) || - opcode == X_QueryExtension || - opcode == X_ListExtensions || - opcode == X_GetInputFocus) - { - return 0; - } - - #ifdef DEBUG - *logofs << "handleFastReadReply: Encoding raw reply OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ - << " with size " << size << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeMemory(buffer, size); - - // - // Send back the reply as soon - // as possible. - // - - priority_++; - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - *logofs << "handleFastReadReply: Handled raw reply OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ << " sequence " - << serverSequence_ << ". " << size << " bytes in, " - << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - #endif - - statistics -> addReplyBits(opcode, size << 3, bits); - - return 1; -} - -int ServerChannel::handleFastReadEvent(EncodeBuffer &encodeBuffer, const unsigned char &opcode, - const unsigned char *&buffer, const unsigned int &size) -{ - #ifdef DEBUG - *logofs << "handleFastReadEvent: Encoding raw " - << (opcode == X_Error ? "error" : "event") << " OPCODE#" - << (unsigned int) opcode << " for FD#" << fd_ - << " with size " << size << ".\n" - << logofs_flush; - #endif - - encodeBuffer.encodeMemory(buffer, size); - - switch (opcode) - { - case X_Error: - case ButtonPress: - case ButtonRelease: - case KeyPress: - case KeyRelease: - { - priority_++; - } - } - - int bits = encodeBuffer.diffBits(); - - #if defined(TEST) || defined(OPCODES) - - if (opcode == X_Error) - { - unsigned char code = *(buffer + 1); - - *logofs << "handleFastReadEvent: Handled error ERR_CODE#" - << (unsigned int) code << " for FD#" << fd_; - - *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_); - - *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_); - - *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10); - - *logofs << " sequence " << serverSequence_ << ". " << size - << " bytes in, " << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - } - else - { - *logofs << "handleFastReadEvent: Handled event OPCODE#" - << (unsigned int) *buffer << " for FD#" << fd_ - << " sequence " << serverSequence_ << ". " << size - << " bytes in, " << bits << " bits (" << ((float) bits) / 8 - << " bytes) out.\n" << logofs_flush; - } - - #endif - - statistics -> addEventBits(opcode, size << 3, bits); - - return 1; -} - -void ServerChannel::initCommitQueue() -{ - #ifdef TEST - *logofs << "initCommitQueue: Resetting the queue of split commits " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE; i++) - { - commitSequenceQueue_[i] = 0; - } -} - -void ServerChannel::updateCommitQueue(unsigned short sequence) -{ - for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE - 1; i++) - { - commitSequenceQueue_[i + 1] = commitSequenceQueue_[i]; - } - - #ifdef TEST - *logofs << "updateCommitQueue: Saved " << sequence - << " as last sequence number of image to commit.\n" - << logofs_flush; - #endif - - commitSequenceQueue_[0] = sequence; -} - -int ServerChannel::checkCommitError(unsigned char error, unsigned short sequence, - const unsigned char *buffer) -{ - // - // Check if error is due to an image commit - // generated at the end of a split. - // - // TODO: It should zero the head of the list - // when an event comes with a sequence number - // greater than the value of the last element - // added. - // - - for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE && - commitSequenceQueue_[i] != 0; i++) - { - #ifdef TEST - *logofs << "checkCommitError: Checking committed image's " - << "sequence number " << commitSequenceQueue_[i] - << " with input sequence " << sequence << ".\n" - << logofs_flush; - #endif - - if (commitSequenceQueue_[i] == sequence) - { - #ifdef WARNING - - *logofs << "checkCommitError: WARNING! Failed operation for " - << "FD#" << fd_ << " with ERR_CODE#" - << (unsigned int) *(buffer + 1); - - *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_); - - *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_); - - *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10); - - *logofs << " sequence " << sequence << ".\n"; - - *logofs << logofs_flush; - - #endif - - cerr << "Warning" << ": Failed commit operation " - << "with ERR_CODE#" << (unsigned int) error; - - cerr << " RES_ID#" << GetULONG(buffer + 4, bigEndian_); - - cerr << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_); - - cerr << " MAJ_OP#" << (unsigned int) *(buffer + 10); - - cerr << ".\n"; - - #ifdef WARNING - *logofs << "checkCommitError: WARNING! Suppressing error on " - << "OPCODE#" << (unsigned int) opcodeStore_ -> commitSplit - << " for FD#" << fd_ << " with sequence " << sequence - << " at position " << i << ".\n" << logofs_flush; - #endif - - return 0; - } - } - - return 0; -} - -// -// Check if the user pressed the CTRL+ALT+SHIFT+ESC -// keystroke. At the present moment it uses different -// keycodes based on the client OS. This should be -// implemented in a way that is platform independent -// (that's not an easy task, considered that we don't -// have access to the higher level X libraries). -// - -int ServerChannel::checkKeyboardEvent(unsigned char event, unsigned short sequence, - const unsigned char *buffer) -{ - #ifdef TEST - *logofs << "checkKeyboardEvent: Checking escape sequence with byte [1] " - << (void *) ((unsigned) *(buffer + 1)) << " and bytes [28-29] " - << (void *) ((unsigned) GetUINT(buffer + 28, bigEndian_)) - << " for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - #ifdef __APPLE__ - - int alert = (*(buffer + 1) == 0x3d && - GetUINT(buffer + 28, bigEndian_) == 0x2005); - - #else - - int alert = (*(buffer + 1) == 0x09 && - ((GetUINT(buffer + 28, bigEndian_) & - 0x0d) == 0x0d)); - - #endif - - if (alert == 1) - { - #ifdef PANIC - *logofs << "checkKeyboardEvent: PANIC! Received sequence " - << "CTRL+ALT+SHIFT+ESC " << "for FD#"<< fd_ - << ". Showing the abort dialog.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Received sequence CTRL+ALT+SHIFT+ESC. " - << "Showing the abort dialog.\n"; - - HandleAlert(CLOSE_UNRESPONSIVE_X_SERVER_ALERT, 1); - } - - return alert; -} - -// -// Handle the MIT-SHM initialization -// messages exchanged with the remote -// proxy. -// - -int ServerChannel::handleShmemReply(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned int stage, const unsigned char *buffer, - const unsigned int size) -{ - #ifdef TEST - *logofs << "handleShmemReply: Returning shmem reply for " - << "stage " << stage << ".\n" << logofs_flush; - #endif - - if (opcode == X_QueryExtension) - { - encodeBuffer.encodeValue(stage, 2); - -#ifndef ANDROID - shmemState_ -> present = *(buffer + 8); -#else - shmemState_ -> present = 0; - cerr << "Info: handleShmemReply: In android no shared memory. Setting present to 0 hardcoded\n"; -#endif - shmemState_ -> opcode = *(buffer + 9); - shmemState_ -> event = *(buffer + 10); - shmemState_ -> error = *(buffer + 11); - - #ifdef TEST - *logofs << "handleShmemReply: Extension present is " - << shmemState_ -> present << " with base OPCODE#" - << (unsigned int) shmemState_ -> opcode << " base event " - << (unsigned int) shmemState_ -> event << " base error " - << (unsigned int) shmemState_ -> error << ".\n" - << logofs_flush; - #endif - } - else if (opcode == X_GetInputFocus) - { - encodeBuffer.encodeValue(stage, 2); - - encodeBuffer.encodeBoolValue(0); - - if (shmemState_ -> present == 1 && - shmemState_ -> address != NULL && - shmemState_ -> segment > 0 && - shmemState_ -> id > 0) - { - cerr << "Info" << ": Using shared memory parameters 1/" - << (shmemState_ -> size / 1024) << "K.\n"; - -#ifndef ANDROID - shmemState_ -> enabled = 1; -#else - cerr << "Info: handleShmemReply: In android no shared memory. Setting enabled to -1. This should not be displayed\n"; - shmemState_ -> enabled = -1; -#endif - - encodeBuffer.encodeBoolValue(1); - } - else - { - #ifdef TEST - *logofs << "handleShmemReply: WARNING! Not using shared memory " - << "support in X server for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - cerr << "Info" << ": Using shared memory parameters 0/0K.\n"; - - handleShmemStateRemove(); - - encodeBuffer.encodeBoolValue(0); - } - } - else - { - #ifdef PANIC - *logofs << "handleShmemReply: PANIC! Conversation error " - << "handling shared memory support for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Conversation error handling " - << "shared memory support.\n"; - - return -1; - } - - return 1; -} - -int ServerChannel::handleShmemRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - // - // We need to query and initialize MIT-SHM on - // the real X server. To do this we'll need 3 - // requests. At the end we'll have to encode - // the final reply for the X client side. - // - - handleShmemStateAlloc(); - - unsigned int stage; - - decodeBuffer.decodeValue(stage, 2); - - unsigned int expected = shmemState_ -> stage + 1; - - if (stage != expected || stage > 2) - { - #ifdef PANIC - *logofs << "handleShmemRequest: PANIC! Unexpected stage " - << stage << " in handling shared memory " - << "support for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Unexpected stage " - << stage << " in handling shared memory " - << "support for FD#" << fd_ << ".\n"; - - return -1; - } - - switch (stage) - { - case 0: - { - unsigned int enableClient; - unsigned int enableServer; - - decodeBuffer.decodeBoolValue(enableClient); - decodeBuffer.decodeBoolValue(enableServer); - - unsigned int clientSegment; - unsigned int serverSegment; - - decodeBuffer.decodeValue(clientSegment, 29, 9); - decodeBuffer.decodeValue(serverSegment, 29, 9); - - shmemState_ -> segment = serverSegment; - - #ifdef TEST - *logofs << "handleShmemRequest: Size of the shared memory " - << "segment will be " << control -> ShmemServerSize - << ".\n" << logofs_flush; - #endif - - #ifdef TEST - *logofs << "handleShmemRequest: Sending X_QueryExtension request " - << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int) - opcodeStore_ -> getShmemParameters << " in stage " - << stage << ".\n" << logofs_flush; - #endif - - opcode = X_QueryExtension; - - size = 16; - buffer = writeBuffer_.addMessage(size); - - PutUINT(7, buffer + 4, bigEndian_); - - // - // Simply make the query fail if shared - // memory support is disabled by the - // user. - // -#ifndef ANDROID - if (control -> ShmemServer == 1 && - control -> ShmemServerSize > 0 && - enableServer == 1) - { - memcpy(buffer + 8, "MIT-SHM", 7); - } - else - { - memcpy(buffer + 8, "NO-MIT-", 7); - } -#else - cerr << "Info: handleShmemRequest: In android no shared memory. Returning NO-MIT- answer\n"; - - memcpy(buffer + 8, "NO-MIT-", 7); -#endif - sequenceQueue_.push(clientSequence_, opcode, - opcodeStore_ -> getShmemParameters, stage); - - // - // Save the sequence number so we can - // later identify any matching X error - // received from server. - // - - shmemState_ -> sequence = clientSequence_; - - break; - } - case 1: - { - if (shmemState_ -> present == 1) - { - // - // Make the segment read-write for everybody on - // Cygwin (to avoid any lack of support or any - // performance issue) and on MacOS/X (where the - // 0600 mask doesn't seem to work). - // - - #if defined(__CYGWIN32__) || defined(__APPLE__) - - int permissions = 0777; - - #else - - int permissions = 0600; - - #endif - - shmemState_ -> size = control -> ShmemServerSize; - -#ifndef ANDROID - shmemState_ -> id = shmget(IPC_PRIVATE, shmemState_ -> size, - IPC_CREAT | permissions); -#else - cerr << "Info: handleShmemReqyest: In android no shared memory (shmget). This message should not be displayed present should never be 1 in android\n"; - shmemState_ -> id = -1; -#endif - if (shmemState_ -> id >= 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleShmemRequest: Allocated shared memory " - << "segment of " << shmemState_ -> size - << " bytes with id " << shmemState_ -> id - << ".\n" << logofs_flush; - #endif - - -#ifndef ANDROID - shmemState_ -> address = shmat(shmemState_ -> id, 0, 0); -#else - cerr << "Info: handleShmemReqyest: In android no shared memory (shmat). This message should not be displayed. present should never be 1 in android\n"; - shmemState_ -> address = NULL; -#endif - if (shmemState_ -> address != NULL) - { - #ifdef TEST - *logofs << "handleShmemRequest: Sending X_ShmAttach request " - << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int) - opcodeStore_ -> getShmemParameters << " in stage " - << stage << ".\n" << logofs_flush; - #endif - - opcode = shmemState_ -> opcode; - - size = 16; - buffer = writeBuffer_.addMessage(size); - - *(buffer + 1) = X_ShmAttach; - - PutULONG(shmemState_ -> segment, buffer + 4, bigEndian_); - PutULONG(shmemState_ -> id, buffer + 8, bigEndian_); - - *(buffer + 12) = 1; - - shmemState_ -> sequence = clientSequence_; - - break; - } - else - { - #ifdef WARNING - *logofs << "handleShmemRequest: WARNING! Can't attach the shared " - << "memory segment. Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Can't attach the shared memory " - << "segment. Error is " << EGET() << " '" - << ESTR() << "'.\n"; - } - } - else - { - #ifndef __CYGWIN32__ - - #ifdef WARNING - *logofs << "handleShmemRequest: WARNING! Can't create the shared " - << "memory segment. Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Can't create the shared memory " - << "segment. Error is " << EGET() << " '" - << ESTR() << "'.\n"; - - #else - - #ifdef TEST - *logofs << "handleShmemRequest: WARNING! Can't create the shared " - << "memory segment. Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - #endif - } - } - - if (shmemState_ -> present != 0) - { - #ifdef TEST - *logofs << "handleShmemRequest: Resetting shared memory " - << "presence flag for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - shmemState_ -> present = 0; - } - - handleNullRequest(opcode, buffer, size); - - break; - } - default: - { - #ifdef TEST - *logofs << "handleShmemRequest: Sending X_GetInputFocus request " - << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int) - opcodeStore_ -> getShmemParameters << " in stage " - << stage << ".\n" << logofs_flush; - #endif - - opcode = X_GetInputFocus; - - size = 4; - buffer = writeBuffer_.addMessage(size); - - sequenceQueue_.push(clientSequence_, opcode, - opcodeStore_ -> getShmemParameters, stage); - break; - } - } - - shmemState_ -> stage += 1; - - return 1; -} - -// -// Handling of MIT-SHM extension has been plugged late in -// the design, so we have to make some assumptions. Image -// is a X_PutImage request contained either in the scratch -// buffer or in the normal write buffer. We need to move -// the image data to the shared memory segment and replace -// the X_PutImage request with a X_ShmPutImage. -// - -int ServerChannel::handleShmem(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size) -{ - if (shmemState_ == NULL || shmemState_ -> enabled != 1) - { - #ifdef TEST - - if (shmemState_ != NULL) - { - *logofs << "handleShmem: PANIC! Shared memory " - << "state found but support is not enabled " - << "for FD#" << fd_ << " in stage " - << shmemState_ -> stage << ".\n" - << logofs_flush; - } - - #endif - - return 0; - } -#ifdef ANDROID - cerr << "Info: handleShmem: In android no shared memory. enabled should never be 1. This should not be displayed\n"; - return 0; -#endif - - // - // Ignore null requests and requests that will not result - // in a single X_PutImage. To conform with the other func- - // tions, we get the opcode passed as a parameter. It can - // be zero if we don't want the write loop to put opcode - // and length in the resulting buffer. Anyway we are only - // interested in the original opcode of the request, that - // is stored in the image state. - // - - unsigned char *dstData = buffer + 24; - unsigned int dstDataSize = size - 24; - - if (dstDataSize == 0 || dstDataSize > - (unsigned int) control -> MaximumRequestSize) - { - #ifdef TEST - *logofs << "handleShmem: Ignoring image with opcode " - << (unsigned int) imageState_ -> opcode - << " and size " << size << " for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - return 0; - } - - #ifdef TEST - *logofs << "handleShmem: Handling image with opcode " - << (unsigned int) imageState_ -> opcode - << " and size " << size << " for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - // - // Get image data from buffer. - // - - if (imageState_ -> opcode == X_PutImage) - { - // - // We still need to get the image's data. - // - - imageState_ -> format = *(buffer + 1); - - imageState_ -> drawable = GetULONG(buffer + 4, bigEndian_); - imageState_ -> gcontext = GetULONG(buffer + 8, bigEndian_); - - imageState_ -> dstWidth = GetUINT(buffer + 12, bigEndian_); - imageState_ -> dstHeight = GetUINT(buffer + 14, bigEndian_); - - imageState_ -> srcX = 0; - imageState_ -> srcY = 0; - - imageState_ -> srcWidth = imageState_ -> dstWidth; - imageState_ -> srcHeight = imageState_ -> dstHeight; - - imageState_ -> dstX = GetUINT(buffer + 16, bigEndian_); - imageState_ -> dstY = GetUINT(buffer + 18, bigEndian_); - - imageState_ -> leftPad = *(buffer + 20); - imageState_ -> dstDepth = *(buffer + 21); - - imageState_ -> dstLines = imageState_ -> dstHeight; - - imageState_ -> dstLength = size - 24; - } - - // - // Skip the MIT-SHM operation if the image - // is 1 bits-per-plane. - // - - if (imageState_ -> dstDepth == 1) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleShmem: Ignoring image with opcode " - << (unsigned int) imageState_ -> opcode << " depth " - << (unsigned int) imageState_ -> dstDepth << " and " - << "size " << size << " for FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - return 0; - } - - // - // If the image can't fit in the available - // space, check if the completion event is - // arrived. - // - - #if defined(TEST) || defined(INFO) - - if (isTimestamp(shmemState_ -> last) == 0 && - shmemState_ -> offset != 0) - { - *logofs << "handleShmem: PANIC! No timestamp for sequence " - << shmemState_ -> sequence << " with offset " - << shmemState_ -> offset << ".\n" - << logofs_flush; - } - - #endif - - if (shmemState_ -> offset + imageState_ -> dstLength > - shmemState_ -> size) - { - if (imageState_ -> dstLength > shmemState_ -> size) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleShmem: WARNING! Can't fit the image " - << "in the available memory segment for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - return 0; - } - else if (handleShmemEvent() <= 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleShmem: WARNING! Missing completion " - << "after " << diffTimestamp(shmemState_ -> last, - getTimestamp()) << " Ms for shared memory " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - return 0; - } - } - - // - // Let image start at current offset - // in the shared segment. - // - - #ifdef TEST - *logofs << "handleShmem: Copying " << dstDataSize - << " bytes to shared memory at offset " - << shmemState_ -> offset << " for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - memcpy((unsigned char *) shmemState_ -> address + - shmemState_ -> offset, dstData, dstDataSize); - - // - // Get rid of the original X_PutImage - // request. - // - - if (writeBuffer_.getScratchData() != NULL) - { - writeBuffer_.removeScratchMessage(); - } - else - { - writeBuffer_.removeMessage(size); - } - - // - // Add a X_ShmPutImage request to the - // write buffer. - // - - buffer = writeBuffer_.addMessage(40); - - *buffer = shmemState_ -> opcode; - - *(buffer + 1) = X_ShmPutImage; - - PutUINT(40 >> 2, buffer + 2, bigEndian_); - - PutULONG(imageState_ -> drawable, buffer + 4, bigEndian_); - PutULONG(imageState_ -> gcontext, buffer + 8, bigEndian_); - - PutUINT(imageState_ -> dstWidth, buffer + 12, bigEndian_); - PutUINT(imageState_ -> dstLines, buffer + 14, bigEndian_); - - PutUINT(imageState_ -> srcX, buffer + 16, bigEndian_); - PutUINT(imageState_ -> srcY, buffer + 18, bigEndian_); - - PutUINT(imageState_ -> dstWidth, buffer + 20, bigEndian_); - PutUINT(imageState_ -> dstLines, buffer + 22, bigEndian_); - - PutUINT(imageState_ -> dstX, buffer + 24, bigEndian_); - PutUINT(imageState_ -> dstY, buffer + 26, bigEndian_); - - *(buffer + 28) = imageState_ -> dstDepth; - *(buffer + 29) = imageState_ -> format; - *(buffer + 30) = 1; - - PutULONG(shmemState_ -> segment, buffer + 32, bigEndian_); - PutULONG(shmemState_ -> offset, buffer + 36, bigEndian_); - - shmemState_ -> offset += dstDataSize; - - shmemState_ -> sequence = clientSequence_; - shmemState_ -> last = getTimestamp(); - - #ifdef TEST - *logofs << "handleShmem: Saved shared memory sequence " - << shmemState_ -> sequence << " for FD#" << fd_ - << " with offset " << shmemState_ -> offset - << " at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - // - // Make the X server read immediately - // from the shared memory buffer and - // produce the completion event. - // - - handleFlush(flush_if_any); - - return 1; -} - -// -// Try to read more events from the socket in the -// attempt to get the completion event required -// to reset the MIT-SHM segment. -// - -int ServerChannel::handleShmemEvent() -{ - #if defined(TEST) || defined(INFO) - *logofs << "handleShmemEvent: Waiting for shared memory " - << "sequence " << shmemState_ -> sequence - << " for X server FD#" << fd_ << ".\n" - << logofs_flush; - - T_timestamp startTs = getTimestamp(); - - #endif - - while (isTimestamp(shmemState_ -> last) != 0) - { - if (handleWait(control -> ShmemTimeout) <= 0) - { - break; - } - #if defined(TEST) || defined(INFO) - else - { - *logofs << "handleShmemEvent: WARNING! Encoded events " - << "for FD#" << fd_ << " at " << strMsTimestamp() - << ".\n" << logofs_flush; - } - #endif - } - - if (isTimestamp(shmemState_ -> last) == 0) - { - #if defined(TEST) || defined(INFO) - *logofs << "handleShmemEvent: Spent " - << diffTimestamp(startTs, getTimestamp()) << " Ms " - << "waiting for shared memory sequence for FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - return 1; - } - - #if defined(TEST) || defined(INFO) - *logofs << "handleShmemEvent: WARNING! Can't reset shared " - << "memory sequence for FD#" << fd_ << " after " - << diffTimestamp(shmemState_ -> last, getTimestamp()) - << " Ms.\n" << logofs_flush; - #endif - - return 0; -} - -int ServerChannel::checkShmemEvent(unsigned char event, unsigned short sequence, - const unsigned char *buffer) -{ - if (isTimestamp(shmemState_ -> last) == 1 && - sequence == shmemState_ -> sequence) - { - #ifdef TEST - *logofs << "checkShmemEvent: Reset shared memory sequence " - << shmemState_ -> sequence << " for FD#" << fd_ - << " after " << diffTimestamp(shmemState_ -> last, - getTimestamp()) << " Ms.\n" << logofs_flush; - #endif - - shmemState_ -> sequence = 0; - shmemState_ -> offset = 0; - shmemState_ -> last = nullTimestamp(); - } - #ifdef TEST - else - { - *logofs << "checkShmemEvent: Skipping past shared memory " - << "image sequence " << sequence << " for FD#" - << fd_ << ".\n" << logofs_flush; - } - #endif - - return 1; -} - -int ServerChannel::checkShmemError(unsigned char error, unsigned short sequence, - const unsigned char *buffer) -{ - #ifdef TEST - - *logofs << "checkShmemError: WARNING! Failed operation for " - << "FD#" << fd_ << " in stage " << shmemState_ -> stage - << " with ERR_CODE#" << (unsigned int) *(buffer + 1); - - *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_); - - *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_); - - *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10); - - *logofs << " sequence " << sequence << ".\n"; - - *logofs << logofs_flush; - - #endif - - // - // If enabled flag is <= 0 we are still - // in the inizialization phase. In this - // case force presence to false. - // - - if (shmemState_ -> enabled != 1) - { - if (shmemState_ -> present != 0) - { - #ifdef TEST - *logofs << "checkShmemError: Resetting shared memory " - << "presence flag for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - shmemState_ -> present = 0; - } - - return 0; - } - - if (shmemState_ -> sequence == sequence) - { - // - // Reset the sequence and timestamp. - // - - shmemState_ -> sequence = 0; - shmemState_ -> offset = 0; - shmemState_ -> last = nullTimestamp(); - } - - return 1; -} - -int ServerChannel::handleFontRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - // - // Send a synchronization request and use - // the reply to return the requested font - // path. - // - - #ifdef TEST - *logofs << "handleFontRequest: Sending X_GetInputFocus request " - << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int) - opcodeStore_ -> getFontParameters << ".\n" - << logofs_flush; - #endif - - opcode = X_GetInputFocus; - - size = 4; - buffer = writeBuffer_.addMessage(size); - - sequenceQueue_.push(clientSequence_, X_GetInputFocus, - opcodeStore_ -> getFontParameters); - - return 1; -} - -int ServerChannel::handleFontReply(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) -{ - #ifdef TEST - *logofs << "handleFontReply: Encoding font operation " - << "reply with size " << size << ".\n" - << logofs_flush; - #endif - - char data[256]; - - if (fontPort_ != -1) - { - sprintf(data + 1, "tcp/localhost:%d", fontPort_); - } - else - { - *(data + 1) = '\0'; - } - - *data = strlen(data + 1); - - unsigned char *next = (unsigned char *) data; - - unsigned int length = (unsigned int) (*next++); - - encodeBuffer.encodeValue(length, 8); - - encodeBuffer.encodeTextData(next, length); - - return 1; -} - -int ServerChannel::handleCacheRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - unsigned int mask; - - decodeBuffer.decodeCachedValue(mask, 32, clientCache_ -> - setCacheParametersCache); - - splitState_.save = (mask >> 8) & 0xff; - splitState_.load = mask & 0xff; - - #ifdef TEST - *logofs << "handleCacheRequest: Set cache parameters to " - << "save " << splitState_.save << " load " - << splitState_.load << ".\n" << logofs_flush; - #endif - - handleNullRequest(opcode, buffer, size); - - return 1; -} - -int ServerChannel::handleStartSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - // - // Prepare for the split for the selected - // resource. Old proxy versions only used - // the split store at position 0. - // - - // Since ProtoStep7 (#issue 108) - unsigned char resource; - - decodeBuffer.decodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - splitState_.resource = resource; - - splitState_.current = splitState_.resource; - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleStartSplitRequest: SPLIT! Registered id " - << splitState_.resource << " as resource " - << "waiting for a split.\n" << logofs_flush; - #endif - - handleNullRequest(opcode, buffer, size); - - return 1; -} - -int ServerChannel::handleEndSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size) -{ - // - // Verify that the agent resource matches. - // - - // Since ProtoStep7 (#issue 108) - unsigned char resource; - - decodeBuffer.decodeCachedValue(resource, 8, - clientCache_ -> resourceCache); - - #ifdef TEST - - if (splitState_.resource == nothing) - { - #ifdef PANIC - *logofs << "handleEndSplitRequest: PANIC! SPLIT! Received an end of " - << "split for resource id " << (unsigned int) *(buffer + 1) - << " without a previous start.\n" - << logofs_flush; - #endif - - HandleCleanup(); - } - else if (resource != splitState_.resource) - { - #ifdef PANIC - *logofs << "handleEndSplitRequest: PANIC! SPLIT! Invalid resource id " - << resource << " received while waiting for resource id " - << splitState_.resource << ".\n" << logofs_flush; - #endif - - HandleCleanup(); - } - - #endif - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleEndSplitRequest: SPLIT! Reset id " - << splitState_.resource << " as resource " - << "selected for splits.\n" << logofs_flush; - #endif - - splitState_.resource = nothing; - - handleNullRequest(opcode, buffer, size); - - return 1; -} - -int ServerChannel::handleSplitChecksum(DecodeBuffer &decodeBuffer, T_checksum &checksum) -{ - unsigned int receive; - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeBoolValue(receive); - - if (receive == 1) - { - checksum = new md5_byte_t[MD5_LENGTH]; - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - decodeBuffer.decodeValue(receive, 8); - - if (checksum != NULL) - { - checksum[i] = (unsigned char) receive; - } - } - - #if defined(TEST) || defined(SPLIT) - *logofs << "handleSplitChecksum: SPLIT! Received checksum " - << "[" << DumpChecksum(checksum) << "].\n" - << logofs_flush; - #endif - - return 1; - } - - return 0; -} - -void ServerChannel::handleShmemStateAlloc() -{ - if (shmemState_ == NULL) - { - shmemState_ = new T_shmem_state(); - - shmemState_ -> stage = -1; - shmemState_ -> present = -1; - shmemState_ -> enabled = -1; - - shmemState_ -> segment = -1; - shmemState_ -> id = -1; - shmemState_ -> address = NULL; - shmemState_ -> size = 0; - - shmemState_ -> opcode = 0xff; - shmemState_ -> event = 0xff; - shmemState_ -> error = 0xff; - - shmemState_ -> sequence = 0; - shmemState_ -> offset = 0; - shmemState_ -> last = nullTimestamp(); - - shmemState_ -> checked = 0; - } -} - -void ServerChannel::handleShmemStateRemove() -{ - if (shmemState_ != NULL) - { - if (shmemState_ -> address != NULL) - { -#ifndef ANDROID - shmdt((char *) shmemState_ -> address); -#else - cerr << "Info: handleShmemStateRemove: In android no shared memory. This should not be displayed. address should always be NULL\n"; -#endif - } - - if (shmemState_ -> id > 0) - { -#ifndef ANDROID - shmctl(shmemState_ -> id, IPC_RMID, 0); -#else - cerr << "Info: handleShmemStateRemove: In android no shared memory. This should not be displayed. id should always be 0\n"; -#endif - } - - delete shmemState_; - - shmemState_ = NULL; - } -} - -void ServerChannel::handleUnpackStateInit(int resource) -{ - if (unpackState_[resource] == NULL) - { - unpackState_[resource] = new T_unpack_state(); - - if (unpackState_[resource] == NULL) - { - #ifdef PANIC - *logofs << "handleUnpackStateInit: PANIC! Can't allocate " - << "memory for unpack state in context [A].\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "unpack state in context [A].\n"; - - HandleAbort(); - } - - unpackState_[resource] -> geometry = NULL; - unpackState_[resource] -> colormap = NULL; - unpackState_[resource] -> alpha = NULL; - } -} - -void ServerChannel::handleUnpackAllocGeometry(int resource) -{ - if (unpackState_[resource] -> geometry == NULL) - { - unpackState_[resource] -> geometry = new T_geometry(); - - if (unpackState_[resource] -> geometry == NULL) - { - #ifdef PANIC - *logofs << "handleUnpackAllocGeometry: PANIC! Can't allocate " - << "memory for unpack state in context [B].\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "unpack state in context [B].\n"; - - HandleAbort(); - } - - unpackState_[resource] -> geometry -> depth1_bpp = 4; - unpackState_[resource] -> geometry -> depth4_bpp = 4; - unpackState_[resource] -> geometry -> depth8_bpp = 8; - unpackState_[resource] -> geometry -> depth16_bpp = 16; - unpackState_[resource] -> geometry -> depth24_bpp = 32; - unpackState_[resource] -> geometry -> depth32_bpp = 32; - - unpackState_[resource] -> geometry -> red_mask = 0xff0000; - unpackState_[resource] -> geometry -> green_mask = 0x00ff00; - unpackState_[resource] -> geometry -> blue_mask = 0x0000ff; - - unpackState_[resource] -> geometry -> image_byte_order = imageByteOrder_; - unpackState_[resource] -> geometry -> bitmap_bit_order = bitmapBitOrder_; - unpackState_[resource] -> geometry -> scanline_unit = scanlineUnit_; - unpackState_[resource] -> geometry -> scanline_pad = scanlinePad_; - } -} - -void ServerChannel::handleUnpackAllocColormap(int resource) -{ - if (unpackState_[resource] -> colormap == NULL) - { - unpackState_[resource] -> colormap = new T_colormap(); - - if (unpackState_[resource] -> colormap == NULL) - { - #ifdef PANIC - *logofs << "handleUnpackAllocColormap: PANIC! Can't allocate " - << "memory for unpack state in context [C].\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "unpack state in context [C].\n"; - - HandleAbort(); - } - - unpackState_[resource] -> colormap -> entries = 0; - unpackState_[resource] -> colormap -> data = NULL; - } -} - -void ServerChannel::handleUnpackAllocAlpha(int resource) -{ - if (unpackState_[resource] -> alpha == NULL) - { - unpackState_[resource] -> alpha = new T_alpha(); - - if (unpackState_[resource] -> alpha == NULL) - { - #ifdef PANIC - *logofs << "handleUnpackAllocAlpha: PANIC! Can't allocate " - << "memory for unpack state in context [D].\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "unpack state in context [D].\n"; - - HandleAbort(); - } - - unpackState_[resource] -> alpha -> entries = 0; - unpackState_[resource] -> alpha -> data = NULL; - } -} - -void ServerChannel::handleUnpackStateRemove(int resource) -{ - if (unpackState_[resource] != NULL) - { - delete unpackState_[resource] -> geometry; - - if (unpackState_[resource] -> colormap != NULL) - { - delete [] unpackState_[resource] -> colormap -> data; - } - - delete unpackState_[resource] -> colormap; - - if (unpackState_[resource] -> alpha != NULL) - { - delete [] unpackState_[resource] -> alpha -> data; - } - - delete unpackState_[resource] -> alpha; - - delete unpackState_[resource]; - - unpackState_[resource] = NULL; - } -} - -void ServerChannel::handleEncodeCharInfo(const unsigned char *nextSrc, EncodeBuffer &encodeBuffer) -{ - unsigned int value = GetUINT(nextSrc, bigEndian_) | - (GetUINT(nextSrc + 10, bigEndian_) << 16); - - encodeBuffer.encodeCachedValue(value, 32, - *serverCache_ -> queryFontCharInfoCache[0], 6); - - nextSrc += 2; - - for (unsigned int i = 1; i < 5; i++) - { - unsigned int value = GetUINT(nextSrc, bigEndian_); - - nextSrc += 2; - - encodeBuffer.encodeCachedValue(value, 16, - *serverCache_ -> queryFontCharInfoCache[i], 6); - } -} - -int ServerChannel::setBigEndian(int flag) -{ - bigEndian_ = flag; - - readBuffer_.setBigEndian(flag); - - return 1; -} - -int ServerChannel::setReferences() -{ - #ifdef TEST - *logofs << "ServerChannel: Initializing the static " - << "members for the server channels.\n" - << logofs_flush; - #endif - - #ifdef REFERENCES - - references_ = 0; - - #endif - - return 1; -} diff --git a/nxcomp/ServerChannel.h b/nxcomp/ServerChannel.h deleted file mode 100644 index 374e52896..000000000 --- a/nxcomp/ServerChannel.h +++ /dev/null @@ -1,529 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ServerChannel_H -#define ServerChannel_H - -#include "List.h" -#include "Channel.h" - -#include "SequenceQueue.h" - -#include "ServerReadBuffer.h" - -#include "Unpack.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// How many sequence numbers of split commit -// requests we are going to save in order to -// mask errors. -// - -#define MAX_COMMIT_SEQUENCE_QUEUE 16 - -// -// Define this to know when a channel -// is created or destroyed. -// - -#undef REFERENCES - -// -// This class implements the X server -// side compression of X protocol. -// - -class ServerChannel : public Channel -{ - public: - - ServerChannel(Transport *transport, StaticCompressor *compressor); - - virtual ~ServerChannel(); - - virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, - unsigned int length); - - virtual int handleWrite(const unsigned char *message, unsigned int length); - - virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, - T_store_action action, int position, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size) - { - return 0; - } - - virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, - T_store_action action, int position, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - virtual int handleSplit(EncodeBuffer &encodeBuffer) - { - return 0; - } - - virtual int handleSplit(DecodeBuffer &decodeBuffer); - - virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split); - - virtual int handleSplitEvent(DecodeBuffer &decodeBuffer) - { - return 0; - } - - // - // Send the last motion notify event - // received from the X server to the - // remote proxy. - // - - virtual int handleMotion(EncodeBuffer &encodeBuffer); - - virtual int handleCompletion(EncodeBuffer &encodeBuffer) - { - return 0; - } - - virtual int handleConfiguration(); - - virtual int handleFinish(); - - virtual int handleAsyncEvents(); - - virtual int needSplit() const - { - return 0; - } - - virtual int needMotion() const - { - return (lastMotion_[0] != '\0'); - } - - virtual T_channel_type getType() const - { - return channel_x11; - } - - int setBigEndian(int flag); - - // - // Initialize the static members. - // - - static int setReferences(); - - private: - - int handleFastReadReply(EncodeBuffer &encodeBuffer, const unsigned char &opcode, - const unsigned char *&buffer, const unsigned int &size); - - int handleFastReadEvent(EncodeBuffer &encodeBuffer, const unsigned char &opcode, - const unsigned char *&buffer, const unsigned int &size); - - int handleFastWriteRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - // - // Handle the fake authorization cookie - // and the X server's reply. - // - - int handleAuthorization(unsigned char *buffer); - int handleAuthorization(const unsigned char *buffer, int size); - - // - // Set the unpack colormap and the alpha - // blending data to be used to unpack - // images. - // - - int handleGeometry(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size); - - int handleColormap(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size); - - int handleAlpha(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size); - - // - // Manage the decoded buffer to unpack - // the image and move the data to the - // shared memory segment. - // - - int handleImage(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size); - - // - // Uncompress a packed image in one - // or more graphic X requests. - // - - int handleUnpack(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size); - - // - // Move the image to the shared - // memory buffer. - // - - int handleShmem(unsigned char &opcode, unsigned char *&buffer, - unsigned int &size); - - // - // Handle suppression of error on - // commit of image splits. - // - - void initCommitQueue(); - - void updateCommitQueue(unsigned short sequence); - - int checkCommitError(unsigned char error, unsigned short sequence, - const unsigned char *buffer); - - void clearCommitQueue() - { - if (commitSequenceQueue_[0] != 0) - { - initCommitQueue(); - } - } - - // - // Check if the user pressed the - // CTRL+ALT+SHIFT+ESC keystroke. - // - - int checkKeyboardEvent(unsigned char event, unsigned short sequence, - const unsigned char *buffer); - - // - // Other utilities. - // - - void handleEncodeCharInfo(const unsigned char *nextSrc, EncodeBuffer &encodeBuffer); - - // - // Handle the MIT-SHM initialization - // messages exchanged with the remote - // proxy. - // - - int handleShmemRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - - int handleShmemReply(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned int stage, const unsigned char *buffer, - const unsigned int size); - - // - // Try to read more events in the attempt to - // get the MIT-SHM image completion event - // from the X server. - // - - int handleShmemEvent(); - - // - // Handle the MIT-SHM events as they are read - // from the socket. - // - - int checkShmemEvent(unsigned char event, unsigned short sequence, - const unsigned char *buffer); - - int checkShmemError(unsigned char error, unsigned short sequence, - const unsigned char *buffer); - - // - // Query the port used to tunnel - // the font server connections. - // - - int handleFontRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - int handleFontReply(EncodeBuffer &encodeBuffer, const unsigned char opcode, - const unsigned char *buffer, const unsigned int size); - - // - // Set the cache policy for image - // requests. - // - - int handleCacheRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - // - // Decode the start and end split - // requests. - // - - int handleStartSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - int handleEndSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - // - // Remove the split store and the - // incomplete messages from the - // memory cache. - // - - int handleAbortSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - // - // Send the split requests to the - // X server once they have been - // recomposed. - // - - int handleCommitSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, - unsigned char *&buffer, unsigned int &size); - - int handleSplitChecksum(DecodeBuffer &decodeBuffer, T_checksum &checksum); - - // - // Allocate and free the shared memory - // support resources. - // - - void handleShmemStateAlloc(); - void handleShmemStateRemove(); - - // - // Temporary storage for the image info. - // - - void handleImageStateAlloc(unsigned char opcode) - { - if (imageState_ == NULL) - { - imageState_ = new T_image_state(); - } - - imageState_ -> opcode = opcode; - } - - void handleImageStateRemove() - { - if (imageState_ != NULL) - { - delete imageState_; - - imageState_ = NULL; - } - } - - // - // Store the information needed to unpack - // images per each known agent's client. - // - - void handleUnpackStateInit(int resource); - - void handleUnpackAllocGeometry(int resource); - void handleUnpackAllocColormap(int resource); - void handleUnpackAllocAlpha(int resource); - - void handleUnpackStateRemove(int resource); - - typedef struct - { - T_geometry *geometry; - T_colormap *colormap; - T_alpha *alpha; - - } T_unpack_state; - - T_unpack_state *unpackState_[256]; - - // - // Own read buffer. It is able to identify - // full messages read from X descriptor. - // - - ServerReadBuffer readBuffer_; - - // - // Sequence number of last request coming - // from X client or X server. - // - - unsigned int clientSequence_; - unsigned int serverSequence_; - - // - // Used to identify replies based on sequence - // number of original request. - // - - SequenceQueue sequenceQueue_; - - // - // Last motion notify read from the X server. - // - - unsigned char lastMotion_[32]; - - // - // Sequence numbers of last auto-generated - // put image requests. Needed to intercept - // and suppress errors generated by such - // requests. - // - - unsigned int commitSequenceQueue_[MAX_COMMIT_SEQUENCE_QUEUE]; - - // - // Let agent select which expose - // events is going to receive. - // - - unsigned int enableExpose_; - unsigned int enableGraphicsExpose_; - unsigned int enableNoExpose_; - - // - // Used in initialization and handling - // of MIT-SHM shared memory put images. - // - - typedef struct - { - int stage; - int present; - int enabled; - int segment; - int id; - void *address; - unsigned int size; - - unsigned char opcode; - unsigned char event; - unsigned char error; - - unsigned int sequence; - unsigned int offset; - T_timestamp last; - - unsigned int checked; - - } T_shmem_state; - - T_shmem_state *shmemState_; - - // - // Used to pass current image data between - // the different decompression stages. - // - - typedef struct - { - unsigned char opcode; - - unsigned int drawable; - unsigned int gcontext; - - unsigned char method; - - unsigned char format; - unsigned char srcDepth; - unsigned char dstDepth; - - unsigned int srcLength; - unsigned int dstLength; - unsigned int dstLines; - - short int srcX; - short int srcY; - unsigned short srcWidth; - unsigned short srcHeight; - - short int dstX; - short int dstY; - unsigned short dstWidth; - unsigned short dstHeight; - - unsigned char leftPad; - - } T_image_state; - - T_image_state *imageState_; - - // - // The flags is set according to the - // split load and save policy set by - // the encoding side. - // - - typedef struct - { - int resource; - int current; - int load; - int save; - int commit; - - } T_split_state; - - T_split_state splitState_; - - // - // List of agent resources. - // - - List splitResources_; - - // - // Keep track of object creation and - // deletion. - // - - private: - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -#endif /* ServerChannel_H */ diff --git a/nxcomp/ServerProxy.cpp b/nxcomp/ServerProxy.cpp deleted file mode 100644 index 5d1765183..000000000 --- a/nxcomp/ServerProxy.cpp +++ /dev/null @@ -1,617 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include - -#include "NXalert.h" - -#include "Socket.h" - -#include "ServerProxy.h" - -#include "ServerChannel.h" -#include "GenericChannel.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Log the operations related to sending -// and receiving the control tokens. -// - -#undef TOKEN - -ServerProxy::ServerProxy(int proxyFd) : Proxy(proxyFd) - -{ - xServerAddrFamily_ = -1; - xServerAddrLength_ = 0; - - xServerAddr_ = NULL; - xServerDisplay_ = NULL; - - cupsServerPort_ = NULL; - smbServerPort_ = NULL; - mediaServerPort_ = NULL; - httpServerPort_ = NULL; - - fontServerPort_ = NULL; - - #ifdef DEBUG - *logofs << "ServerProxy: Created new object at " << this - << ".\n" << logofs_flush; - #endif -} - -ServerProxy::~ServerProxy() -{ - delete xServerAddr_; - - delete [] xServerDisplay_; - - delete [] fontServerPort_; - - #ifdef DEBUG - *logofs << "ServerProxy: Deleted object at " << this - << ".\n" << logofs_flush; - #endif -} - -void ServerProxy::handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, - sockaddr *xServerAddr, unsigned int xServerAddrLength) -{ - delete xServerAddr_; - - xServerAddr_ = xServerAddr; - - xServerAddrFamily_ = xServerAddrFamily; - xServerAddrLength_ = xServerAddrLength; - - delete [] xServerDisplay_; - - xServerDisplay_ = new char[strlen(xServerDisplay) + 1]; - - strcpy(xServerDisplay_, xServerDisplay); - - #ifdef DEBUG - *logofs << "ServerProxy: Set display configuration to display '" - << xServerDisplay_ << "'.\n" - << logofs_flush; - #endif -} - -void ServerProxy::handlePortConfiguration(ChannelEndPoint &cupsServerPort, - ChannelEndPoint &smbServerPort, - ChannelEndPoint &mediaServerPort, - ChannelEndPoint &httpServerPort, - const char *fontServerPort) -{ - cupsServerPort_ = cupsServerPort; - smbServerPort_ = smbServerPort; - mediaServerPort_ = mediaServerPort; - httpServerPort_ = httpServerPort; - - delete [] fontServerPort_; - - fontServerPort_ = new char[strlen(fontServerPort) + 1]; - - strcpy(fontServerPort_, fontServerPort); - - #ifdef DEBUG - *logofs << "ServerProxy: Set port configuration to CUPS " - << cupsServerPort_ << ", SMB " << smbServerPort_ - << ", media " << mediaServerPort_ << ", HTTP " - << httpServerPort_ << ".\n" - << logofs_flush; - #endif -} - -int ServerProxy::handleNewConnection(T_channel_type type, int clientFd) -{ - switch (type) - { - case channel_font: - { - return handleNewGenericConnection(clientFd, channel_font, "font"); - } - case channel_slave: - { - return handleNewSlaveConnection(clientFd); - } - default: - { - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Unsupported channel with type '" - << getTypeName(type) << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unsupported channel with type '" - << getTypeName(type) << "'.\n"; - - return -1; - } - } -} - -int ServerProxy::handleNewConnectionFromProxy(T_channel_type type, int channelId) -{ - switch (type) - { - case channel_x11: - { - return handleNewXConnectionFromProxy(channelId); - } - case channel_cups: - { - return handleNewGenericConnectionFromProxy(channelId, channel_cups, - cupsServerPort_, "CUPS"); - } - case channel_smb: - { - smbServerPort_.setDefaultTCPInterface(1); - return handleNewGenericConnectionFromProxy(channelId, channel_smb, - smbServerPort_, "SMB"); - } - case channel_media: - { - return handleNewGenericConnectionFromProxy(channelId, channel_media, - mediaServerPort_, "media"); - } - case channel_http: - { - return handleNewGenericConnectionFromProxy(channelId, channel_http, - httpServerPort_, "HTTP"); - } - case channel_slave: - { - return handleNewSlaveConnectionFromProxy(channelId); - } - default: - { - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Unsupported channel with type '" - << getTypeName(type) << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Unsupported channel with type '" - << getTypeName(type) << "'.\n"; - - return -1; - } - } -} - -int ServerProxy::handleNewAgentConnection(Agent *agent) -{ - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Can't create an agent " - << "connection at this side.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't create an agent " - << "connection at this side.\n"; - - return -1; -} - -int ServerProxy::handleNewXConnection(int clientFd) -{ - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Can't create a new X channel " - << "with FD#" << clientFd << " at this side.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't create a new X channel " - << "with FD#" << clientFd << " at this side.\n"; - - return -1; -} - -int ServerProxy::handleNewXConnectionFromProxy(int channelId) -{ - // - // Connect to the real X server. - // - - int retryConnect = control -> OptionServerRetryConnect; - - int xServerFd; - - for (;;) - { - xServerFd = socket(xServerAddrFamily_, SOCK_STREAM, PF_UNSPEC); - - if (xServerFd < 0) - { - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Call to socket failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Call to socket failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - return -1; - } - - #ifdef TEST - *logofs << "ServerProxy: Trying to connect to X server '" - << xServerDisplay_ << "'.\n" << logofs_flush; - #endif - - int result = connect(xServerFd, xServerAddr_, xServerAddrLength_); - - getNewTimestamp(); - - if (result < 0) - { - #ifdef WARNING - *logofs << "ServerProxy: WARNING! Connection to '" - << xServerDisplay_ << "' failed with error '" - << ESTR() << "'. Retrying.\n" << logofs_flush; - #endif - - close(xServerFd); - - if (--retryConnect == 0) - { - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Connection to '" - << xServerDisplay_ << "' for channel ID#" - << channelId << " failed. Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Connection to '" - << xServerDisplay_ << "' failed. Error is " - << EGET() << " '" << ESTR() << "'.\n"; - - close(xServerFd); - - return -1; - } - - if (activeChannels_.getSize() == 0) - { - sleep(2); - } - else - { - sleep(1); - } - } - else - { - break; - } - } - - assignChannelMap(channelId, xServerFd); - - #ifdef TEST - *logofs << "ServerProxy: X server descriptor FD#" << xServerFd - << " mapped to channel ID#" << channelId << ".\n" - << logofs_flush; - #endif - - // - // Turn queuing off for path proxy-to-X-server. - // - - if (control -> OptionServerNoDelay == 1) - { - SetNoDelay(xServerFd, control -> OptionServerNoDelay); - } - - // - // If requested, set the size of the TCP send - // and receive buffers. - // - - if (control -> OptionServerSendBuffer != -1) - { - SetSendBuffer(xServerFd, control -> OptionServerSendBuffer); - } - - if (control -> OptionServerReceiveBuffer != -1) - { - SetReceiveBuffer(xServerFd, control -> OptionServerReceiveBuffer); - } - - if (allocateTransport(xServerFd, channelId) < 0) - { - return -1; - } - - // - // Starting from protocol level 3 client and server - // caches are created in proxy and shared between all - // channels. If remote proxy has older protocol level - // pointers are NULL and channels must create their - // own instances. - // - - channels_[channelId] = new ServerChannel(transports_[channelId], compressor_); - - if (channels_[channelId] == NULL) - { - deallocateTransport(channelId); - - return -1; - } - - increaseChannels(channelId); - - // - // Propagate channel stores and caches to the new - // channel. - // - - channels_[channelId] -> setOpcodes(opcodeStore_); - - channels_[channelId] -> setStores(clientStore_, serverStore_); - - channels_[channelId] -> setCaches(clientCache_, serverCache_); - - int port = atoi(fontServerPort_); - - if (port > 0) - { - channels_[channelId] -> setPorts(port); - } - - // - // Let channel configure itself according - // to control parameters. - // - - channels_[channelId] -> handleConfiguration(); - - // - // Check if we have successfully loaded the - // selected cache and, if not, remove it - // from disk. - // - - handleCheckLoad(); - - return 1; -} - -// -// Check if we still need to drop a channel. We need -// to check this explicitly at the time we receive a -// request to load or save the cache because we could -// receive the control message before having entered -// the function handling the channel events. -// - -int ServerProxy::handleCheckDrop() -{ - T_list channelList = activeChannels_.copyList(); - - for (T_list::iterator j = channelList.begin(); - j != channelList.end(); j++) - { - int channelId = *j; - - if (channels_[channelId] != NULL && - (channels_[channelId] -> getDrop() == 1 || - channels_[channelId] -> getClosing() == 1)) - { - #ifdef TEST - *logofs << "ServerProxy: Dropping the descriptor FD#" - << getFd(channelId) << " channel ID#" - << channelId << ".\n" << logofs_flush; - #endif - - handleDrop(channelId); - } - } - - return 1; -} - -int ServerProxy::handleCheckLoad() -{ - // - // Check if we just created the first X channel - // but the client side didn't tell us to load - // the cache selected at the session negotiation. - // This is very likely because the load operation - // failed at the remote side, for example because - // the cache was invalid or corrupted. - // - - int channelCount = getChannels(channel_x11); - - if (channelCount != 1) - { - return 0; - } - - if (control -> PersistentCacheEnableLoad == 1 && - control -> PersistentCachePath != NULL && - control -> PersistentCacheName != NULL && - isTimestamp(timeouts_.loadTs) == 0) - { - #ifdef WARNING - *logofs << "ServerProxy: WARNING! Cache file '" << control -> PersistentCachePath - << "/" << control -> PersistentCacheName << "' not loaded.\n" - << logofs_flush; - #endif - - // - // Remove the cache file. - // - - #ifdef WARNING - *logofs << "ServerProxy: WARNING! Removing supposedly " - << "incompatible cache '" << control -> PersistentCachePath - << "/" << control -> PersistentCacheName - << "'.\n" << logofs_flush; - #endif - - handleResetPersistentCache(); - } - - return 1; -} - -int ServerProxy::handleLoadFromProxy() -{ - // - // Be sure we drop any confirmed channel. - // - - handleCheckDrop(); - - // - // Check that either no X channel is - // remaining or we are inside a reset. - // - - int channelCount = getChannels(channel_x11); - - if (channelCount > 0) - { - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Protocol violation " - << "in command load with " << channelCount - << " channels.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Protocol violation " - << "in command load from proxy.\n"; - - return -1; - } - else if (handleLoadStores() < 0) - { - #ifdef WARNING - *logofs << "ServerProxy: WARNING! Failed to load content " - << "of persistent cache.\n" << logofs_flush; - #endif - - return -1; - } - - return 1; -} - -int ServerProxy::handleSaveFromProxy() -{ - // - // Be sure we drop any confirmed channel. - // - - handleCheckDrop(); - - // - // Now verify that all channels are gone. - // - - int channelCount = getChannels(channel_x11); - - if (channelCount > 0) - { - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Protocol violation " - << "in command save with " << channelCount - << " channels.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Protocol violation " - << "in command save from proxy.\n"; - - return -1; - } - else if (handleSaveStores() < 0) - { - #ifdef PANIC - *logofs << "ServerProxy: PANIC! Failed to save stores " - << "to persistent cache.\n" << logofs_flush; - #endif - - return -1; - } - - return 1; -} - -int ServerProxy::handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient) const -{ - if (clientStore_ -> saveRequestStores(cachefs, md5StateStream, md5StateClient, - discard_checksum, use_data) < 0) - { - return -1; - } - else if (serverStore_ -> saveReplyStores(cachefs, md5StateStream, md5StateClient, - use_checksum, discard_data) < 0) - { - return -1; - } - else if (serverStore_ -> saveEventStores(cachefs, md5StateStream, md5StateClient, - use_checksum, discard_data) < 0) - { - return -1; - } - - return 1; -} - -int ServerProxy::handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const -{ - if (clientStore_ -> loadRequestStores(cachefs, md5StateStream, - discard_checksum, use_data) < 0) - { - return -1; - } - else if (serverStore_ -> loadReplyStores(cachefs, md5StateStream, - use_checksum, discard_data) < 0) - { - return -1; - } - else if (serverStore_ -> loadEventStores(cachefs, md5StateStream, - use_checksum, discard_data) < 0) - { - return -1; - } - - return 1; -} diff --git a/nxcomp/ServerProxy.h b/nxcomp/ServerProxy.h deleted file mode 100644 index e169c4aec..000000000 --- a/nxcomp/ServerProxy.h +++ /dev/null @@ -1,154 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ServerProxy_H -#define ServerProxy_H - -#include -#include - -#include "Proxy.h" - -#include "Misc.h" -#include "ChannelEndPoint.h" - -// -// Set the verbosity level. -// - -#undef TEST -#undef DEBUG - -class ServerProxy : public Proxy -{ - public: - - ServerProxy(int proxyFd); - - virtual ~ServerProxy(); - - virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, - sockaddr *xServerAddr, unsigned int xServerAddrLength); - - virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort, - ChannelEndPoint &smbServerPort, - ChannelEndPoint &mediaServerPort, - ChannelEndPoint &httpServerPort, - const char *fontServerPort); - - protected: - - // - // Create a new channel. - // - - virtual int handleNewConnection(T_channel_type type, int clientFd); - - virtual int handleNewConnectionFromProxy(T_channel_type type, int channelId); - - virtual int handleNewAgentConnection(Agent *agent); - - virtual int handleNewXConnection(int clientFd); - - virtual int handleNewXConnectionFromProxy(int channelId); - - // - // Implement persistence according - // to our proxy mode. - // - - virtual int handleLoad(T_load_type type) - { - return 0; - } - - virtual int handleSave() - { - return 0; - } - - virtual int handleAsyncEvents() - { - return 0; - } - - virtual int handleLoadFromProxy(); - virtual int handleSaveFromProxy(); - - virtual int handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient) const; - - virtual int handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const; - - int handleCheckDrop(); - int handleCheckLoad(); - - // - // Utility function used to realize - // a new connection. - // - - protected: - - virtual int checkLocalChannelMap(int channelId) - { - // Since ProtoStep7 (#issue 108) - return ((channelId & control -> ChannelMask) == 0); - } - - private: - - // FIXME: Use a ChannelEndPoint object also for the X server! - int xServerAddrFamily_; - sockaddr *xServerAddr_; - unsigned int xServerAddrLength_; - - // - // This is the name of the X display where - // we are going to forward connections. - // - - char *xServerDisplay_; - - // - // Ports where to forward extended services' - // TCP connections. - // - - ChannelEndPoint cupsServerPort_; - ChannelEndPoint smbServerPort_; - ChannelEndPoint mediaServerPort_; - ChannelEndPoint httpServerPort_; - - // - // It will have to be passed to the channel - // so that it can set the port where the - // font server connections are tunneled. - // - - char *fontServerPort_; -}; - -#endif /* ServerProxy_H */ diff --git a/nxcomp/ServerReadBuffer.cpp b/nxcomp/ServerReadBuffer.cpp deleted file mode 100644 index 5bd9bb60f..000000000 --- a/nxcomp/ServerReadBuffer.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ServerReadBuffer.h" -#include "ServerChannel.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -unsigned int ServerReadBuffer::suggestedLength(unsigned int pendingLength) -{ - // - // Always read all the data that - // is available. - // - - int readable = transport_ -> readable(); - - unsigned int readLength = (readable == -1 ? 0 : (unsigned int) readable); - - if (readLength < pendingLength) - { - readLength = pendingLength; - } - - // - // Even if the readable data is not - // enough to make a complete message, - // resize the buffer to accommodate - // it all. - // - - if (pendingLength < remaining_) - { - readLength = remaining_; - } - - return readLength; -} - -int ServerReadBuffer::locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength) -{ - unsigned int size = end - start; - - #ifdef TEST - *logofs << "ServerReadBuffer: Locating message for FD#" - << transport_ -> fd() << " with " << size - << " bytes.\n" << logofs_flush; - #endif - - if (firstMessage_) - { - if (size < 8) - { - remaining_ = 8 - size; - - #ifdef TEST - *logofs << "ServerReadBuffer: No message was located " - << "with remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - dataLength = 8 + (GetUINT(start + 6, bigEndian_) << 2); - } - else - { - if (size < 32) - { - remaining_ = 32 - size; - - #ifdef TEST - *logofs << "ServerReadBuffer: No message was located " - << "with remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - if (*start == 1) - { - dataLength = 32 + (GetULONG(start + 4, bigEndian_) << 2); - } - else - { - dataLength = 32; - } - - if (dataLength < 32) - { - #ifdef TEST - *logofs << "ServerReadBuffer: WARNING! Assuming length 32 " - << "for suspicious message of length " << dataLength - << ".\n" << logofs_flush; - #endif - - dataLength = 32; - } - } - - #ifdef TEST - *logofs << "ServerReadBuffer: Length of the next message is " - << dataLength << ".\n" << logofs_flush; - #endif - - if (size < dataLength) - { - remaining_ = dataLength - size; - - #ifdef TEST - *logofs << "ServerReadBuffer: No message was located " - << "with remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - firstMessage_ = 0; - - controlLength = 0; - trailerLength = 0; - - remaining_ = 0; - - #ifdef TEST - *logofs << "ServerReadBuffer: Located message with " - << "remaining " << remaining_ << ".\n" - << logofs_flush; - #endif - - return 1; -} - -// -// Check if the data already read contains a -// message matching the opcode and sequence, -// starting at the given offset. -// - -unsigned char *ServerReadBuffer::peekMessage(unsigned int &offset, unsigned char opcode, - unsigned short sequence) -{ - #ifdef TEST - *logofs << "ServerReadBuffer: Peeking message " - << "for FD#" << transport_ -> fd() << " with size " - << length_ << " offset " << offset << " opcode " - << (unsigned int) opcode << " and sequence " - << sequence << ".\n" << logofs_flush; - #endif - - if (firstMessage_) - { - return NULL; - } - - unsigned char *next = buffer_ + start_ + offset; - unsigned char *end = buffer_ + start_ + length_; - - int found = 0; - - while (end - next >= 32) - { - #ifdef DEBUG - *logofs << "ServerReadBuffer: Checking opcode " - << (unsigned int) *next << " sequence " - << GetUINT(next + 2, bigEndian_) - << " at " << next - buffer_ + start_ - << ".\n" << logofs_flush; - #endif - - if (*next == opcode && GetUINT(next + 2, bigEndian_) == sequence) - { - found = 1; - - break; - } - else if (*next == 1) - { - next += (32 + (GetULONG(next + 4, bigEndian_) << 2)); - } - else - { - next += 32; - } - } - - offset = next - buffer_ + start_; - - if (found == 1) - { - #ifdef TEST - *logofs << "ServerReadBuffer: Found message at " - << "offset " << next - buffer_ + start_ - << ".\n" << logofs_flush; - #endif - - return next; - } - - #ifdef TEST - *logofs << "ServerReadBuffer: Quitting loop at " - << "offset " << next - buffer_ + start_ - << ".\n" << logofs_flush; - #endif - - return NULL; -} diff --git a/nxcomp/ServerReadBuffer.h b/nxcomp/ServerReadBuffer.h deleted file mode 100644 index d6c207ead..000000000 --- a/nxcomp/ServerReadBuffer.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ServerReadBuffer_H -#define ServerReadBuffer_H - -#include "ReadBuffer.h" -#include "Control.h" - -class ServerChannel; - -class ServerReadBuffer : public ReadBuffer -{ - public: - - ServerReadBuffer(Transport *transport, ServerChannel *channel) - - : ReadBuffer(transport), firstMessage_(1), channel_(channel) - { - } - - virtual ~ServerReadBuffer() - { - } - - void setBigEndian(int flag) - { - bigEndian_ = flag; - } - - unsigned char *peekMessage(unsigned int &offset, unsigned char opcode, - unsigned short sequence); - - protected: - - virtual unsigned int suggestedLength(unsigned int pendingLength); - - virtual int locateMessage(const unsigned char *start, - const unsigned char *end, - unsigned int &controlLength, - unsigned int &dataLength, - unsigned int &trailerLength); - - int bigEndian_; - - int firstMessage_; - - ServerChannel *channel_; -}; - -#endif /* ServerReadBuffer_H */ diff --git a/nxcomp/ServerStore.cpp b/nxcomp/ServerStore.cpp deleted file mode 100644 index 0fb17d974..000000000 --- a/nxcomp/ServerStore.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ServerStore.h" - -// -// Cached reply classes. -// - -#include "GetImageReply.h" -#include "ListFontsReply.h" -#include "QueryFontReply.h" -#include "GetPropertyReply.h" -#include "GenericReply.h" - -// -// Set the verbosity level. -// - -#define WARNING -#define PANIC -#undef TEST - -ServerStore::ServerStore(StaticCompressor *compressor) -{ - if (logofs == NULL) - { - logofs = &cout; - } - - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - replies_[i] = NULL; - events_[i] = NULL; - } - - replies_[X_ListFonts] = new ListFontsReplyStore(compressor); - replies_[X_QueryFont] = new QueryFontReplyStore(compressor); - replies_[X_GetImage] = new GetImageReplyStore(compressor); - replies_[X_GetProperty] = new GetPropertyReplyStore(compressor); - - replies_[X_NXInternalGenericReply] = new GenericReplyStore(compressor); -} - -ServerStore::~ServerStore() -{ - if (logofs == NULL) - { - logofs = &cout; - } - - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - delete replies_[i]; - delete events_[i]; - } -} - -int ServerStore::saveReplyStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient, T_checksum_action checksumAction, - T_data_action dataAction) const -{ - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - if (replies_[i] != NULL && - replies_[i] -> saveStore(cachefs, md5StateStream, md5StateClient, - checksumAction, dataAction, - storeBigEndian()) < 0) - { - #ifdef PANIC - *logofs << "ServerStore: PANIC! Error saving reply store " - << "for OPCODE#" << (unsigned int) i << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error saving reply store " - << "for opcode '" << (unsigned int) i << "'.\n"; - - return -1; - } - } - - return 1; -} - -int ServerStore::saveEventStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient, T_checksum_action checksumAction, - T_data_action dataAction) const -{ - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - if (events_[i] != NULL && - events_[i] -> saveStore(cachefs, md5StateStream, md5StateClient, - checksumAction, dataAction, - storeBigEndian()) < 0) - { - #ifdef PANIC - *logofs << "ServerStore: PANIC! Error saving event store " - << "for OPCODE#" << (unsigned int) i << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Error saving event store " - << "for opcode '" << (unsigned int) i << "'.\n"; - - return -1; - } - } - - return 1; -} - -int ServerStore::loadReplyStores(istream *cachefs, md5_state_t *md5StateStream, - T_checksum_action checksumAction, T_data_action dataAction) const -{ - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - if (replies_[i] != NULL && - replies_[i] -> loadStore(cachefs, md5StateStream, - checksumAction, dataAction, - storeBigEndian()) < 0) - { - #ifdef PANIC - *logofs << "ServerStore: PANIC! Error loading reply store " - << "for OPCODE#" << (unsigned int) i << ".\n" - << logofs_flush; - #endif - - return -1; - } - } - - return 1; -} - -int ServerStore::loadEventStores(istream *cachefs, md5_state_t *md5StateStream, - T_checksum_action checksumAction, T_data_action dataAction) const -{ - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - if (events_[i] != NULL && - events_[i] -> loadStore(cachefs, md5StateStream, - checksumAction, dataAction, - storeBigEndian()) < 0) - { - #ifdef PANIC - *logofs << "ServerStore: PANIC! Error loading event store " - << "for OPCODE#" << (unsigned int) i << ".\n" - << logofs_flush; - #endif - - return -1; - } - } - - return 1; -} diff --git a/nxcomp/ServerStore.h b/nxcomp/ServerStore.h deleted file mode 100644 index dbbb968e5..000000000 --- a/nxcomp/ServerStore.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ServerStore_H -#define ServerStore_H - -#include "Message.h" - -#include "ChannelStore.h" - -class StaticCompressor; - -class ServerStore : public ChannelStore -{ - public: - - ServerStore(StaticCompressor *compressor); - - virtual ~ServerStore(); - - MessageStore *getReplyStore(unsigned char opcode) const - { - return replies_[opcode]; - } - - MessageStore *getEventStore(unsigned char opcode) const - { - return events_[opcode]; - } - - // - // Actually save the message store - // to disk according to proxy mode. - // - - int saveReplyStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient, T_checksum_action checksumAction, - T_data_action dataAction) const; - - int saveEventStores(ostream *cachefs, md5_state_t *md5StateStream, - md5_state_t *md5StateClient, T_checksum_action checksumAction, - T_data_action dataAction) const; - - - int loadReplyStores(istream *cachefs, md5_state_t *md5StateStream, - T_checksum_action checksumAction, T_data_action dataAction) const; - - int loadEventStores(istream *cachefs, md5_state_t *md5StateStream, - T_checksum_action checksumAction, T_data_action dataAction) const; - - private: - - // - // A server store contains replies and events. - // - - MessageStore *replies_[CHANNEL_STORE_OPCODE_LIMIT]; - MessageStore *events_[CHANNEL_STORE_OPCODE_LIMIT]; -}; - -#endif /* ServerStore_H */ diff --git a/nxcomp/SetClipRectangles.cpp b/nxcomp/SetClipRectangles.cpp deleted file mode 100644 index 164ead006..000000000 --- a/nxcomp/SetClipRectangles.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "SetClipRectangles.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int SetClipRectanglesStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; - - // - // Here is the fingerprint. - // - - setClipRectangles -> ordering = *(buffer + 1); - - setClipRectangles -> gcontext = GetULONG(buffer + 4, bigEndian); - - setClipRectangles -> x_origin = GetUINT(buffer + 8, bigEndian); - setClipRectangles -> y_origin = GetUINT(buffer + 10, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int SetClipRectanglesStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; - - // - // Fill all the message's fields. - // - - *(buffer + 1) = setClipRectangles -> ordering; - - PutULONG(setClipRectangles -> gcontext, buffer + 4, bigEndian); - - PutUINT(setClipRectangles -> x_origin, buffer + 8, bigEndian); - PutUINT(setClipRectangles -> y_origin, buffer + 10, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void SetClipRectanglesStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; - - *logofs << name() << ": Identity ordering " << (unsigned int) setClipRectangles -> ordering - << ", gcontext " << setClipRectangles -> gcontext << ", x_origin " - << setClipRectangles -> x_origin << ", y_origin " - << setClipRectangles -> y_origin << ", size " - << setClipRectangles -> size_ << ".\n" << logofs_flush; - #endif -} - -void SetClipRectanglesStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 1, 1); - md5_append(md5_state_, buffer + 8, 4); -} - -void SetClipRectanglesStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; - SetClipRectanglesMessage *cachedSetClipRectangles = (SetClipRectanglesMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " << setClipRectangles -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeXidValue(setClipRectangles -> gcontext, clientCache -> gcCache); - - cachedSetClipRectangles -> gcontext = setClipRectangles -> gcontext; -} - -void SetClipRectanglesStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - decodeBuffer.decodeXidValue(value, clientCache -> gcCache); - - setClipRectangles -> gcontext = value; - - #ifdef DEBUG - *logofs << name() << ": Decoded value " << setClipRectangles -> gcontext - << " as gcontext field.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/SetClipRectangles.h b/nxcomp/SetClipRectangles.h deleted file mode 100644 index a2245360c..000000000 --- a/nxcomp/SetClipRectangles.h +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef SetClipRectangles_H -#define SetClipRectangles_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define SETCLIPRECTANGLES_ENABLE_CACHE 1 -#define SETCLIPRECTANGLES_ENABLE_DATA 0 -#define SETCLIPRECTANGLES_ENABLE_SPLIT 0 -#define SETCLIPRECTANGLES_ENABLE_COMPRESS 0 - -#define SETCLIPRECTANGLES_DATA_LIMIT 2048 -#define SETCLIPRECTANGLES_DATA_OFFSET 12 - -#define SETCLIPRECTANGLES_CACHE_SLOTS 3000 -#define SETCLIPRECTANGLES_CACHE_THRESHOLD 3 -#define SETCLIPRECTANGLES_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class SetClipRectanglesMessage : public Message -{ - friend class SetClipRectanglesStore; - - public: - - SetClipRectanglesMessage() - { - } - - ~SetClipRectanglesMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char ordering; - unsigned int gcontext; - unsigned short x_origin; - unsigned short y_origin; -}; - -class SetClipRectanglesStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - SetClipRectanglesStore() : MessageStore() - { - enableCache = SETCLIPRECTANGLES_ENABLE_CACHE; - enableData = SETCLIPRECTANGLES_ENABLE_DATA; - enableSplit = SETCLIPRECTANGLES_ENABLE_SPLIT; - enableCompress = SETCLIPRECTANGLES_ENABLE_COMPRESS; - - dataLimit = SETCLIPRECTANGLES_DATA_LIMIT; - dataOffset = SETCLIPRECTANGLES_DATA_OFFSET; - - cacheSlots = SETCLIPRECTANGLES_CACHE_SLOTS; - cacheThreshold = SETCLIPRECTANGLES_CACHE_THRESHOLD; - cacheLowerThreshold = SETCLIPRECTANGLES_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~SetClipRectanglesStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "SetClipRectangles"; - } - - virtual unsigned char opcode() const - { - return X_SetClipRectangles; - } - - virtual unsigned int storage() const - { - return sizeof(SetClipRectanglesMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new SetClipRectanglesMessage(); - } - - virtual Message *create(const Message &message) const - { - return new SetClipRectanglesMessage((const SetClipRectanglesMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (SetClipRectanglesMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* SetClipRectangles_H */ diff --git a/nxcomp/SetUnpackAlpha.cpp b/nxcomp/SetUnpackAlpha.cpp deleted file mode 100644 index cf09074e3..000000000 --- a/nxcomp/SetUnpackAlpha.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "SetUnpackAlpha.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -SetUnpackAlphaStore::SetUnpackAlphaStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = SETUNPACKALPHA_ENABLE_CACHE; - enableData = SETUNPACKALPHA_ENABLE_DATA; - enableCompress = SETUNPACKALPHA_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = SETUNPACKALPHA_DATA_LIMIT; - dataOffset = SETUNPACKALPHA_DATA_OFFSET_IF_PROTO_STEP_7; - - cacheSlots = SETUNPACKALPHA_CACHE_SLOTS; - cacheThreshold = SETUNPACKALPHA_CACHE_THRESHOLD; - cacheLowerThreshold = SETUNPACKALPHA_CACHE_LOWER_THRESHOLD; - - // Since ProtoStep8 (#issue 108) - enableSplit = SETUNPACKALPHA_ENABLE_SPLIT_IF_PROTO_STEP_8; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -SetUnpackAlphaStore::~SetUnpackAlphaStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int SetUnpackAlphaStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; - #endif - - // - // Encode the source length first because - // we need it to determine the size of - // the output buffer. - // - - // SrcLength. - encodeBuffer.encodeValue(GetULONG(buffer + 8, bigEndian), 32, 9); - - // Client. - encodeBuffer.encodeCachedValue(*(buffer + 1), 8, - clientCache -> resourceCache); - // Method. - encodeBuffer.encodeCachedValue(*(buffer + 4), 8, - clientCache -> methodCache); - // DstLength. - encodeBuffer.encodeValue(GetULONG(buffer + 12, bigEndian), 32, 9); - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackAlphaStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; - #endif - - unsigned int value; - unsigned char cValue; - - // SrcLength. - decodeBuffer.decodeValue(value, 32, 9); - - size = RoundUp4(value) + 16; - - buffer = writeBuffer -> addMessage(size); - - PutULONG(value, buffer + 8, bigEndian); - - // Client. - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> resourceCache); - - *(buffer + 1) = cValue; - - // Method. - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> methodCache); - - *(buffer + 4) = cValue; - - // DstLength. - decodeBuffer.decodeValue(value, 32, 9); - - PutULONG(value, buffer + 12, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackAlphaStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; - - setUnpackAlpha -> client = *(buffer + 1); - setUnpackAlpha -> method = *(buffer + 4); - - setUnpackAlpha -> src_length = GetULONG(buffer + 8, bigEndian); - setUnpackAlpha -> dst_length = GetULONG(buffer + 12, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackAlphaStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; - - *(buffer + 1) = setUnpackAlpha -> client; - *(buffer + 4) = setUnpackAlpha -> method; - - PutULONG(setUnpackAlpha -> src_length, buffer + 8, bigEndian); - PutULONG(setUnpackAlpha -> dst_length, buffer + 12, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void SetUnpackAlphaStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; - - *logofs << name() << ": Identity client " - << (unsigned int) setUnpackAlpha -> client << " method " - << (unsigned int) setUnpackAlpha -> method << " source length " - << setUnpackAlpha -> src_length << " destination length " - << setUnpackAlpha -> dst_length << " size " - << setUnpackAlpha -> size_ << ".\n"; - - #endif -} - -void SetUnpackAlphaStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Include the pack method and the source - // and destination length. - // - - md5_append(md5_state_, buffer + 4, 1); - md5_append(md5_state_, buffer + 8, 8); -} - -void SetUnpackAlphaStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; - SetUnpackAlphaMessage *cachedSetUnpackAlpha = (SetUnpackAlphaMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(setUnpackAlpha -> client, 8, - clientCache -> resourceCache); - - cachedSetUnpackAlpha -> client = setUnpackAlpha -> client; -} - -void SetUnpackAlphaStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(setUnpackAlpha -> client, 8, - clientCache -> resourceCache); -} diff --git a/nxcomp/SetUnpackAlpha.h b/nxcomp/SetUnpackAlpha.h deleted file mode 100644 index 54714efaa..000000000 --- a/nxcomp/SetUnpackAlpha.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef SetUnpackAlpha_H -#define SetUnpackAlpha_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define SETUNPACKALPHA_ENABLE_CACHE 1 -#define SETUNPACKALPHA_ENABLE_DATA 1 - -#define SETUNPACKALPHA_DATA_LIMIT 16384 - -#define SETUNPACKALPHA_CACHE_SLOTS 2000 -#define SETUNPACKALPHA_CACHE_THRESHOLD 10 -#define SETUNPACKALPHA_CACHE_LOWER_THRESHOLD 5 - -#define SETUNPACKALPHA_DATA_OFFSET_IF_PROTO_STEP_7 16 -#define SETUNPACKALPHA_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -#define SETUNPACKALPHA_ENABLE_SPLIT_IF_PROTO_STEP_8 0 - -// -// The message class. -// - -class SetUnpackAlphaMessage : public Message -{ - friend class SetUnpackAlphaStore; - - public: - - SetUnpackAlphaMessage() - { - } - - ~SetUnpackAlphaMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char client; - unsigned char method; - - unsigned int src_length; - unsigned int dst_length; -}; - -class SetUnpackAlphaStore : public MessageStore -{ - public: - - SetUnpackAlphaStore(StaticCompressor *compressor); - - virtual ~SetUnpackAlphaStore(); - - virtual const char *name() const - { - return "SetUnpackAlpha"; - } - - virtual unsigned char opcode() const - { - return X_NXSetUnpackAlpha; - } - - virtual unsigned int storage() const - { - return sizeof(SetUnpackAlphaMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new SetUnpackAlphaMessage(); - } - - virtual Message *create(const Message &message) const - { - return new SetUnpackAlphaMessage((const SetUnpackAlphaMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (SetUnpackAlphaMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* SetUnpackAlpha_H */ diff --git a/nxcomp/SetUnpackColormap.cpp b/nxcomp/SetUnpackColormap.cpp deleted file mode 100644 index b44a7cf13..000000000 --- a/nxcomp/SetUnpackColormap.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "SetUnpackColormap.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -SetUnpackColormapStore::SetUnpackColormapStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = SETUNPACKCOLORMAP_ENABLE_CACHE; - enableData = SETUNPACKCOLORMAP_ENABLE_DATA; - enableCompress = SETUNPACKCOLORMAP_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = SETUNPACKCOLORMAP_DATA_LIMIT; - dataOffset = SETUNPACKCOLORMAP_DATA_OFFSET_IF_PROTO_STEP_7; - - cacheSlots = SETUNPACKCOLORMAP_CACHE_SLOTS; - cacheThreshold = SETUNPACKCOLORMAP_CACHE_THRESHOLD; - cacheLowerThreshold = SETUNPACKCOLORMAP_CACHE_LOWER_THRESHOLD; - - // Since ProtoStep8 (#issue 108) - enableSplit = SETUNPACKCOLORMAP_ENABLE_SPLIT_IF_PROTO_STEP_8; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -SetUnpackColormapStore::~SetUnpackColormapStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int SetUnpackColormapStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; - #endif - - // - // Encode the source length first because - // we need it to determine the size of - // the output buffer. - // - - // SrcLength. - encodeBuffer.encodeValue(GetULONG(buffer + 8, bigEndian), 32, 9); - - // Client. - encodeBuffer.encodeCachedValue(*(buffer + 1), 8, - clientCache -> resourceCache); - // Method. - encodeBuffer.encodeCachedValue(*(buffer + 4), 8, - clientCache -> methodCache); - // DstLength. - encodeBuffer.encodeValue(GetULONG(buffer + 12, bigEndian), 32, 9); - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackColormapStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; - #endif - - unsigned int value; - unsigned char cValue; - - // SrcLength. - decodeBuffer.decodeValue(value, 32, 9); - - size = RoundUp4(value) + 16; - - buffer = writeBuffer -> addMessage(size); - - PutULONG(value, buffer + 8, bigEndian); - - // Client. - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> resourceCache); - - *(buffer + 1) = cValue; - - // Method. - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> methodCache); - - *(buffer + 4) = cValue; - - // DstLength. - decodeBuffer.decodeValue(value, 32, 9); - - PutULONG(value, buffer + 12, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackColormapStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; - - setUnpackColormap -> client = *(buffer + 1); - setUnpackColormap -> method = *(buffer + 4); - - setUnpackColormap -> src_length = GetULONG(buffer + 8, bigEndian); - setUnpackColormap -> dst_length = GetULONG(buffer + 12, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackColormapStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; - - *(buffer + 1) = setUnpackColormap -> client; - *(buffer + 4) = setUnpackColormap -> method; - - PutULONG(setUnpackColormap -> src_length, buffer + 8, bigEndian); - PutULONG(setUnpackColormap -> dst_length, buffer + 12, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void SetUnpackColormapStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; - - *logofs << name() << ": Identity client " - << (unsigned int) setUnpackColormap -> client << " method " - << (unsigned int) setUnpackColormap -> method << " source length " - << setUnpackColormap -> src_length << " destination length " - << setUnpackColormap -> dst_length << " size " - << setUnpackColormap -> size_ << ".\n"; - - #endif -} - -void SetUnpackColormapStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Include the pack method and the source - // and destination length. - // - - md5_append(md5_state_, buffer + 4, 1); - md5_append(md5_state_, buffer + 8, 8); -} - -void SetUnpackColormapStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; - SetUnpackColormapMessage *cachedSetUnpackColormap = (SetUnpackColormapMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - encodeBuffer.encodeCachedValue(setUnpackColormap -> client, 8, - clientCache -> resourceCache); - - cachedSetUnpackColormap -> client = setUnpackColormap -> client; -} - -void SetUnpackColormapStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(setUnpackColormap -> client, 8, - clientCache -> resourceCache); -} diff --git a/nxcomp/SetUnpackColormap.h b/nxcomp/SetUnpackColormap.h deleted file mode 100644 index 779366531..000000000 --- a/nxcomp/SetUnpackColormap.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef SetUnpackColormap_H -#define SetUnpackColormap_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define SETUNPACKCOLORMAP_ENABLE_CACHE 1 -#define SETUNPACKCOLORMAP_ENABLE_DATA 1 - -#define SETUNPACKCOLORMAP_DATA_LIMIT 4096 - -#define SETUNPACKCOLORMAP_CACHE_SLOTS 2000 -#define SETUNPACKCOLORMAP_CACHE_THRESHOLD 5 -#define SETUNPACKCOLORMAP_CACHE_LOWER_THRESHOLD 0 - -#define SETUNPACKCOLORMAP_DATA_OFFSET_IF_PROTO_STEP_7 16 -#define SETUNPACKCOLORMAP_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -#define SETUNPACKCOLORMAP_ENABLE_SPLIT_IF_PROTO_STEP_8 0 - -// -// The message class. -// - -class SetUnpackColormapMessage : public Message -{ - friend class SetUnpackColormapStore; - - public: - - SetUnpackColormapMessage() - { - } - - ~SetUnpackColormapMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char client; - unsigned char method; - - unsigned int src_length; - unsigned int dst_length; -}; - -class SetUnpackColormapStore : public MessageStore -{ - public: - - SetUnpackColormapStore(StaticCompressor *compressor); - - virtual ~SetUnpackColormapStore(); - - virtual const char *name() const - { - return "SetUnpackColormap"; - } - - virtual unsigned char opcode() const - { - return X_NXSetUnpackColormap; - } - - virtual unsigned int storage() const - { - return sizeof(SetUnpackColormapMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new SetUnpackColormapMessage(); - } - - virtual Message *create(const Message &message) const - { - return new SetUnpackColormapMessage((const SetUnpackColormapMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (SetUnpackColormapMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* SetUnpackColormap_H */ diff --git a/nxcomp/SetUnpackGeometry.cpp b/nxcomp/SetUnpackGeometry.cpp deleted file mode 100644 index 49fa4344e..000000000 --- a/nxcomp/SetUnpackGeometry.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "SetUnpackGeometry.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -SetUnpackGeometryStore::SetUnpackGeometryStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = SETUNPACKGEOMETRY_ENABLE_CACHE; - enableData = SETUNPACKGEOMETRY_ENABLE_DATA; - enableSplit = SETUNPACKGEOMETRY_ENABLE_SPLIT; - enableCompress = SETUNPACKGEOMETRY_ENABLE_COMPRESS; - - dataLimit = SETUNPACKGEOMETRY_DATA_LIMIT; - dataOffset = SETUNPACKGEOMETRY_DATA_OFFSET; - - cacheSlots = SETUNPACKGEOMETRY_CACHE_SLOTS; - cacheThreshold = SETUNPACKGEOMETRY_CACHE_THRESHOLD; - cacheLowerThreshold = SETUNPACKGEOMETRY_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -SetUnpackGeometryStore::~SetUnpackGeometryStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int SetUnpackGeometryStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(*(buffer + 1), 8, - clientCache -> resourceCache); - - const unsigned char *nextChar = buffer + 4; - - for (int i = 0; i < 6; i++) - { - encodeBuffer.encodeCachedValue(*nextChar++, 8, - clientCache -> depthCache); - } - - encodeBuffer.encodeValue(GetULONG(buffer + 12, bigEndian), 32); - encodeBuffer.encodeValue(GetULONG(buffer + 16, bigEndian), 32); - encodeBuffer.encodeValue(GetULONG(buffer + 20, bigEndian), 32); - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackGeometryStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; - #endif - - size = 24; - buffer = writeBuffer -> addMessage(size); - - unsigned char cValue; - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> resourceCache); - *(buffer + 1) = cValue; - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - *(buffer + 4) = cValue; - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - *(buffer + 5) = cValue; - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - *(buffer + 6) = cValue; - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - *(buffer + 7) = cValue; - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - *(buffer + 8) = cValue; - - decodeBuffer.decodeCachedValue(cValue, 8, - clientCache -> depthCache); - *(buffer + 9) = cValue; - - unsigned int value; - - decodeBuffer.decodeValue(value, 32); - PutULONG(value, buffer + 12, bigEndian); - - decodeBuffer.decodeValue(value, 32); - PutULONG(value, buffer + 16, bigEndian); - - decodeBuffer.decodeValue(value, 32); - PutULONG(value, buffer + 20, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackGeometryStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; - - setUnpackGeometry -> client = *(buffer + 1); - - setUnpackGeometry -> depth_1_bpp = *(buffer + 4); - setUnpackGeometry -> depth_4_bpp = *(buffer + 5); - setUnpackGeometry -> depth_8_bpp = *(buffer + 6); - setUnpackGeometry -> depth_16_bpp = *(buffer + 7); - setUnpackGeometry -> depth_24_bpp = *(buffer + 8); - setUnpackGeometry -> depth_32_bpp = *(buffer + 9); - - setUnpackGeometry -> red_mask = GetULONG(buffer + 12, bigEndian); - setUnpackGeometry -> green_mask = GetULONG(buffer + 16, bigEndian); - setUnpackGeometry -> blue_mask = GetULONG(buffer + 20, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -int SetUnpackGeometryStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; - - *(buffer + 1) = setUnpackGeometry -> client; - - *(buffer + 4) = setUnpackGeometry -> depth_1_bpp; - *(buffer + 5) = setUnpackGeometry -> depth_4_bpp; - *(buffer + 6) = setUnpackGeometry -> depth_8_bpp; - *(buffer + 7) = setUnpackGeometry -> depth_16_bpp; - *(buffer + 8) = setUnpackGeometry -> depth_24_bpp; - *(buffer + 9) = setUnpackGeometry -> depth_32_bpp; - - PutULONG(setUnpackGeometry -> red_mask, buffer + 12, bigEndian); - PutULONG(setUnpackGeometry -> green_mask, buffer + 16, bigEndian); - PutULONG(setUnpackGeometry -> blue_mask, buffer + 20, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; - #endif - - return 1; -} - -void SetUnpackGeometryStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; - - *logofs << name() << ": Identity client " - << (unsigned) setUnpackGeometry -> client << " depth_1_bpp " - << (unsigned) setUnpackGeometry -> depth_1_bpp << " depth_4_bpp " - << (unsigned int) setUnpackGeometry -> depth_4_bpp << " depth_8_bpp " - << (unsigned int) setUnpackGeometry -> depth_8_bpp << " depth_16_bpp " - << (unsigned int) setUnpackGeometry -> depth_16_bpp << " depth_24_bpp " - << (unsigned int) setUnpackGeometry -> depth_24_bpp << " depth_32_bpp " - << (unsigned int) setUnpackGeometry -> depth_32_bpp - - << " red_mask " << setUnpackGeometry -> red_mask - << " green_mask " << setUnpackGeometry -> green_mask - << " blue_mask " << setUnpackGeometry -> blue_mask - - << " size " << setUnpackGeometry -> size_ << ".\n"; - - #endif -} - -void SetUnpackGeometryStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 4, 6); - md5_append(md5_state_, buffer + 12, 12); -} - -void SetUnpackGeometryStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; - SetUnpackGeometryMessage *cachedSetUnpackGeometry = (SetUnpackGeometryMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef TEST - *logofs << name() << ": Encoding value " - << (unsigned int) setUnpackGeometry -> client - << " as client field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue(setUnpackGeometry -> client, 8, - clientCache -> resourceCache); - - cachedSetUnpackGeometry -> client = setUnpackGeometry -> client; -} - -void SetUnpackGeometryStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - decodeBuffer.decodeCachedValue(setUnpackGeometry -> client, 8, - clientCache -> resourceCache); - - #ifdef DEBUG - *logofs << name() << ": Decoded value " - << (unsigned int) setUnpackGeometry -> client - << " as client field.\n" << logofs_flush; - #endif -} diff --git a/nxcomp/SetUnpackGeometry.h b/nxcomp/SetUnpackGeometry.h deleted file mode 100644 index 96104f57f..000000000 --- a/nxcomp/SetUnpackGeometry.h +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef SetUnpackGeometry_H -#define SetUnpackGeometry_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define SETUNPACKGEOMETRY_ENABLE_CACHE 1 -#define SETUNPACKGEOMETRY_ENABLE_DATA 0 -#define SETUNPACKGEOMETRY_ENABLE_SPLIT 0 -#define SETUNPACKGEOMETRY_ENABLE_COMPRESS 0 - -#define SETUNPACKGEOMETRY_DATA_LIMIT 24 -#define SETUNPACKGEOMETRY_DATA_OFFSET 24 - -#define SETUNPACKGEOMETRY_CACHE_SLOTS 20 -#define SETUNPACKGEOMETRY_CACHE_THRESHOLD 1 -#define SETUNPACKGEOMETRY_CACHE_LOWER_THRESHOLD 0 - -// -// The message class. -// - -class SetUnpackGeometryMessage : public Message -{ - friend class SetUnpackGeometryStore; - - public: - - SetUnpackGeometryMessage() - { - } - - ~SetUnpackGeometryMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned char client; - - unsigned char depth_1_bpp; - unsigned char depth_4_bpp; - unsigned char depth_8_bpp; - unsigned char depth_16_bpp; - unsigned char depth_24_bpp; - unsigned char depth_32_bpp; - - unsigned int red_mask; - unsigned int green_mask; - unsigned int blue_mask; -}; - -class SetUnpackGeometryStore : public MessageStore -{ - public: - - SetUnpackGeometryStore(StaticCompressor *compressor); - - virtual ~SetUnpackGeometryStore(); - - virtual const char *name() const - { - return "SetUnpackGeometry"; - } - - virtual unsigned char opcode() const - { - return X_NXSetUnpackGeometry; - } - - virtual unsigned int storage() const - { - return sizeof(SetUnpackGeometryMessage); - } - - // - // Message handling methods. - // - - protected: - - virtual Message *create() const - { - return new SetUnpackGeometryMessage(); - } - - virtual Message *create(const Message &message) const - { - return new SetUnpackGeometryMessage((const SetUnpackGeometryMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (SetUnpackGeometryMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* SetUnpackGeometry_H */ diff --git a/nxcomp/ShapeExtension.cpp b/nxcomp/ShapeExtension.cpp deleted file mode 100644 index be3b9a903..000000000 --- a/nxcomp/ShapeExtension.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "ShapeExtension.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "WriteBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Constructors and destructors. -// - -ShapeExtensionStore::ShapeExtensionStore(StaticCompressor *compressor) - - : MessageStore(compressor) -{ - enableCache = SHAPEEXTENSION_ENABLE_CACHE; - enableData = SHAPEEXTENSION_ENABLE_DATA; - enableSplit = SHAPEEXTENSION_ENABLE_SPLIT; - - // Since ProtoStep7 (#issue 108) - enableCompress = SHAPEEXTENSION_ENABLE_COMPRESS_IF_PROTO_STEP_7; - - dataLimit = SHAPEEXTENSION_DATA_LIMIT; - dataOffset = SHAPEEXTENSION_DATA_OFFSET; - - cacheSlots = SHAPEEXTENSION_CACHE_SLOTS; - cacheThreshold = SHAPEEXTENSION_CACHE_THRESHOLD; - cacheLowerThreshold = SHAPEEXTENSION_CACHE_LOWER_THRESHOLD; - - opcode_ = X_NXInternalShapeExtension; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; -} - -ShapeExtensionStore::~ShapeExtensionStore() -{ - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); -} - -// -// Here are the methods to handle messages' content. -// - -int ShapeExtensionStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const -{ - // - // Handle this extension in a way similar to shape. - // - - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; - #endif - - // - // We handle all possible requests of this extension - // using the same opcode. We give to message a data - // offset of 4 (or 16 if proto is >= 3) and handle - // the first 16 bytes through an array of caches. - // - - encodeBuffer.encodeValue(size >> 2, 16, 10); - - encodeBuffer.encodeCachedValue(*(buffer + 1), 8, - clientCache -> shapeOpcodeCache); - - for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) - { - encodeBuffer.encodeCachedValue(GetUINT(buffer + (i * 2) + 4, bigEndian), 16, - *clientCache -> shapeDataCache[i]); - } - - #ifdef DEBUG - *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int ShapeExtensionStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const -{ - ClientCache *clientCache = (ClientCache *) channelCache; - - #ifdef DEBUG - *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; - #endif - - decodeBuffer.decodeValue(size, 16, 10); - - size <<= 2; - - buffer = writeBuffer -> addMessage(size); - - decodeBuffer.decodeCachedValue(*(buffer + 1), 8, - clientCache -> shapeOpcodeCache); - - unsigned int value; - - for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache -> shapeDataCache[i]); - - PutUINT(value, buffer + 4 + (i * 2), bigEndian); - } - - #ifdef DEBUG - *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; - #endif - - return 1; -} - -int ShapeExtensionStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; - - shapeExtension -> opcode = *(buffer + 1); - - for (unsigned int i = 0; i < 8; i++) - { - if ((i * 2 + 4) < size) - { - shapeExtension -> data[i] = GetUINT(buffer + i * 2 + 4, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed data[" << i << "].\n" - << logofs_flush; - #endif - } - else - { - shapeExtension -> data[i] = 0; - } - } - - #ifdef DEBUG - *logofs << name() << ": Parsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int ShapeExtensionStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; - - *(buffer + 1) = shapeExtension -> opcode; - - for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) - { - PutUINT(shapeExtension -> data[i], buffer + i * 2 + 4, bigEndian); - } - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " - << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void ShapeExtensionStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; - - *logofs << name() << ": Identity opcode " << (unsigned) shapeExtension -> opcode; - - for (int i = 0; i < 8; i++) - { - *logofs << ", data[" << i << "] " << shapeExtension -> data[i]; - } - - *logofs << ", size " << shapeExtension -> size_ << ".\n" << logofs_flush; - - #endif -} - -void ShapeExtensionStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - // - // Include minor opcode in the checksum. As data - // offset can be beyond the real end of message, - // we need to include size or we will match any - // message of size less or equal to data offset. - // - - md5_append(md5_state_, buffer + 1, 3); -} - -void ShapeExtensionStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const -{ - // - // Encode the variant part. - // - - ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; - ShapeExtensionMessage *cachedShapeExtension = (ShapeExtensionMessage *) cachedMessage; - - ClientCache *clientCache = (ClientCache *) channelCache; - - for (int i = 0; i < 8 && (i * 2 + 4) < shapeExtension -> size_; i++) - { - #ifdef TEST - *logofs << name() << ": Encoding value " << shapeExtension -> data[i] - << " as data[" << i << "] field.\n" << logofs_flush; - #endif - - encodeBuffer.encodeCachedValue((unsigned int) shapeExtension -> data[i], 16, - *clientCache -> shapeDataCache[i]); - - cachedShapeExtension -> data[i] = shapeExtension -> data[i]; - } -} - -void ShapeExtensionStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const -{ - ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; - - ClientCache *clientCache = (ClientCache *) channelCache; - - unsigned int value; - - for (int i = 0; i < 8 && (i * 2 + 4) < shapeExtension -> size_; i++) - { - decodeBuffer.decodeCachedValue(value, 16, - *clientCache -> shapeDataCache[i]); - - shapeExtension -> data[i] = (unsigned short) value; - - #ifdef TEST - *logofs << name() << ": Decoded value " << shapeExtension -> data[i] - << " as data[" << i << "] field.\n" << logofs_flush; - #endif - } -} diff --git a/nxcomp/ShapeExtension.h b/nxcomp/ShapeExtension.h deleted file mode 100644 index 4dd636847..000000000 --- a/nxcomp/ShapeExtension.h +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef ShapeExtension_H -#define ShapeExtension_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define SHAPEEXTENSION_ENABLE_CACHE 1 -#define SHAPEEXTENSION_ENABLE_DATA 1 -#define SHAPEEXTENSION_ENABLE_SPLIT 0 - -#define SHAPEEXTENSION_DATA_LIMIT 3200 -#define SHAPEEXTENSION_DATA_OFFSET 20 - -#define SHAPEEXTENSION_CACHE_SLOTS 3000 -#define SHAPEEXTENSION_CACHE_THRESHOLD 10 -#define SHAPEEXTENSION_CACHE_LOWER_THRESHOLD 5 - -#define SHAPEEXTENSION_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 - -// -// The message class. -// - -class ShapeExtensionMessage : public Message -{ - friend class ShapeExtensionStore; - - public: - - ShapeExtensionMessage() - { - } - - ~ShapeExtensionMessage() - { - } - - // - // Note for encoding in protocol level 1: we consider - // for this message a data offset of 4. Bytes from 5 - // to 20, if present, are taken as part of identity - // and encoded through an array of int caches. - // - - private: - - unsigned char opcode; - unsigned short data[8]; -}; - -class ShapeExtensionStore : public MessageStore -{ - public: - - ShapeExtensionStore(StaticCompressor *compressor); - - virtual ~ShapeExtensionStore(); - - virtual const char *name() const - { - return "ShapeExtension"; - } - - virtual unsigned char opcode() const - { - return opcode_; - } - - virtual unsigned int storage() const - { - return sizeof(ShapeExtensionMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new ShapeExtensionMessage(); - } - - virtual Message *create(const Message &message) const - { - return new ShapeExtensionMessage((const ShapeExtensionMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (ShapeExtensionMessage *) message; - } - - virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, - const unsigned int size, int bigEndian, - ChannelCache *channelCache) const; - - virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, - unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, - ChannelCache *channelCache) const; - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, - const Message *cachedMessage, - ChannelCache *channelCache) const; - - virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, - ChannelCache *channelCache) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; - - private: - - unsigned char opcode_; -}; - -#endif /* ShapeExtension_H */ diff --git a/nxcomp/Socket.cpp b/nxcomp/Socket.cpp deleted file mode 100644 index 28cb5646d..000000000 --- a/nxcomp/Socket.cpp +++ /dev/null @@ -1,753 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include - -#if defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun) -#include -#endif - -#ifdef __sun -#include -#include -#endif - -#include -#include -#include -#include - -#include -#include - -// -// System specific defines. -// - -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun) -#define SOL_IP IPPROTO_IP -#endif - -#ifdef __sun -#define INADDR_NONE ((unsigned int) -1) -#endif - -// -// The TIOCOUTQ ioctl is not implemented on Cygwin. -// Note also that TIOCOUTQ and IPTOS_LOWDELAY are -// disabled when running on MacOS/X. -// - -#ifdef __CYGWIN32__ -#define TIOCOUTQ ((unsigned int) -1) -#endif - -// -// NX includes. -// - -#include "Misc.h" -#include "Socket.h" - -// -// Set verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Set this only once by querying OS details. -// - -static int _kernelStep = -1; - -int GetKernelStep() -{ - if (_kernelStep < 0) - { - // - // At the moment only NX clients run on Win32 - // and MacOS/X so we are not really interested - // in the relevant OS dependent functions. - // - - #if defined(__CYGWIN32__) || defined(__APPLE__) - - _kernelStep = 0; - - #else - - struct utsname buffer; - - if (uname(&buffer) < 0) - { - #ifdef WARNING - *logofs << "Socket: WARNING! Failed to get system info. Error is " - << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; - - *logofs << "Socket: WARNING! Assuming lowest system support.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Failed to get system info. Error is " - << EGET() << " '" << ESTR() << "'.\n"; - - cerr << "Warning" << ": Assuming lowest system support.\n"; - - _kernelStep = 0; - } - else - { - #ifdef TEST - *logofs << "Socket: System is '" << buffer.sysname - << "' nodename '" << buffer.nodename << "' release '" - << buffer.release << "'.\n" << logofs_flush; - - *logofs << "Socket: Version is '" << buffer.version << "' machine '" - << buffer.machine << "'.\n" << logofs_flush; - #endif - - // - // Should test support on other operating systems. - // - - if (strcmp(buffer.sysname, "Linux") == 0) - { - if (strncmp(buffer.release, "2.0.", 4) == 0 || - strncmp(buffer.release, "2.2.", 4) == 0) - { - #ifdef TEST - *logofs << "Socket: Assuming level 2 system support.\n" - << logofs_flush; - #endif - - _kernelStep = 2; - } - else - { - #ifdef TEST - *logofs << "Socket: Assuming level 3 system support.\n" - << logofs_flush; - #endif - - _kernelStep = 3; - } - } - else if (strcmp(buffer.sysname, "SunOS") == 0) - { - #ifdef TEST - *logofs << "Socket: Assuming level 1 system support.\n" - << logofs_flush; - #endif - - _kernelStep = 1; - } - else - { - #ifdef TEST - *logofs << "Socket: Assuming level 0 system support.\n" - << logofs_flush; - #endif - - _kernelStep = 0; - } - } - - #endif /* #if defined(__CYGWIN32__) || defined(__APPLE__) */ - } - - return _kernelStep; -} - -int SetReuseAddress(int fd) -{ - int flag = 1; - - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - (char *) &flag, sizeof(flag)) < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to set SO_REUSEADDR flag on FD#" - << fd << ". Error is " << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to set SO_REUSEADDR flag on FD#" - << fd << ". Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - return -1; - } - #ifdef TEST - else - { - *logofs << "Socket: Set SO_REUSEADDR flag on FD#" - << fd << ".\n" << logofs_flush; - } - #endif - - return 1; -} - -int SetNonBlocking(int fd, int value) -{ - int flags = fcntl(fd, F_GETFL); - - if (flags >= 0) - { - if (value == 0) - { - flags &= ~O_NONBLOCK; - } - else - { - flags |= O_NONBLOCK; - } - } - - if (flags < 0 || fcntl(fd, F_SETFL, flags) < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to set O_NONBLOCK flag on FD#" - << fd << " to " << value << ". Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to set O_NONBLOCK flag on FD#" - << fd << " to " << value << ". Error is " << EGET() - << " '" << ESTR() << "'.\n"; - - return -1; - } - #ifdef TEST - else - { - *logofs << "Socket: Set O_NONBLOCK flag on FD#" - << fd << " to " << value << ".\n" - << logofs_flush; - } - #endif - - return 1; -} - -int SetLingerTimeout(int fd, int timeout) -{ - struct linger linger_value; - - if (timeout > 0) - { - linger_value.l_onoff = 1; - linger_value.l_linger = timeout; - } - else - { - linger_value.l_onoff = 0; - linger_value.l_linger = 0; - } - - if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger_value, sizeof(linger_value)) < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to set SO_LINGER values to " - << linger_value.l_onoff << " and " << linger_value.l_linger - << " on FD#" << fd << ". Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to set SO_LINGER values to " - << linger_value.l_onoff << " and " << linger_value.l_linger - << " on FD#" << fd << ". Error is " << EGET() << " '" - << ESTR() << "'.\n"; - - return -1; - } - #ifdef TEST - else - { - *logofs << "Socket: Set SO_LINGER values to " - << linger_value.l_onoff << " and " << linger_value.l_linger - << " on FD#" << fd << ".\n" << logofs_flush; - } - #endif - - return 1; -} - -int SetSendBuffer(int fd, int size) -{ - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to set SO_SNDBUF size to " - << size << " on FD#" << fd << ". Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to set SO_SNDBUF size to " - << size << " on FD#" << fd << ". Error is " - << EGET() << " '" << ESTR() << "'.\n"; - - return -1; - } - #ifdef TEST - else - { - *logofs << "Socket: Set SO_SNDBUF on FD#" << fd - << " to " << size << " bytes.\n" - << logofs_flush; - } - #endif - - return 1; -} - -int SetReceiveBuffer(int fd, int size) -{ - if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to set SO_RCVBUF size to " - << size << " on FD#" << fd << ". Error is " - << EGET() << " '" << ESTR() << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to set SO_RCVBUF size to " - << size << " on FD#" << fd << ". Error is " - << EGET() << " '" << ESTR() << "'.\n"; - - return -1; - } - #ifdef TEST - else - { - *logofs << "Socket: Set SO_RCVBUF on FD#" << fd - << " to " << size << " bytes.\n" - << logofs_flush; - } - #endif - - return 1; -} - -int SetNoDelay(int fd, int value) -{ - int result = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); - - if (result == 0) - { - result = 1; - } - else if (result < 0) - { - // - // Is it become a different error on - // Mac OSX 10.4? - // - - #if defined(__APPLE__) - - result = 0; - - #endif - - #if defined(__sun) - - if (EGET() == ENOPROTOOPT) - { - result = 0; - } - - #endif - - #if !defined(__APPLE__) && !defined(__sun) - - if (EGET() == EOPNOTSUPP) - { - result = 0; - } - - #endif - } - - if (result < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to set TCP_NODELAY flag on " - << "FD#" << fd << " to " << value << ". Error is " - << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to set TCP_NODELAY flag on " - << "FD#" << fd << " to " << value << ". Error is " - << EGET() << " '" << ESTR() << "'.\n"; - } - #ifdef TEST - else if (result == 0) - { - #ifdef TEST - *logofs << "Socket: Option TCP_NODELAY not supported " - << "on FD#" << fd << ".\n" << logofs_flush; - #endif - } - else - { - *logofs << "Socket: Set TCP_NODELAY flag on FD#" - << fd << " to " << value << ".\n" - << logofs_flush; - } - #endif - - return result; -} - -int SetKeepAlive(int fd) -{ - int flag = 1; - - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(flag)) < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to set SO_KEEPALIVE flag on " - << "FD#" << fd << ". Error is " << EGET() << " '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to set SO_KEEPALIVE flag on " - << "FD#" << fd << ". Error is " << EGET() << " '" - << ESTR() << "'.\n"; - - return -1; - } - #ifdef TEST - else - { - *logofs << "Socket: Set SO_KEEPALIVE flag on FD#" - << fd << ".\n" << logofs_flush; - } - #endif - - return 1; -} - -int SetLowDelay(int fd) -{ - if (_kernelStep < 0) - { - GetKernelStep(); - } - - switch (_kernelStep) - { - case 3: - case 2: - case 1: - { - int flag = IPTOS_LOWDELAY; - - if (setsockopt(fd, SOL_IP, IP_TOS, &flag, sizeof(flag)) < 0) - { - if (EGET() == EOPNOTSUPP) - { - #ifdef TEST - *logofs << "Socket: Option IPTOS_LOWDELAY not supported " - << "on FD#" << fd << ".\n" << logofs_flush; - #endif - - return 0; - } - else - { - #ifdef WARNING - *logofs << "Socket: WARNING! Failed to set IPTOS_LOWDELAY flag on " - << "FD#" << fd << ". Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Failed to set IPTOS_LOWDELAY flag on " - << "FD#" << fd << ". Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - return -1; - } - } - #ifdef TEST - else - { - *logofs << "Socket: Set IPTOS_LOWDELAY flag on FD#" - << fd << ".\n" << logofs_flush; - } - #endif - - return 1; - } - default: - { - #ifdef TEST - *logofs << "Socket: Option IPTOS_LOWDELAY not " - << "supported on FD#" << fd << ".\n" - << logofs_flush; - #endif - - return 0; - } - } -} - -int SetCloseOnExec(int fd) -{ - if (fcntl(fd, F_SETFD, 1) != 0) - { - #ifdef TEST - *logofs << "NXClient: PANIC! Cannot set close-on-exec " - << "on FD#" << fd << ". Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot set close-on-exec on FD#" - << fd << ". Error is " << EGET() << " '" << ESTR() - << "'.\n"; - - return -1; - } - - return 1; -} - -int GetBytesReadable(int fd) -{ - long readable = 0; - - // - // It may fail, for example at session - // shutdown. - // - - if (ioctl(fd, FIONREAD, &readable) < 0) - { - #ifdef TEST - *logofs << "Socket: PANIC! Failed to get bytes readable " - << "from FD#" << fd << ". Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - return -1; - } - - #ifdef TEST - *logofs << "Socket: Returning " << (int) readable - << " bytes readable on FD#" << fd << ".\n" - << logofs_flush; - #endif - - return (int) readable; -} - -int GetBytesWritable(int fd) -{ - if (_kernelStep < 0) - { - GetKernelStep(); - } - - long writable; - - switch (_kernelStep) - { - case 3: - { - // - // TODO: Should query the real size - // of the TCP write buffer. - // - - writable = 16384 - GetBytesQueued(fd); - - if (writable < 0) - { - writable = 0; - } - - break; - } - case 2: - { - if (ioctl(fd, TIOCOUTQ, (void *) &writable) < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to get bytes writable " - << "on FD#" << fd << ". Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to get bytes writable " - << "on FD#" << fd << ". Error is " << EGET() - << " '" << ESTR() << "'.\n"; - - return -1; - } - - break; - } - default: - { - #ifdef TEST - *logofs << "Socket: Option TIOCOUTQ not supported " - << "on FD#" << fd << ",\n" << logofs_flush; - #endif - - // - // TODO: Should query the real size - // of the TCP write buffer. - // - - writable = 16384; - - break; - } - } - - #ifdef TEST - *logofs << "Socket: Returning " << writable - << " bytes writable on FD#" << fd - << ".\n" << logofs_flush; - #endif - - return (int) writable; -} - -int GetBytesQueued(int fd) -{ - // - // The TIOCOUTQ ioctl is not implemented on Cygwin - // and returns the space available on Linux Kernels - // 2.0 and 2.2 (like current MIPS for PS/2). - // - - if (_kernelStep < 0) - { - GetKernelStep(); - } - - long queued; - - switch (_kernelStep) - { - case 3: - { - if (ioctl(fd, TIOCOUTQ, (void *) &queued) < 0) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to get bytes queued " - << "on FD#" << fd << ". Error is " << EGET() - << " '" << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to get bytes queued " - << "on FD#" << fd << ". Error is " << EGET() - << " '" << ESTR() << "'.\n"; - - return -1; - } - - break; - } - case 2: - { - // - // TODO: Should query the real size - // of the TCP write buffer. - // - - queued = 16384 - GetBytesWritable(fd); - - if (queued < 0) - { - queued = 0; - } - - break; - } - default: - { - #ifdef TEST - *logofs << "Socket: Option TIOCOUTQ not supported " - << "on FD#" << fd << ",\n" << logofs_flush; - #endif - - queued = 0; - - break; - } - } - - #ifdef TEST - *logofs << "Socket: Returning " << queued - << " bytes queued on FD#" << fd - << ".\n" << logofs_flush; - #endif - - return (int) queued; -} - -int GetHostAddress(const char *name) -{ - hostent *host = gethostbyname(name); - - if (host == NULL) - { - // - // On some Unices gethostbyname() doesn't - // accept IP addresses, so try inet_addr. - // - - IN_ADDR_T address = inet_addr(name); - - if (address == INADDR_NONE) - { - #ifdef PANIC - *logofs << "Socket: PANIC! Failed to resolve address of '" - << name << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed to resolve address of '" - << name << "'.\n"; - - return 0; - } - - return (int) address; - } - else - { - return (*((int *) host -> h_addr_list[0])); - } -} diff --git a/nxcomp/Socket.h b/nxcomp/Socket.h deleted file mode 100644 index 5e7e47705..000000000 --- a/nxcomp/Socket.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Socket_H -#define Socket_H - -#include -#include -#include - -#ifdef __sun -#include -#include -#endif - -// -// Set socket options. -// - -int SetReuseAddress(int fd); -int SetNonBlocking(int fd, int value); -int SetLingerTimeout(int fd, int timeout); -int SetSendBuffer(int fd, int size); -int SetReceiveBuffer(int fd, int size); -int SetNoDelay(int fd, int value); -int SetKeepAlive(int fd); -int SetLowDelay(int fd); -int SetCloseOnExec(int fd); - -// -// Get kernel support level. -// - -int GetKernelStep(); - -// -// Get socket info. -// - -int GetBytesReadable(int fd); -int GetBytesWritable(int fd); -int GetBytesQueued(int fd); - -// -// Inline version, providing direct access -// to the interface. -// - -#include "Misc.h" - -inline int GetBytesReadable(int fd, int *readable) -{ - long t; - - int result = ioctl(fd, FIONREAD, &t); - - #ifdef DEBUG - *logofs << "Socket: Bytes readable from FD#" - << fd << " are " << t << " with result " - << result << ".\n" << logofs_flush; - #endif - - *readable = (int) t; - - return result; -} - -// -// Query Internet address. -// - -int GetHostAddress(const char *name); - -#endif /* Socket_H */ diff --git a/nxcomp/Split.cpp b/nxcomp/Split.cpp deleted file mode 100644 index b6828c7cb..000000000 --- a/nxcomp/Split.cpp +++ /dev/null @@ -1,1835 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include -#include - -#include "Misc.h" - -#include "Split.h" - -#include "Control.h" -#include "Statistics.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "StaticCompressor.h" - -#include "Unpack.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Define this to trace elements -// allocated and deallocated. -// - -#undef REFERENCES - -// -// Counters used for store control. -// - -int SplitStore::totalSplitSize_; -int SplitStore::totalSplitStorageSize_; - -// -// This is used for reference count. -// - -#ifdef REFERENCES - -int Split::references_ = 0; - -#endif - -Split::Split() -{ - resource_ = nothing; - position_ = nothing; - - store_ = NULL; - - d_size_ = 0; - i_size_ = 0; - c_size_ = 0; - r_size_ = 0; - - next_ = 0; - load_ = 0; - save_ = 0; - - checksum_ = NULL; - state_ = split_undefined; - mode_ = split_none; - action_ = is_discarded; - - #ifdef REFERENCES - - references_++; - - *logofs << "Split: Created new Split at " - << this << " out of " << references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -Split::~Split() -{ - delete [] checksum_; - - #ifdef REFERENCES - - references_--; - - *logofs << "Split: Deleted Split at " - << this << " out of " << references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -SplitStore::SplitStore(StaticCompressor *compressor, CommitStore *commits, int resource) - - : compressor_(compressor), commits_(commits), resource_(resource) -{ - splits_ = new T_splits(); - - current_ = splits_ -> end(); - - splitStorageSize_ = 0; - - #ifdef TEST - *logofs << "SplitStore: Created new store ["; - - if (resource_ != nothing) - { - *logofs << resource_; - } - else - { - *logofs << "commit"; - } - - *logofs << "].\n" << logofs_flush; - - *logofs << "SplitStore: Total messages in stores are " - << totalSplitSize_ << " with total storage size " - << totalSplitStorageSize_ << ".\n" - << logofs_flush; - #endif -} - -SplitStore::~SplitStore() -{ - totalSplitSize_ -= splits_ -> size(); - - totalSplitStorageSize_ -= splitStorageSize_; - - for (T_splits::iterator i = splits_ -> begin(); - i != splits_ -> end(); i++) - { - delete *i; - } - - delete splits_; - - #ifdef TEST - *logofs << "SplitStore: Deleted store ["; - - if (resource_ != nothing) - { - *logofs << resource_; - } - else - { - *logofs << "commit"; - } - - *logofs << "] with storage size " << splitStorageSize_ - << ".\n" << logofs_flush; - - *logofs << "SplitStore: Total messages in stores are " - << totalSplitSize_ << " with total storage size " - << totalSplitStorageSize_ << ".\n" - << logofs_flush; - #endif -} - -// -// This is called at the encoding side. -// - -Split *SplitStore::add(MessageStore *store, int resource, T_split_mode mode, - int position, T_store_action action, T_checksum checksum, - const unsigned char *buffer, const int size) -{ - #ifdef TEST - *logofs << "SplitStore: Adding message [" << (unsigned int) store -> - opcode() << "] resource " << resource << " mode " << mode - << " position " << position << " action [" << DumpAction(action) - << "] and checksum [" << DumpChecksum(checksum) << "]" - << ".\n" << logofs_flush; - #endif - - Split *split = new Split(); - - if (split == NULL) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Can't allocate " - << "memory for the split.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory " - << "for the split.\n"; - - HandleAbort(); - } - - split -> store_ = store; - split -> resource_ = resource; - split -> mode_ = mode; - split -> position_ = position; - split -> action_ = action; - - split -> store_ -> validateSize(size); - - // - // The checksum is not provided if the - // message is cached. - // - - if (checksum != NULL) - { - split -> checksum_ = new md5_byte_t[MD5_LENGTH]; - - memcpy(split -> checksum_, checksum, MD5_LENGTH); - } - - // - // We don't need the identity data at the - // encoding side. This qualifies the split - // as a split generated at the encoding - // side. - // - - split -> i_size_ = store -> identitySize(buffer, size); - - split -> d_size_ = size - split -> i_size_; - - if (action == IS_ADDED || action == is_discarded) - { - // - // If the message was added to message - // store or discarded we need to save - // the real data so we can transfer it - // at later time. - // - - split -> data_.resize(split -> d_size_); - - memcpy(split -> data_.begin(), buffer + split -> i_size_, split -> d_size_); - - // - // If the message was added, lock it so - // it will not be used by the encoding - // side until it is recomposed. - // - - if (action == IS_ADDED) - { - split -> store_ -> lock(split -> position_); - - #ifdef TEST - - commits_ -> validate(split); - - #endif - } - } - #ifdef WARNING - else - { - *logofs << "SplitStore: WARNING! Not copying data for the cached message.\n" - << logofs_flush; - } - #endif - - push(split); - - return split; -} - -// -// This is called at decoding side. If checksum -// is provided, the message can be searched on -// disk, then, if message is found, an event is -// sent to abort the data transfer. -// - -Split *SplitStore::add(MessageStore *store, int resource, int position, - T_store_action action, T_checksum checksum, - unsigned char *buffer, const int size) -{ - #ifdef TEST - *logofs << "SplitStore: Adding message [" - << (unsigned int) store -> opcode() << "] resource " - << resource << " position " << position << " action [" - << DumpAction(action) << "] and checksum [" - << DumpChecksum(checksum) << "].\n" << logofs_flush; - #endif - - Split *split = new Split(); - - if (split == NULL) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Can't allocate " - << "memory for the split.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory " - << "for the split.\n"; - - HandleAbort(); - } - - split -> store_ = store; - split -> resource_ = resource; - split -> position_ = position; - split -> action_ = action; - - split -> store_ -> validateSize(size); - - // - // Check if the checksum was provided - // by the remote. - // - - if (checksum != NULL) - { - split -> checksum_ = new md5_byte_t[MD5_LENGTH]; - - memcpy(split -> checksum_, checksum, MD5_LENGTH); - } - - split -> i_size_ = store -> identitySize(buffer, size); - - // - // Copy the identity so we can expand the - // message when it is committed. - // - - split -> identity_.resize(split -> i_size_); - - memcpy(split -> identity_.begin(), buffer, split -> i_size_); - - split -> d_size_ = size - split -> i_size_; - - if (action == IS_ADDED || action == is_discarded) - { - // - // The unpack procedure will check if the - // first 2 bytes of the buffer contain the - // pattern and will not try to expand the - // image. - // - - split -> data_.resize(2); - - unsigned char *data = split -> data_.begin(); - - data[0] = SPLIT_PATTERN; - data[1] = SPLIT_PATTERN; - - // - // If the message was added to the store, - // we don't have the data part, yet, so - // we need to lock the message until it - // is recomposed. - // - - if (action == IS_ADDED) - { - split -> store_ -> lock(split -> position_); - - #ifdef TEST - - commits_ -> validate(split); - - #endif - } - } - else - { - #ifdef WARNING - *logofs << "SplitStore: WARNING! Copying data for the cached message.\n" - << logofs_flush; - #endif - - // - // We may optionally take the data from the - // message store in compressed form, but, - // as the data has been decompressed in the - // buffer, we save a further decompression. - // - - split -> data_.resize(split -> d_size_); - - memcpy(split -> data_.begin(), buffer + split -> i_size_, split -> d_size_); - } - - push(split); - - return split; -} - -void SplitStore::push(Split *split) -{ - splits_ -> push_back(split); - - splitStorageSize_ += getNodeSize(split); - - totalSplitSize_++; - - totalSplitStorageSize_ += getNodeSize(split); - - statistics -> addSplit(); - - #ifdef TEST - *logofs << "SplitStore: There are " << splits_ -> size() - << " messages in store [" << resource_ << "] with " - << "storage size " << splitStorageSize_ << ".\n" - << logofs_flush; - - *logofs << "SplitStore: Total messages in stores are " - << totalSplitSize_ << " with total storage size " - << totalSplitStorageSize_ << ".\n" - << logofs_flush; - #endif - - split -> state_ = split_added; -} - -void SplitStore::dump() -{ - #ifdef DUMP - - int n; - - Split *split; - - *logofs << "SplitStore: DUMP! Dumping content of "; - - if (commits_ == NULL) - { - *logofs << "[commits]"; - } - else - { - *logofs << "[splits] for store [" << resource_ << "]"; - } - - *logofs << " with [" << getSize() << "] elements " - << "in the store.\n" << logofs_flush; - - n = 0; - - for (T_splits::iterator i = splits_ -> begin(); i != splits_ -> end(); i++, n++) - { - split = *i; - - *logofs << "SplitStore: DUMP! Split [" << n << "] has action [" - << DumpAction(split -> action_) << "] state [" - << DumpState(split -> state_) << "] "; - - if (split -> resource_ >= 0) - { - *logofs << "resource " << split -> resource_; - } - - *logofs << " request " << (unsigned) split -> store_ -> opcode() - << " position " << split -> position_ << " size is " - << split -> data_.size() << " (" << split -> d_size_ - << "/" << split -> c_size_ << "/" << split -> r_size_ - << ") with " << split -> data_.size() - split -> next_ - << "] bytes to go.\n" << logofs_flush; - } - - #endif -} - -int SplitStore::send(EncodeBuffer &encodeBuffer, int packetSize) -{ - if (splits_ -> size() == 0) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Function send called with no splits available.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Function send called with no splits available.\n"; - - HandleAbort(); - } - - // - // A start operation must always be executed on - // the split, even in the case the split will be - // later aborted. - // - - if (current_ == splits_ -> end()) - { - start(encodeBuffer); - } - - // - // If we have matched the checksum received from - // the remote side then we must abort the current - // split, else we can send another block of data - // to the remote peer. - // - - Split *split = *current_; - - unsigned int abort = 0; - - if (split -> state_ == split_loaded) - { - abort = 1; - } - - encodeBuffer.encodeBoolValue(abort); - - if (abort == 1) - { - #ifdef TEST - *logofs << "SplitStore: Aborting split for checksum [" - << DumpChecksum(split -> checksum_) << "] position " - << split -> position_ << " with " << (split -> - data_.size() - split -> next_) << " bytes to go " - << "out of " << split -> data_.size() - << ".\n" << logofs_flush; - #endif - - statistics -> addSplitAborted(); - - statistics -> addSplitAbortedBytesOut(split -> data_.size() - split -> next_); - - split -> next_ = split -> data_.size(); - - split -> state_ = split_aborted; - } - else - { - int count = (packetSize <= 0 || split -> next_ + - packetSize > (int) split -> data_.size() ? - split -> data_.size() - split -> next_ : packetSize); - - #ifdef TEST - *logofs << "SplitStore: Sending split for checksum [" - << DumpChecksum(split -> checksum_) << "] count " - << count << " position " << split -> position_ - << ". Data size is " << split -> data_.size() << " (" - << split -> d_size_ << "/" << split -> c_size_ << "), " - << split -> data_.size() - (split -> next_ + count) - << " to go.\n" << logofs_flush; - #endif - - encodeBuffer.encodeValue(count, 32, 10); - - encodeBuffer.encodeMemory(split -> data_.begin() + split -> next_, count); - - split -> next_ += count; - } - - // - // Was data completely transferred? We are the - // sending side. We must update the message in - // store, even if split was aborted. - // - - if (split -> next_ != ((int) split -> data_.size())) - { - return 0; - } - - // - // Move the split at the head of the - // list to the commits. - // - - remove(split); - - // - // Reset current position to the - // end of repository. - // - - current_ = splits_ -> end(); - - #ifdef TEST - *logofs << "SplitStore: Removed split at head of the list. " - << "Resource is " << split -> resource_ << " request " - << (unsigned) split -> store_ -> opcode() << " position " - << split -> position_ << ".\n" << logofs_flush; - #endif - - return 1; -} - -int SplitStore::start(EncodeBuffer &encodeBuffer) -{ - // - // Get the element at the top of the - // list. - // - - current_ = splits_ -> begin(); - - Split *split = *current_; - - #ifdef TEST - *logofs << "SplitStore: Starting split for checksum [" - << DumpChecksum(split -> checksum_) << "] position " - << split -> position_ << " with " << (split -> - data_.size() - split -> next_) << " bytes to go " - << "out of " << split -> data_.size() - << ".\n" << logofs_flush; - #endif - - // - // See if compression of the data part is - // enabled. - // - - if (split -> store_ -> enableCompress) - { - // - // If the split is going to be aborted don't - // compress the data and go straight to the - // send. The new data size will be assumed - // from the disk cache. - // - - if (split -> state_ != split_loaded) - { - unsigned int compressedSize = 0; - unsigned char *compressedData = NULL; - - if (control -> LocalDataCompression && - (compressor_ -> compressBuffer(split -> data_.begin(), split -> d_size_, - compressedData, compressedSize))) - { - // - // Replace the data with the one in - // compressed form. - // - - #ifdef TEST - *logofs << "SplitStore: Split data of size " << split -> d_size_ - << " has been compressed to " << compressedSize - << " bytes.\n" << logofs_flush; - #endif - - split -> data_.clear(); - - split -> data_.resize(compressedSize); - - memcpy(split -> data_.begin(), compressedData, compressedSize); - - split -> c_size_ = compressedSize; - - // - // Inform our peer that the data is - // compressed and send the new size. - // - - encodeBuffer.encodeBoolValue(1); - - encodeBuffer.encodeValue(compressedSize, 32, 14); - - #ifdef TEST - *logofs << "SplitStore: Signaled " << split -> c_size_ - << " bytes of compressed data for this message.\n" - << logofs_flush; - #endif - - return 1; - } - } - #ifdef TEST - else - { - *logofs << "SplitStore: Not trying to compress the " - << "loaded message.\n" << logofs_flush; - } - #endif - - // - // Tell to the remote that data will - // follow uncompressed. - // - - encodeBuffer.encodeBoolValue(0); - } - - return 1; -} - -int SplitStore::start(DecodeBuffer &decodeBuffer) -{ - #ifdef TEST - *logofs << "SplitStore: Going to receive a new split from the remote side.\n" - << logofs_flush; - #endif - - // - // Get the element at the head - // of the list. - // - - current_ = splits_ -> begin(); - - Split *split = *current_; - - unsigned int compressedSize = 0; - - // - // Save the data size known by the remote. - // This information will be needed if the - // remote will not have a chance to abort - // the split. - // - - split -> r_size_ = split -> d_size_; - - // - // Find out if data was compressed by the - // remote. - // - - if (split -> store_ -> enableCompress) - { - decodeBuffer.decodeBoolValue(compressedSize); - - if (compressedSize == 1) - { - // - // Get the compressed size. - // - - // Since ProtoStep7 (#issue 108) - decodeBuffer.decodeValue(compressedSize, 32, 14); - - split -> store_ -> validateSize(split -> d_size_, compressedSize); - - split -> r_size_ = compressedSize; - } - } - - // - // Update the size if the split - // was not already loaded. - // - - if (split -> state_ != split_loaded) - { - split -> data_.clear(); - - if (compressedSize > 0) - { - split -> c_size_ = compressedSize; - - #ifdef TEST - *logofs << "SplitStore: Split data of size " - << split -> d_size_ << " was compressed to " - << split -> c_size_ << " bytes.\n" - << logofs_flush; - #endif - - split -> data_.resize(split -> c_size_); - } - else - { - split -> data_.resize(split -> d_size_); - } - - unsigned char *data = split -> data_.begin(); - - data[0] = SPLIT_PATTERN; - data[1] = SPLIT_PATTERN; - } - #ifdef TEST - else - { - // - // The message had been already - // loaded from disk. - // - - if (compressedSize > 0) - { - if ((int) compressedSize != split -> c_size_) - { - *logofs << "SplitStore: WARNING! Compressed data size is " - << "different than the loaded compressed size.\n" - << logofs_flush; - } - - *logofs << "SplitStore: Ignoring the new size with " - << "loaded compressed size " << split -> c_size_ - << ".\n" << logofs_flush; - } - } - #endif - - return 1; -} - -int SplitStore::receive(DecodeBuffer &decodeBuffer) -{ - if (splits_ -> size() == 0) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Function receive called with no splits available.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Function receive called with no splits available.\n"; - - HandleAbort(); - } - - if (current_ == splits_ -> end()) - { - start(decodeBuffer); - } - - // - // Check first if split was aborted, else add - // any new data to message being recomposed. - // - - Split *split = *current_; - - unsigned int abort = 0; - - decodeBuffer.decodeBoolValue(abort); - - if (abort == 1) - { - #ifdef TEST - *logofs << "SplitStore: Aborting split for checksum [" - << DumpChecksum(split -> checksum_) << "] position " - << split -> position_ << " with " << (split -> - data_.size() - split -> next_) << " bytes to go " - << "out of " << split -> data_.size() - << ".\n" << logofs_flush; - #endif - - statistics -> addSplitAborted(); - - statistics -> addSplitAbortedBytesOut(split -> r_size_ - split -> next_); - - split -> next_ = split -> r_size_; - - split -> state_ = split_aborted; - } - else - { - // - // Get the size of the packet. - // - - unsigned int count; - - decodeBuffer.decodeValue(count, 32, 10); - - // - // If the split was not already loaded from - // disk, decode the packet and update our - // copy of the data. The encoding side may - // have not received the abort event, yet, - // and may be unaware that the message is - // stored in compressed form at our side. - // - - #ifdef TEST - *logofs << "SplitStore: Receiving split for checksum [" - << DumpChecksum(split -> checksum_) << "] count " - << count << " position " << split -> position_ - << ". Data size is " << split -> data_.size() << " (" - << split -> d_size_ << "/" << split -> c_size_ << "/" - << split -> r_size_ << "), " << split -> r_size_ - - (split -> next_ + count) << " to go.\n" - << logofs_flush; - #endif - - if (split -> next_ + count > (unsigned) split -> r_size_) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Invalid data count " - << count << "provided in the split.\n" - << logofs_flush; - - *logofs << "SplitStore: PANIC! While receiving split for " - << "checksum [" << DumpChecksum(split -> checksum_) - << "] with count " << count << " action [" - << DumpAction(split -> action_) << "] state [" - << DumpState(split -> state_) << "]. Data size is " - << split -> data_.size() << " (" << split -> d_size_ - << "/" << split -> c_size_ << "), " << split -> - data_.size() - (split -> next_ + count) - << " to go.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Invalid data count " - << count << "provided in the split.\n"; - - HandleAbort(); - } - - if (split -> state_ != split_loaded) - { - #ifdef TEST - - if (split -> next_ + count > split -> data_.size()) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Inconsistent split data size " - << split -> data_.size() << " with expected size " - << split -> r_size_ << ".\n" - << logofs_flush; - #endif - - HandleAbort(); - } - - #endif - - memcpy(split -> data_.begin() + split -> next_, - decodeBuffer.decodeMemory(count), count); - } - else - { - #ifdef TEST - *logofs << "SplitStore: WARNING! Data discarded with split " - << "loaded from disk.\n" << logofs_flush; - #endif - - decodeBuffer.decodeMemory(count); - } - - split -> next_ += count; - } - - // - // Is unsplit complete? - // - - if (split -> next_ != split -> r_size_) - { - return 0; - } - - // - // If the persistent cache is enabled, - // we have a valid checksum and the - // split was not originally retrieved - // from disk, save the message on disk. - // - - if (split -> state_ != split_loaded && - split -> state_ != split_aborted) - { - save(split); - } - - // - // Move the split at the head of the - // list to the commits. - // - - remove(split); - - // - // Reset the current position to the - // end of the repository. - // - - current_ = splits_ -> end(); - - #ifdef TEST - *logofs << "SplitStore: Removed split at head of the list. " - << "Resource is " << split -> resource_ << " request " - << (unsigned) split -> store_ -> opcode() << " position " - << split -> position_ << ".\n" << logofs_flush; - #endif - - return 1; -} - -Split *SplitStore::pop() -{ - if (splits_ -> size() == 0) - { - #ifdef TEST - *logofs << "SplitStore: The split store is empty.\n" - << logofs_flush; - #endif - - return NULL; - } - - // - // Move the pointer at the end of the list. - // The next send operation will eventually - // start a new split. - // - - current_ = splits_ -> end(); - - Split *split = *(splits_ -> begin()); - - splits_ -> pop_front(); - - #ifdef TEST - *logofs << "SplitStore: Removed split at the head of the " - << "list with resource " << split -> resource_ - << " request " << (unsigned) split -> store_ -> - opcode() << " position " << split -> position_ - << ".\n" << logofs_flush; - #endif - - splitStorageSize_ -= getNodeSize(split); - - totalSplitSize_--; - - totalSplitStorageSize_ -= getNodeSize(split); - - #ifdef TEST - *logofs << "SplitStore: There are " << splits_ -> size() - << " messages in store [" << resource_ << "] with " - << "storage size " << splitStorageSize_ << ".\n" - << logofs_flush; - - *logofs << "SplitStore: Total messages in stores are " - << totalSplitSize_ << " with total storage size " - << totalSplitStorageSize_ << ".\n" - << logofs_flush; - #endif - - return split; -} - -void SplitStore::remove(Split *split) -{ - #ifdef TEST - *logofs << "SplitStore: Going to remove the split from the list.\n" - << logofs_flush; - #endif - - #ifdef TEST - - if (split != getFirstSplit()) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Trying to remove a split " - << "not at the head of the list.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Trying to remove a split " - << "not at the head of the list.\n"; - - HandleAbort(); - } - - #endif - - // - // Move the split to the commit store. - // - - splits_ -> pop_front(); - - commits_ -> splits_ -> push_back(split); - - splitStorageSize_ -= getNodeSize(split); - - totalSplitSize_--; - - totalSplitStorageSize_ -= getNodeSize(split); - - #ifdef TEST - *logofs << "SplitStore: There are " << splits_ -> size() - << " messages in store [" << resource_ << "] with " - << "storage size " << splitStorageSize_ << ".\n" - << logofs_flush; - - *logofs << "SplitStore: Total messages in stores are " - << totalSplitSize_ << " with total storage size " - << totalSplitStorageSize_ << ".\n" - << logofs_flush; - #endif - - #ifdef TEST - - if (splits_ -> size() == 0) - { - if (splitStorageSize_ != 0) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Internal error calculating " - << "split data size. It is " << splitStorageSize_ - << " while should be 0.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Internal error calculating " - << "split data size. It is " << splitStorageSize_ - << " while should be 0.\n"; - - HandleAbort(); - } - } - - #endif -} - -const char *SplitStore::name(const T_checksum checksum) -{ - if (checksum == NULL) - { - return NULL; - } - - char *pathName = control -> ImageCachePath; - - if (pathName == NULL) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Cannot determine directory of " - << "NX image files.\n" << logofs_flush; - #endif - - return NULL; - } - - int pathSize = strlen(pathName); - - // - // File name is "[path][/I-c/I-][checksum][\0]", - // where c is the first hex digit of checksum. - // - - int nameSize = pathSize + 7 + MD5_LENGTH * 2 + 1; - - char *fileName = new char[nameSize]; - - if (fileName == NULL) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Cannot allocate space for " - << "NX image file name.\n" << logofs_flush; - #endif - - return NULL; - } - - strcpy(fileName, pathName); - - sprintf(fileName + pathSize, "/I-%1X/I-", - *((unsigned char *) checksum) >> 4); - - for (unsigned int i = 0; i < MD5_LENGTH; i++) - { - sprintf(fileName + pathSize + 7 + (i * 2), "%02X", - ((unsigned char *) checksum)[i]); - } - - return fileName; -} - -int SplitStore::save(Split *split) -{ - // - // Check if saving the message on the - // persistent cache is enabled. - // - - if (split -> save_ == 0) - { - return 0; - } - - T_checksum checksum = split -> checksum_; - - const char *fileName = name(checksum); - - if (fileName == NULL) - { - return 0; - } - - unsigned int splitSize; - - ostream *fileStream = NULL; - - unsigned char *fileHeader = NULL; - - // - // Get the other data from the split. - // - - unsigned char opcode = split -> store_ -> opcode(); - - unsigned char *data = split -> data_.begin(); - - int dataSize = split -> d_size_; - int compressedSize = split -> c_size_; - - #ifdef DEBUG - *logofs << "SplitStore: Going to save split OPCODE#" - << (unsigned int) opcode << " to file '" << fileName - << "' with size " << dataSize << " and compressed size " - << compressedSize << ".\n" << logofs_flush; - #endif - - DisableSignals(); - - // - // Change the mask to make the file only - // readable by the user, then restore the - // old mask. - // - - mode_t fileMode; - - // - // Check if the file already exists. We try to - // load the message when the split is started - // and save it only if it is not found. Still - // the remote side may send the same image mul- - // tiple time and we may not have the time to - // notify the abort. - // - - struct stat fileStat; - - if (stat(fileName, &fileStat) == 0) - { - #ifdef TEST - *logofs << "SplitStore: Image file '" << fileName - << "' already present on disk.\n" - << logofs_flush; - #endif - - goto SplitStoreSaveError; - } - - fileMode = umask(0077); - - fileStream = new ofstream(fileName, ios::out | ios::binary); - - umask(fileMode); - - if (CheckData(fileStream) < 0) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Cannot open file '" << fileName - << "' for output.\n" << logofs_flush; - #endif - - goto SplitStoreSaveError; - } - - fileHeader = new unsigned char[SPLIT_HEADER_SIZE]; - - if (fileHeader == NULL) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Cannot allocate space for " - << "NX image header.\n" << logofs_flush; - #endif - - goto SplitStoreSaveError; - } - - // - // Leave 3 bytes for future use. Please note - // that, on some CPUs, we can't use PutULONG() - // to write integers that are not aligned to - // the word boundary. - // - - *fileHeader = opcode; - - *(fileHeader + 1) = 0; - *(fileHeader + 2) = 0; - *(fileHeader + 3) = 0; - - PutULONG(dataSize, fileHeader + 4, false); - PutULONG(compressedSize, fileHeader + 8, false); - - splitSize = (compressedSize > 0 ? compressedSize : dataSize); - - if (PutData(fileStream, fileHeader, SPLIT_HEADER_SIZE) < 0 || - PutData(fileStream, data, splitSize) < 0) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Cannot write to NX " - << "image file '" << fileName << "'.\n" - << logofs_flush; - #endif - - goto SplitStoreSaveError; - } - - // - // Check if all the data was written on the - // disk and, if not, remove the faulty copy. - // - - FlushData(fileStream); - - if (CheckData(fileStream) < 0) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Failed to write NX " - << "image file '" << fileName << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Failed to write NX " - << "image file '" << fileName << "'.\n"; - - goto SplitStoreSaveError; - } - - #ifdef TEST - *logofs << "SplitStore: Saved split to file '" << fileName - << "' with data size " << dataSize << " and " - << "compressed data size " << compressedSize - << ".\n" << logofs_flush; - #endif - - delete fileStream; - - delete [] fileName; - delete [] fileHeader; - - EnableSignals(); - - // - // Update the timestamp as the operation - // may have taken some time. - // - - getNewTimestamp(); - - return 1; - -SplitStoreSaveError: - - delete fileStream; - - if (fileName != NULL) - { - unlink(fileName); - } - - delete [] fileName; - delete [] fileHeader; - - EnableSignals(); - - return -1; -} - -int SplitStore::find(Split *split) -{ - const char *fileName = name(split -> checksum_); - - if (fileName == NULL) - { - return 0; - } - - #ifdef DEBUG - *logofs << "SplitStore: Going to find split OPCODE#" - << (unsigned) split -> store_ -> opcode() - << " in file '" << fileName << "'.\n" - << logofs_flush; - #endif - - // - // Check if the file exists and, at the - // same time, update the modification - // time to prevent its deletion. - // - - if (utime(fileName, NULL) == 0) - { - #ifdef TEST - *logofs << "SplitStore: Found split OPCODE#" - << (unsigned) split -> store_ -> opcode() - << " in file '" << fileName << "'.\n" - << logofs_flush; - #endif - - delete [] fileName; - - return 1; - } - - #ifdef TEST - *logofs << "SplitStore: WARNING! Can't find split " - << "OPCODE#" << (unsigned) split -> store_ -> - opcode() << " in file '" << fileName - << "'.\n" << logofs_flush; - #endif - - delete [] fileName; - - return 0; -} - -int SplitStore::load(Split *split) -{ - // - // Check if loading the image is enabled. - // - - if (split -> load_ == 0) - { - return 0; - } - - const char *fileName = name(split -> checksum_); - - if (fileName == NULL) - { - return 0; - } - - unsigned char fileOpcode; - - int fileSize; - int fileCSize; - - istream *fileStream = NULL; - - unsigned char *fileHeader = NULL; - - DisableSignals(); - - #ifdef DEBUG - *logofs << "SplitStore: Going to load split OPCODE#" - << (unsigned int) split -> store_ -> opcode() - << " from file '" << fileName << "'.\n" - << logofs_flush; - #endif - - fileStream = new ifstream(fileName, ios::in | ios::binary); - - if (CheckData(fileStream) < 0) - { - #ifdef TEST - *logofs << "SplitStore: WARNING! Can't open image file '" - << fileName << "' on disk.\n" << logofs_flush; - #endif - - goto SplitStoreLoadError; - } - - fileHeader = new unsigned char[SPLIT_HEADER_SIZE]; - - if (fileHeader == NULL) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Cannot allocate space for " - << "NX image header.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot allocate space for " - << "NX image header.\n"; - - goto SplitStoreLoadError; - } - - if (GetData(fileStream, fileHeader, SPLIT_HEADER_SIZE) < 0) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Cannot read header from " - << "NX image file '" << fileName << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Cannot read header from " - << "NX image file '" << fileName << "'.\n"; - - goto SplitStoreLoadError; - } - - fileOpcode = *fileHeader; - - fileSize = GetULONG(fileHeader + 4, false); - fileCSize = GetULONG(fileHeader + 8, false); - - // - // Don't complain if we find that data was saved - // in compressed form even if we were not aware - // of the compressed data size. The remote side - // compresses the data only at the time it starts - // the transferral of the split. We replace our - // copy of the data with whatever we find on the - // disk. - // - - if (fileOpcode != split -> store_ -> opcode() || - fileSize != split -> d_size_ || - fileSize > control -> MaximumRequestSize || - fileCSize > control -> MaximumRequestSize) - - { - #ifdef TEST - *logofs << "SplitStore: PANIC! Corrupted image file '" << fileName - << "'. Expected " << (unsigned int) split -> store_ -> opcode() - << "/" << split -> d_size_ << "/" << split -> c_size_ << " found " - << (unsigned int) fileOpcode << "/" << fileSize << "/" - << fileCSize << ".\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Corrupted image file '" << fileName - << "'. Expected " << (unsigned int) split -> store_ -> opcode() - << "/" << split -> d_size_ << "/" << split -> c_size_ << " found " - << (unsigned int) fileOpcode << "/" << fileSize << "/" - << fileCSize << ".\n"; - - goto SplitStoreLoadError; - } - - // - // Update the data size with the size - // we got from the disk record. - // - - split -> d_size_ = fileSize; - split -> c_size_ = fileCSize; - - unsigned int splitSize; - - if (fileCSize > 0) - { - splitSize = fileCSize; - } - else - { - splitSize = fileSize; - } - - // - // Allocate a new buffer if we didn't - // do that already or if the size is - // different. - // - - if (split -> data_.size() != splitSize) - { - split -> data_.clear(); - - split -> data_.resize(splitSize); - } - - if (GetData(fileStream, split -> data_.begin(), splitSize) < 0) - { - #ifdef PANIC - *logofs << "SplitStore: PANIC! Cannot read data from " - << "NX image file '" << fileName << "'.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Cannot read data from " - << "NX image file '" << fileName << "'.\n"; - - goto SplitStoreLoadError; - } - - delete fileStream; - - delete [] fileHeader; - delete [] fileName; - - EnableSignals(); - - // - // Update the timestamp as the operation - // may have taken some time. - // - - getNewTimestamp(); - - return 1; - -SplitStoreLoadError: - - delete fileStream; - - unlink(fileName); - - delete [] fileName; - delete [] fileHeader; - - EnableSignals(); - - return -1; -} - -Split *CommitStore::pop() -{ - if (splits_ -> size() == 0) - { - #ifdef TEST - *logofs << "CommitStore: The commit store is empty.\n" - << logofs_flush; - #endif - - return NULL; - } - - Split *split = *(splits_ -> begin()); - - splits_ -> pop_front(); - - #ifdef TEST - *logofs << "CommitStore: Removed commit split at the head " - << "of the list with resource " << split -> resource_ - << " request " << (unsigned) split -> store_ -> - opcode() << " position " << split -> position_ - << ".\n" << logofs_flush; - #endif - - return split; -} - -int CommitStore::expand(Split *split, unsigned char *buffer, const int size) -{ - #ifdef TEST - *logofs << "CommitStore: Expanding split data with " - << size << " bytes to write.\n" - << logofs_flush; - #endif - - #ifdef TEST - - if (size < split -> i_size_ + split -> d_size_) - { - #ifdef PANIC - *logofs << "CommitStore: PANIC! Wrong size of the provided " - << "buffer. It should be " << split -> i_size_ + - split -> d_size_ << " instead of " << size - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Wrong size of the provided " - << "buffer. It should be " << split -> i_size_ + - split -> d_size_ << " instead of " << size - << ".\n"; - - HandleAbort(); - } - - #endif - - #ifdef DEBUG - *logofs << "CommitStore: Copying " << split -> i_size_ - << " bytes of identity.\n" << logofs_flush; - #endif - - memcpy(buffer, split -> identity_.begin(), split -> i_size_); - - // - // Copy data, if any, to the buffer. - // - - if (size > split -> i_size_) - { - // - // Check if message has been stored - // in compressed format. - // - - if (split -> c_size_ == 0) - { - #ifdef DEBUG - *logofs << "CommitStore: Copying " << split -> d_size_ - << " bytes of plain data.\n" << logofs_flush; - #endif - - memcpy(buffer + split -> i_size_, split -> data_.begin(), split -> d_size_); - } - else - { - #ifdef DEBUG - *logofs << "CommitStore: Decompressing " << split -> c_size_ - << " bytes and copying " << split -> d_size_ - << " bytes of data.\n" << logofs_flush; - #endif - - if (compressor_ -> - decompressBuffer(buffer + split -> i_size_, - split -> d_size_, split -> data_.begin(), - split -> c_size_) < 0) - { - #ifdef PANIC - *logofs << "CommitStore: PANIC! Split data decompression failed.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Split data decompression failed.\n"; - - return -1; - } - } - } - - return 1; -} - -int CommitStore::update(Split *split) -{ - if (split -> action_ != IS_ADDED) - { - return 0; - } - - // - // We don't need the identity data at - // the encoding side. - // - - if (split -> identity_.size() == 0) - { - #ifdef TEST - *logofs << "SplitStore: Going to update the size " - << "for object at position " << split -> position_ - << " with data size " << split -> d_size_ - << " and compressed data size " << split -> - c_size_ << ".\n" << logofs_flush; - #endif - - split -> store_ -> updateData(split -> position_, split -> d_size_, - split -> c_size_); - } - else - { - #ifdef TEST - *logofs << "SplitStore: Going to update data and size " - << "for object at position " << split -> position_ - << " with data size " << split -> d_size_ - << " and compressed data size " << split -> - c_size_ << ".\n" << logofs_flush; - #endif - - split -> store_ -> updateData(split -> position_, split -> data_.begin(), - split -> d_size_, split -> c_size_); - } - - // - // Unlock message so that we can remove - // or save it on disk at shutdown. - // - - if (split -> action_ == IS_ADDED) - { - split -> store_ -> unlock(split -> position_); - - #ifdef TEST - - validate(split); - - #endif - } - - return 1; -} - -int CommitStore::validate(Split *split) -{ - MessageStore *store = split -> store_; - - int p, n, s; - - s = store -> cacheSlots; - - for (p = 0, n = 0; p < s; p++) - { - if (store -> getLocks(p) == 1) - { - n++; - } - else if (store -> getLocks(p) != 0) - { - #ifdef PANIC - *logofs << "CommitStore: PANIC! Repository for OPCODE#" - << (unsigned int) store -> opcode() << " has " - << store -> getLocks(p) << " locks for message " - << "at position " << p << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Repository for OPCODE#" - << (unsigned int) store -> opcode() << " has " - << store -> getLocks(p) << " locks for message " - << "at position " << p << ".\n"; - - HandleAbort(); - } - } - - #ifdef TEST - *logofs << "CommitStore: Repository for OPCODE#" - << (unsigned int) store -> opcode() - << " has " << n << " locked messages.\n" - << logofs_flush; - #endif - - return 1; -} diff --git a/nxcomp/Split.h b/nxcomp/Split.h deleted file mode 100644 index ee5eae7fe..000000000 --- a/nxcomp/Split.h +++ /dev/null @@ -1,543 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Split_H -#define Split_H - -#include "Types.h" -#include "Timestamp.h" -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Define this to know how many splits -// are allocated and deallocated. -// - -#undef REFERENCES - -// -// Size of header of messages saved on -// disk. -// - -#define SPLIT_HEADER_SIZE 12 - -// -// This class is used to divide big messages -// in smaller chunks and send them at idle -// time. -// - -class EncodeBuffer; -class DecodeBuffer; - -class SplitStore; -class CommitStore; - -// -// Preferred message streaming policy. -// - -typedef enum -{ - split_none = -1, - split_async = 1, - split_sync - -} T_split_mode; - -// -// Current state of the split. Used to -// implement the state machine. -// - -typedef enum -{ - split_undefined = -1, - split_added, - split_missed, - split_loaded, - split_aborted, - split_notified - -} T_split_state; - -class Split -{ - friend class SplitStore; - friend class CommitStore; - - public: - - Split(); - - ~Split(); - - // - // Note that, differently from the message - // store, the split store doesn't account - // for the data offset when dealing with - // the data. This means that both the size_ - // and c_size members represent the actual - // size of the data part. - // - - void compressedSize(int size) - { - c_size_ = size; - - store_ -> validateSize(d_size_, c_size_); - } - - int compressedSize() - { - return c_size_; - } - - int plainSize() - { - return i_size_ + d_size_; - } - - T_checksum getChecksum() - { - return checksum_; - } - - MessageStore *getStore() - { - return store_; - } - - T_split_state getState() - { - return state_; - } - - T_store_action getAction() - { - return action_; - } - - // - // We may need to find the resource - // associated to the split message - // because old protocol version use - // a single store for all splits. - // - - int getResource() - { - return resource_; - } - - int getRequest() - { - return store_ -> opcode(); - } - - int getPosition() - { - return position_; - } - - T_split_mode getMode() - { - return mode_; - } - - void setPolicy(int load, int save) - { - load_ = load; - save_ = save; - } - - void setState(T_split_state state) - { - state_ = state; - } - - private: - - // - // The agent's resource which is splitting - // the message. - // - - int resource_; - - // - // Where to find the message in the message - // store or the X sequence number of the - // original request, in recent versions. - // - - int position_; - - // - // Which store is involved. - // - - MessageStore *store_; - - // - // Identity size of the message. - // - - int i_size_; - - // - // This is the uncompressed data size of the - // original message. - // - - int d_size_; - - // - // This is the size of the compressed data, - // if the data is stored in this form. - // - - int c_size_; - - // - // Size of the data buffer, as known by the - // encoding side. This field is only used at - // the decoding side. The remote size can be - // different from the actual data size, if - // the encoding side did not confirm that it - // received the abort split event. - // - - int r_size_; - - // - // Position in the data buffer that will be - // the target of the next send or receive - // operation while streaming the message. - // - - int next_; - - // - // Load or save the split to disk. - // - - int load_; - int save_; - - // - // Checksum of the original message. - // - - T_checksum checksum_; - - // - // Was this split confirmed or aborted? - // - - T_split_state state_; - - // - // What's the policy for sending this split? - // - - T_split_mode mode_; - - // - // Operation that had been performed on the - // store at the time the split was added. - // - - T_store_action action_; - - // - // Container for the identity and data part - // of the X message. - // - - T_data identity_; - T_data data_; - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -class SplitStore -{ - public: - - SplitStore(StaticCompressor *compressor, CommitStore *commits, int resource); - - ~SplitStore(); - - Split *getFirstSplit() const - { - if (splits_ -> size() > 0) - { - return (*(splits_ -> begin())); - } - - return NULL; - } - - Split *getLastSplit() const - { - if (splits_ -> size() > 0) - { - return (*(--(splits_ -> end()))); - } - - return NULL; - } - - int getNodeSize(const Split *split) const - { - // - // Take in account 64 bytes of overhead - // for each node. - // - - return (sizeof(class Split) + 64 + - split -> i_size_ + split -> d_size_); - } - - int getStorageSize() - { - return splitStorageSize_; - } - - static int getTotalSize() - { - return totalSplitSize_; - } - - static int getTotalStorageSize() - { - return totalSplitStorageSize_; - } - - int getResource() - { - return resource_; - } - - int getSize() - { - return splits_ -> size(); - } - - T_splits *getSplits() - { - return splits_; - } - - // - // Used, respectively, at the encoding - // and decoding side. - // - - Split *add(MessageStore *store, int resource, T_split_mode mode, - int position, T_store_action action, T_checksum checksum, - const unsigned char *buffer, const int size); - - Split *add(MessageStore *store, int resource, int position, - T_store_action action, T_checksum checksum, - unsigned char *buffer, const int size); - - // - // Handle the streaming of the message data. - // - - int send(EncodeBuffer &encodeBuffer, int packetSize); - - int receive(DecodeBuffer &decodeBuffer); - - // - // Remove the top element of the split store - // and update the storage size. - // - - void remove(Split *split); - - // - // Load the message from disk and replace the - // message in the store with the new copy. - // - - int load(Split *split); - - // - // Save the data to disk after the message has - // been recomposed at the local side. - // - - int save(Split *split); - - // - // Find the message on disk and update the last - // modification time. This is currently unused. - // - - int find(Split *split); - - // - // Remove the element on top of the queue and - // discard any split data that still needs to - // be transferred. - // - - Split *pop(); - - // - // Dump the content of the store. - // - - void dump(); - - protected: - - // - // Repository where to add the splits. - // - - T_splits *splits_; - - // - // Compress and decompress the data payload. - // - - StaticCompressor *compressor_; - - private: - - int start(EncodeBuffer &encodeBuffer); - - int start(DecodeBuffer &decodeBuffer); - - void push(Split *split); - - // - // Determine the name of the file object based - // on the checksum. - // - - const char *name(const T_checksum checksum); - - // - // The number of elements and data bytes - // in the repository. - // - - int splitStorageSize_; - - static int totalSplitSize_; - static int totalSplitStorageSize_; - - // - // Current element being transferred. - // - - T_splits::iterator current_; - - // - // Repository where to move the splits - // after they are completely recomposed. - // - - CommitStore *commits_; - - // - // Index in the client store or none, - // if this is a commit store. - // - - int resource_; - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -class CommitStore : public SplitStore -{ - // - // This is just a split store. - // - - public: - - CommitStore(StaticCompressor *compressor) - - : SplitStore(compressor, NULL, nothing) - { - } - - // - // Move identity and data of the split to the - // provided buffer, uncompressing the message, - // if needed. - // - - int expand(Split *split, unsigned char *buffer, const int size); - - // - // We recomposed the data part. If the message - // was originally added to the message store, - // replace the data and/or update the size. - // - - int update(Split *split); - - // - // Remove the split from the commit queue. - // - - Split *pop(); - - // - // This is just used for debug. It checks - // if any message in the message store has - // an invalid number of locks. - // - - int validate(Split *split); -}; - -#endif /* Split_H */ diff --git a/nxcomp/StaticCompressor.cpp b/nxcomp/StaticCompressor.cpp deleted file mode 100644 index 93103af41..000000000 --- a/nxcomp/StaticCompressor.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Z.h" -#include "Misc.h" -#include "Control.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -#include "StaticCompressor.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -StaticCompressor::StaticCompressor(int compressionLevel, - int compressionThreshold) -{ - buffer_ = NULL; - bufferSize_ = 0; - - compressionStream_.zalloc = (alloc_func) 0; - compressionStream_.zfree = (free_func) 0; - compressionStream_.opaque = (voidpf) 0; - - decompressionStream_.zalloc = (alloc_func) 0; - decompressionStream_.zfree = (free_func) 0; - decompressionStream_.opaque = (void *) 0; - - decompressionStream_.next_in = (Bytef *) 0; - decompressionStream_.avail_in = 0; - - #ifdef TEST - *logofs << "StaticCompressor: Compression level is " - << compressionLevel << ".\n" << logofs_flush; - #endif - - int result = deflateInit2(&compressionStream_, compressionLevel, Z_DEFLATED, - 15, 9, Z_DEFAULT_STRATEGY); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Cannot initialize the " - << "compression stream. Error is '" << zError(result) - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot initialize the compression " - << "stream. Error is '" << zError(result) << "'.\n"; - - HandleAbort(); - } - - result = inflateInit2(&decompressionStream_, 15); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Cannot initialize the " - << "decompression stream. Error is '" << zError(result) - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot initialize the decompression " - << "stream. Error is '" << zError(result) << "'.\n"; - - HandleAbort(); - } - - #ifdef TEST - *logofs << "StaticCompressor: Compression threshold is " - << compressionThreshold << ".\n" << logofs_flush; - #endif - - threshold_ = compressionThreshold; -} - -StaticCompressor::~StaticCompressor() -{ - int result = deflateEnd(&compressionStream_); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Cannot deinitialize the " - << "compression stream. Error is '" << zError(result) - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot deinitialize the compression " - << "stream. Error is '" << zError(result) << "'.\n"; - } - - result = inflateEnd(&decompressionStream_); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Cannot deinitialize the " - << "decompression stream. Error is '" << zError(result) - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot deinitialize the decompression " - << "stream. Error is '" << zError(result) << "'.\n"; - } - - delete [] buffer_; -} - -// -// This function compresses and encodes the compressed -// buffer. It returns a pointer to the internal buffer -// where data was compressed. -// - -int StaticCompressor::compressBuffer(const unsigned char *plainBuffer, - const unsigned int plainSize, - unsigned char *&compressedBuffer, - unsigned int &compressedSize, - EncodeBuffer &encodeBuffer) -{ - if (control -> LocalDataCompression == 0 || - compressBuffer(plainBuffer, plainSize, - compressedBuffer, compressedSize) <= 0) - { - encodeBuffer.encodeBoolValue(0); - - encodeBuffer.encodeMemory(plainBuffer, plainSize); - - return 0; - } - else - { - encodeBuffer.encodeBoolValue(1); - - encodeBuffer.encodeValue(compressedSize, 32, 14); - encodeBuffer.encodeValue(plainSize, 32, 14); - - encodeBuffer.encodeMemory(compressedBuffer, compressedSize); - - return 1; - } -} - -// -// This function compresses data into a dynamically -// allocated buffer and returns a pointer to it, so -// application must copy data before the next call. -// - -int StaticCompressor::compressBuffer(const unsigned char *plainBuffer, - const unsigned int plainSize, - unsigned char *&compressedBuffer, - unsigned int &compressedSize) -{ - #ifdef DEBUG - *logofs << "StaticCompressor: Called for buffer at " - << (void *) plainBuffer << ".\n" - << logofs_flush; - #endif - - compressedSize = plainSize; - - if (plainSize < (unsigned int) threshold_) - { - #ifdef TEST - *logofs << "StaticCompressor: Leaving buffer unchanged. " - << "Plain size is " << plainSize << " with threshold " - << (unsigned int) threshold_ << ".\n" << logofs_flush; - #endif - - return 0; - } - - // - // Determine the size of the temporary - // buffer. - // - - unsigned int newSize = plainSize + (plainSize / 1000) + 12; - - // - // Allocate a new buffer if it grows - // beyond 64K. - // - - if (buffer_ == NULL || (bufferSize_ > 65536 && - newSize < bufferSize_ / 2) || newSize > bufferSize_) - { - delete [] buffer_; - - buffer_ = new unsigned char[newSize]; - - if (buffer_ == NULL) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Can't allocate compression " - << "buffer of " << newSize << " bytes. Error is " << EGET() - << " ' " << ESTR() << "'.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Can't allocate compression buffer of " - << newSize << " bytes. Error is " << EGET() - << " '" << ESTR() << "'.\n"; - - bufferSize_ = 0; - - return 0; - } - - bufferSize_ = newSize; - } - - unsigned int resultingSize = newSize; - - int result = ZCompress(&compressionStream_, buffer_, &resultingSize, - plainBuffer, plainSize); - - if (result == Z_OK) - { - if (resultingSize > newSize) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Overflow in compression " - << "buffer size. " << "Expected size was " << newSize - << " while it is " << resultingSize << ".\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Overflow in compress buffer size. " - << "Expected size was " << newSize << " while it is " - << resultingSize << ".\n"; - - return -1; - } - else if (resultingSize >= plainSize) - { - #ifdef TEST - *logofs << "StaticCompressor: Leaving buffer unchanged. " - << "Plain size is " << plainSize << " compressed " - << "size is " << resultingSize << ".\n" - << logofs_flush; - #endif - - return 0; - } - - compressedBuffer = buffer_; - compressedSize = resultingSize; - - #ifdef TEST - *logofs << "StaticCompressor: Compressed buffer from " - << plainSize << " to " << resultingSize - << " bytes.\n" << logofs_flush; - #endif - - return 1; - } - - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Failed compression of buffer. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed compression of buffer. " - << "Error is '" << zError(result) << "'.\n"; - - return -1; -} - -int StaticCompressor::decompressBuffer(unsigned char *plainBuffer, - unsigned int plainSize, - const unsigned char *&compressedBuffer, - unsigned int &compressedSize, - DecodeBuffer &decodeBuffer) -{ - #ifdef DEBUG - *logofs << "StaticCompressor: Called for buffer at " - << (void *) plainBuffer << ".\n" - << logofs_flush; - #endif - - unsigned int value; - - decodeBuffer.decodeBoolValue(value); - - if (value == 0) - { - memcpy(plainBuffer, - decodeBuffer.decodeMemory(plainSize), - plainSize); - - return 0; - } - - unsigned int checkSize = plainSize; - - decodeBuffer.decodeValue(value, 32, 14); - compressedSize = value; - - decodeBuffer.decodeValue(value, 32, 14); - checkSize = value; - - // - // If caller needs the original compressed - // data it must copy this to its own buffer - // before using any further decode function. - // - - compressedBuffer = decodeBuffer.decodeMemory(compressedSize); - - int result = ZDecompress(&decompressionStream_, plainBuffer, &checkSize, - compressedBuffer, compressedSize); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Failure decompressing buffer. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failure decompressing buffer. " - << "Error is '" << zError(result) << "'.\n"; - - return -1; - } - else if (plainSize != checkSize) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Expected decompressed size was " - << plainSize << " while it is " << checkSize - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Expected decompressed size was " - << plainSize << " while it is " << checkSize - << ".\n"; - - return -1; - } - - return 1; -} - -// -// This is used to uncompress on-the-fly -// messages whose data has been stored -// in compressed format. -// - -int StaticCompressor::decompressBuffer(unsigned char *plainBuffer, - const unsigned int plainSize, - const unsigned char *compressedBuffer, - const unsigned int compressedSize) -{ - #ifdef TEST - *logofs << "StaticCompressor: Called for buffer at " - << (void *) plainBuffer << ".\n" - << logofs_flush; - #endif - - unsigned int checkSize = plainSize; - - int result = ZDecompress(&decompressionStream_, plainBuffer, &checkSize, - compressedBuffer, compressedSize); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Failure decompressing buffer. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - return -1; - } - - if (plainSize != checkSize) - { - #ifdef PANIC - *logofs << "StaticCompressor: PANIC! Expected decompressed size was " - << plainSize << " while it is " << checkSize - << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Expected decompressed size was " - << plainSize << " while it is " << checkSize - << ".\n"; - - return -1; - } - - #ifdef TEST - *logofs << "StaticCompressor: Decompressed buffer from " - << compressedSize << " to " << plainSize - << " bytes.\n" << logofs_flush; - #endif - - return 1; -} diff --git a/nxcomp/StaticCompressor.h b/nxcomp/StaticCompressor.h deleted file mode 100644 index e0b81a527..000000000 --- a/nxcomp/StaticCompressor.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef StaticCompressor_H -#define StaticCompressor_H - -#include "Z.h" - -class EncodeBuffer; -class DecodeBuffer; - -class StaticCompressor -{ - public: - - StaticCompressor(int compressionLevel, int compressionThreshold); - - ~StaticCompressor(); - - int compressBuffer(const unsigned char *plainBuffer, const unsigned int plainSize, - unsigned char *&compressedBuffer, unsigned int &compressedSize, - EncodeBuffer &encodeBuffer); - - int compressBuffer(const unsigned char *plainBuffer, const unsigned int plainSize, - unsigned char *&compressedBuffer, unsigned int &compressedSize); - - int decompressBuffer(unsigned char *plainBuffer, unsigned int plainSize, - const unsigned char *&compressedBuffer, unsigned int &compressedSize, - DecodeBuffer &decodeBuffer); - - int decompressBuffer(unsigned char *plainBuffer, const unsigned int plainSize, - const unsigned char *compressedBuffer, const unsigned compressedSize); - - static int isCompressionLevel(int compressionLevel) - { - return (compressionLevel == Z_DEFAULT_COMPRESSION || - (compressionLevel >= Z_NO_COMPRESSION && - compressionLevel <= Z_BEST_COMPRESSION)); - } - - int fullReset() - { - return (deflateReset(&compressionStream_) == Z_OK && - inflateReset(&decompressionStream_) == Z_OK); - } - - private: - - z_stream compressionStream_; - z_stream decompressionStream_; - - unsigned char *buffer_; - unsigned int bufferSize_; - - int threshold_; -}; - -#endif diff --git a/nxcomp/Statistics.cpp b/nxcomp/Statistics.cpp deleted file mode 100644 index baad7ef60..000000000 --- a/nxcomp/Statistics.cpp +++ /dev/null @@ -1,2003 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include - -#include "Statistics.h" - -#include "Control.h" - -#include "Proxy.h" - -#include "ClientStore.h" -#include "ServerStore.h" - -// -// Length of temporary buffer -// used to format output. -// - -#define FORMAT_LENGTH 1024 - -// -// Log level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Note that when presenting statistics we invert the -// correct semantics of X client and server entities. -// This is questionable, but matches the user's pers- -// pective of running remote X applications on its -// local client. -// - -Statistics::Statistics(Proxy *proxy) : proxy_(proxy) -{ - transportPartial_.idleTime_ = 0; - transportPartial_.readTime_ = 0; - transportPartial_.writeTime_ = 0; - transportPartial_.proxyBytesIn_ = 0; - transportPartial_.proxyBytesOut_ = 0; - transportPartial_.proxyFramesIn_ = 0; - transportPartial_.proxyFramesOut_ = 0; - transportPartial_.proxyWritesOut_ = 0; - transportPartial_.compressedBytesIn_ = 0; - transportPartial_.compressedBytesOut_ = 0; - transportPartial_.decompressedBytesIn_ = 0; - transportPartial_.decompressedBytesOut_ = 0; - transportPartial_.framingBitsOut_ = 0; - - transportTotal_.idleTime_ = 0; - transportTotal_.readTime_ = 0; - transportTotal_.writeTime_ = 0; - transportTotal_.proxyBytesIn_ = 0; - transportTotal_.proxyBytesOut_ = 0; - transportTotal_.proxyFramesIn_ = 0; - transportTotal_.proxyFramesOut_ = 0; - transportTotal_.proxyWritesOut_ = 0; - transportTotal_.compressedBytesIn_ = 0; - transportTotal_.compressedBytesOut_ = 0; - transportTotal_.decompressedBytesIn_ = 0; - transportTotal_.decompressedBytesOut_ = 0; - transportTotal_.framingBitsOut_ = 0; - - for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) - { - protocolPartial_.requestCached_[i] = 0; - protocolPartial_.requestReplied_[i] = 0; - protocolPartial_.requestCount_[i] = 0; - protocolPartial_.requestBitsIn_[i] = 0; - protocolPartial_.requestBitsOut_[i] = 0; - - protocolPartial_.renderRequestCached_[i] = 0; - protocolPartial_.renderRequestCount_[i] = 0; - protocolPartial_.renderRequestBitsIn_[i] = 0; - protocolPartial_.renderRequestBitsOut_[i] = 0; - - protocolPartial_.replyCached_[i] = 0; - protocolPartial_.replyCount_[i] = 0; - protocolPartial_.replyBitsIn_[i] = 0; - protocolPartial_.replyBitsOut_[i] = 0; - - protocolPartial_.eventCached_[i] = 0; - protocolPartial_.eventCount_[i] = 0; - protocolPartial_.eventBitsIn_[i] = 0; - protocolPartial_.eventBitsOut_[i] = 0; - - protocolTotal_.requestCached_[i] = 0; - protocolTotal_.requestReplied_[i] = 0; - protocolTotal_.requestCount_[i] = 0; - protocolTotal_.requestBitsIn_[i] = 0; - protocolTotal_.requestBitsOut_[i] = 0; - - protocolTotal_.renderRequestCached_[i] = 0; - protocolTotal_.renderRequestCount_[i] = 0; - protocolTotal_.renderRequestBitsIn_[i] = 0; - protocolTotal_.renderRequestBitsOut_[i] = 0; - - protocolTotal_.replyCached_[i] = 0; - protocolTotal_.replyCount_[i] = 0; - protocolTotal_.replyBitsIn_[i] = 0; - protocolTotal_.replyBitsOut_[i] = 0; - - protocolTotal_.eventCached_[i] = 0; - protocolTotal_.eventCount_[i] = 0; - protocolTotal_.eventBitsIn_[i] = 0; - protocolTotal_.eventBitsOut_[i] = 0; - } - - protocolPartial_.cupsCount_ = 0; - protocolPartial_.cupsBitsIn_ = 0; - protocolPartial_.cupsBitsOut_ = 0; - - protocolPartial_.smbCount_ = 0; - protocolPartial_.smbBitsIn_ = 0; - protocolPartial_.smbBitsOut_ = 0; - - protocolPartial_.mediaCount_ = 0; - protocolPartial_.mediaBitsIn_ = 0; - protocolPartial_.mediaBitsOut_ = 0; - - protocolPartial_.httpCount_ = 0; - protocolPartial_.httpBitsIn_ = 0; - protocolPartial_.httpBitsOut_ = 0; - - protocolPartial_.fontCount_ = 0; - protocolPartial_.fontBitsIn_ = 0; - protocolPartial_.fontBitsOut_ = 0; - - protocolPartial_.slaveCount_ = 0; - protocolPartial_.slaveBitsIn_ = 0; - protocolPartial_.slaveBitsOut_ = 0; - - protocolTotal_.cupsCount_ = 0; - protocolTotal_.cupsBitsIn_ = 0; - protocolTotal_.cupsBitsOut_ = 0; - - protocolTotal_.smbCount_ = 0; - protocolTotal_.smbBitsIn_ = 0; - protocolTotal_.smbBitsOut_ = 0; - - protocolTotal_.mediaCount_ = 0; - protocolTotal_.mediaBitsIn_ = 0; - protocolTotal_.mediaBitsOut_ = 0; - - protocolTotal_.httpCount_ = 0; - protocolTotal_.httpBitsIn_ = 0; - protocolTotal_.httpBitsOut_ = 0; - - protocolTotal_.fontCount_ = 0; - protocolTotal_.fontBitsIn_ = 0; - protocolTotal_.fontBitsOut_ = 0; - - protocolTotal_.slaveCount_ = 0; - protocolTotal_.slaveBitsIn_ = 0; - protocolTotal_.slaveBitsOut_ = 0; - - packedPartial_.packedBytesIn_ = 0; - packedPartial_.packedBytesOut_ = 0; - - packedTotal_.packedBytesIn_ = 0; - packedTotal_.packedBytesOut_ = 0; - - splitPartial_.splitCount_ = 0; - splitPartial_.splitAborted_ = 0; - splitPartial_.splitAbortedBytesOut_ = 0; - - splitTotal_.splitCount_ = 0; - splitTotal_.splitAborted_ = 0; - splitTotal_.splitAbortedBytesOut_ = 0; - - overallPartial_.overallBytesIn_ = 0; - overallPartial_.overallBytesOut_ = 0; - - overallTotal_.overallBytesIn_ = 0; - overallTotal_.overallBytesOut_ = 0; - - proxyData_.protocolCount_ = 0; - proxyData_.controlCount_ = 0; - proxyData_.splitCount_ = 0; - proxyData_.dataCount_ = 0; - - proxyData_.streamRatio_ = 1; - - startShortFrameTs_ = getTimestamp(); - startLongFrameTs_ = getTimestamp(); - startFrameTs_ = getTimestamp(); - - bytesInShortFrame_ = 0; - bytesInLongFrame_ = 0; - - bitrateInShortFrame_ = 0; - bitrateInLongFrame_ = 0; - - topBitrate_ = 0; - - congestionInFrame_ = 0; -} - -Statistics::~Statistics() -{ -} - -int Statistics::resetPartialStats() -{ - transportPartial_.idleTime_ = 0; - transportPartial_.readTime_ = 0; - transportPartial_.writeTime_ = 0; - transportPartial_.proxyBytesIn_ = 0; - transportPartial_.proxyBytesOut_ = 0; - transportPartial_.proxyFramesIn_ = 0; - transportPartial_.proxyFramesOut_ = 0; - transportPartial_.proxyWritesOut_ = 0; - transportPartial_.compressedBytesIn_ = 0; - transportPartial_.compressedBytesOut_ = 0; - transportPartial_.decompressedBytesIn_ = 0; - transportPartial_.decompressedBytesOut_ = 0; - transportPartial_.framingBitsOut_ = 0; - - for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) - { - protocolPartial_.requestCached_[i] = 0; - protocolPartial_.requestReplied_[i] = 0; - protocolPartial_.requestCount_[i] = 0; - protocolPartial_.requestBitsIn_[i] = 0; - protocolPartial_.requestBitsOut_[i] = 0; - - protocolPartial_.renderRequestCached_[i] = 0; - protocolPartial_.renderRequestCount_[i] = 0; - protocolPartial_.renderRequestBitsIn_[i] = 0; - protocolPartial_.renderRequestBitsOut_[i] = 0; - - protocolPartial_.replyCached_[i] = 0; - protocolPartial_.replyCount_[i] = 0; - protocolPartial_.replyBitsIn_[i] = 0; - protocolPartial_.replyBitsOut_[i] = 0; - - protocolPartial_.eventCached_[i] = 0; - protocolPartial_.eventCount_[i] = 0; - protocolPartial_.eventBitsIn_[i] = 0; - protocolPartial_.eventBitsOut_[i] = 0; - } - - protocolPartial_.cupsCount_ = 0; - protocolPartial_.cupsBitsIn_ = 0; - protocolPartial_.cupsBitsOut_ = 0; - - protocolPartial_.smbCount_ = 0; - protocolPartial_.smbBitsIn_ = 0; - protocolPartial_.smbBitsOut_ = 0; - - protocolPartial_.mediaCount_ = 0; - protocolPartial_.mediaBitsIn_ = 0; - protocolPartial_.mediaBitsOut_ = 0; - - protocolPartial_.httpCount_ = 0; - protocolPartial_.httpBitsIn_ = 0; - protocolPartial_.httpBitsOut_ = 0; - - protocolPartial_.fontCount_ = 0; - protocolPartial_.fontBitsIn_ = 0; - protocolPartial_.fontBitsOut_ = 0; - - protocolPartial_.slaveCount_ = 0; - protocolPartial_.slaveBitsIn_ = 0; - protocolPartial_.slaveBitsOut_ = 0; - - packedPartial_.packedBytesIn_ = 0; - packedPartial_.packedBytesOut_ = 0; - - splitPartial_.splitCount_ = 0; - splitPartial_.splitAborted_ = 0; - splitPartial_.splitAbortedBytesOut_ = 0; - - overallPartial_.overallBytesIn_ = 0; - overallPartial_.overallBytesOut_ = 0; - - return 1; -} - -void Statistics::addCompressedBytes(unsigned int bytesIn, unsigned int bytesOut) -{ - transportPartial_.compressedBytesIn_ += bytesIn; - transportTotal_.compressedBytesIn_ += bytesIn; - - transportPartial_.compressedBytesOut_ += bytesOut; - transportTotal_.compressedBytesOut_ += bytesOut; - - double ratio = bytesIn / bytesOut; - - if (ratio < 1) - { - ratio = 1; - } - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! Old ratio was " - << proxyData_.streamRatio_ << " current is " - << (double) ratio << " new ratio is " << (double) - ((proxyData_.streamRatio_ * 2) + ratio) / 3 << ".\n" - << logofs_flush; - #endif - - proxyData_.streamRatio_ = ((proxyData_.streamRatio_ * 2) + ratio) / 3; - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! Updated compressed bytes " - << "with " << bytesIn << " in " << bytesOut << " out " - << "and ratio " << (double) proxyData_.streamRatio_ - << ".\n" << logofs_flush; - #endif -} - -// -// Recalculate the current bitrate. The bytes written -// are accounted at the time the transport actually -// writes the data to the network, not at the time it -// receives the data from the upper layers. The reason -// is that data can be compressed by the stream com- -// pressor, so we can become aware of the new bitrate -// only afer having flushed the ZLIB stream. This also -// means that, to have a reliable estimate, we need to -// flush the link often. -// - -void Statistics::updateBitrate(int bytes) -{ - T_timestamp thisFrameTs = getNewTimestamp(); - - int diffFramesInMs = diffTimestamp(startFrameTs_, thisFrameTs); - - #ifdef DEBUG - *logofs << "Statistics: Difference since previous timestamp is " - << diffFramesInMs << " Ms.\n" << logofs_flush; - #endif - - if (diffFramesInMs > 0) - { - #ifdef DEBUG - *logofs << "Statistics: Removing " << diffFramesInMs - << " Ms in short and long time frame.\n" - << logofs_flush; - #endif - - int shortBytesToRemove = (int) (((double) bytesInShortFrame_ * (double) diffFramesInMs) / - (double) control -> ShortBitrateTimeFrame); - - int longBytesToRemove = (int) (((double) bytesInLongFrame_ * (double) diffFramesInMs) / - (double) control -> LongBitrateTimeFrame); - - #ifdef DEBUG - *logofs << "Statistics: Removing " << shortBytesToRemove - << " bytes from " << bytesInShortFrame_ - << " in the short frame.\n" << logofs_flush; - #endif - - bytesInShortFrame_ -= shortBytesToRemove; - - if (bytesInShortFrame_ < 0) - { - #ifdef TEST - *logofs << "Statistics: Bytes in short frame are " - << bytesInShortFrame_ << ". Set to 0.\n" - << logofs_flush; - #endif - - bytesInShortFrame_ = 0; - } - - #ifdef DEBUG - *logofs << "Statistics: Removing " << longBytesToRemove - << " bytes from " << bytesInLongFrame_ - << " in the long frame.\n" << logofs_flush; - #endif - - bytesInLongFrame_ -= longBytesToRemove; - - if (bytesInLongFrame_ < 0) - { - #ifdef TEST - *logofs << "Statistics: Bytes in long frame are " - << bytesInLongFrame_ << ". Set to 0.\n" - << logofs_flush; - #endif - - bytesInLongFrame_ = 0; - } - - int diffStartInMs; - - diffStartInMs = diffTimestamp(thisFrameTs, startShortFrameTs_); - - if (diffStartInMs > control -> ShortBitrateTimeFrame) - { - addMsTimestamp(startShortFrameTs_, diffStartInMs); - } - - diffStartInMs = diffTimestamp(thisFrameTs, startLongFrameTs_); - - if (diffStartInMs > control -> LongBitrateTimeFrame) - { - addMsTimestamp(startLongFrameTs_, diffStartInMs); - } - - startFrameTs_ = thisFrameTs; - } - - #ifdef DEBUG - *logofs << "Statistics: Adding " << bytes << " bytes to " - << bytesInShortFrame_ << " in the short frame.\n" - << logofs_flush; - #endif - - bytesInShortFrame_ = bytesInShortFrame_ + bytes; - - #ifdef DEBUG - *logofs << "Statistics: Adding " << bytes << " bytes to " - << bytesInLongFrame_ << " in the long frame.\n" - << logofs_flush; - #endif - - bytesInLongFrame_ = bytesInLongFrame_ + bytes; - - bitrateInShortFrame_ = (int) ((double) bytesInShortFrame_ / - ((double) control -> ShortBitrateTimeFrame / 1000)); - - bitrateInLongFrame_ = (int) ((double) bytesInLongFrame_ / - ((double) control -> LongBitrateTimeFrame / 1000)); - - if (bitrateInShortFrame_ > topBitrate_) - { - topBitrate_ = bitrateInShortFrame_; - } - - #ifdef TEST - *logofs << "Statistics: Current bitrate is short " << bitrateInShortFrame_ - << " long " << bitrateInLongFrame_ << " top " << topBitrate_ - << ".\n" << logofs_flush; - #endif -} - -void Statistics::updateCongestion(int remaining, int limit) -{ - #ifdef TEST - *logofs << "Statistics: Updating the congestion " - << "counters at " << strMsTimestamp() - << ".\n" << logofs_flush; - #endif - - double current = remaining; - - if (current < 0) - { - current = 0; - } - - current = 9 * (limit - current) / limit; - - #ifdef TEST - *logofs << "Statistics: Current congestion is " - << current << " with " << limit << " tokens " - << "and " << remaining << " remaining.\n" - << logofs_flush; - #endif - - // - // If the current congestion counter is greater - // than the previous, take the current value, - // otherwise ramp down the value by calculating - // the average of the last 8 updates. - // - - #ifdef TEST - *logofs << "Statistics: Old congestion was " - << congestionInFrame_; - #endif - - if (current >= congestionInFrame_) - { - congestionInFrame_ = current; - } - else - { - congestionInFrame_ = ((congestionInFrame_ * 7) + current) / 8; - } - - #ifdef TEST - *logofs << " new congestion is " - << ((congestionInFrame_ * 7) + current) / 8 - << ".\n" << logofs_flush; - #endif - - // - // Call the function with 0 bytes flushed - // so the agent can update its congestion - // counter. - // - - FlushCallback(0); -} - -int Statistics::getClientCacheStats(int type, char *&buffer) -{ - if (type != PARTIAL_STATS && type != TOTAL_STATS) - { - #ifdef PANIC - *logofs << "Statistics: PANIC! Cannot produce statistics " - << "with qualifier '" << type << "'.\n" - << logofs_flush; - #endif - - return -1; - } - - // - // Print message cache data according - // to local and remote view. - // - - MessageStore *currentStore = NULL; - MessageStore *anyStore = NULL; - - char format[FORMAT_LENGTH]; - - strcat(buffer, "\nNX Cache Statistics\n"); - strcat(buffer, "-------------------\n\n"); - - for (int m = proxy_client; m <= proxy_server; m++) - { - if (m == proxy_client) - { - strcat(buffer, "Request\tCached\tSize at Server\t\tSize at Client\t\tCache limit\n"); - strcat(buffer, "-------\t------\t--------------\t\t--------------\t\t-----------\n"); - } - else - { - strcat(buffer, "\nReply\tCached\tSize at Server\t\tSize at Client\t\tCache limit\n"); - strcat(buffer, "-----\t------\t--------------\t\t--------------\t\t-----------\n"); - } - - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - if (m == proxy_client) - { - currentStore = proxy_ -> getClientStore() -> getRequestStore(i); - } - else - { - currentStore = proxy_ -> getServerStore() -> getReplyStore(i); - } - - if (currentStore != NULL && - (currentStore -> getLocalStorageSize() || - currentStore -> getRemoteStorageSize())) - { - anyStore = currentStore; - - sprintf(format, "#%d\t%d\t", i, currentStore -> getSize()); - - strcat(buffer, format); - - sprintf(format, "%d (%.0f KB)\t\t", currentStore -> getLocalStorageSize(), - ((double) currentStore -> getLocalStorageSize()) / 1024); - - strcat(buffer, format); - - sprintf(format, "%d (%.0f KB)\t\t", currentStore -> getRemoteStorageSize(), - ((double) currentStore -> getRemoteStorageSize()) / 1024); - - strcat(buffer, format); - - sprintf(format, "%d/%.0f KB\n", currentStore -> cacheSlots, - ((double) control -> getUpperStorageSize() / 100 * - currentStore -> cacheThreshold) / 1024); - - strcat(buffer, format); - } - } - - if (anyStore == NULL) - { - strcat(buffer, "N/A\n"); - } - } - - if (anyStore != NULL) - { - sprintf(format, "\ncache: %d bytes (%d KB) available at server.\n", - control -> ClientTotalStorageSize, - control -> ClientTotalStorageSize / 1024); - - strcat(buffer, format); - - sprintf(format, " %d bytes (%d KB) available at client.\n\n", - control -> ServerTotalStorageSize, - control -> ServerTotalStorageSize / 1024); - - strcat(buffer, format); - - sprintf(format, " %d bytes (%d KB) allocated at server.\n", - anyStore -> getLocalTotalStorageSize(), - anyStore -> getLocalTotalStorageSize() / 1024); - - strcat(buffer, format); - - sprintf(format, " %d bytes (%d KB) allocated at client.\n\n\n", - anyStore -> getRemoteTotalStorageSize(), - anyStore -> getRemoteTotalStorageSize() / 1024); - - strcat(buffer, format); - } - else - { - strcat(buffer, "\ncache: N/A\n\n"); - } - - return 1; -} - -int Statistics::getClientProtocolStats(int type, char *&buffer) -{ - if (type != PARTIAL_STATS && type != TOTAL_STATS) - { - #ifdef PANIC - *logofs << "Statistics: PANIC! Cannot produce statistics " - << "with qualifier '" << type << "'.\n" - << logofs_flush; - #endif - - return -1; - } - - struct T_transportData *transportData; - struct T_protocolData *protocolData; - struct T_overallData *overallData; - - if (type == PARTIAL_STATS) - { - transportData = &transportPartial_; - protocolData = &protocolPartial_; - overallData = &overallPartial_; - } - else - { - transportData = &transportTotal_; - protocolData = &protocolTotal_; - overallData = &overallTotal_; - } - - char format[FORMAT_LENGTH]; - - double countRequestIn = 0; - double countCachedRequestIn = 0; - double countRepliedRequestIn = 0; - - double countRequestBitsIn = 0; - double countRequestBitsOut = 0; - - double countAnyIn = 0; - double countBitsIn = 0; - double countBitsOut = 0; - - // - // Print request data. - // - - strcat(buffer, "NX Server Side Protocol Statistics\n"); - strcat(buffer, "----------------------------------\n\n"); - - // - // Print render data. - // - - strcat(buffer, "Render Total\tCached\tBits In\t\tBits Out\tBits/Request\t\tRatio\n"); - strcat(buffer, "------- -----\t------\t-------\t\t--------\t------------\t\t-----\n"); - - for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) - { - if (protocolData -> renderRequestCount_[i]) - { - sprintf(format, "#%d ", i); - - while (strlen(format) < 8) - { - strcat(format, " "); - } - - strcat(buffer, format); - - if (protocolData -> renderRequestCached_[i] > 0) - { - sprintf(format, "%.0f\t%.0f", protocolData -> renderRequestCount_[i], - protocolData -> renderRequestCached_[i]); - } - else - { - sprintf(format, "%.0f\t", protocolData -> renderRequestCount_[i]); - } - - strcat(buffer, format); - - sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", - protocolData -> renderRequestBitsIn_[i], protocolData -> renderRequestBitsIn_[i] / 8192, - protocolData -> renderRequestBitsOut_[i], protocolData -> renderRequestBitsOut_[i] / 8192, - protocolData -> renderRequestBitsIn_[i] / protocolData -> renderRequestCount_[i], - protocolData -> renderRequestBitsOut_[i] / protocolData -> renderRequestCount_[i]); - - strcat(buffer, format); - - if (protocolData -> renderRequestBitsOut_[i] > 0) - { - sprintf(format, "%5.3f:1\n", protocolData -> renderRequestBitsIn_[i] / - protocolData -> renderRequestBitsOut_[i]); - - strcat(buffer, format); - } - else - { - strcat(buffer, "1:1\n"); - } - } - - countRequestIn += protocolData -> renderRequestCount_[i]; - countCachedRequestIn += protocolData -> renderRequestCached_[i]; - - countRequestBitsIn += protocolData -> renderRequestBitsIn_[i]; - countRequestBitsOut += protocolData -> renderRequestBitsOut_[i]; - - countAnyIn += protocolData -> renderRequestCount_[i]; - countBitsIn += protocolData -> renderRequestBitsIn_[i]; - countBitsOut += protocolData -> renderRequestBitsOut_[i]; - } - - if (countRequestIn > 0) - { - if (countCachedRequestIn > 0) - { - sprintf(format, "\ntotal: %.0f\t%.0f", countRequestIn, countCachedRequestIn); - } - else - { - sprintf(format, "\ntotal: %.0f\t", countRequestIn); - } - - strcat(buffer, format); - - sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", - countRequestBitsIn, countRequestBitsIn / 8192, countRequestBitsOut, - countRequestBitsOut / 8192, countRequestBitsIn / countRequestIn, - countRequestBitsOut / countRequestIn); - - strcat(buffer, format); - - if (countRequestBitsOut > 0) - { - sprintf(format, "%5.3f:1\n", countRequestBitsIn / countRequestBitsOut); - } - else - { - sprintf(format, "1:1\n"); - } - - strcat(buffer, format); - } - else - { - strcat(buffer, "N/A\n\n"); - } - - countRequestIn = 0; - countCachedRequestIn = 0; - - countRequestBitsIn = 0; - countRequestBitsOut = 0; - - countAnyIn = 0; - countBitsIn = 0; - countBitsOut = 0; - - // - // Print other requests' data. - // - - strcat(buffer, "\nRequest Total\tCached\tBits In\t\tBits Out\tBits/Request\t\tRatio\n"); - strcat(buffer, "------- -----\t------\t-------\t\t--------\t------------\t\t-----\n"); - - for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) - { - if (protocolData -> requestCount_[i]) - { - sprintf(format, "#%d ", i); - - while (strlen(format) < 5) - { - strcat(format, " "); - } - - // - // Mark NX agent-related requests, those - // having a reply and finally those that - // have been probably tainted by client - // side. - // - - if (i >= X_NXFirstOpcode && i <= X_NXLastOpcode) - { - strcat(format, "A"); - } - - if (i != X_NXInternalGenericReply && protocolData -> requestReplied_[i] > 0) - { - strcat(format, "R"); - } - - if (i == X_NoOperation && control -> TaintReplies) - { - strcat(format, "T"); - } - - while (strlen(format) < 8) - { - strcat(format, " "); - } - - strcat(buffer, format); - - if (protocolData -> requestCached_[i] > 0) - { - sprintf(format, "%.0f\t%.0f", protocolData -> requestCount_[i], - protocolData -> requestCached_[i]); - } - else - { - sprintf(format, "%.0f\t", protocolData -> requestCount_[i]); - } - - strcat(buffer, format); - - sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", - protocolData -> requestBitsIn_[i], protocolData -> requestBitsIn_[i] / 8192, - protocolData -> requestBitsOut_[i], protocolData -> requestBitsOut_[i] / 8192, - protocolData -> requestBitsIn_[i] / protocolData -> requestCount_[i], - protocolData -> requestBitsOut_[i] / protocolData -> requestCount_[i]); - - strcat(buffer, format); - - if (protocolData -> requestBitsOut_[i] > 0) - { - sprintf(format, "%5.3f:1\n", protocolData -> requestBitsIn_[i] / - protocolData -> requestBitsOut_[i]); - - strcat(buffer, format); - } - else - { - strcat(buffer, "1:1\n"); - } - } - - countRequestIn += protocolData -> requestCount_[i]; - countCachedRequestIn += protocolData -> requestCached_[i]; - countRepliedRequestIn += protocolData -> requestReplied_[i]; - - countRequestBitsIn += protocolData -> requestBitsIn_[i]; - countRequestBitsOut += protocolData -> requestBitsOut_[i]; - - countAnyIn += protocolData -> requestCount_[i]; - countBitsIn += protocolData -> requestBitsIn_[i]; - countBitsOut += protocolData -> requestBitsOut_[i]; - } - - if (countRequestIn > 0) - { - if (countCachedRequestIn > 0) - { - sprintf(format, "\ntotal: %.0f\t%.0f", countRequestIn, countCachedRequestIn); - } - else - { - sprintf(format, "\ntotal: %.0f\t", countRequestIn); - } - - strcat(buffer, format); - - sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", - countRequestBitsIn, countRequestBitsIn / 8192, countRequestBitsOut, - countRequestBitsOut / 8192, countRequestBitsIn / countRequestIn, - countRequestBitsOut / countRequestIn); - - strcat(buffer, format); - - if (countRequestBitsOut > 0) - { - sprintf(format, "%5.3f:1\n", countRequestBitsIn / countRequestBitsOut); - } - else - { - sprintf(format, "1:1\n"); - } - - strcat(buffer, format); - } - else - { - strcat(buffer, "N/A\n\n"); - } - - // - // Print transport data. - // - - getTimeStats(type, buffer); - - countAnyIn += protocolData -> cupsCount_; - countBitsIn += protocolData -> cupsBitsIn_; - countBitsOut += protocolData -> cupsBitsOut_; - - countAnyIn += protocolData -> smbCount_; - countBitsIn += protocolData -> smbBitsIn_; - countBitsOut += protocolData -> smbBitsOut_; - - countAnyIn += protocolData -> mediaCount_; - countBitsIn += protocolData -> mediaBitsIn_; - countBitsOut += protocolData -> mediaBitsOut_; - - countAnyIn += protocolData -> httpCount_; - countBitsIn += protocolData -> httpBitsIn_; - countBitsOut += protocolData -> httpBitsOut_; - - countAnyIn += protocolData -> fontCount_; - countBitsIn += protocolData -> fontBitsIn_; - countBitsOut += protocolData -> fontBitsOut_; - - countAnyIn += protocolData -> slaveCount_; - countBitsIn += protocolData -> slaveBitsIn_; - countBitsOut += protocolData -> slaveBitsOut_; - - // - // Save the overall amount of bytes - // coming from X clients. - // - - overallData -> overallBytesIn_ = countBitsIn / 8; - - // - // Print performance data. - // - - if (transportData -> readTime_ > 0) - { - sprintf(format, " %.0f messages (%.0f KB) encoded per second.\n\n", - countAnyIn / (transportData -> readTime_ / 1000), - (countBitsIn + transportData -> framingBitsOut_) / 8192 / - (transportData -> readTime_ / 1000)); - } - else - { - sprintf(format, " %.0f messages (%.0f KB) encoded per second.\n\n", - countAnyIn, (countBitsIn + transportData -> - framingBitsOut_) / 8192); - } - - strcat(buffer, format); - - strcat(buffer, "link: "); - - // - // ZLIB compression stats. - // - - getStreamStats(type, buffer); - - // - // Save the overall amount of bytes - // sent on NX proxy link. - // - - if (transportData -> compressedBytesOut_ > 0) - { - overallData -> overallBytesOut_ = transportData -> compressedBytesOut_; - } - else - { - overallData -> overallBytesOut_ = countBitsOut / 8; - } - - // - // Print info on multiplexing overhead. - // - - getFramingStats(type, buffer); - - // - // Print stats about additional channels. - // - - getServicesStats(type, buffer); - - // - // Compression summary. - // - - double ratio = 1; - - if (transportData -> compressedBytesOut_ / 1024 > 0) - { - ratio = ((countBitsIn + transportData -> framingBitsOut_) / 8192) / - (transportData -> compressedBytesOut_ / 1024); - - } - else if (countBitsOut > 0) - { - ratio = (countBitsIn + transportData -> framingBitsOut_) / - countBitsOut; - } - - sprintf(format, " Protocol compression ratio is %5.3f:1.\n\n", - ratio); - - strcat(buffer, format); - - getBitrateStats(type, buffer); - - getSplitStats(type, buffer); - - sprintf(format, " %.0f total handled replies (%.0f unmatched).\n\n\n", - countRepliedRequestIn, protocolData -> requestReplied_[X_NXInternalGenericReply]); - - strcat(buffer, format); - - return 1; -} - -int Statistics::getClientOverallStats(int type, char *&buffer) -{ - if (type != PARTIAL_STATS && type != TOTAL_STATS) - { - #ifdef PANIC - *logofs << "Statistics: PANIC! Cannot produce statistics " - << "with qualifier '" << type << "'.\n" - << logofs_flush; - #endif - - return -1; - } - - struct T_overallData *overallData; - struct T_packedData *packedData; - - if (type == PARTIAL_STATS) - { - overallData = &overallPartial_; - packedData = &packedPartial_; - } - else - { - overallData = &overallTotal_; - packedData = &packedTotal_; - } - - char format[FORMAT_LENGTH]; - - // - // Print header including link type, - // followed by info on packed images. - // - - strcat(buffer, "NX Compression Summary\n"); - strcat(buffer, "----------------------\n\n"); - - char label[FORMAT_LENGTH]; - - switch (control -> LinkMode) - { - case LINK_TYPE_NONE: - { - strcpy(label, "NONE"); - - break; - } - case LINK_TYPE_MODEM: - { - strcpy(label, "MODEM"); - - break; - } - case LINK_TYPE_ISDN: - { - strcpy(label, "ISDN"); - - break; - } - case LINK_TYPE_ADSL: - { - strcpy(label, "ADSL"); - - break; - } - case LINK_TYPE_WAN: - { - strcpy(label, "WAN"); - - break; - } - case LINK_TYPE_LAN: - { - strcpy(label, "LAN"); - - break; - } - default: - { - strcpy(label, "Unknown"); - - break; - } - } - - sprintf(format, "link: %s", label); - - if (control -> LocalDeltaCompression == 1) - { - strcat(format, " with protocol compression enabled."); - } - else - { - strcat(format, " with protocol compression disabled."); - } - - strcat(format, "\n\n"); - - strcat(buffer, format); - - if (packedData -> packedBytesIn_ > 0) - { - sprintf(format, "images: %.0f bytes (%.0f KB) packed to %.0f (%.0f KB).\n\n", - packedData -> packedBytesOut_, packedData -> packedBytesOut_ / 1024, - packedData -> packedBytesIn_, packedData -> packedBytesIn_ / 1024); - - strcat(buffer, format); - - sprintf(format, " Images compression ratio is %5.3f:1.\n\n", - packedData -> packedBytesOut_ / packedData -> packedBytesIn_); - - strcat(buffer, format); - } - - double overallIn = overallData -> overallBytesIn_ - packedData -> packedBytesIn_ + - packedData -> packedBytesOut_; - - double overallOut = overallData -> overallBytesOut_; - - sprintf(format, "overall: %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", - overallIn, overallIn / 1024, overallOut, overallOut / 1024); - - strcat(buffer, format); - - if (overallData -> overallBytesOut_ > 0) - { - sprintf(format, " Overall NX server compression ratio is %5.3f:1.\n\n\n", - overallIn / overallOut); - } - else - { - sprintf(format, " Overall NX server compression ratio is 1:1.\n\n\n"); - } - - strcat(buffer, format); - - return 1; -} - -int Statistics::getServerCacheStats(int type, char *&buffer) -{ - if (type != PARTIAL_STATS && type != TOTAL_STATS) - { - #ifdef PANIC - *logofs << "Statistics: PANIC! Cannot produce statistics " - << "with qualifier '" << type << "'.\n" - << logofs_flush; - #endif - - return -1; - } - - // - // Print message cache data according - // to local and remote view. - // - - MessageStore *currentStore = NULL; - MessageStore *anyStore = NULL; - - char format[FORMAT_LENGTH]; - - strcat(buffer, "\nNX Cache Statistics\n"); - strcat(buffer, "-------------------\n\n"); - - for (int m = proxy_client; m <= proxy_server; m++) - { - if (m == proxy_client) - { - strcat(buffer, "Request\tCached\tSize at Server\t\tSize at Client\t\tCache limit\n"); - strcat(buffer, "-------\t------\t--------------\t\t--------------\t\t-----------\n"); - } - else - { - strcat(buffer, "\nReply\tCached\tSize at Server\t\tSize at Client\t\tCache limit\n"); - strcat(buffer, "-----\t------\t--------------\t\t--------------\t\t-----------\n"); - } - - for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) - { - if (m == proxy_client) - { - currentStore = proxy_ -> getClientStore() -> getRequestStore(i); - } - else - { - currentStore = proxy_ -> getServerStore() -> getReplyStore(i); - } - - if (currentStore != NULL && - (currentStore -> getLocalStorageSize() || - currentStore -> getRemoteStorageSize())) - { - anyStore = currentStore; - - sprintf(format, "#%d\t%d\t", i, currentStore -> getSize()); - - strcat(buffer, format); - - sprintf(format, "%d (%.0f KB)\t\t", currentStore -> getRemoteStorageSize(), - ((double) currentStore -> getRemoteStorageSize()) / 1024); - - strcat(buffer, format); - - sprintf(format, "%d (%.0f KB)\t\t", currentStore -> getLocalStorageSize(), - ((double) currentStore -> getLocalStorageSize()) / 1024); - - strcat(buffer, format); - - sprintf(format, "%d/%.0f KB\n", currentStore -> cacheSlots, - ((double) control -> getUpperStorageSize() / 100 * - currentStore -> cacheThreshold) / 1024); - - strcat(buffer, format); - } - } - - if (anyStore == NULL) - { - strcat(buffer, "N/A\n"); - } - } - - if (anyStore != NULL) - { - sprintf(format, "\ncache: %d bytes (%d KB) available at server.\n", - control -> ClientTotalStorageSize, - control -> ClientTotalStorageSize / 1024); - - strcat(buffer, format); - - sprintf(format, " %d bytes (%d KB) available at client.\n\n", - control -> ServerTotalStorageSize, - control -> ServerTotalStorageSize / 1024); - - strcat(buffer, format); - - sprintf(format, " %d bytes (%d KB) allocated at server.\n", - anyStore -> getRemoteTotalStorageSize(), - anyStore -> getRemoteTotalStorageSize() / 1024); - - strcat(buffer, format); - - sprintf(format, " %d bytes (%d KB) allocated at client.\n\n\n", - anyStore -> getLocalTotalStorageSize(), - anyStore -> getLocalTotalStorageSize() / 1024); - - strcat(buffer, format); - } - else - { - strcat(buffer, "\ncache: N/A\n\n"); - } - - return 1; -} - -int Statistics::getServerProtocolStats(int type, char *&buffer) -{ - if (type != PARTIAL_STATS && type != TOTAL_STATS) - { - #ifdef PANIC - *logofs << "Statistics: PANIC! Cannot produce statistics " - << "with qualifier '" << type << "'.\n" - << logofs_flush; - #endif - - return -1; - } - - struct T_transportData *transportData; - struct T_protocolData *protocolData; - struct T_overallData *overallData; - - if (type == PARTIAL_STATS) - { - transportData = &transportPartial_; - protocolData = &protocolPartial_; - overallData = &overallPartial_; - } - else - { - transportData = &transportTotal_; - protocolData = &protocolTotal_; - overallData = &overallTotal_; - } - - char format[FORMAT_LENGTH]; - - double countReplyBitsIn = 0; - double countReplyBitsOut = 0; - - double countReplyIn = 0; - double countCachedReplyIn = 0; - - double countEventBitsIn = 0; - double countEventBitsOut = 0; - - double countEventIn = 0; - double countCachedEventIn = 0; - - double countAnyIn = 0; - double countBitsIn = 0; - double countBitsOut = 0; - - // - // Print reply data. - // - - strcat(buffer, "NX Client Side Protocol Statistics\n"); - strcat(buffer, "----------------------------------\n\n"); - - strcat(buffer, "Reply Total\tCached\tBits In\t\tBits Out\tBits/Reply\t\tRatio\n"); - strcat(buffer, "------- -----\t------\t-------\t\t--------\t----------\t\t-----\n"); - - for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) - { - if (protocolData -> replyCount_[i]) - { - sprintf(format, "#%d ", i); - - while (strlen(format) < 5) - { - strcat(format, " "); - } - - // - // Mark replies originated - // by NX agent requests. - // - - if (i >= X_NXFirstOpcode && i <= X_NXLastOpcode) - { - strcat(format, "A"); - } - - // - // Mark replies that we didn't - // match against a request. - // - - if (i == 1) - { - strcat(format, "U"); - } - - while (strlen(format) < 8) - { - strcat(format, " "); - } - - strcat(buffer, format); - - if (protocolData -> replyCached_[i] > 0) - { - sprintf(format, "%.0f\t%.0f", protocolData -> replyCount_[i], - protocolData -> replyCached_[i]); - } - else - { - sprintf(format, "%.0f\t", protocolData -> replyCount_[i]); - } - - strcat(buffer, format); - - sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", - protocolData -> replyBitsIn_[i], protocolData -> replyBitsIn_[i] / 8192, - protocolData -> replyBitsOut_[i], protocolData -> replyBitsOut_[i] / 8192, - protocolData -> replyBitsIn_[i] / protocolData -> replyCount_[i], - protocolData -> replyBitsOut_[i] / protocolData -> replyCount_[i]); - - strcat(buffer, format); - - if (protocolData -> replyBitsOut_[i] > 0) - { - sprintf(format, "%5.3f:1\n", protocolData -> replyBitsIn_[i] / - protocolData -> replyBitsOut_[i]); - } - else - { - sprintf(format, "1:1\n"); - } - - strcat(buffer, format); - } - - countReplyIn += protocolData -> replyCount_[i]; - countCachedReplyIn += protocolData -> replyCached_[i]; - - countReplyBitsIn += protocolData -> replyBitsIn_[i]; - countReplyBitsOut += protocolData -> replyBitsOut_[i]; - - countAnyIn += protocolData -> replyCount_[i]; - countBitsIn += protocolData -> replyBitsIn_[i]; - countBitsOut += protocolData -> replyBitsOut_[i]; - } - - if (countReplyIn > 0) - { - if (countCachedReplyIn > 0) - { - sprintf(format, "\ntotal: %.0f\t%.0f", countReplyIn, countCachedReplyIn); - } - else - { - sprintf(format, "\ntotal: %.0f\t", countReplyIn); - } - - strcat(buffer, format); - - sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", - countReplyBitsIn, countReplyBitsIn / 8192, countReplyBitsOut, - countReplyBitsOut / 8192, countReplyBitsIn / countReplyIn, - countReplyBitsOut / countReplyIn); - - strcat(buffer, format); - - if (countReplyBitsOut > 0) - { - sprintf(format, "%5.3f:1\n", countReplyBitsIn / countReplyBitsOut); - } - else - { - sprintf(format, "1:1\n"); - } - - strcat(buffer, format); - } - else - { - strcat(buffer, "N/A\n"); - } - - strcat(buffer, "\n"); - - // - // Print event and error data. - // - - strcat(buffer, "Event Total\tCached\tBits In\t\tBits Out\tBits/Event\t\tRatio\n"); - strcat(buffer, "------- -----\t------\t-------\t\t--------\t----------\t\t-----\n"); - - for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) - { - if (protocolData -> eventCount_[i]) - { - sprintf(format, "#%d ", i); - - while (strlen(format) < 8) - { - strcat(format, " "); - } - - strcat(buffer, format); - - if (protocolData -> eventCached_[i] > 0) - { - sprintf(format, "%.0f\t%.0f", protocolData -> eventCount_[i], - protocolData -> eventCached_[i]); - } - else - { - sprintf(format, "%.0f\t", protocolData -> eventCount_[i]); - } - - strcat(buffer, format); - - sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", - protocolData -> eventBitsIn_[i], protocolData -> eventBitsIn_[i] / 8192, - protocolData -> eventBitsOut_[i], protocolData -> eventBitsOut_[i] / 8192, - protocolData -> eventBitsIn_[i] / protocolData -> eventCount_[i], - protocolData -> eventBitsOut_[i] / protocolData -> eventCount_[i]); - - strcat(buffer, format); - - if (protocolData -> eventBitsOut_[i] > 0) - { - sprintf(format, "%5.3f:1\n", protocolData -> eventBitsIn_[i] / - protocolData -> eventBitsOut_[i]); - } - else - { - sprintf(format, "1:1\n"); - } - - strcat(buffer, format); - } - - countEventIn += protocolData -> eventCount_[i]; - countCachedEventIn += protocolData -> eventCached_[i]; - - countEventBitsIn += protocolData -> eventBitsIn_[i]; - countEventBitsOut += protocolData -> eventBitsOut_[i]; - - countAnyIn += protocolData -> eventCount_[i]; - countBitsIn += protocolData -> eventBitsIn_[i]; - countBitsOut += protocolData -> eventBitsOut_[i]; - } - - if (countEventIn > 0) - { - if (countCachedEventIn > 0) - { - sprintf(format, "\ntotal: %.0f\t%.0f", countEventIn, countCachedEventIn); - } - else - { - sprintf(format, "\ntotal: %.0f\t", countEventIn); - } - - strcat(buffer, format); - - sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", - countEventBitsIn, countEventBitsIn / 8192, countEventBitsOut, - countEventBitsOut / 8192, countEventBitsIn / countEventIn, - countEventBitsOut / countEventIn); - - strcat(buffer, format); - - if (countEventBitsOut > 0) - { - sprintf(format, "%5.3f:1\n", countEventBitsIn / countEventBitsOut); - } - else - { - sprintf(format, "1:1\n"); - } - - strcat(buffer, format); - } - else - { - strcat(buffer, "N/A\n\n"); - } - - // - // Print transport data. - // - - getTimeStats(type, buffer); - - countAnyIn += protocolData -> cupsCount_; - countBitsIn += protocolData -> cupsBitsIn_; - countBitsOut += protocolData -> cupsBitsOut_; - - countAnyIn += protocolData -> smbCount_; - countBitsIn += protocolData -> smbBitsIn_; - countBitsOut += protocolData -> smbBitsOut_; - - countAnyIn += protocolData -> mediaCount_; - countBitsIn += protocolData -> mediaBitsIn_; - countBitsOut += protocolData -> mediaBitsOut_; - - countAnyIn += protocolData -> httpCount_; - countBitsIn += protocolData -> httpBitsIn_; - countBitsOut += protocolData -> httpBitsOut_; - - countAnyIn += protocolData -> fontCount_; - countBitsIn += protocolData -> fontBitsIn_; - countBitsOut += protocolData -> fontBitsOut_; - - countAnyIn += protocolData -> slaveCount_; - countBitsIn += protocolData -> slaveBitsIn_; - countBitsOut += protocolData -> slaveBitsOut_; - - // - // Save the overall amount of bytes - // coming from X clients. - // - - overallData -> overallBytesIn_ = countBitsIn / 8; - - // - // Print performance data. - // - - if (transportData -> readTime_ > 0) - { - sprintf(format, " %.0f messages (%.0f KB) encoded per second.\n\n", - countAnyIn / (transportData -> readTime_ / 1000), - (countBitsIn + transportData -> framingBitsOut_) / 8192 / - (transportData -> readTime_ / 1000)); - } - else - { - sprintf(format, " %.0f messages (%.0f KB) encoded per second.\n\n", - countAnyIn, (countBitsIn + transportData -> - framingBitsOut_) / 8192); - } - - strcat(buffer, format); - - strcat(buffer, "link: "); - - // - // ZLIB compression stats. - // - - getStreamStats(type, buffer); - - // - // Save the overall amount of bytes - // sent on NX proxy link. - // - - if (transportData -> compressedBytesOut_ > 0) - { - overallData -> overallBytesOut_ = transportData -> compressedBytesOut_; - } - else - { - overallData -> overallBytesOut_ = countBitsOut / 8; - } - - // - // Print info on multiplexing overhead. - // - - getFramingStats(type, buffer); - - // - // Print stats about additional channels. - // - - getServicesStats(type, buffer); - - // - // Compression summary. - // - - double ratio = 1; - - if (transportData -> compressedBytesOut_ / 1024 > 0) - { - ratio = ((countBitsIn + transportData -> framingBitsOut_) / 8192) / - (transportData -> compressedBytesOut_ / 1024); - - } - else if (countBitsOut > 0) - { - ratio = (countBitsIn + transportData -> framingBitsOut_) / - countBitsOut; - } - - sprintf(format, " Protocol compression ratio is %5.3f:1.\n\n", - ratio); - - strcat(buffer, format); - - getBitrateStats(type, buffer); - - // - // These are not included in output. - // - // getSplitStats(type, buffer); - // - - strcat(buffer, "\n"); - - // - // These statistics are not included in output. - // You can check it anyway to get the effective - // amount of bytes produced by unpack procedure. - // - // getClientOverallStats(type, buffer); - // - - return 1; -} - -int Statistics::getServerOverallStats(int type, char *&buffer) -{ - return 1; -} - -int Statistics::getTimeStats(int type, char *&buffer) -{ - struct T_transportData *transportData; - - if (type == PARTIAL_STATS) - { - transportData = &transportPartial_; - } - else - { - transportData = &transportTotal_; - } - - char format[FORMAT_LENGTH]; - - sprintf(format, "\ntime: %.0f Ms idle, %.0f Ms (%.0f Ms in read, %.0f Ms in write) running.\n\n", - transportData -> idleTime_, transportData -> readTime_, - transportData -> readTime_ - transportData -> writeTime_, - transportData -> writeTime_); - - strcat(buffer, format); - - return 1; -} - -int Statistics::getStreamStats(int type, char *&buffer) -{ - struct T_transportData *transportData; - - if (type == PARTIAL_STATS) - { - transportData = &transportPartial_; - } - else - { - transportData = &transportTotal_; - } - - char format[FORMAT_LENGTH]; - - if (transportData -> compressedBytesOut_ > 0) - { - sprintf(format, "%.0f bytes (%.0f KB) compressed to %.0f (%.0f KB).\n", - transportData -> compressedBytesIn_, transportData -> compressedBytesIn_ / 1024, - transportData -> compressedBytesOut_, transportData -> compressedBytesOut_ / 1024); - - strcat(buffer, format); - - sprintf(format, " %5.3f:1 stream compression ratio.\n\n", - transportData -> compressedBytesIn_ / transportData -> compressedBytesOut_); - - strcat(buffer, format); - } - - if (transportData -> decompressedBytesOut_ > 0) - { - if (transportData -> compressedBytesOut_ > 0) - { - strcat(buffer, " "); - } - - sprintf(format, "%.0f bytes (%.0f KB) decompressed to %.0f (%.0f KB).\n", - transportData -> decompressedBytesIn_, transportData -> decompressedBytesIn_ / 1024, - transportData -> decompressedBytesOut_, transportData -> decompressedBytesOut_ / 1024); - - strcat(buffer, format); - - sprintf(format, " %5.3f:1 stream compression ratio.\n\n", - transportData -> decompressedBytesOut_ / transportData -> decompressedBytesIn_); - - strcat(buffer, format); - } - - if (transportData -> compressedBytesOut_ > 0 || - transportData -> decompressedBytesOut_ > 0) - { - strcat(buffer, " "); - } - - return 1; -} - -int Statistics::getServicesStats(int type, char *&buffer) -{ - struct T_protocolData *protocolData; - - if (type == PARTIAL_STATS) - { - protocolData = &protocolPartial_; - } - else - { - protocolData = &protocolTotal_; - } - - char format[FORMAT_LENGTH]; - - if (protocolData -> cupsBitsOut_ > 0) - { - sprintf(format, " %.0f CUPS messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", - protocolData -> cupsCount_ , protocolData -> cupsBitsIn_ / 8, - protocolData -> cupsBitsIn_ / 8192, protocolData -> cupsBitsOut_ / 8, - protocolData -> cupsBitsOut_ / 8192); - - strcat(buffer, format); - } - - if (protocolData -> smbBitsOut_ > 0) - { - sprintf(format, " %.0f SMB messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", - protocolData -> smbCount_ , protocolData -> smbBitsIn_ / 8, - protocolData -> smbBitsIn_ / 8192, protocolData -> smbBitsOut_ / 8, - protocolData -> smbBitsOut_ / 8192); - - strcat(buffer, format); - } - - if (protocolData -> mediaBitsOut_ > 0) - { - sprintf(format, " %.0f multimedia messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", - protocolData -> mediaCount_ , protocolData -> mediaBitsIn_ / 8, - protocolData -> mediaBitsIn_ / 8192, protocolData -> mediaBitsOut_ / 8, - protocolData -> mediaBitsOut_ / 8192); - - strcat(buffer, format); - } - - if (protocolData -> httpBitsOut_ > 0) - { - sprintf(format, " %.0f HTTP messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", - protocolData -> httpCount_ , protocolData -> httpBitsIn_ / 8, - protocolData -> httpBitsIn_ / 8192, protocolData -> httpBitsOut_ / 8, - protocolData -> httpBitsOut_ / 8192); - - strcat(buffer, format); - } - - if (protocolData -> fontBitsOut_ > 0) - { - sprintf(format, " %.0f font server messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", - protocolData -> fontCount_ , protocolData -> fontBitsIn_ / 8, - protocolData -> fontBitsIn_ / 8192, protocolData -> fontBitsOut_ / 8, - protocolData -> fontBitsOut_ / 8192); - - strcat(buffer, format); - } - - if (protocolData -> slaveBitsOut_ > 0) - { - sprintf(format, " %.0f slave messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", - protocolData -> slaveCount_ , protocolData -> slaveBitsIn_ / 8, - protocolData -> slaveBitsIn_ / 8192, protocolData -> slaveBitsOut_ / 8, - protocolData -> slaveBitsOut_ / 8192); - - strcat(buffer, format); - } - - return 1; -} - -int Statistics::getFramingStats(int type, char *&buffer) -{ - struct T_transportData *transportData; - - if (type == PARTIAL_STATS) - { - transportData = &transportPartial_; - } - else - { - transportData = &transportTotal_; - } - - char format[FORMAT_LENGTH]; - - // - // Print info on multiplexing overhead. - // - - sprintf(format, "%.0f frames in, %.0f frames out, %.0f writes out.\n\n", - transportData -> proxyFramesIn_, transportData -> proxyFramesOut_, - transportData -> proxyWritesOut_); - - strcat(buffer, format); - - sprintf(format, " %.0f bytes (%.0f KB) used for framing and multiplexing.\n\n", - transportData -> framingBitsOut_ / 8, transportData -> framingBitsOut_ / 8192); - - strcat(buffer, format); - - return 1; -} - -int Statistics::getBitrateStats(int type, char *&buffer) -{ - struct T_transportData *transportData; - struct T_overallData *overallData; - - if (type == PARTIAL_STATS) - { - transportData = &transportPartial_; - overallData = &overallPartial_; - } - else - { - transportData = &transportTotal_; - overallData = &overallTotal_; - } - - double total = 0; - - if (transportData -> idleTime_ + transportData -> readTime_ > 0) - { - total = overallData -> overallBytesOut_ / - ((transportData -> idleTime_ + transportData -> readTime_) / 1000); - } - - char format[FORMAT_LENGTH]; - - sprintf(format, " %.0f B/s average, %d B/s %ds, %d B/s %ds, %d B/s maximum.\n\n", - total, getBitrateInShortFrame(), control -> ShortBitrateTimeFrame / 1000, - getBitrateInLongFrame(), control -> LongBitrateTimeFrame / 1000, - getTopBitrate()); - - strcat(buffer, format); - - resetTopBitrate(); - - return 1; -} - -int Statistics::getSplitStats(int type, char *&buffer) -{ - // - // Don't print these statistics if persistent - // cache of images is disabled. - // - - if (control -> ImageCacheEnableLoad == 0 && - control -> ImageCacheEnableSave == 0) - { - return 0; - } - - struct T_splitData *splitData; - - if (type == PARTIAL_STATS) - { - splitData = &splitPartial_; - } - else - { - splitData = &splitTotal_; - } - - char format[FORMAT_LENGTH]; - - // - // Print info on split messages restored from disk. - // - - sprintf(format, " %.0f images streamed, %.0f restored, %.0f bytes (%.0f KB) cached.\n\n", - splitData -> splitCount_, splitData -> splitAborted_, splitData -> splitAbortedBytesOut_, - splitData -> splitAbortedBytesOut_ / 1024); - - strcat(buffer, format); - - return 1; -} diff --git a/nxcomp/Statistics.h b/nxcomp/Statistics.h deleted file mode 100644 index 1ffb6b5d6..000000000 --- a/nxcomp/Statistics.h +++ /dev/null @@ -1,745 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Statistics_H -#define Statistics_H - -#include "NXproto.h" - -#include "Misc.h" -#include "Timestamp.h" - -class Proxy; - -// -// Opcode 255 is for generic requests, 1 is for -// generic replies (those which haven't a speci- -// fic differential encoding), opcode 0 is for -// generic messages from the auxiliary channels. -// - -#define STATISTICS_OPCODE_MAX 256 - -// -// Maximum length of the buffer allocated for -// the statistics output. -// - -#define STATISTICS_LENGTH 16384 - -// -// Query type. -// - -#define TOTAL_STATS 1 -#define PARTIAL_STATS 2 -#define NO_STATS 3 - -// -// Log level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Log the operations related to updating -// the control tokens. -// - -#undef TOKEN - -class Statistics -{ - public: - - // - // Use the proxy class to get access - // to the message stores. - // - - Statistics(Proxy *proxy); - - ~Statistics(); - - void addIdleTime(unsigned int numMs) - { - transportPartial_.idleTime_ += numMs; - transportTotal_.idleTime_ += numMs; - } - - void subIdleTime(unsigned int numMs) - { - transportPartial_.idleTime_ -= numMs; - transportTotal_.idleTime_ -= numMs; - } - - void addReadTime(unsigned int numMs) - { - transportPartial_.readTime_ += numMs; - transportTotal_.readTime_ += numMs; - } - - void subReadTime(unsigned int numMs) - { - transportPartial_.readTime_ -= numMs; - transportTotal_.readTime_ -= numMs; - } - - void addWriteTime(unsigned int numMs) - { - transportPartial_.writeTime_ += numMs; - transportTotal_.writeTime_ += numMs; - } - - void subWriteTime(unsigned int numMs) - { - transportPartial_.writeTime_ -= numMs; - transportTotal_.writeTime_ -= numMs; - } - - void addBytesIn(unsigned int numBytes) - { - transportPartial_.proxyBytesIn_ += numBytes; - transportTotal_.proxyBytesIn_ += numBytes; - } - - double getBytesIn() - { - return transportTotal_.proxyBytesIn_; - } - - void addBytesOut(unsigned int numBytes) - { - transportPartial_.proxyBytesOut_ += numBytes; - transportTotal_.proxyBytesOut_ += numBytes; - } - - double getBytesOut() - { - return transportTotal_.proxyBytesOut_; - } - - void addFrameIn() - { - transportPartial_.proxyFramesIn_++; - transportTotal_.proxyFramesIn_++; - - #ifdef TEST - *logofs << "Statistics: Updated total proxy frames in to " - << transportTotal_.proxyFramesIn_ << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - } - - void addFrameOut() - { - transportPartial_.proxyFramesOut_++; - transportTotal_.proxyFramesOut_++; - - #ifdef TEST - *logofs << "Statistics: Updated total proxy frames out to " - << transportTotal_.proxyFramesOut_ << " at " - << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - } - - void addWriteOut() - { - transportPartial_.proxyWritesOut_++; - transportTotal_.proxyWritesOut_++; - - #ifdef TEST - *logofs << "Statistics: Updated total proxy writes out to " - << transportTotal_.proxyWritesOut_ << " at " - << strMsTimestamp() << ".\n" << logofs_flush; - #endif - } - - void addCompressedBytes(unsigned int bytesIn, unsigned int bytesOut); - - void addDecompressedBytes(unsigned int bytesIn, unsigned int bytesOut) - { - transportPartial_.decompressedBytesIn_ += bytesIn; - transportTotal_.decompressedBytesIn_ += bytesIn; - - transportPartial_.decompressedBytesOut_ += bytesOut; - transportTotal_.decompressedBytesOut_ += bytesOut; - } - - void addFramingBits(unsigned int bitsOut) - { - transportPartial_.framingBitsOut_ += bitsOut; - transportTotal_.framingBitsOut_ += bitsOut; - - proxyData_.protocolCount_ += bitsOut; - } - - void addCachedRequest(unsigned int opcode) - { - protocolPartial_.requestCached_[opcode]++; - protocolTotal_.requestCached_[opcode]++; - } - - void addRenderCachedRequest(unsigned int opcode) - { - protocolPartial_.renderRequestCached_[opcode]++; - protocolTotal_.renderRequestCached_[opcode]++; - } - - void addRepliedRequest(unsigned int opcode) - { - protocolPartial_.requestReplied_[opcode]++; - protocolTotal_.requestReplied_[opcode]++; - } - - void addCachedReply(unsigned int opcode) - { - protocolPartial_.replyCached_[opcode]++; - protocolTotal_.replyCached_[opcode]++; - } - - void addRequestBits(unsigned int opcode, unsigned int bitsIn, unsigned int bitsOut) - { - #ifdef DEBUG - *logofs << "Statistcs: Added " << bitsIn << " bits in and " - << bitsOut << " bits out to opcode " << opcode - << ".\n" << logofs_flush; - #endif - - protocolPartial_.requestCount_[opcode]++; - protocolTotal_.requestCount_[opcode]++; - - protocolPartial_.requestBitsIn_[opcode] += bitsIn; - protocolTotal_.requestBitsIn_[opcode] += bitsIn; - - protocolPartial_.requestBitsOut_[opcode] += bitsOut; - protocolTotal_.requestBitsOut_[opcode] += bitsOut; - - // - // Don't account the split bits - // to the control token. - // - - if (opcode != X_NXSplitData && opcode != X_NXSplitEvent) - { - proxyData_.protocolCount_ += bitsOut; - } - } - - void addRenderRequestBits(unsigned int opcode, unsigned int bitsIn, unsigned int bitsOut) - { - #ifdef DEBUG - *logofs << "Statistcs: Added " << bitsIn << " bits in and " - << bitsOut << " bits out to render opcode " << opcode - << ".\n" << logofs_flush; - #endif - - protocolPartial_.renderRequestCount_[opcode]++; - protocolTotal_.renderRequestCount_[opcode]++; - - protocolPartial_.renderRequestBitsIn_[opcode] += bitsIn; - protocolTotal_.renderRequestBitsIn_[opcode] += bitsIn; - - protocolPartial_.renderRequestBitsOut_[opcode] += bitsOut; - protocolTotal_.renderRequestBitsOut_[opcode] += bitsOut; - } - - void addReplyBits(unsigned int opcode, unsigned int bitsIn, unsigned int bitsOut) - { - protocolPartial_.replyCount_[opcode]++; - protocolTotal_.replyCount_[opcode]++; - - protocolPartial_.replyBitsIn_[opcode] += bitsIn; - protocolTotal_.replyBitsIn_[opcode] += bitsIn; - - protocolPartial_.replyBitsOut_[opcode] += bitsOut; - protocolTotal_.replyBitsOut_[opcode] += bitsOut; - - proxyData_.protocolCount_ += bitsOut; - } - - void addEventBits(unsigned int opcode, unsigned int bitsIn, unsigned int bitsOut) - { - protocolPartial_.eventCount_[opcode]++; - protocolTotal_.eventCount_[opcode]++; - - protocolPartial_.eventBitsIn_[opcode] += bitsIn; - protocolTotal_.eventBitsIn_[opcode] += bitsIn; - - protocolPartial_.eventBitsOut_[opcode] += bitsOut; - protocolTotal_.eventBitsOut_[opcode] += bitsOut; - - proxyData_.protocolCount_ += bitsOut; - } - - void addCupsBits(unsigned int bitsIn, unsigned int bitsOut) - { - protocolPartial_.cupsCount_++; - protocolTotal_.cupsCount_++; - - protocolPartial_.cupsBitsIn_ += bitsIn; - protocolTotal_.cupsBitsIn_ += bitsIn; - - protocolPartial_.cupsBitsOut_ += bitsOut; - protocolTotal_.cupsBitsOut_ += bitsOut; - } - - void addSmbBits(unsigned int bitsIn, unsigned int bitsOut) - { - protocolPartial_.smbCount_++; - protocolTotal_.smbCount_++; - - protocolPartial_.smbBitsIn_ += bitsIn; - protocolTotal_.smbBitsIn_ += bitsIn; - - protocolPartial_.smbBitsOut_ += bitsOut; - protocolTotal_.smbBitsOut_ += bitsOut; - } - - void addMediaBits(unsigned int bitsIn, unsigned int bitsOut) - { - protocolPartial_.mediaCount_++; - protocolTotal_.mediaCount_++; - - protocolPartial_.mediaBitsIn_ += bitsIn; - protocolTotal_.mediaBitsIn_ += bitsIn; - - protocolPartial_.mediaBitsOut_ += bitsOut; - protocolTotal_.mediaBitsOut_ += bitsOut; - } - - void addHttpBits(unsigned int bitsIn, unsigned int bitsOut) - { - protocolPartial_.httpCount_++; - protocolTotal_.httpCount_++; - - protocolPartial_.httpBitsIn_ += bitsIn; - protocolTotal_.httpBitsIn_ += bitsIn; - - protocolPartial_.httpBitsOut_ += bitsOut; - protocolTotal_.httpBitsOut_ += bitsOut; - } - - void addFontBits(unsigned int bitsIn, unsigned int bitsOut) - { - protocolPartial_.fontCount_++; - protocolTotal_.fontCount_++; - - protocolPartial_.fontBitsIn_ += bitsIn; - protocolTotal_.fontBitsIn_ += bitsIn; - - protocolPartial_.fontBitsOut_ += bitsOut; - protocolTotal_.fontBitsOut_ += bitsOut; - } - - void addSlaveBits(unsigned int bitsIn, unsigned int bitsOut) - { - protocolPartial_.slaveCount_++; - protocolTotal_.slaveCount_++; - - protocolPartial_.slaveBitsIn_ += bitsIn; - protocolTotal_.slaveBitsIn_ += bitsIn; - - protocolPartial_.slaveBitsOut_ += bitsOut; - protocolTotal_.slaveBitsOut_ += bitsOut; - } - - void addPackedBytesIn(unsigned int numBytes) - { - packedPartial_.packedBytesIn_ += numBytes; - packedTotal_.packedBytesIn_ += numBytes; - } - - void addPackedBytesOut(unsigned int numBytes) - { - packedPartial_.packedBytesOut_ += numBytes; - packedTotal_.packedBytesOut_ += numBytes; - } - - void addSplit() - { - splitPartial_.splitCount_++; - splitTotal_.splitCount_++; - } - - void addSplitAborted() - { - splitPartial_.splitAborted_++; - splitTotal_.splitAborted_++; - } - - void addSplitAbortedBytesOut(unsigned int numBytes) - { - splitPartial_.splitAbortedBytesOut_ += numBytes; - splitTotal_.splitAbortedBytesOut_ += numBytes; - } - - // - // Add the recorded protocol data to the proxy - // token counters. We want to send bpth the token - // request message and the data payload using a - // single system write, so we must guess how many - // output bytes we will generate. - // - - void updateControlToken(int &count) - { - // - // Total is the total number of protocol bytes - // generated so far. We have saved the number - // of bytes generated the last time the function - // was called so we can calculate the difference. - // - // The number of protocol bits is updated as soon - // as new bits are accumulated, to avoid summing - // up all the opcodes in this routine. We add a - // byte to the control bytes difference to account - // for the framing bits that are very likely to - // be added to the payload. - // - - double total = proxyData_.protocolCount_ / 8; - - double diff = total - proxyData_.controlCount_ + 1; - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! Protocol bytes are " - << total << " control bytes are " - << proxyData_.controlCount_ << " difference is " - << diff << ".\n" << logofs_flush; - #endif - - count += (int) (diff / proxyData_.streamRatio_); - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! Adding " - << (int) (diff / proxyData_.streamRatio_) - << " bytes to the control token with ratio " - << proxyData_.streamRatio_ << ".\n" - << logofs_flush; - #endif - - proxyData_.controlCount_ = total; - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! New control token has " - << count << " bytes with total control bytes " - << proxyData_.controlCount_ << ".\n" - << logofs_flush; - #endif - } - - void updateSplitToken(int &count) - { - double total = (protocolTotal_.requestBitsOut_[X_NXSplitData] + - protocolTotal_.eventBitsOut_[X_NXSplitEvent]) / 8; - - double diff = total - proxyData_.splitCount_; - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! Protocol bytes are " - << total << " split bytes are " - << proxyData_.splitCount_ << " difference is " - << diff << ".\n" << logofs_flush; - #endif - - count += (int) (diff / proxyData_.streamRatio_); - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! Adding " - << (int) (diff / proxyData_.streamRatio_) - << " bytes to the split token with ratio " - << proxyData_.streamRatio_ << ".\n" - << logofs_flush; - #endif - - proxyData_.splitCount_ = total; - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! New split token has " - << count << " bytes with total split bytes " - << proxyData_.splitCount_ << ".\n" - << logofs_flush; - #endif - } - - void updateDataToken(int &count) - { - double total = (protocolTotal_.cupsBitsOut_ + - protocolTotal_.smbBitsOut_ + - protocolTotal_.mediaBitsOut_ + - protocolTotal_.httpBitsOut_ + - protocolTotal_.fontBitsOut_ + - protocolTotal_.slaveBitsOut_) / 8; - - double diff = total - proxyData_.dataCount_; - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! Protocol bytes are " - << total << " data bytes are " - << proxyData_.dataCount_ << " difference is " - << diff << ".\n" << logofs_flush; - #endif - - count += (int) (diff / proxyData_.streamRatio_); - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! Adding " - << (int) (diff / proxyData_.streamRatio_) - << " bytes to the data token with ratio " - << proxyData_.streamRatio_ << ".\n" - << logofs_flush; - #endif - - proxyData_.dataCount_ = total; - - #if defined(TEST) || defined(TOKEN) - *logofs << "Statistics: TOKEN! New data token has " - << count << " bytes with total data bytes " - << proxyData_.dataCount_ << ".\n" - << logofs_flush; - #endif - } - - // - // Update the current bitrate. - // - - void updateBitrate(int bytes); - - // - // Return the current bitrate. - // - - int getBitrateInShortFrame() - { - return bitrateInShortFrame_; - } - - int getBitrateInLongFrame() - { - return bitrateInLongFrame_; - } - - int getTopBitrate() - { - return topBitrate_; - } - - void resetTopBitrate() - { - topBitrate_ = 0; - } - - double getStreamRatio() - { - return proxyData_.streamRatio_; - } - - // - // Manage the congestion level. - // - - void updateCongestion(int remaining, int limit); - - double getCongestionInFrame() - { - return congestionInFrame_; - } - - // - // Produce a dump of the statistics on - // the provided buffer. - // - - int getClientCacheStats(int type, char *&buffer); - int getClientProtocolStats(int type, char *&buffer); - int getClientOverallStats(int type, char *&buffer); - - int getServerCacheStats(int type, char *&buffer); - int getServerProtocolStats(int type, char *&buffer); - int getServerOverallStats(int type, char *&buffer); - - int resetPartialStats(); - - private: - - int getTimeStats(int type, char *&buffer); - int getServicesStats(int type, char *&buffer); - int getFramingStats(int type, char *&buffer); - int getBitrateStats(int type, char *&buffer); - int getStreamStats(int type, char *&buffer); - int getSplitStats(int type, char *&buffer); - - struct T_protocolData - { - double requestCached_[STATISTICS_OPCODE_MAX]; - double requestReplied_[STATISTICS_OPCODE_MAX]; - double requestCount_[STATISTICS_OPCODE_MAX]; - double requestBitsIn_[STATISTICS_OPCODE_MAX]; - double requestBitsOut_[STATISTICS_OPCODE_MAX]; - - double renderRequestCached_[STATISTICS_OPCODE_MAX]; - double renderRequestCount_[STATISTICS_OPCODE_MAX]; - double renderRequestBitsIn_[STATISTICS_OPCODE_MAX]; - double renderRequestBitsOut_[STATISTICS_OPCODE_MAX]; - - double replyCached_[STATISTICS_OPCODE_MAX]; - double replyCount_[STATISTICS_OPCODE_MAX]; - double replyBitsIn_[STATISTICS_OPCODE_MAX]; - double replyBitsOut_[STATISTICS_OPCODE_MAX]; - - double eventCached_[STATISTICS_OPCODE_MAX]; - double eventCount_[STATISTICS_OPCODE_MAX]; - double eventBitsIn_[STATISTICS_OPCODE_MAX]; - double eventBitsOut_[STATISTICS_OPCODE_MAX]; - - double cupsCount_; - double cupsBitsIn_; - double cupsBitsOut_; - - double smbCount_; - double smbBitsIn_; - double smbBitsOut_; - - double mediaCount_; - double mediaBitsIn_; - double mediaBitsOut_; - - double httpCount_; - double httpBitsIn_; - double httpBitsOut_; - - double fontCount_; - double fontBitsIn_; - double fontBitsOut_; - - double slaveCount_; - double slaveBitsIn_; - double slaveBitsOut_; - }; - - struct T_transportData - { - double idleTime_; - double readTime_; - double writeTime_; - - double proxyBytesIn_; - double proxyBytesOut_; - - double proxyFramesIn_; - double proxyFramesOut_; - double proxyWritesOut_; - - double compressedBytesIn_; - double compressedBytesOut_; - - double decompressedBytesIn_; - double decompressedBytesOut_; - - double framingBitsOut_; - }; - - struct T_packedData - { - double packedBytesIn_; - double packedBytesOut_; - }; - - struct T_splitData - { - double splitCount_; - double splitAborted_; - double splitAbortedBytesOut_; - }; - - struct T_overallData - { - double overallBytesIn_; - double overallBytesOut_; - }; - - struct T_proxyData - { - double protocolCount_; - double controlCount_; - double splitCount_; - double dataCount_; - - double streamRatio_; - }; - - T_protocolData protocolPartial_; - T_protocolData protocolTotal_; - - T_transportData transportPartial_; - T_transportData transportTotal_; - - T_packedData packedPartial_; - T_packedData packedTotal_; - - T_splitData splitPartial_; - T_splitData splitTotal_; - - T_overallData overallPartial_; - T_overallData overallTotal_; - - T_proxyData proxyData_; - - // - // Used to calculate the bandwidth usage - // of the proxy link. - // - - T_timestamp startShortFrameTs_; - T_timestamp startLongFrameTs_; - T_timestamp startFrameTs_; - - int bytesInShortFrame_; - int bytesInLongFrame_; - - int bitrateInShortFrame_; - int bitrateInLongFrame_; - - int topBitrate_; - - double congestionInFrame_; - - // - // Need the proxy pointer to print the - // statistics related to the client and - // server stores and to add the protocol - // data to the proxy token accumulators. - // - - Proxy *proxy_; -}; - -#endif /* Statistics_H */ diff --git a/nxcomp/Timestamp.cpp b/nxcomp/Timestamp.cpp deleted file mode 100644 index d5b3d613b..000000000 --- a/nxcomp/Timestamp.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Timestamp.h" - -// -// Log level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Last timestamp taken from the system. -// - -T_timestamp timestamp; - -// -// The following functions all use the ctime -// static buffer from the C library. -// - -char *strTimestamp(const T_timestamp &ts) -{ - char *ctime_now = ctime((time_t *) &ts.tv_sec); - - ctime_now[24] = '\0'; - - return ctime_now; -} - -// -// This is especially dirty. -// - -char *strMsTimestamp(const T_timestamp &ts) -{ - char *ctime_now = ctime((time_t *) &ts.tv_sec); - - char ctime_new[25]; - - sprintf(ctime_new, "%.8s:%3.3f", ctime_now + 11, - (float) ts.tv_usec / 1000); - - strncpy(ctime_now, ctime_new, 24); - - return ctime_now; -} diff --git a/nxcomp/Timestamp.h b/nxcomp/Timestamp.h deleted file mode 100644 index 604f5a3bc..000000000 --- a/nxcomp/Timestamp.h +++ /dev/null @@ -1,307 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Timestamp_H -#define Timestamp_H - -#include -#include -#include - -#include -#include - -#include "Misc.h" - -// -// Log level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// If not defined, always query the system time. -// - -#undef CACHE_TIMESTAMP - -// -// Log a warning if the time difference since -// the last update exceeds the given number -// of milliseconds. -// - -#define DRIFT_TIMESTAMP 1 - -// -// Type used for timeout manipulation. -// - -typedef struct timeval T_timestamp; - -// -// Last timestamp taken from the system. If the -// timestamp is cached, we need to explicitly -// get a new timestamp after any operation that -// may have required a relevant amount of time. -// - -extern T_timestamp timestamp; - -// -// Get a timestamp instance with values set -// at the given amount of milliseconds. -// - -inline T_timestamp getTimestamp(long ms) -{ - struct timeval ts; - - ts.tv_sec = ms / 1000; - ts.tv_usec = (ms % 1000) * 1000; - - return ts; -} - -// -// Return the difference in milliseconds -// between the two timestamps. -// - -inline long diffTimestamp(const T_timestamp &ts1, const T_timestamp &ts2) -{ - // - // Add 500 microseconds to round up - // to the nearest millisecond. - // - - return ((ts2.tv_sec * 1000 + (ts2.tv_usec + 500) / 1000) - - (ts1.tv_sec * 1000 + (ts1.tv_usec + 500) / 1000)); -} - -// -// The same in microseconds. It doesn't -// round the value. -// - -inline long diffUsTimestamp(const T_timestamp &ts1, const T_timestamp &ts2) -{ - return ((ts2.tv_sec * 1000000 + ts2.tv_usec) - - (ts1.tv_sec * 1000000 + ts1.tv_usec)); -} - -// -// Return the last timestamp taken from the -// system. It doesn't update the timestamp. -// - -inline T_timestamp getTimestamp() -{ - #ifdef CACHE_TIMESTAMP - - #ifdef TEST - - T_timestamp ts; - - gettimeofday(&ts, NULL); - - long diffTs = diffTimestamp(timestamp, ts); - - if (diffTs > DRIFT_TIMESTAMP) - { - *logofs << "Timestamp: WARNING! Time difference since the " - << "current timestamp is " << diffTs << " Ms.\n" - << logofs_flush; - } - - #endif - - return timestamp; - - #else - - gettimeofday(×tamp, NULL); - - return timestamp; - - #endif -} - -inline T_timestamp &setTimestamp(T_timestamp &ts, long ms) -{ - ts.tv_sec = ms / 1000; - ts.tv_usec = (ms % 1000) * 1000; - - return ts; -} - -// -// Return the smaller between two timestamps. -// - -inline T_timestamp &setMinTimestamp(T_timestamp &ts, long ms) -{ - if ((ts.tv_sec * 1000 + ts.tv_usec / 1000) > ms) - { - ts.tv_sec = ms / 1000; - ts.tv_usec = (ms % 1000) * 1000; - } - - return ts; -} - -inline T_timestamp &setMinTimestamp(T_timestamp &ts1, T_timestamp &ts2) -{ - if ((ts1.tv_sec * 1000000 + ts1.tv_usec) > - (ts2.tv_sec * 1000000 + ts2.tv_usec)) - { - ts1.tv_sec = ts2.tv_sec; - ts1.tv_usec = ts2.tv_usec; - } - - return ts1; -} - -// -// Convert a timestamp in the total number -// of milliseconds. -// - -inline long getMsTimestamp(const T_timestamp &ts) -{ - return ts.tv_sec * 1000 + ts.tv_usec / 1000; -} - -// -// A 0 value on both seconds and microseconds -// fields means that timestamp is invalid or -// not set. -// - -inline T_timestamp nullTimestamp() -{ - struct timeval ts; - - ts.tv_sec = 0; - ts.tv_usec = 0; - - return ts; -} - -inline bool isTimestamp(const T_timestamp &ts) -{ - if (ts.tv_sec == 0 && ts.tv_usec == 0) - { - return 0; - } - - return 1; -} - -inline void subMsTimestamp(T_timestamp &ts, long ms) -{ - ts.tv_sec -= ms / 1000; - ts.tv_usec -= (ms % 1000) * 1000; -} - -inline void addMsTimestamp(T_timestamp &ts, long ms) -{ - ts.tv_sec += ms / 1000; - ts.tv_usec += (ms % 1000) * 1000; -} - -// -// Check the difference between timestamps. -// Return 0 if the system time went backward -// compared to the second timestamp, or the -// difference between the timestamps exceeds -// the given number of milliseconds. -// - -inline int checkDiffTimestamp(const T_timestamp &ts1, const T_timestamp &ts2, - long ms = 30000) -{ - long diffTs = diffTimestamp(ts1, ts2); - - if (diffTs < 0 || diffTs > ms) - { - return 0; - } - - return 1; -} - -// -// Return a string representing the timestamp. -// - -char *strTimestamp(const T_timestamp &ts); -char *strMsTimestamp(const T_timestamp &ts); - -inline char *strTimestamp() -{ - return strTimestamp(getTimestamp()); -} - -inline char *strMsTimestamp() -{ - return strMsTimestamp(getTimestamp()); -} - -// -// Update the current timestamp. -// - -inline T_timestamp getNewTimestamp() -{ - #ifdef TEST - - T_timestamp ts; - - gettimeofday(&ts, NULL); - - *logofs << "Timestamp: Updating the current timestamp at " - << strMsTimestamp(ts) << ".\n" << logofs_flush; - - long diffTs = diffTimestamp(timestamp, ts); - - if (diffTs > DRIFT_TIMESTAMP) - { - *logofs << "Timestamp: WARNING! Time difference since the " - << "old timestamp is " << diffTs << " Ms.\n" - << logofs_flush; - } - - #endif - - gettimeofday(×tamp, NULL); - - return timestamp; -} - -#endif /* Timestamp_H */ diff --git a/nxcomp/TranslateCoords.cpp b/nxcomp/TranslateCoords.cpp deleted file mode 100644 index 97bd285e1..000000000 --- a/nxcomp/TranslateCoords.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "TranslateCoords.h" - -#include "ClientCache.h" - -#include "EncodeBuffer.h" -#include "DecodeBuffer.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Here are the methods to handle messages' content. -// - -int TranslateCoordsStore::parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - TranslateCoordsMessage *translateCoords = (TranslateCoordsMessage *) message; - - // - // Here is the fingerprint. - // - - translateCoords -> src_window = GetULONG(buffer + 4, bigEndian); - translateCoords -> dst_window = GetULONG(buffer + 8, bigEndian); - - translateCoords -> src_x = GetUINT(buffer + 12, bigEndian); - translateCoords -> src_y = GetUINT(buffer + 14, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -int TranslateCoordsStore::unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - TranslateCoordsMessage *translateCoords = (TranslateCoordsMessage *) message; - - // - // Fill all the message's fields. - // - - PutULONG(translateCoords -> src_window, buffer + 4, bigEndian); - PutULONG(translateCoords -> dst_window, buffer + 8, bigEndian); - - PutUINT(translateCoords -> src_x, buffer + 12, bigEndian); - PutUINT(translateCoords -> src_y, buffer + 14, bigEndian); - - #ifdef DEBUG - *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; - #endif - - return 1; -} - -void TranslateCoordsStore::dumpIdentity(const Message *message) const -{ - #ifdef DUMP - - TranslateCoordsMessage *translateCoords = (TranslateCoordsMessage *) message; - - *logofs << name() << ": Identity src_window " << translateCoords -> src_window << ", dst_window " - << translateCoords -> dst_window << ", src_x " << translateCoords -> src_x << ", src_y " - << translateCoords -> src_y << ", size " << translateCoords -> size_ << ".\n" << logofs_flush; - - #endif -} - -void TranslateCoordsStore::identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const -{ - md5_append(md5_state_, buffer + 4, 4); - md5_append(md5_state_, buffer + 8, 4); - md5_append(md5_state_, buffer + 12, 2); - md5_append(md5_state_, buffer + 14, 2); -} diff --git a/nxcomp/TranslateCoords.h b/nxcomp/TranslateCoords.h deleted file mode 100644 index 997d079e1..000000000 --- a/nxcomp/TranslateCoords.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef TranslateCoords_H -#define TranslateCoords_H - -#include "Message.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef DUMP - -// -// Set default values. -// - -#define TRANSLATECOORDS_ENABLE_CACHE 1 -#define TRANSLATECOORDS_ENABLE_DATA 0 -#define TRANSLATECOORDS_ENABLE_SPLIT 0 -#define TRANSLATECOORDS_ENABLE_COMPRESS 0 - -#define TRANSLATECOORDS_DATA_LIMIT 0 -#define TRANSLATECOORDS_DATA_OFFSET 16 - -#define TRANSLATECOORDS_CACHE_SLOTS 3000 -#define TRANSLATECOORDS_CACHE_THRESHOLD 3 -#define TRANSLATECOORDS_CACHE_LOWER_THRESHOLD 1 - -// -// The message class. -// - -class TranslateCoordsMessage : public Message -{ - friend class TranslateCoordsStore; - - public: - - TranslateCoordsMessage() - { - } - - ~TranslateCoordsMessage() - { - } - - // - // Put here the fields which constitute - // the 'identity' part of the message. - // - - private: - - unsigned int src_window; - unsigned int dst_window; - unsigned int src_x; - unsigned int src_y; - - unsigned char r_same_screen; - unsigned int r_child_window; - unsigned int r_dst_x; - unsigned int r_dst_y; -}; - -class TranslateCoordsStore : public MessageStore -{ - // - // Constructors and destructors. - // - - public: - - TranslateCoordsStore() : MessageStore() - { - enableCache = TRANSLATECOORDS_ENABLE_CACHE; - enableData = TRANSLATECOORDS_ENABLE_DATA; - enableSplit = TRANSLATECOORDS_ENABLE_SPLIT; - enableCompress = TRANSLATECOORDS_ENABLE_COMPRESS; - - dataLimit = TRANSLATECOORDS_DATA_LIMIT; - dataOffset = TRANSLATECOORDS_DATA_OFFSET; - - cacheSlots = TRANSLATECOORDS_CACHE_SLOTS; - cacheThreshold = TRANSLATECOORDS_CACHE_THRESHOLD; - cacheLowerThreshold = TRANSLATECOORDS_CACHE_LOWER_THRESHOLD; - - messages_ -> resize(cacheSlots); - - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - *i = NULL; - } - - temporary_ = NULL; - } - - virtual ~TranslateCoordsStore() - { - for (T_messages::iterator i = messages_ -> begin(); - i < messages_ -> end(); i++) - { - destroy(*i); - } - - destroy(temporary_); - } - - virtual const char *name() const - { - return "TranslateCoords"; - } - - virtual unsigned char opcode() const - { - return X_TranslateCoords; - } - - virtual unsigned int storage() const - { - return sizeof(TranslateCoordsMessage); - } - - // - // Message handling methods. - // - - public: - - virtual Message *create() const - { - return new TranslateCoordsMessage(); - } - - virtual Message *create(const Message &message) const - { - return new TranslateCoordsMessage((const TranslateCoordsMessage &) message); - } - - virtual void destroy(Message *message) const - { - delete (TranslateCoordsMessage *) message; - } - - virtual int parseIdentity(Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual int unparseIdentity(const Message *message, unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void identityChecksum(const Message *message, const unsigned char *buffer, - unsigned int size, int bigEndian) const; - - virtual void dumpIdentity(const Message *message) const; -}; - -#endif /* TranslateCoords_H */ diff --git a/nxcomp/Transport.cpp b/nxcomp/Transport.cpp deleted file mode 100644 index eaf9775af..000000000 --- a/nxcomp/Transport.cpp +++ /dev/null @@ -1,3064 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include -#include - -#include "Transport.h" - -#include "Statistics.h" - -// -// Set the verbosity level. You also -// need to define DUMP in Misc.cpp -// if DUMP is defined here. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG -#undef INSPECT -#undef DUMP - -// -// Used to lock and unlock the transport -// buffers before they are accessed by -// different threads. -// - -#undef THREADS - -// -// Define this to get logging all the -// operations performed by the parent -// thread, the one that enqueues and -// dequeues data. -// - -#define PARENT - -// -// Define this to know when a channel -// is created or destroyed. -// - -#undef REFERENCES - -// -// Reference count for allocated buffers. -// - -#ifdef REFERENCES - -int Transport::references_; -int ProxyTransport::references_; -int InternalTransport::references_; - -#endif - -// -// This is the base class providing methods for read -// and write buffering. -// - -Transport::Transport(int fd) : fd_(fd) -{ - #ifdef TEST - *logofs << "Transport: Going to create base transport " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - type_ = transport_base; - - // - // Set up the write buffer. - // - - w_buffer_.length_ = 0; - w_buffer_.start_ = 0; - - initialSize_ = TRANSPORT_BUFFER_DEFAULT_SIZE; - thresholdSize_ = TRANSPORT_BUFFER_DEFAULT_SIZE << 1; - maximumSize_ = TRANSPORT_BUFFER_DEFAULT_SIZE << 4; - - w_buffer_.data_.resize(initialSize_); - - // - // Set non-blocking IO on socket. - // - - SetNonBlocking(fd_, 1); - - blocked_ = 0; - finish_ = 0; - - #ifdef REFERENCES - *logofs << "Transport: Created new object at " - << this << " out of " << ++references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -Transport::~Transport() -{ - #ifdef TEST - *logofs << "Transport: Going to destroy base class " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - ::close(fd_); - - #ifdef REFERENCES - *logofs << "Transport: Deleted object at " - << this << " out of " << --references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -// -// Read data from its file descriptor. -// - -int Transport::read(unsigned char *data, unsigned int size) -{ - #ifdef DEBUG - *logofs << "Transport: Going to read " << size << " bytes from " - << "FD#" << fd_ << ".\n" << logofs_flush; - #endif - - // - // Read the available data from the socket. - // - - int result = ::read(fd_, data, size); - - // - // Update the current timestamp as the read - // can have scheduled some other process. - // - - getNewTimestamp(); - - if (result < 0) - { - if (EGET() == EAGAIN) - { - #ifdef TEST - *logofs << "Transport: WARNING! Read of " << size << " bytes from " - << "FD#" << fd_ << " would block.\n" << logofs_flush; - #endif - - return 0; - } - else if (EGET() == EINTR) - { - #ifdef TEST - *logofs << "Transport: Read of " << size << " bytes from " - << "FD#" << fd_ << " was interrupted.\n" - << logofs_flush; - #endif - - return 0; - } - else - { - #ifdef TEST - *logofs << "Transport: Error reading from " - << "FD#" << fd_ << ".\n" << logofs_flush; - #endif - - finish(); - - return -1; - } - } - else if (result == 0) - { - #ifdef TEST - *logofs << "Transport: No data read from " - << "FD#" << fd_ << ".\n" << logofs_flush; - #endif - - finish(); - - return -1; - } - - #ifdef TEST - *logofs << "Transport: Read " << result << " bytes out of " - << size << " from FD#" << fd_ << ".\n" << logofs_flush; - #endif - - #ifdef DUMP - - *logofs << "Transport: Dumping content of read data.\n" - << logofs_flush; - - DumpData(data, result); - - #endif - - return result; -} - -// -// Write as many bytes as possible to socket. -// Append the remaining data bytes to the end -// of the buffer and update length to reflect -// changes. -// - -int Transport::write(T_write type, const unsigned char *data, const unsigned int size) -{ - // - // If an immediate write was requested then - // flush the enqueued data first. - // - // Alternatively may try to write only if - // the socket is not blocked. - // - // if (w_buffer_.length_ > 0 && blocked_ == 0 && - // type == write_immediate) - // { - // ... - // } - // - - if (w_buffer_.length_ > 0 && type == write_immediate) - - { - #ifdef TEST - *logofs << "Transport: Writing " << w_buffer_.length_ - << " bytes of previous data to FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - int result = Transport::flush(); - - if (result < 0) - { - return -1; - } - } - - // - // If nothing is remained, write immediately - // to the socket. - // - - unsigned int written = 0; - - if (w_buffer_.length_ == 0 && blocked_ == 0 && - type == write_immediate) - { - // - // Limit the amount of data sent. - // - - unsigned int toWrite = size; - - #ifdef DUMP - - *logofs << "Transport: Going to write " << toWrite - << " bytes to FD#" << fd_ << " with checksum "; - - DumpChecksum(data, size); - - *logofs << ".\n" << logofs_flush; - - #endif - - T_timestamp writeTs; - - int diffTs; - - while (written < toWrite) - { - // - // Trace system time spent writing data. - // - - writeTs = getTimestamp(); - - int result = ::write(fd_, data + written, toWrite - written); - - diffTs = diffTimestamp(writeTs, getNewTimestamp()); - - statistics -> addWriteTime(diffTs); - - if (result <= 0) - { - if (EGET() == EAGAIN) - { - #ifdef TEST - *logofs << "Transport: Write of " << toWrite - written - << " bytes on FD#" << fd_ << " would block.\n" - << logofs_flush; - #endif - - blocked_ = 1; - - break; - } - else if (EGET() == EINTR) - { - #ifdef TEST - *logofs << "Transport: Write of " << toWrite - written - << " bytes on FD#" << fd_ << " was interrupted.\n" - << logofs_flush; - #endif - - continue; - } - else - { - #ifdef TEST - *logofs << "Transport: Write to " << "FD#" - << fd_ << " failed.\n" << logofs_flush; - #endif - - finish(); - - return -1; - } - } - else - { - #ifdef TEST - *logofs << "Transport: Immediately written " << result - << " bytes on " << "FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - written += result; - } - } - - #ifdef DUMP - - if (written > 0) - { - *logofs << "Transport: Dumping content of immediately written data.\n" - << logofs_flush; - - DumpData(data, written); - } - - #endif - } - - if (written == size) - { - // - // We will not affect the write buffer. - // - - return written; - } - - #ifdef DEBUG - *logofs << "Transport: Going to append " << size - written - << " bytes to write buffer for " << "FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - if (resize(w_buffer_, size - written) < 0) - { - return -1; - } - - memmove(w_buffer_.data_.begin() + w_buffer_.start_ + w_buffer_.length_, - data + written, size - written); - - w_buffer_.length_ += size - written; - - #ifdef TEST - *logofs << "Transport: Write buffer for FD#" << fd_ - << " has data for " << w_buffer_.length_ << " bytes.\n" - << logofs_flush; - - *logofs << "Transport: Start is " << w_buffer_.start_ - << " length is " << w_buffer_.length_ << " size is " - << w_buffer_.data_.size() << " capacity is " - << w_buffer_.data_.capacity() << ".\n" - << logofs_flush; - #endif - - // - // Note that this function always returns the whole - // size of buffer that was provided, either if not - // all the data could be actually written. - // - - return size; -} - -// -// Write pending data to its file descriptor. -// - -int Transport::flush() -{ - if (w_buffer_.length_ == 0) - { - #ifdef TEST - *logofs << "Transport: No data to flush on " - << "FD#" << fd_ << ".\n" << logofs_flush; - #endif - - #ifdef WARNING - if (blocked_ != 0) - { - *logofs << "Transport: Blocked flag is " << blocked_ - << " with no data to flush on FD#" << fd_ - << ".\n" << logofs_flush; - } - #endif - - return 0; - } - - // - // It's time to move data from the - // write buffer to the real link. - // - - int written = 0; - - int toWrite = w_buffer_.length_; - - // - // We will do our best to write any available - // data to the socket, so let's say we start - // from a clean state. - // - - blocked_ = 0; - - #ifdef TEST - *logofs << "Transport: Going to flush " << toWrite - << " bytes on FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - T_timestamp writeTs; - - int diffTs; - - while (written < toWrite) - { - writeTs = getTimestamp(); - - int result = ::write(fd_, w_buffer_.data_.begin() + w_buffer_.start_ + - written, toWrite - written); - - diffTs = diffTimestamp(writeTs, getNewTimestamp()); - - statistics -> addWriteTime(diffTs); - - if (result <= 0) - { - if (EGET() == EAGAIN) - { - #ifdef TEST - *logofs << "Transport: Write of " << toWrite - written - << " bytes on FD#" << fd_ << " would block.\n" - << logofs_flush; - #endif - - blocked_ = 1; - - break; - } - else if (EGET() == EINTR) - { - #ifdef TEST - *logofs << "Transport: Write of " << toWrite - written - << " bytes on FD#" << fd_ << " was interrupted.\n" - << logofs_flush; - #endif - - continue; - } - else - { - #ifdef TEST - *logofs << "Transport: Write to " << "FD#" - << fd_ << " failed.\n" << logofs_flush; - #endif - - finish(); - - return -1; - } - } - else - { - #ifdef TEST - *logofs << "Transport: Flushed " << result << " bytes on " - << "FD#" << fd_ << ".\n" << logofs_flush; - #endif - - written += result; - } - } - - if (written > 0) - { - #ifdef DUMP - - *logofs << "Transport: Dumping content of flushed data.\n" - << logofs_flush; - - DumpData(w_buffer_.data_.begin() + w_buffer_.start_, written); - - #endif - - // - // Update the buffer status. - // - - w_buffer_.length_ -= written; - - if (w_buffer_.length_ == 0) - { - w_buffer_.start_ = 0; - } - else - { - w_buffer_.start_ += written; - } - } - - // - // It can be that we wrote less bytes than - // available because of the write limit. - // - - if (w_buffer_.length_ > 0) - { - #ifdef TEST - *logofs << "Transport: There are still " << w_buffer_.length_ - << " bytes in write buffer for " << "FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - blocked_ = 1; - } - - #ifdef TEST - *logofs << "Transport: Write buffer for FD#" << fd_ - << " has data for " << w_buffer_.length_ << " bytes.\n" - << logofs_flush; - - *logofs << "Transport: Start is " << w_buffer_.start_ - << " length is " << w_buffer_.length_ << " size is " - << w_buffer_.data_.size() << " capacity is " - << w_buffer_.data_.capacity() << ".\n" - << logofs_flush; - #endif - - // - // No new data was produced for the link except - // any outstanding data from previous writes. - // - - return 0; -} - -int Transport::drain(int limit, int timeout) -{ - if (w_buffer_.length_ <= limit) - { - return 1; - } - - // - // Write the data accumulated in the write - // buffer until it is below the limit or - // the timeout is elapsed. - // - - int toWrite = w_buffer_.length_; - - int written = 0; - - #ifdef TEST - *logofs << "Transport: Draining " << toWrite - limit - << " bytes on FD#" << fd_ << " with limit set to " - << limit << ".\n" << logofs_flush; - #endif - - T_timestamp startTs = getNewTimestamp(); - - T_timestamp selectTs; - T_timestamp writeTs; - T_timestamp idleTs; - - T_timestamp nowTs = startTs; - - int diffTs; - - fd_set writeSet; - fd_set readSet; - - FD_ZERO(&writeSet); - FD_ZERO(&readSet); - - int result; - int ready; - - while (w_buffer_.length_ - written > limit) - { - nowTs = getNewTimestamp(); - - // - // Wait for descriptor to become - // readable or writable. - // - - FD_SET(fd_, &writeSet); - FD_SET(fd_, &readSet); - - setTimestamp(selectTs, timeout / 2); - - idleTs = nowTs; - - result = select(fd_ + 1, &readSet, &writeSet, NULL, &selectTs); - - nowTs = getNewTimestamp(); - - diffTs = diffTimestamp(idleTs, nowTs); - - statistics -> addIdleTime(diffTs); - - statistics -> subReadTime(diffTs); - - if (result < 0) - { - if (EGET() == EINTR) - { - #ifdef TEST - *logofs << "Transport: Select on FD#" << fd_ - << " was interrupted.\n" << logofs_flush; - #endif - - continue; - } - else - { - #ifdef TEST - *logofs << "Transport: Select on FD#" << fd_ - << " failed.\n" << logofs_flush; - #endif - - finish(); - - return -1; - } - } - else if (result > 0) - { - ready = result; - - if (FD_ISSET(fd_, &writeSet)) - { - writeTs = getNewTimestamp(); - - result = ::write(fd_, w_buffer_.data_.begin() + w_buffer_.start_ + - written, toWrite - written); - - nowTs = getNewTimestamp(); - - diffTs = diffTimestamp(writeTs, nowTs); - - statistics -> addWriteTime(diffTs); - - if (result > 0) - { - #ifdef TEST - *logofs << "Transport: Forced flush of " << result - << " bytes on " << "FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - written += result; - } - else if (result < 0 && EGET() == EINTR) - { - #ifdef TEST - *logofs << "Transport: Write to FD#" << fd_ - << " was interrupted.\n" << logofs_flush; - #endif - - continue; - } - else - { - #ifdef TEST - *logofs << "Transport: Write to FD#" << fd_ - << " failed.\n" << logofs_flush; - #endif - - finish(); - - return -1; - } - - ready--; - } - - if (ready > 0) - { - if (FD_ISSET(fd_, &readSet)) - { - #ifdef TEST - *logofs << "Transport: Not draining further " - << "due to data readable on FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - break; - } - } - } - #ifdef TEST - else - { - *logofs << "Transport: Timeout encountered " - << "waiting for FD#" << fd_ << ".\n" - << logofs_flush; - } - #endif - - nowTs = getNewTimestamp(); - - diffTs = diffTimestamp(startTs, nowTs); - - if (diffTs >= timeout) - { - #ifdef TEST - *logofs << "Transport: Not draining further " - << "due to the timeout on FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - break; - } - } - - if (written > 0) - { - #ifdef DUMP - - *logofs << "Transport: Dumping content of flushed data.\n" - << logofs_flush; - - DumpData(w_buffer_.data_.begin() + w_buffer_.start_, written); - - #endif - - // - // Update the buffer status. - // - - w_buffer_.length_ -= written; - - if (w_buffer_.length_ == 0) - { - w_buffer_.start_ = 0; - - blocked_ = 0; - } - else - { - w_buffer_.start_ += written; - - #ifdef TEST - *logofs << "Transport: There are still " << w_buffer_.length_ - << " bytes in write buffer for " << "FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - blocked_ = 1; - } - } - #ifdef TEST - else - { - *logofs << "Transport: WARNING! No data written to FD#" << fd_ - << " with " << toWrite << " bytes to drain and limit " - << "set to " << limit << ".\n" << logofs_flush; - } - #endif - - #ifdef TEST - *logofs << "Transport: Write buffer for FD#" << fd_ - << " has data for " << w_buffer_.length_ << " bytes.\n" - << logofs_flush; - - *logofs << "Transport: Start is " << w_buffer_.start_ - << " length is " << w_buffer_.length_ << " size is " - << w_buffer_.data_.size() << " capacity is " - << w_buffer_.data_.capacity() << ".\n" - << logofs_flush; - #endif - - return (w_buffer_.length_ <= limit); -} - -int Transport::wait(int timeout) const -{ - T_timestamp startTs = getNewTimestamp(); - - T_timestamp idleTs; - T_timestamp selectTs; - - T_timestamp nowTs = startTs; - - long available = 0; - int result = 0; - - int diffTs; - - fd_set readSet; - - FD_ZERO(&readSet); - FD_SET(fd_, &readSet); - - for (;;) - { - available = readable(); - - diffTs = diffTimestamp(startTs, nowTs); - - if (available != 0 || timeout == 0 || - (diffTs + (timeout / 10)) >= timeout) - { - #ifdef TEST - *logofs << "Transport: There are " << available - << " bytes on FD#" << fd_ << " after " - << diffTs << " Ms.\n" << logofs_flush; - #endif - - return available; - } - else if (available == 0 && result > 0) - { - #ifdef TEST - *logofs << "Transport: Read on " << "FD#" - << fd_ << " failed.\n" << logofs_flush; - #endif - - return -1; - } - - // - // TODO: Should subtract the time - // already spent in select. - // - - selectTs.tv_sec = 0; - selectTs.tv_usec = timeout * 1000; - - idleTs = nowTs; - - // - // Wait for descriptor to become readable. - // - - result = select(fd_ + 1, &readSet, NULL, NULL, &selectTs); - - nowTs = getNewTimestamp(); - - diffTs = diffTimestamp(idleTs, nowTs); - - statistics -> addIdleTime(diffTs); - - statistics -> subReadTime(diffTs); - - if (result < 0) - { - if (EGET() == EINTR) - { - #ifdef TEST - *logofs << "Transport: Select on FD#" << fd_ - << " was interrupted.\n" << logofs_flush; - #endif - - continue; - } - else - { - #ifdef TEST - *logofs << "Transport: Select on " << "FD#" - << fd_ << " failed.\n" << logofs_flush; - #endif - - return -1; - } - } - #ifdef TEST - else if (result == 0) - { - *logofs << "Transport: No data available on FD#" << fd_ - << " after " << diffTimestamp(startTs, nowTs) - << " Ms.\n" << logofs_flush; - } - else - { - *logofs << "Transport: Data became available on FD#" << fd_ - << " after " << diffTimestamp(startTs, nowTs) - << " Ms.\n" << logofs_flush; - } - #endif - } -} - -void Transport::setSize(unsigned int initialSize, unsigned int thresholdSize, - unsigned int maximumSize) -{ - initialSize_ = initialSize; - thresholdSize_ = thresholdSize; - maximumSize_ = maximumSize; - - #ifdef TEST - *logofs << "Transport: Set buffer sizes for FD#" << fd_ - << " to " << initialSize_ << "/" << thresholdSize_ - << "/" << maximumSize_ << ".\n" << logofs_flush; - #endif -} - -void Transport::fullReset() -{ - blocked_ = 0; - finish_ = 0; - - fullReset(w_buffer_); -} - -int Transport::resize(T_buffer &buffer, const int &size) -{ - if ((int) buffer.data_.size() >= (buffer.length_ + size) && - (buffer.start_ + buffer.length_ + size) > - (int) buffer.data_.size()) - { - if (buffer.length_ > 0) - { - // - // There is enough space in buffer but we need - // to move existing data at the beginning. - // - - #ifdef TEST - *logofs << "Transport: Moving " << buffer.length_ - << " bytes of data for " << "FD#" << fd_ - << " to make room in the buffer.\n" - << logofs_flush; - #endif - - memmove(buffer.data_.begin(), buffer.data_.begin() + - buffer.start_, buffer.length_); - } - - buffer.start_ = 0; - - #ifdef DEBUG - *logofs << "Transport: Made room for " - << buffer.data_.size() - buffer.start_ - << " bytes in buffer for " << "FD#" - << fd_ << ".\n" << logofs_flush; - #endif - } - else if ((buffer.length_ + size) > (int) buffer.data_.size()) - { - // - // Not enough space, so increase - // the size of the buffer. - // - - if (buffer.start_ != 0 && buffer.length_ > 0) - { - #ifdef TEST - *logofs << "Transport: Moving " << buffer.length_ - << " bytes of data for " << "FD#" << fd_ - << " to resize the buffer.\n" - << logofs_flush; - #endif - - memmove(buffer.data_.begin(), buffer.data_.begin() + - buffer.start_, buffer.length_); - } - - buffer.start_ = 0; - - unsigned int newSize = thresholdSize_; - - while (newSize < (unsigned int) buffer.length_ + size) - { - newSize <<= 1; - - if (newSize >= maximumSize_) - { - newSize = buffer.length_ + size + initialSize_; - } - } - - #ifdef DEBUG - *logofs << "Transport: Buffer for " << "FD#" << fd_ - << " will be enlarged from " << buffer.data_.size() - << " to at least " << buffer.length_ + size - << " bytes.\n" << logofs_flush; - #endif - - buffer.data_.resize(newSize); - - #ifdef TEST - if (newSize >= maximumSize_) - { - *logofs << "Transport: WARNING! Buffer for FD#" << fd_ - << " grown to reach size of " << newSize - << " bytes.\n" << logofs_flush; - } - #endif - - #ifdef TEST - *logofs << "Transport: Data buffer for " << "FD#" - << fd_ << " has now size " << buffer.data_.size() - << " and capacity " << buffer.data_.capacity() - << ".\n" << logofs_flush; - #endif - } - - return (buffer.length_ + size); -} - -void Transport::fullReset(T_buffer &buffer) -{ - // - // Force deallocation and allocation - // of the initial size. - // - - #ifdef TEST - *logofs << "Transport: Resetting buffer for " << "FD#" - << fd_ << " with size " << buffer.data_.size() - << " and capacity " << buffer.data_.capacity() - << ".\n" << logofs_flush; - #endif - - buffer.start_ = 0; - buffer.length_ = 0; - - if (buffer.data_.size() > (unsigned int) initialSize_ && - buffer.data_.capacity() > (unsigned int) initialSize_) - { - buffer.data_.clear(); - - buffer.data_.resize(initialSize_); - - #ifdef TEST - *logofs << "Transport: Data buffer for " << "FD#" - << fd_ << " shrunk to size " << buffer.data_.size() - << " and capacity " << buffer.data_.capacity() - << ".\n" << logofs_flush; - #endif - } -} - -ProxyTransport::ProxyTransport(int fd) : Transport(fd) -{ - #ifdef TEST - *logofs << "ProxyTransport: Going to create proxy transport " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - type_ = transport_proxy; - - // - // Set up the read buffer. - // - - r_buffer_.length_ = 0; - r_buffer_.start_ = 0; - - r_buffer_.data_.resize(initialSize_); - - // - // For now we own the buffer. - // - - owner_ = 1; - - // - // Set up ZLIB compression. - // - - int result; - - r_stream_.zalloc = NULL; - r_stream_.zfree = NULL; - r_stream_.opaque = NULL; - - r_stream_.next_in = NULL; - r_stream_.avail_in = 0; - - if ((result = inflateInit2(&r_stream_, 15)) != Z_OK) - { - #ifdef PANIC - *logofs << "ProxyTransport: PANIC! Failed initialization of ZLIB read stream. " - << "Error is '" << zError(result) << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed initialization of ZLIB read stream. " - << "Error is '" << zError(result) << "'.\n"; - - HandleCleanup(); - } - - if (control -> LocalStreamCompression) - { - w_stream_.zalloc = NULL; - w_stream_.zfree = NULL; - w_stream_.opaque = NULL; - - if ((result = deflateInit2(&w_stream_, control -> LocalStreamCompressionLevel, Z_DEFLATED, - 15, 9, Z_DEFAULT_STRATEGY)) != Z_OK) - { - #ifdef PANIC - *logofs << "ProxyTransport: PANIC! Failed initialization of ZLIB write stream. " - << "Error is '" << zError(result) << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Failed initialization of ZLIB write stream. " - << "Error is '" << zError(result) << "'.\n"; - - HandleCleanup(); - } - } - - // - // No ZLIB stream to flush yet. - // - - flush_ = 0; - - #ifdef REFERENCES - *logofs << "ProxyTransport: Created new object at " - << this << " out of " << ++references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -ProxyTransport::~ProxyTransport() -{ - #ifdef TEST - *logofs << "ProxyTransport: Going to destroy derived class " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - // - // Deallocate the ZLIB stream state. - // - - inflateEnd(&r_stream_); - - if (control -> LocalStreamCompression) - { - deflateEnd(&w_stream_); - } - - #ifdef REFERENCES - *logofs << "ProxyTransport: Deleted object at " - << this << " out of " << --references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -// -// Read data from its file descriptor. -// - -int ProxyTransport::read(unsigned char *data, unsigned int size) -{ - // - // If the remote peer is not compressing - // the stream then just return any byte - // read from the socket. - // - - if (control -> RemoteStreamCompression == 0) - { - int result = Transport::read(data, size); - - if (result <= 0) - { - return result; - } - - statistics -> addBytesIn(result); - - return result; - } - - // - // Return any pending data first. - // - - if (r_buffer_.length_ > 0) - { - // - // If the size of the buffer doesn't - // match the amount of data pending, - // force the caller to retry. - // - - if ((int) size < r_buffer_.length_) - { - #ifdef TEST - *logofs << "ProxyTransport: WARNING! Forcing a retry with " - << r_buffer_.length_ << " bytes pending and " - << size << " in the buffer.\n" - << logofs_flush; - #endif - - ESET(EAGAIN); - - return -1; - } - - int copied = (r_buffer_.length_ > ((int) size) ? - ((int) size) : r_buffer_.length_); - - memcpy(data, r_buffer_.data_.begin() + r_buffer_.start_, copied); - - // - // Update the buffer status. - // - - #ifdef DEBUG - *logofs << "ProxyTransport: Going to immediately return " << copied - << " bytes from proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - r_buffer_.length_ -= copied; - - if (r_buffer_.length_ == 0) - { - r_buffer_.start_ = 0; - } - else - { - r_buffer_.start_ += copied; - - #ifdef TEST - *logofs << "ProxyTransport: There are still " << r_buffer_.length_ - << " bytes in read buffer for proxy " << "FD#" - << fd_ << ".\n" << logofs_flush; - #endif - } - - return copied; - } - - // - // Read data in the user buffer. - // - - int result = Transport::read(data, size); - - if (result <= 0) - { - return result; - } - - statistics -> addBytesIn(result); - - // - // Decompress the data into the read - // buffer. - // - - #ifdef DEBUG - *logofs << "ProxyTransport: Going to decompress data for " - << "proxy FD#" << fd_ << ".\n" << logofs_flush; - #endif - - int saveTotalIn = r_stream_.total_in; - int saveTotalOut = r_stream_.total_out; - - int oldTotalIn = saveTotalIn; - int oldTotalOut = saveTotalOut; - - int diffTotalIn; - int diffTotalOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: oldTotalIn = " << oldTotalIn - << ".\n" << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: oldTotalOut = " << oldTotalOut - << ".\n" << logofs_flush; - #endif - - r_stream_.next_in = (Bytef *) data; - r_stream_.avail_in = result; - - // - // Let ZLIB use all the space already - // available in the buffer. - // - - unsigned int newAvailOut = r_buffer_.data_.size() - r_buffer_.start_ - - r_buffer_.length_; - - #ifdef TEST - *logofs << "ProxyTransport: Initial decompress buffer is " - << newAvailOut << " bytes.\n" << logofs_flush; - #endif - - for (;;) - { - #ifdef INSPECT - *logofs << "\nProxyTransport: Running the decompress loop.\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_buffer_.length_ = " << r_buffer_.length_ - << ".\n" << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_buffer_.data_.size() = " << r_buffer_.data_.size() - << ".\n" << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: newAvailOut = " << newAvailOut - << ".\n" << logofs_flush; - #endif - - if (resize(r_buffer_, newAvailOut) < 0) - { - return -1; - } - - #ifdef INSPECT - *logofs << "ProxyTransport: r_buffer_.data_.size() = " - << r_buffer_.data_.size() << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_stream_.next_in = " - << (void *) r_stream_.next_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_stream_.avail_in = " - << r_stream_.avail_in << ".\n" - << logofs_flush; - #endif - - r_stream_.next_out = r_buffer_.data_.begin() + r_buffer_.start_ + - r_buffer_.length_; - - r_stream_.avail_out = newAvailOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: r_stream_.next_out = " - << (void *) r_stream_.next_out << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_stream_.avail_out = " - << r_stream_.avail_out << ".\n" - << logofs_flush; - #endif - - int result = inflate(&r_stream_, Z_SYNC_FLUSH); - - #ifdef INSPECT - *logofs << "ProxyTransport: Called inflate() result is " - << result << ".\n" << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_stream_.avail_in = " - << r_stream_.avail_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_stream_.avail_out = " - << r_stream_.avail_out << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_stream_.total_in = " - << r_stream_.total_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_stream_.total_out = " - << r_stream_.total_out << ".\n" - << logofs_flush; - #endif - - diffTotalIn = r_stream_.total_in - oldTotalIn; - diffTotalOut = r_stream_.total_out - oldTotalOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: diffTotalIn = " - << diffTotalIn << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: diffTotalOut = " - << diffTotalOut << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: r_buffer_.length_ = " - << r_buffer_.length_ << ".\n" - << logofs_flush; - #endif - - r_buffer_.length_ += diffTotalOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: r_buffer_.length_ = " - << r_buffer_.length_ << ".\n" - << logofs_flush; - #endif - - oldTotalIn = r_stream_.total_in; - oldTotalOut = r_stream_.total_out; - - if (result == Z_OK) - { - if (r_stream_.avail_in == 0 && r_stream_.avail_out > 0) - { - break; - } - } - else if (result == Z_BUF_ERROR && r_stream_.avail_out > 0 && - r_stream_.avail_in == 0) - { - #ifdef TEST - *logofs << "ProxyTransport: WARNING! Raised Z_BUF_ERROR decompressing data.\n" - << logofs_flush; - #endif - - break; - } - else - { - #ifdef PANIC - *logofs << "ProxyTransport: PANIC! Decompression of data failed. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Decompression of data failed. Error is '" - << zError(result) << "'.\n"; - - finish(); - - return -1; - } - - // - // Add more bytes to the buffer. - // - - if (newAvailOut < thresholdSize_) - { - newAvailOut = thresholdSize_; - } - - #ifdef TEST - *logofs << "ProxyTransport: Need to add " << newAvailOut - << " bytes to the decompress buffer in read.\n" - << logofs_flush; - #endif - } - - diffTotalIn = r_stream_.total_in - saveTotalIn; - diffTotalOut = r_stream_.total_out - saveTotalOut; - - #ifdef DEBUG - *logofs << "ProxyTransport: Decompressed data from " - << diffTotalIn << " to " << diffTotalOut - << " bytes.\n" << logofs_flush; - #endif - - statistics -> addDecompressedBytes(diffTotalIn, diffTotalOut); - - // - // Check if the size of the buffer - // matches the produced data. - // - - if ((int) size < r_buffer_.length_) - { - #ifdef TEST - *logofs << "ProxyTransport: WARNING! Forcing a retry with " - << r_buffer_.length_ << " bytes pending and " - << size << " in the buffer.\n" - << logofs_flush; - #endif - - ESET(EAGAIN); - - return -1; - } - - // - // Copy the decompressed data to the - // provided buffer. - // - - int copied = (r_buffer_.length_ > ((int) size) ? - ((int) size) : r_buffer_.length_); - - #ifdef DEBUG - *logofs << "ProxyTransport: Going to return " << copied - << " bytes from proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - memcpy(data, r_buffer_.data_.begin() + r_buffer_.start_, copied); - - // - // Update the buffer status. - // - - r_buffer_.length_ -= copied; - - if (r_buffer_.length_ == 0) - { - r_buffer_.start_ = 0; - } - else - { - r_buffer_.start_ += copied; - - #ifdef TEST - *logofs << "ProxyTransport: There are still " << r_buffer_.length_ - << " bytes in read buffer for proxy FD#" << fd_ - << ".\n" << logofs_flush; - #endif - } - - return copied; -} - -// -// If required compress data, else write it to socket. -// - -int ProxyTransport::write(T_write type, const unsigned char *data, const unsigned int size) -{ - #ifdef TEST - if (size == 0) - { - *logofs << "ProxyTransport: WARNING! Write called for FD#" - << fd_ << " without any data to write.\n" - << logofs_flush; - - return 0; - } - #endif - - // - // If there is no compression revert to - // plain socket management. - // - - if (control -> LocalStreamCompression == 0) - { - int result = Transport::write(type, data, size); - - if (result <= 0) - { - return result; - } - - statistics -> addBytesOut(result); - - statistics -> updateBitrate(result); - - FlushCallback(result); - - return result; - } - - #ifdef DEBUG - *logofs << "ProxyTransport: Going to compress " << size - << " bytes to write buffer for proxy FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - // - // Compress data into the write buffer. - // - - int saveTotalIn = w_stream_.total_in; - int saveTotalOut = w_stream_.total_out; - - int oldTotalIn = saveTotalIn; - int oldTotalOut = saveTotalOut; - - int diffTotalIn; - int diffTotalOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: oldTotalIn = " << oldTotalIn - << ".\n" << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: oldTotalOut = " << oldTotalOut - << ".\n" << logofs_flush; - #endif - - w_stream_.next_in = (Bytef *) data; - w_stream_.avail_in = size; - - // - // Let ZLIB use all the space already - // available in the buffer. - // - - unsigned int newAvailOut = w_buffer_.data_.size() - w_buffer_.start_ - - w_buffer_.length_; - - #ifdef TEST - *logofs << "ProxyTransport: Initial compress buffer is " - << newAvailOut << " bytes.\n" << logofs_flush; - #endif - - for (;;) - { - #ifdef INSPECT - *logofs << "\nProxyTransport: Running the compress loop.\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.length_ = " - << w_buffer_.length_ << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.data_.size() = " - << w_buffer_.data_.size() << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: newAvailOut = " - << newAvailOut << ".\n" - << logofs_flush; - #endif - - if (resize(w_buffer_, newAvailOut) < 0) - { - return -1; - } - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.data_.size() = " - << w_buffer_.data_.size() << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.next_in = " - << (void *) w_stream_.next_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.avail_in = " - << w_stream_.avail_in << ".\n" - << logofs_flush; - #endif - - w_stream_.next_out = w_buffer_.data_.begin() + w_buffer_.start_ + - w_buffer_.length_; - - w_stream_.avail_out = newAvailOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.next_out = " - << (void *) w_stream_.next_out << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.avail_out = " - << w_stream_.avail_out << ".\n" - << logofs_flush; - #endif - - int result = deflate(&w_stream_, (type == write_delayed ? - Z_NO_FLUSH : Z_SYNC_FLUSH)); - - #ifdef INSPECT - *logofs << "ProxyTransport: Called deflate() result is " - << result << ".\n" << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.avail_in = " - << w_stream_.avail_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.avail_out = " - << w_stream_.avail_out << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.total_in = " - << w_stream_.total_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.total_out = " - << w_stream_.total_out << ".\n" - << logofs_flush; - #endif - - diffTotalOut = w_stream_.total_out - oldTotalOut; - diffTotalIn = w_stream_.total_in - oldTotalIn; - - #ifdef INSPECT - *logofs << "ProxyTransport: diffTotalIn = " - << diffTotalIn << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: diffTotalOut = " - << diffTotalOut << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.length_ = " - << w_buffer_.length_ << ".\n" - << logofs_flush; - #endif - - w_buffer_.length_ += diffTotalOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.length_ = " - << w_buffer_.length_ << ".\n" - << logofs_flush; - #endif - - oldTotalOut = w_stream_.total_out; - oldTotalIn = w_stream_.total_in; - - if (result == Z_OK) - { - if (w_stream_.avail_in == 0 && w_stream_.avail_out > 0) - { - break; - } - } - else if (result == Z_BUF_ERROR && w_stream_.avail_out > 0 && - w_stream_.avail_in == 0) - { - #ifdef TEST - *logofs << "ProxyTransport: WARNING! Raised Z_BUF_ERROR compressing data.\n" - << logofs_flush; - #endif - - break; - } - else - { - #ifdef PANIC - *logofs << "ProxyTransport: PANIC! Compression of data failed. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Compression of data failed. Error is '" - << zError(result) << "'.\n"; - - finish(); - - return -1; - } - - // - // Add more bytes to the buffer. - // - - if (newAvailOut < thresholdSize_) - { - newAvailOut = thresholdSize_; - } - - #ifdef TEST - *logofs << "ProxyTransport: Need to add " << newAvailOut - << " bytes to the compress buffer in write.\n" - << logofs_flush; - #endif - } - - diffTotalIn = w_stream_.total_in - saveTotalIn; - diffTotalOut = w_stream_.total_out - saveTotalOut; - - #ifdef TEST - - *logofs << "ProxyTransport: Compressed data from " - << diffTotalIn << " to " << diffTotalOut - << " bytes.\n" << logofs_flush; - - if (diffTotalIn != (int) size) - { - #ifdef PANIC - *logofs << "ProxyTransport: PANIC! Bytes provided to ZLIB stream " - << "should be " << size << " but they look to be " - << diffTotalIn << ".\n" << logofs_flush; - #endif - } - - #endif - - // - // Find out what we have to do with the - // produced data. - // - - if (type == write_immediate) - { - // - // If user requested an immediate write we - // flushed the ZLIB buffer. We can now reset - // the counter and write data to socket. - // - - flush_ = 0; - - #ifdef TEST - *logofs << "ProxyTransport: Write buffer for proxy FD#" << fd_ - << " has data for " << w_buffer_.length_ << " bytes.\n" - << logofs_flush; - - *logofs << "ProxyTransport: Start is " << w_buffer_.start_ - << " length is " << w_buffer_.length_ << " flush is " - << flush_ << " size is " << w_buffer_.data_.size() - << " capacity is " << w_buffer_.data_.capacity() - << ".\n" << logofs_flush; - #endif - - // - // Alternatively may try to write only if - // the socket is not blocked. - // - // if (w_buffer_.length_ > 0 && blocked_ == 0) - // { - // ... - // } - // - - if (w_buffer_.length_ > 0) - - { - #ifdef TEST - *logofs << "ProxyTransport: Writing " << w_buffer_.length_ - << " bytes of produced data to FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - int result = Transport::flush(); - - if (result < 0) - { - return -1; - } - } - } - else - { - // - // We haven't flushed the ZLIB compression - // buffer, so user will have to call proxy - // transport's flush explicitly. - // - - flush_ += diffTotalIn; - } - - // - // We either wrote the data or added it to the - // write buffer. It's convenient to update the - // counters at this stage to get the current - // bitrate earlier. - // - - statistics -> addCompressedBytes(diffTotalIn, diffTotalOut); - - statistics -> addBytesOut(diffTotalOut); - - statistics -> updateBitrate(diffTotalOut); - - FlushCallback(diffTotalOut); - - #ifdef TEST - *logofs << "ProxyTransport: Write buffer for proxy FD#" << fd_ - << " has data for " << w_buffer_.length_ << " bytes.\n" - << logofs_flush; - - *logofs << "ProxyTransport: Start is " << w_buffer_.start_ - << " length is " << w_buffer_.length_ << " flush is " - << flush_ << " size is " << w_buffer_.data_.size() - << " capacity is " << w_buffer_.data_.capacity() - << ".\n" << logofs_flush; - #endif - - return size; -} - -// -// Write data to its file descriptor. -// - -int ProxyTransport::flush() -{ - // - // If there is no compression or we already compressed - // outgoing data and just need to write it to socket - // because of previous incomplete writes then revert - // to plain socket management. - // - - if (flush_ == 0 || control -> LocalStreamCompression == 0) - { - int result = Transport::flush(); - - if (result < 0) - { - return -1; - } - - return result; - } - - #ifdef DEBUG - *logofs << "ProxyTransport: Going to flush compression on " - << "proxy FD#" << fd_ << ".\n" << logofs_flush; - #endif - - #ifdef TEST - *logofs << "ProxyTransport: Flush counter for proxy FD#" << fd_ - << " is " << flush_ << " bytes.\n" << logofs_flush; - #endif - - // - // Flush ZLIB stream into the write buffer. - // - - int saveTotalIn = w_stream_.total_in; - int saveTotalOut = w_stream_.total_out; - - int oldTotalIn = saveTotalIn; - int oldTotalOut = saveTotalOut; - - int diffTotalOut; - int diffTotalIn; - - #ifdef INSPECT - *logofs << "ProxyTransport: oldTotalIn = " << oldTotalIn - << ".\n" << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: oldTotalOut = " << oldTotalOut - << ".\n" << logofs_flush; - #endif - - w_stream_.next_in = w_buffer_.data_.begin() + w_buffer_.start_ + w_buffer_.length_; - w_stream_.avail_in = 0; - - // - // Let ZLIB use all the space already - // available in the buffer. - // - - unsigned int newAvailOut = w_buffer_.data_.size() - w_buffer_.start_ - - w_buffer_.length_; - - #ifdef DEBUG - *logofs << "ProxyTransport: Initial flush buffer is " - << newAvailOut << " bytes.\n" << logofs_flush; - #endif - - for (;;) - { - #ifdef INSPECT - *logofs << "\nProxyTransport: Running the flush loop.\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.length_ = " - << w_buffer_.length_ << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.data_.size() = " - << w_buffer_.data_.size() << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: newAvailOut = " - << newAvailOut << ".\n" - << logofs_flush; - #endif - - if (resize(w_buffer_, newAvailOut) < 0) - { - return -1; - } - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.data_.size() = " - << w_buffer_.data_.size() << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.next_in = " - << (void *) w_stream_.next_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.avail_in = " - << w_stream_.avail_in << ".\n" - << logofs_flush; - #endif - - w_stream_.next_out = w_buffer_.data_.begin() + w_buffer_.start_ + - w_buffer_.length_; - - w_stream_.avail_out = newAvailOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.next_out = " - << (void *) w_stream_.next_out << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.avail_out = " - << w_stream_.avail_out << ".\n" - << logofs_flush; - #endif - - int result = deflate(&w_stream_, Z_SYNC_FLUSH); - - #ifdef INSPECT - *logofs << "ProxyTransport: Called deflate() result is " - << result << ".\n" << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.avail_in = " - << w_stream_.avail_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.avail_out = " - << w_stream_.avail_out << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.total_in = " - << w_stream_.total_in << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_stream_.total_out = " - << w_stream_.total_out << ".\n" - << logofs_flush; - #endif - - diffTotalOut = w_stream_.total_out - oldTotalOut; - diffTotalIn = w_stream_.total_in - oldTotalIn; - - #ifdef INSPECT - *logofs << "ProxyTransport: diffTotalIn = " - << diffTotalIn << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: diffTotalOut = " - << diffTotalOut << ".\n" - << logofs_flush; - #endif - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.length_ = " - << w_buffer_.length_ << ".\n" - << logofs_flush; - #endif - - w_buffer_.length_ += diffTotalOut; - - #ifdef INSPECT - *logofs << "ProxyTransport: w_buffer_.length_ = " - << w_buffer_.length_ << ".\n" - << logofs_flush; - #endif - - oldTotalOut = w_stream_.total_out; - oldTotalIn = w_stream_.total_in; - - if (result == Z_OK) - { - if (w_stream_.avail_in == 0 && w_stream_.avail_out > 0) - { - break; - } - } - else if (result == Z_BUF_ERROR && w_stream_.avail_out > 0 && - w_stream_.avail_in == 0) - { - #ifdef TEST - *logofs << "ProxyTransport: WARNING! Raised Z_BUF_ERROR flushing data.\n" - << logofs_flush; - #endif - - break; - } - else - { - #ifdef PANIC - *logofs << "ProxyTransport: PANIC! Flush of compressed data failed. " - << "Error is '" << zError(result) << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Flush of compressed data failed. Error is '" - << zError(result) << "'.\n"; - - finish(); - - return -1; - } - - // - // Add more bytes to the buffer. - // - - if (newAvailOut < thresholdSize_) - { - newAvailOut = thresholdSize_; - } - - #ifdef TEST - *logofs << "ProxyTransport: Need to add " << newAvailOut - << " bytes to the compress buffer in flush.\n" - << logofs_flush; - #endif - } - - diffTotalIn = w_stream_.total_in - saveTotalIn; - diffTotalOut = w_stream_.total_out - saveTotalOut; - - #ifdef TEST - *logofs << "ProxyTransport: Compressed flush data from " - << diffTotalIn << " to " << diffTotalOut - << " bytes.\n" << logofs_flush; - #endif - - // - // Time to move data from the write - // buffer to the real link. - // - - #ifdef DEBUG - *logofs << "ProxyTransport: Reset flush counter for proxy FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - flush_ = 0; - - #ifdef TEST - *logofs << "ProxyTransport: Write buffer for proxy FD#" << fd_ - << " has data for " << w_buffer_.length_ << " bytes.\n" - << logofs_flush; - - *logofs << "ProxyTransport: Start is " << w_buffer_.start_ - << " length is " << w_buffer_.length_ << " flush is " - << flush_ << " size is " << w_buffer_.data_.size() - << " capacity is " << w_buffer_.data_.capacity() - << ".\n" << logofs_flush; - #endif - - int result = Transport::flush(); - - if (result < 0) - { - return -1; - } - - // - // Update all the counters. - // - - statistics -> addCompressedBytes(diffTotalIn, diffTotalOut); - - statistics -> addBytesOut(diffTotalOut); - - statistics -> updateBitrate(diffTotalOut); - - FlushCallback(diffTotalOut); - - return result; -} - -unsigned int ProxyTransport::getPending(unsigned char *&data) -{ - // - // Return a pointer to the data in the - // read buffer. It is up to the caller - // to ensure that the data is consumed - // before the read buffer is reused. - // - - if (r_buffer_.length_ > 0) - { - unsigned int size = r_buffer_.length_; - - data = r_buffer_.data_.begin() + r_buffer_.start_; - - #ifdef DEBUG - *logofs << "ProxyTransport: Returning " << size - << " pending bytes from proxy FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - r_buffer_.length_ = 0; - r_buffer_.start_ = 0; - - // - // Prevent the deletion of the buffer. - // - - owner_ = 0; - - return size; - } - - #ifdef TEST - *logofs << "ProxyTransport: WARNING! No pending data " - << "for proxy FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - data = NULL; - - return 0; -} - -void ProxyTransport::fullReset() -{ - blocked_ = 0; - finish_ = 0; - flush_ = 0; - - if (control -> RemoteStreamCompression) - { - inflateReset(&r_stream_); - } - - if (control -> LocalStreamCompression) - { - deflateReset(&w_stream_); - } - - if (owner_ == 1) - { - Transport::fullReset(r_buffer_); - } - - Transport::fullReset(w_buffer_); -} - -AgentTransport::AgentTransport(int fd) : Transport(fd) -{ - #ifdef TEST - *logofs << "AgentTransport: Going to create agent transport " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - type_ = transport_agent; - - // - // Set up the read buffer. - // - - r_buffer_.length_ = 0; - r_buffer_.start_ = 0; - - r_buffer_.data_.resize(initialSize_); - - // - // For now we own the buffer. - // - - owner_ = 1; - - // - // Set up the mutexes. - // - - #ifdef THREADS - - pthread_mutexattr_t m_attributes; - - pthread_mutexattr_init(&m_attributes); - - // - // Interfaces in pthread to handle mutex - // type do not work in current version. - // - - m_attributes.__mutexkind = PTHREAD_MUTEX_ERRORCHECK_NP; - - if (pthread_mutex_init(&m_read_, &m_attributes) != 0) - { - #ifdef TEST - *logofs << "AgentTransport: Child: Creation of read mutex failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - } - - if (pthread_mutex_init(&m_write_, &m_attributes) != 0) - { - #ifdef TEST - *logofs << "AgentTransport: Child: Creation of write mutex failed. " - << "Error is " << EGET() << " '" << ESTR() - << "'.\n" << logofs_flush; - #endif - } - - #endif - - #ifdef REFERENCES - *logofs << "AgentTransport: Child: Created new object at " - << this << " out of " << ++references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -AgentTransport::~AgentTransport() -{ - #ifdef TEST - *logofs << "AgentTransport: Going to destroy derived class " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - // - // Unlock and free all mutexes. - // - - #ifdef THREADS - - pthread_mutex_unlock(&m_read_); - pthread_mutex_unlock(&m_write_); - - pthread_mutex_destroy(&m_read_); - pthread_mutex_destroy(&m_write_); - - #endif - - #ifdef REFERENCES - *logofs << "AgentTransport: Child: Deleted object at " - << this << " out of " << --references_ - << " allocated references.\n" << logofs_flush; - #endif -} - -// -// Read data enqueued by the other thread. -// - -int AgentTransport::read(unsigned char *data, unsigned int size) -{ - #ifdef THREADS - - lockRead(); - - #endif - - #ifdef DEBUG - *logofs << "AgentTransport: Child: Going to read " << size - << " bytes from " << "FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - int copied = -1; - - if (r_buffer_.length_ > 0) - { - if ((int) size < r_buffer_.length_) - { - #ifdef TEST - *logofs << "AgentTransport: WARNING! Forcing a retry with " - << r_buffer_.length_ << " bytes pending and " - << size << " in the buffer.\n" - << logofs_flush; - #endif - - ESET(EAGAIN); - } - else - { - copied = (r_buffer_.length_ > ((int) size) ? - ((int) size) : r_buffer_.length_); - - memcpy(data, r_buffer_.data_.begin() + r_buffer_.start_, copied); - - // - // Update the buffer status. - // - - #ifdef TEST - *logofs << "AgentTransport: Child: Going to immediately return " - << copied << " bytes from FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - #ifdef DUMP - - *logofs << "AgentTransport: Child: Dumping content of read data.\n" - << logofs_flush; - - DumpData(data, copied); - - #endif - - r_buffer_.length_ -= copied; - - if (r_buffer_.length_ == 0) - { - r_buffer_.start_ = 0; - } - else - { - r_buffer_.start_ += copied; - - #ifdef TEST - *logofs << "AgentTransport: Child: There are still " - << r_buffer_.length_ << " bytes in read buffer for " - << "FD#" << fd_ << ".\n" << logofs_flush; - #endif - } - } - } - else - { - #ifdef DEBUG - *logofs << "AgentTransport: Child: No data can be got " - << "from read buffer for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - ESET(EAGAIN); - } - - #ifdef THREADS - - unlockRead(); - - #endif - - return copied; -} - -// -// Write data to buffer so that the other -// thread can get it. -// - -int AgentTransport::write(T_write type, const unsigned char *data, const unsigned int size) -{ - #ifdef THREADS - - lockWrite(); - - #endif - - // - // Just append data to socket's write buffer. - // Note that we don't care if buffer exceeds - // the size limits set for this type of - // transport. - // - - #ifdef TEST - *logofs << "AgentTransport: Child: Going to append " << size - << " bytes to write buffer for " << "FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - int copied = -1; - - if (resize(w_buffer_, size) < 0) - { - finish(); - - ESET(EPIPE); - } - else - { - memmove(w_buffer_.data_.begin() + w_buffer_.start_ + w_buffer_.length_, data, size); - - w_buffer_.length_ += size; - - #ifdef DUMP - - *logofs << "AgentTransport: Child: Dumping content of written data.\n" - << logofs_flush; - - DumpData(data, size); - - #endif - - #ifdef TEST - *logofs << "AgentTransport: Child: Write buffer for FD#" << fd_ - << " has data for " << w_buffer_.length_ << " bytes.\n" - << logofs_flush; - - *logofs << "AgentTransport: Child: Start is " << w_buffer_.start_ - << " length is " << w_buffer_.length_ << " size is " - << w_buffer_.data_.size() << " capacity is " - << w_buffer_.data_.capacity() << ".\n" - << logofs_flush; - #endif - - copied = size; - } - - // - // Let child access again the read buffer. - // - - #ifdef THREADS - - unlockWrite(); - - #endif - - return copied; -} - -int AgentTransport::flush() -{ - // - // In case of memory-to-memory transport - // this function should never be called. - // - - #ifdef PANIC - *logofs << "AgentTransport: Child: PANIC! Called flush() for " - << "memory to memory transport on " << "FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Called flush() for " - << "memory to memory transport on " << "FD#" - << fd_ << ".\n"; - - HandleAbort(); -} - -int AgentTransport::drain(int limit, int timeout) -{ - // - // We can't drain the channel in the case - // of the memory-to-memory transport. Data - // is enqueued for the agent to read but - // the agent could require multiple loops - // to read it all. - // - - // - // In case of memory-to-memory transport - // this function should never be called. - // - - #ifdef PANIC - *logofs << "AgentTransport: Child: PANIC! Called drain() for " - << "memory to memory transport on " << "FD#" - << fd_ << ".\n" << logofs_flush; - #endif - - cerr << "Error" << ": Called drain() for " - << "memory to memory transport on " << "FD#" - << fd_ << ".\n"; - - HandleAbort(); -} - -unsigned int AgentTransport::getPending(unsigned char *&data) -{ - #ifdef THREADS - - lockRead(); - - #endif - - if (r_buffer_.length_ > 0) - { - unsigned int size = r_buffer_.length_; - - data = r_buffer_.data_.begin() + r_buffer_.start_; - - #ifdef DEBUG - *logofs << "AgentTransport: Child: Returning " << size - << " pending bytes from FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - r_buffer_.length_ = 0; - r_buffer_.start_ = 0; - - #ifdef THREADS - - unlockRead(); - - #endif - - // - // Prevent the deletion of the buffer. - // - - owner_ = 0; - - return size; - } - - #ifdef TEST - *logofs << "AgentTransport: WARNING! No pending data " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - #ifdef THREADS - - unlockRead(); - - #endif - - data = NULL; - - return 0; -} - -void AgentTransport::fullReset() -{ - #ifdef THREADS - - lockRead(); - lockWrite(); - - #endif - - #ifdef TEST - *logofs << "AgentTransport: Child: Resetting transport " - << "for FD#" << fd_ << ".\n" << logofs_flush; - #endif - - blocked_ = 0; - finish_ = 0; - - if (owner_ == 1) - { - Transport::fullReset(r_buffer_); - } - - Transport::fullReset(w_buffer_); -} - -int AgentTransport::enqueue(const char *data, const int size) -{ - #ifdef THREADS - - lockRead(); - - #endif - - if (finish_ == 1) - { - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: Returning EPIPE in " - << "write for finishing FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - ESET(EPIPE); - - return -1; - } - - // - // Always allow the agent to write - // all its data. - // - - int toPut = size; - - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: Going to put " << toPut - << " bytes into read buffer for FD#" << fd_ - << ". Buffer length is " << r_buffer_.length_ - << ".\n" << logofs_flush; - #endif - - if (resize(r_buffer_, toPut) < 0) - { - finish(); - - #ifdef THREADS - - unlockRead(); - - #endif - - return -1; - } - - memcpy(r_buffer_.data_.begin() + r_buffer_.start_ + r_buffer_.length_, data, toPut); - - r_buffer_.length_ += toPut; - - #if defined(DUMP) && defined(PARENT) - - *logofs << "AgentTransport: Parent: Dumping content of enqueued data.\n" - << logofs_flush; - - DumpData((const unsigned char *) data, toPut); - - #endif - - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: Read buffer for FD#" << fd_ - << " has now data for " << r_buffer_.length_ - << " bytes.\n" << logofs_flush; - - *logofs << "AgentTransport: Parent: Start is " << r_buffer_.start_ - << " length is " << r_buffer_.length_ << " size is " - << r_buffer_.data_.size() << " capacity is " - << r_buffer_.data_.capacity() << ".\n" - << logofs_flush; - #endif - - #ifdef THREADS - - unlockRead(); - - #endif - - return toPut; -} - -int AgentTransport::dequeue(char *data, int size) -{ - #ifdef THREADS - - lockWrite(); - - #endif - - if (w_buffer_.length_ == 0) - { - if (finish_ == 1) - { - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: Returning 0 in read " - << "for finishing FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - return 0; - } - - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: No data can be read " - << "from write buffer for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - ESET(EAGAIN); - - #ifdef THREADS - - unlockWrite(); - - #endif - - return -1; - } - - // - // Return as many bytes as possible. - // - - int toGet = ((int) size > w_buffer_.length_ ? w_buffer_.length_ : size); - - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: Going to get " << toGet - << " bytes from write buffer for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - memcpy(data, w_buffer_.data_.begin() + w_buffer_.start_, toGet); - - w_buffer_.start_ += toGet; - w_buffer_.length_ -= toGet; - - #if defined(DUMP) && defined(PARENT) - - *logofs << "AgentTransport: Parent: Dumping content of dequeued data.\n" - << logofs_flush; - - DumpData((const unsigned char *) data, toGet); - - #endif - - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: Write buffer for FD#" << fd_ - << " has now data for " << length() << " bytes.\n" - << logofs_flush; - - *logofs << "AgentTransport: Parent: Start is " << w_buffer_.start_ - << " length is " << w_buffer_.length_ << " size is " - << w_buffer_.data_.size() << " capacity is " - << w_buffer_.data_.capacity() << ".\n" - << logofs_flush; - #endif - - #ifdef THREADS - - unlockWrite(); - - #endif - - return toGet; -} - -int AgentTransport::dequeuable() -{ - if (finish_ == 1) - { - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: Returning EPIPE in " - << "readable for finishing FD#" << fd_ - << ".\n" << logofs_flush; - #endif - - ESET(EPIPE); - - return -1; - } - - #if defined(PARENT) && defined(TEST) - *logofs << "AgentTransport: Parent: Returning " - << w_buffer_.length_ << " as data readable " - << "from read buffer for FD#" << fd_ << ".\n" - << logofs_flush; - #endif - - return w_buffer_.length_; -} - -#ifdef THREADS - -int AgentTransport::lockRead() -{ - for (;;) - { - int result = pthread_mutex_lock(&m_read_); - - if (result == 0) - { - #ifdef DEBUG - *logofs << "AgentTransport: Read mutex locked by thread id " - << pthread_self() << ".\n" << logofs_flush; - #endif - - return 0; - } - else if (EGET() == EINTR) - { - continue; - } - else - { - #ifdef WARNING - *logofs << "AgentTransport: WARNING! Locking of read mutex by thread id " - << pthread_self() << " returned " << result << ". Error is '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - return result; - } - } -} - -int AgentTransport::lockWrite() -{ - for (;;) - { - int result = pthread_mutex_lock(&m_write_); - - if (result == 0) - { - #ifdef DEBUG - *logofs << "AgentTransport: Write mutex locked by thread id " - << pthread_self() << ".\n" << logofs_flush; - #endif - - return 0; - } - else if (EGET() == EINTR) - { - continue; - } - else - { - #ifdef WARNING - *logofs << "AgentTransport: WARNING! Locking of write mutex by thread id " - << pthread_self() << " returned " << result << ". Error is '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - return result; - } - } -} - -int AgentTransport::unlockRead() -{ - for (;;) - { - int result = pthread_mutex_unlock(&m_read_); - - if (result == 0) - { - #ifdef DEBUG - *logofs << "AgentTransport: Read mutex unlocked by thread id " - << pthread_self() << ".\n" << logofs_flush; - #endif - - return 0; - } - else if (EGET() == EINTR) - { - continue; - } - else - { - #ifdef WARNING - *logofs << "AgentTransport: WARNING! Unlocking of read mutex by thread id " - << pthread_self() << " returned " << result << ". Error is '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - return result; - } - } -} - -int AgentTransport::unlockWrite() -{ - for (;;) - { - int result = pthread_mutex_unlock(&m_write_); - - if (result == 0) - { - #ifdef DEBUG - *logofs << "AgentTransport: Write mutex unlocked by thread id " - << pthread_self() << ".\n" << logofs_flush; - #endif - - return 0; - } - else if (EGET() == EINTR) - { - continue; - } - else - { - #ifdef WARNING - *logofs << "AgentTransport: WARNING! Unlocking of write mutex by thread id " - << pthread_self() << " returned " << result << ". Error is '" - << ESTR() << "'.\n" << logofs_flush; - #endif - - return result; - } - } -} - -#endif diff --git a/nxcomp/Transport.h b/nxcomp/Transport.h deleted file mode 100644 index 047396af6..000000000 --- a/nxcomp/Transport.h +++ /dev/null @@ -1,577 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Transport_H -#define Transport_H - -#include -#include - -#include -#include -#include - -#include "Misc.h" -#include "Control.h" - -#include "Types.h" -#include "Timestamp.h" -#include "Socket.h" - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Define this to lock and unlock the -// memory-to-memory transport buffers -// before they are accessed. The code -// is outdated and doesn't work with -// the current pthread library. -// - -#undef THREADS - -// -// Define this to know when a socket -// is created or destroyed. -// - -#undef REFERENCES - -// -// Size of buffer if not set by user. -// - -#define TRANSPORT_BUFFER_DEFAULT_SIZE 16384 - -// -// Type of transport. -// - -typedef enum -{ - transport_base, - transport_proxy, - transport_agent, - transport_last_tag - -} T_transport_type; - -// -// This class handles the buffered I/O on -// the network sockets. -// - -// -// TODO: This class is useful but adds a lot of -// overhead. There are many improvements we can -// make here: -// -// - There should be a generic Buffer class, ac- -// comodating a list of memory buffers. This -// would enable the use of the readv() and -// writev() functions to perform the I/O on -// the socket. -// -// - The buffering should be moved to the Write- -// Buffer and ReadBuffer classes. By performing -// the buffering here and there, we are dupli- -// cating a lot of code and are adding a lot -// of useless memory copies. -// -// - Stream compression should be removed. The -// proxy should compress the frames based on -// the type and should include the length of -// the decompressed data in the header of the -// packet. Besides avoiding the compression -// of packets that cannot be reduced in size, -// we would also save the additional memory -// allocations due to the fact that we don't -// know the size of the decode buffer at the -// time we read the packet from the network. -// -// - The other utilities implemented here, like -// the functions forcing a write on the socket -// or waiting for more data to become available -// should be moved to the Proxy or the Channel -// classes. -// - -class Transport -{ - public: - - // - // Member functions. - // - - Transport(int fd); - - virtual ~Transport(); - - int fd() const - { - return fd_; - } - - T_transport_type getType() - { - return type_; - } - - // - // Virtual members redefined by proxy - // and 'memory-to-memory' I/O layers. - // - - virtual int read(unsigned char *data, unsigned int size); - - virtual int write(T_write type, const unsigned char *data, const unsigned int size); - - virtual int flush(); - - virtual int drain(int limit, int timeout); - - virtual void finish() - { - fullReset(); - - finish_ = 1; - } - - virtual int length() const - { - return w_buffer_.length_; - } - - virtual int pending() const - { - return 0; - } - - virtual int readable() const - { - return GetBytesReadable(fd_); - } - - virtual int writable() const - { - return GetBytesWritable(fd_); - } - - virtual int queued() const - { - return GetBytesQueued(fd_); - } - - virtual int flushable() const - { - return 0; - } - - virtual int wait(int timeout) const; - - void setSize(unsigned int initialSize, - unsigned int thresholdSize, - unsigned int maximumSize); - - // - // Return a pointer to the data - // in the read buffer. - // - - virtual unsigned int getPending(unsigned char *&data) - { - data = NULL; - - return 0; - } - - virtual void pendingReset() - { - } - - virtual void partialReset() - { - partialReset(w_buffer_); - } - - virtual void fullReset(); - - int blocked() const - { - return blocked_; - } - - protected: - - // - // Make room in the buffer to accommodate - // at least size bytes. - // - - int resize(T_buffer &buffer, const int &size); - - void partialReset(T_buffer &buffer) - { - if (buffer.length_ == 0 && - (buffer.data_.size() > initialSize_ || - buffer.data_.capacity() > initialSize_)) - { - fullReset(buffer); - } - } - - void fullReset(T_buffer &buffer); - - // - // Data members. - // - - int fd_; - - int blocked_; - int finish_; - - T_buffer w_buffer_; - - unsigned int initialSize_; - unsigned int thresholdSize_; - unsigned int maximumSize_; - - T_transport_type type_; - - private: - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -// -// This class handles buffered I/O and -// compression of the proxy stream. -// - -class ProxyTransport : public Transport -{ - public: - - ProxyTransport(int fd); - - virtual ~ProxyTransport(); - - virtual int read(unsigned char *data, unsigned int size); - - virtual int write(T_write type, const unsigned char *data, const unsigned int size); - - virtual int flush(); - - // - // Same as in the base class. - // - // virtual int drain(int limit, int timeout); - // - // virtual void finish(); - // - - // - // Same as in the base class. - // - // virtual int length() const - // - - virtual int pending() const - { - return r_buffer_.length_; - } - - // - // Same as in the base class. - // - // virtual int readable() const; - // - // virtual int writable() const; - // - // virtual int queued() const; - // - - virtual int flushable() const - { - return flush_; - } - - // - // Same as in the base class, but - // should not be called. - // - // int drained() const; - // - // Same as in the base class. - // - // virtual int wait(int timeout) const; - // - // Same as in the base class. - // - // void setSize(unsigned int initialSize, - // unsigned int thresholdSize, - // unsigned int maximumSize); - // - - virtual unsigned int getPending(unsigned char *&data); - - virtual void pendingReset() - { - owner_ = 1; - } - - virtual void partialReset() - { - if (owner_ == 1) - { - Transport::partialReset(r_buffer_); - } - - Transport::partialReset(w_buffer_); - } - - virtual void fullReset(); - - // - // Same as in the base class. - // - // int blocked() const; - // - - protected: - - int flush_; - int owner_; - - T_buffer r_buffer_; - - z_stream r_stream_; - z_stream w_stream_; - - private: - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -// -// Handle memory-to-memory data transfers between -// an agent and the proxy. -// - -class AgentTransport : public Transport -{ - public: - - AgentTransport(int fd); - - virtual ~AgentTransport(); - - virtual int read(unsigned char *data, unsigned int size); - - virtual int write(T_write type, const unsigned char *data, const unsigned int size); - - // - // These two should never be called. - // - - virtual int flush(); - - virtual int drain(int limit, int timeout); - - // - // Same as in the base class. - // - // virtual void finish(); - // - - // - // Same as in the base class. - // - // virtual int length() const - // - - virtual int pending() const - { - return r_buffer_.length_; - } - - // - // These are intended to operate only - // on the internal buffers. - // - - virtual int readable() const - { - return r_buffer_.length_; - } - - virtual int writable() const - { - return control -> TransportMaximumBufferSize; - } - - virtual int queued() const - { - return 0; - } - - // - // Same as in the base class. - // - // virtual int flushable() const; - // - // Same as in the base class, but - // should not be called. - // - // int drained() const; - // - - // - // Return immediately or will - // block until the timeout. - // - - virtual int wait(int timeout) const - { - return 0; - } - - // - // Same as in the base class. - // - // void setSize(unsigned int initialSize, - // unsigned int thresholdSize, - // unsigned int maximumSize); - // - - virtual unsigned int getPending(unsigned char *&data); - - virtual void pendingReset() - { - owner_ = 1; - } - - virtual void partialReset() - { - if (owner_ == 1) - { - Transport::partialReset(r_buffer_); - } - - Transport::partialReset(w_buffer_); - } - - virtual void fullReset(); - - // - // Same as in the base class. - // - // int blocked() const; - // - - // - // The following are specific of the - // memory-to-memory transport. - // - - int enqueue(const char *data, const int size); - - int dequeue(char *data, int size); - - int queuable() - { - // - // Always allow the agent to enqueue - // more data. - // - - return control -> TransportMaximumBufferSize; - } - - int dequeuable(); - - protected: - - // - // Lock the buffer to handle reads and - // writes safely. - // - - #ifdef THREADS - - int lockRead(); - int lockWrite(); - - int unlockRead(); - int unlockWrite(); - - #endif - - // - // Data members. - // - - int owner_; - - T_buffer r_buffer_; - - // - // Mutexes for safe read and write. - // - - #ifdef THREADS - - pthread_mutex_t m_read_; - pthread_mutex_t m_write_; - - #endif - - private: - - #ifdef REFERENCES - - static int references_; - - #endif -}; - -#endif /* Transport_H */ diff --git a/nxcomp/Types.h b/nxcomp/Types.h deleted file mode 100644 index e82664c81..000000000 --- a/nxcomp/Types.h +++ /dev/null @@ -1,271 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Types_H -#define Types_H - -using namespace std; - -#include -#include -#include -#include - -#include "MD5.h" - -// -// This is MD5 length. -// - -#define MD5_LENGTH 16 - -// -// Types of repositories. Replace the original -// clear() methods from STL in order to actually -// free the unused memory. -// - -class Message; - -class T_data : public vector < unsigned char > -{ - public: - - unsigned char *begin() - { - return &*(vector < unsigned char >::begin()); - } - - const unsigned char *begin() const - { - return &*(vector < unsigned char >::begin()); - } - - // Avoid overriding clear() when using libc++. Fiddling with STL internals - // doesn't really seem like a good idea to me anyway. - #ifndef _LIBCPP_VECTOR - void clear() - { - #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) - - #if defined(__GLIBCPP_INTERNAL_VECTOR_H) - - _Destroy(_M_start, _M_finish); - - #else /* #if defined(__GLIBCPP_INTERNAL_VECTOR_H) */ - - destroy(_M_start, _M_finish); - - #endif /* #if defined(__GLIBCPP_INTERNAL_VECTOR_H) */ - - _M_deallocate(_M_start, _M_end_of_storage - _M_start); - - _M_start = _M_finish = _M_end_of_storage = 0; - - #else /* #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) */ - - #if defined(_GLIBCXX_VECTOR) - - _Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); - - _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); - - this->_M_impl._M_start = this->_M_impl._M_finish = this->_M_impl._M_end_of_storage = 0; - - #else /* #if defined(_GLIBCXX_VECTOR) */ - - destroy(start, finish); - - deallocate(); - - start = finish = end_of_storage = 0; - - #endif /* #if defined(_GLIBCXX_VECTOR) */ - - #endif /* #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) */ - } - #endif /* #ifdef _LIBCPP_VECTOR */ -}; - -class T_messages : public vector < Message * > -{ - public: - - // Avoid overriding clear() when using libc++. Fiddling with STL internals - // doesn't really seem like a good idea to me anyway. - #ifndef _LIBCPP_VECTOR - void clear() - { - #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) - - #if defined(__GLIBCPP_INTERNAL_VECTOR_H) - - _Destroy(_M_start, _M_finish); - - #else /* #if defined(__GLIBCPP_INTERNAL_VECTOR_H) */ - - destroy(_M_start, _M_finish); - - #endif /* #if defined(__GLIBCPP_INTERNAL_VECTOR_H) */ - - _M_deallocate(_M_start, _M_end_of_storage - _M_start); - - _M_start = _M_finish = _M_end_of_storage = 0; - - #else /* #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) */ - - #if defined(_GLIBCXX_VECTOR) - - _Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); - - _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); - - this->_M_impl._M_start = this->_M_impl._M_finish = this->_M_impl._M_end_of_storage = 0; - - #else /* #if defined(_GLIBCXX_VECTOR) */ - - destroy(start, finish); - - deallocate(); - - start = finish = end_of_storage = 0; - - #endif /* #if defined(_GLIBCXX_VECTOR) */ - - #endif /* #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) */ - } - #endif /* #ifndef _LIBCPP_VECTOR */ -}; - -typedef md5_byte_t * T_checksum; - -struct T_less -{ - bool operator()(T_checksum a, T_checksum b) const - { - return (memcmp(a, b, MD5_LENGTH) < 0); - } -}; - -typedef map < T_checksum, int, T_less > T_checksums; - -class Split; - -typedef list < Split * > T_splits; - -class File; - -struct T_older -{ - bool operator()(File *a, File *b) const; -}; - -typedef set < File *, T_older > T_files; - -typedef list < int > T_list; - -// -// Used to accommodate data to be read and -// written to a socket. -// - -typedef struct -{ - T_data data_; - int length_; - int start_; -} -T_buffer; - -// -// The message store operation that was -// executed for the message. The channels -// use these values to determine how to -// handle the message after it has been -// received at the decoding side. -// - -// Since ProtoStep8 (#issue 108) -enum T_store_action -{ - is_hit, - is_added, - is_discarded, - is_removed -}; - -// Since ProtoStep8 (#issue 108) -#define IS_HIT is_hit -#define IS_ADDED is_added - -enum T_checksum_action -{ - use_checksum, - discard_checksum -}; - -enum T_data_action -{ - use_data, - discard_data -}; - -// -// Message is going to be weighted for -// deletion at insert or cleanup time? -// - -enum T_rating -{ - rating_for_insert, - rating_for_clean -}; - -// -// How to handle the writes to the X -// and proxy connections. -// - -enum T_write -{ - write_immediate, - write_delayed -}; - -enum T_flush -{ - flush_if_needed, - flush_if_any -}; - -// -// This is the value to indicate an -// invalid position in the message -// store. -// - -static const int nothing = -1; - -#endif /* Types_H */ diff --git a/nxcomp/Unpack.cpp b/nxcomp/Unpack.cpp deleted file mode 100644 index 50ae890b6..000000000 --- a/nxcomp/Unpack.cpp +++ /dev/null @@ -1,1510 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Misc.h" -#include "Unpack.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Used for the ZLIB decompression -// of RGB, alpha and colormap data. -// - -z_stream unpackStream; - -static int unpackInitialized; - -int Unpack8To8(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack8To8(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack8To16(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack8To16(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack8To24(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack8To24(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack8To32(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack8To32(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack15To16(const unsigned char *data, unsigned char *out, - unsigned char *end); - -int Unpack15To24(const unsigned char *data, unsigned char *out, - unsigned char *end); - -int Unpack15To32(const unsigned char *data, unsigned char *out, - unsigned char *end); - -int Unpack16To16(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack16To16(const unsigned char *data, unsigned char *out, - unsigned char *end, int imageByteOrder); - -int Unpack16To24(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack16To24(const unsigned char *data, unsigned char *out, - unsigned char *end, int imageByteOrder); - -int Unpack16To32(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack16To32(const unsigned char *data, unsigned char *out, - unsigned char *end, int imageByteOrder); - -int Unpack24To24(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack24To24(const unsigned char *data, unsigned char *out, - unsigned char *end); - -int Unpack24To32(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - -int Unpack24To32(const unsigned char *data, unsigned char *out, unsigned char *end); - -int Unpack32To32(const T_colormask *colormask, const unsigned int *data, - unsigned int *out, unsigned int *end); - - -void UnpackInit() -{ - if (unpackInitialized == 0) - { - unpackStream.zalloc = (alloc_func) 0; - unpackStream.zfree = (free_func) 0; - unpackStream.opaque = (voidpf) 0; - - unpackStream.next_in = (Bytef *) 0; - unpackStream.avail_in = 0; - - int result = inflateInit2(&unpackStream, 15); - - if (result != Z_OK) - { - #ifdef PANIC - *logofs << "UnpackInit: PANIC! Cannot initialize the Z stream " - << "for decompression. Error is '" << zError(result) - << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot initialize the Z stream for " - << "decompression. Error is '" << zError(result) - << "'.\n"; - } - else - { - unpackInitialized = 1; - } - } -} - -void UnpackDestroy() -{ - if (unpackInitialized == 1) - { - inflateEnd(&unpackStream); - - unpackInitialized = 0; - } -} - -// -// Get bits per pixel set by client -// according to display geometry. -// - -int UnpackBitsPerPixel(T_geometry *geometry, unsigned int depth) -{ - switch (depth) - { - case 1: - { - return geometry -> depth1_bpp; - } - case 4: - { - return geometry -> depth4_bpp; - } - case 8: - { - return geometry -> depth8_bpp; - } - case 15: - case 16: - { - return geometry -> depth16_bpp; - } - case 24: - { - return geometry -> depth24_bpp; - } - case 32: - { - return geometry -> depth32_bpp; - } - default: - { - return 0; - } - } -} - -int Unpack8To8(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack8To8: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - memcpy(out, data, end - out); - - return 1; -} - -int Unpack8To16(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack8To16: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - unsigned short *out16 = (unsigned short *) out; - unsigned short *end16 = (unsigned short *) end; - - while (out16 < end16) - { - if (*data == 0) - { - *out16 = 0x0; - } - else if (*data == 0xff) - { - *out16 = 0xffff; - } - else - { - // - // Pixel layout: - // - // 8bits 00RRGGBB -> 16bits RR000GG0 000BB000. - // - - *out16 = (((((*data & 0x30) << 2) | colormask -> correction_mask) << 8) & 0xf800) | - (((((*data & 0xc) << 4) | colormask -> correction_mask) << 3) & 0x7e0) | - (((((*data & 0x3) << 6) | colormask -> correction_mask) >> 3) & 0x1f); - } - - out16++; - data++; - } - - return 1; -} - -int Unpack8To24(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack8To24: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - while (out < (end - 2)) - { - if (*data == 0x00) - { - out[0] = out[1] = out[2] = 0x00; - } - else if (*data == 0xff) - { - out[0] = out[1] = out[2] = 0xff; - } - else - { - // - // Pixel layout: - // - // 8bits 00RRGGBB -> 24bits RR000000 GG00000 BB000000. - // - - out[0] = (((*data & 0x30) << 2) | colormask -> correction_mask); - out[1] = (((*data & 0x0c) << 4) | colormask -> correction_mask); - out[2] = (((*data & 0x03) << 6) | colormask -> correction_mask); - } - - out += 3; - data += 1; - } - - return 1; -} - -int Unpack8To32(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack8To32: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - unsigned int *out32 = (unsigned int *) out; - unsigned int *end32 = (unsigned int *) end; - - while (out32 < end32) - { - if (*data == 0) - { - *out32 = 0x0; - } - else if (*data == 0xff) - { - *out32 = 0xffffff; - } - else - { - *out32 = ((((*data & 0x30) << 2) | colormask -> correction_mask) << 16) | - ((((*data & 0xc) << 4) | colormask -> correction_mask) << 8) | - (((*data & 0x3) << 6) | colormask -> correction_mask); - } - - out32++; - data++; - } - - return 1; -} - -int Unpack8(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size) -{ - int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); - - int (*unpack)(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - - switch (dst_bpp) - { - case 8: - { - unpack = Unpack8To8; - - break; - } - case 16: - { - unpack = Unpack8To16; - - break; - } - case 24: - { - unpack = Unpack8To24; - - break; - } - case 32: - { - unpack = Unpack8To32; - - break; - } - default: - { - #ifdef PANIC - *logofs << "Unpack8: PANIC! Bad destination bits per pixel " - << dst_bpp << ". Only 16/24/32 are supported.\n" - << logofs_flush; - #endif - - return -1; - } - } - - if (dst_bpp == 24) - { - unsigned char *dst_end = dst_data; - - #ifdef TEST - *logofs << "Unpack8: Handling 24 bits with dst_size " - << dst_size << ".\n" << logofs_flush; - #endif - - for (int y = 0; y < dst_height; y++) - { - dst_data = dst_end; - - dst_end += RoundUp4(dst_width * 3); - - (*unpack)(colormask, src_data, dst_data, dst_end); - - src_data += src_width; - } - } - else - { - unsigned char *dst_end = dst_data + dst_size; - - (*unpack)(colormask, src_data, dst_data, dst_end); - } - - return 1; -} - -int Unpack16To16(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack16To16: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - if (colormask -> correction_mask) - { - unsigned short *data16 = (unsigned short *) data; - - unsigned short *out16 = (unsigned short *) out; - unsigned short *end16 = (unsigned short *) end; - - while (out16 < end16) - { - if (*data16 == 0x0000) - { - *out16 = 0x0000; - } - else if (*data16 == 0xffff) - { - *out16 = 0xffff; - } - else - { - // - // Pixel layout: - // - // 16bit RRRRRGGG GG0BBBBB -> RRRRRGGG GGGBBBBB. - // - - *out16 = (((((*data16 & 0xf100) >> 8) | colormask -> correction_mask) << 8) & 0xf800) | - (((((*data16 & 0x7c0) >> 3) | colormask -> correction_mask) << 3) & 0x7e0) | - (((((*data16 & 0x1f) << 3) | colormask -> correction_mask) >> 3) & 0x1f); - } - - out16++; - data16++; - } - } - else - { - #ifdef TEST - *logofs << "Unpack16To16: Using bitwise copy due to null correction mask.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) out, (unsigned char *) data, end - out); - } - - return 1; -} - -int Unpack16To24(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack16To24: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - unsigned short *data16 = (unsigned short *) data; - - - while (out < end - 2) - { - if (*data16 == 0x0) - { - out[0] = 0x00; - out[1] = 0x00; - out[2] = 0x00; - } - else if (*data16 == 0xffff) - { - out[0] = 0xff; - out[1] = 0xff; - out[2] = 0xff; - } - else - { - #ifdef TEST - *logofs << "Unpack16To24: Pixel [" << *data16 << "]\n" - << logofs_flush; - #endif - - // - // Pixel layout: - // - // 16bit 0RRRRRGG GGGBBBBB -> 24 bit RRRRR000 GGGGG000 BBBBB000 - // - - out[0] = (((*data16 & 0x7c00) >> 7) | colormask -> correction_mask); - out[1] = (((*data16 & 0x03e0) >> 2) | colormask -> correction_mask); - out[2] = (((*data16 & 0x001f) << 3) | colormask -> correction_mask); - } - - out += 3; - data16 += 1; - } - - return 1; -} - -int Unpack16To32(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack16To32: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - unsigned short *data16 = (unsigned short *) data; - - unsigned int *out32 = (unsigned int *) out; - unsigned int *end32 = (unsigned int *) end; - - while (out32 < end32) - { - if (*data16 == 0x0) - { - *out32 = 0x0; - } - else if (*data16 == 0xffff) - { - *out32 = 0xffffff; - } - else - { - *out32 = ((((*data16 & 0x7c00) >> 7) | colormask -> correction_mask) << 16) | - ((((*data16 & 0x3e0) >> 2) | colormask -> correction_mask) << 8) | - (((*data16 & 0x1f) << 3) | colormask -> correction_mask); - } - - out32++; - data16++; - } - - return 1; -} - -int Unpack16(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size) -{ - int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); - - int (*unpack)(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - - switch (dst_bpp) - { - case 16: - { - unpack = Unpack16To16; - - break; - } - case 24: - { - unpack = Unpack16To24; - - break; - } - case 32: - { - unpack = Unpack16To32; - - break; - } - default: - { - #ifdef PANIC - *logofs << "Unpack16: PANIC! Bad destination bits per pixel " - << dst_bpp << ". Only 24/32 are supported.\n" - << logofs_flush; - #endif - - return -1; - } - } - - if (dst_bpp == 24) - { - unsigned char *dst_end = dst_data; - - for (int y = 0; y < dst_height; y++) - { - dst_data = dst_end; - - dst_end += RoundUp4(dst_width * 3); - - (*unpack)(colormask, src_data, dst_data, dst_end); - - src_data += (src_width * 2); - } - - } - else - { - unsigned char *dst_end = dst_data + dst_size; - - (*unpack)(colormask, src_data, dst_data, dst_end); - } - - return 1; -} - -int Unpack24To24(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack24To24: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - if (colormask -> correction_mask) - { - while (out < end) - { - if (data[0] == 0x00 && - data[1] == 0x00 && - data[2] == 0x00) - { - out[0] = out[1] = out[2] = 0x00; - } - else if (data[0] == 0xff && - data[1] == 0xff && - data[2] == 0xff) - { - out[0] = out[1] = out[2] = 0xff; - } - else - { - out[0] = (data[0] | colormask -> correction_mask); - out[1] = (data[1] | colormask -> correction_mask); - out[2] = (data[2] | colormask -> correction_mask); - } - - out += 3; - data += 3; - } - } - else - { - #ifdef TEST - *logofs << "Unpack24To24: Using bitwise copy due to null correction mask.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) out, (unsigned char *) data, end - out); - } - - return 1; -} - -int Unpack24To32(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack24To32: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - unsigned int *out32 = (unsigned int *) out; - unsigned int *end32 = (unsigned int *) end; - - while (out32 < end32) - { - if (colormask -> color_mask == 0xff) - { - *out32 = (data[0] << 16) | (data[1] << 8) | data[2]; - } - else - { - if (data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x0) - { - *out32 = 0x0; - } - else if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) - { - *out32 = 0xffffff; - } - else - { - *out32 = (((unsigned int) data[0] | colormask -> correction_mask) << 16) | - (((unsigned int) data[1] | colormask -> correction_mask) << 8) | - ((unsigned int) data[2] | colormask -> correction_mask); - } - } - - out32 += 1; - data += 3; - } - - return 1; -} - -int Unpack24(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size) -{ - int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); - - int (*unpack)(const T_colormask *colormask, const unsigned char *data, - unsigned char *out, unsigned char *end); - - switch (dst_bpp) - { - case 24: - { - unpack = Unpack24To24; - - break; - } - case 32: - { - unpack = Unpack24To32; - - break; - } - default: - { - #ifdef PANIC - *logofs << "Unpack24: PANIC! Bad destination bits per pixel " - << dst_bpp << ". Only 32 is supported.\n" - << logofs_flush; - #endif - - return -1; - } - } - - if (dst_bpp == 24) - { - unsigned char *dst_end; - unsigned long scanline_size = RoundUp4(dst_width * dst_bpp / 8); - - dst_end = dst_data; - - #ifdef TEST - *logofs << "Unpack24: Handling 24 bits with dst_height " - << dst_height << " scanline_size " << scanline_size - << " dst_size " << dst_size << ".\n" << logofs_flush; - #endif - - for (int y = 0; y < dst_height; y++) - { - dst_data = dst_end; - - dst_end += scanline_size; - - (*unpack)(colormask, src_data, dst_data, dst_end); - - src_data += scanline_size; - } - } - else - { - unsigned char *dst_end = dst_data + dst_size; - - (*unpack)(colormask, src_data, dst_data, dst_end); - } - - return 1; -} - -int Unpack8To8(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack8To8: Unpacking " << end - out - << " bytes of colormapped data.\n" - << logofs_flush; - #endif - - while (out < end) - { - *(out++) = (unsigned char) colormap -> data[*(data++)]; - } - - return 1; -} - -int Unpack8To16(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack8To16: Unpacking " << end - out - << " bytes of colormapped data.\n" - << logofs_flush; - #endif - - unsigned short *out16 = (unsigned short *) out; - unsigned short *end16 = (unsigned short *) end; - - while (out16 < end16) - { - *(out16++) = (unsigned short) colormap -> data[*(data++)]; - } - - return 1; -} - -int Unpack8To24(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack8To24: Unpacking " << end - out - << " bytes of colormapped data.\n" - << logofs_flush; - #endif - - unsigned int value; - - while (out < end) - { - value = colormap -> data[*(data++)]; - - *(out++) = value; - *(out++) = value >> 8; - *(out++) = value >> 16; - } - - return 1; -} - -int Unpack8To32(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack8To32: Unpacking " << end - out - << " bytes of colormapped data.\n" - << logofs_flush; - #endif - - unsigned int *out32 = (unsigned int *) out; - unsigned int *end32 = (unsigned int *) end; - - while (out32 < end32) - { - *(out32++) = colormap -> data[*(data++)]; - } - - return 1; -} - -int Unpack8(T_geometry *geometry, T_colormap *colormap, int src_depth, int src_width, int src_height, - unsigned char *src_data, int src_size, int dst_depth, int dst_width, - int dst_height, unsigned char *dst_data, int dst_size) -{ - if (src_depth != 8) - { - #ifdef PANIC - *logofs << "Unpack8: PANIC! Cannot unpack colormapped image of source depth " - << src_depth << ".\n" << logofs_flush; - #endif - - return -1; - } - - int (*unpack)(T_colormap *colormap, const unsigned char *data, - unsigned char *out, unsigned char *end); - - int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); - - switch (dst_bpp) - { - case 8: - { - unpack = Unpack8To8; - - break; - } - case 16: - { - unpack = Unpack8To16; - - break; - } - case 24: - { - unpack = Unpack8To24; - - break; - } - case 32: - { - unpack = Unpack8To32; - - break; - } - default: - { - #ifdef PANIC - *logofs << "Unpack8: PANIC! Bad destination bits per pixel " - << dst_bpp << ". Only 8/16/24/32 are supported.\n" - << logofs_flush; - #endif - - return -1; - } - } - - if (src_width == dst_width && - src_height == dst_height) - { - unsigned char *dst_end = dst_data + dst_size; - - (*unpack)(colormap, src_data, dst_data, dst_end); - } - else if (src_width >= dst_width && - src_height >= dst_height) - { - unsigned char *dst_end = dst_data; - - for (int y = 0; y < dst_height; y++) - { - dst_data = dst_end; - - dst_end += RoundUp4(dst_width * dst_bpp / 8); - - (*unpack)(colormap, src_data, dst_data, dst_end); - - src_data += src_width; - } - } - else - { - #ifdef PANIC - *logofs << "Unpack8: PANIC! Cannot unpack image. " - << "Destination area " << dst_width << "x" - << dst_height << " is not fully contained in " - << src_width << "x" << src_height << " source.\n" - << logofs_flush; - #endif - - return -1; - } - - return 1; -} - -int Unpack15To16(const unsigned char *data, unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack15To16: Unpacking " << end - out - << " bytes of colormapped data.\n" - << logofs_flush; - #endif - - unsigned short *data16 = (unsigned short *) data; - unsigned short *out16 = (unsigned short *) out; - unsigned short *end16 = (unsigned short *) end; - - while (out16 < end16) - { - if (*data16 == 0x0) - { - *out16 = 0x0; - } - else if (*data16 == 0x7fff) - { - *out16 = 0xffff; - } - else - { - #ifdef TEST - *logofs << "Unpack15To16: Pixel [" << *data16 << "]\n" - << logofs_flush; - #endif - - *out16 = ((*data16 & 0x7ff0) << 1) | - (*data16 & 0x001f); - } - - out16 += 1; - data16 += 1; - } - - return 1; -} - -int Unpack15To24(const unsigned char *data, unsigned char *out, unsigned char *end) - -{ - #ifdef TEST - *logofs << "Unpack15To24: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - unsigned short *data16 = (unsigned short *) data; - - while (out < end - 2) - { - if (*data16 == 0x0) - { - out[0] = 0x00; - out[1] = 0x00; - out[2] = 0x00; - } - else if (*data16 == 0x7fff) - { - out[0] = 0xff; - out[1] = 0xff; - out[2] = 0xff; - } - else - { - #ifdef TEST - *logofs << "Unpack15To24: Pixel [" << *data16 << "]\n" - << logofs_flush; - #endif - - out[0] = ((*data16 >> 7) & 0xf8) | ((*data16 >> 12) & 0x07); - out[1] = ((*data16 >> 2) & 0xf8) | ((*data16 >> 8) & 0x07); - out[2] = ((*data16 << 3) & 0xf8) | ((*data16 >> 2) & 0x07); - } - - out += 3; - data16 += 1; - } - - return 1; -} - -int Unpack15To32(const unsigned char *data, unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack15To32: Unpacking " << end - out - << " bytes of data.\n" - << logofs_flush; - #endif - - unsigned short *data16 = (unsigned short *) data; - unsigned int *out32 = (unsigned int *) out; - unsigned int *end32 = (unsigned int *) end; - - while (out32 < end32) - { - if (*data16 == 0x0) - { - *out32 = 0x0; - } - else if (*data16 == 0xffff) - { - *out32 = 0xffffff; - } - else - { - *out32 = ((((*data16 >> 7) & 0xf8) | ((*data16 >> 12) & 0x07)) << 16) | - ((((*data16 >> 2) & 0xf8) | ((*data16 >> 8) & 0x07)) << 8) | - (((*data16 << 3) & 0xf8) | ((*data16 >> 2) & 0x07)); - } - - out32++; - data16++; - } - - return 1; -} - -int Unpack15(T_geometry *geometry, int src_depth, int src_width, int src_height, - unsigned char *src_data, int src_size, int dst_depth, int dst_width, - int dst_height, unsigned char *dst_data, int dst_size) -{ - if (src_depth != 16) - { - #ifdef PANIC - *logofs << "Unpack15: PANIC! Cannot unpack colormapped image of source depth " - << src_depth << ".\n" << logofs_flush; - #endif - - return -1; - } - - int (*unpack)(const unsigned char *data, unsigned char *out, unsigned char *end); - - int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); - - switch (dst_bpp) - { - case 16: - { - unpack = Unpack15To16; - - break; - } - case 24: - { - unpack = Unpack15To24; - - break; - } - case 32: - { - unpack = Unpack15To32; - - break; - } - default: - { - #ifdef PANIC - *logofs << "Unpack15: PANIC! Bad destination bits per pixel " - << dst_bpp << ". Only 16/24/32 are supported.\n" - << logofs_flush; - #endif - - return -1; - } - } - - if (src_width == dst_width && src_height == dst_height) - { - unsigned char *dst_end = dst_data + dst_size; - - (*unpack)(src_data, dst_data, dst_end); - } - else if (src_width >= dst_width && src_height >= dst_height) - { - unsigned char *dst_end = dst_data; - - for (int y = 0; y < dst_height; y++) - { - dst_data = dst_end; - dst_end += RoundUp4(dst_width * dst_bpp / 8); - - (*unpack)(src_data, dst_data, dst_end); - - src_data += src_width * 2; - } - } - else - { - #ifdef PANIC - *logofs << "Unpack15: PANIC! Cannot unpack image. " - << "Destination area " << dst_width << "x" - << dst_height << " is not fully contained in " - << src_width << "x" << src_height << " source.\n" - << logofs_flush; - #endif - - return -1; - } - - return 1; -} - -int Unpack16To16(const unsigned char *data, unsigned char *out, - unsigned char *end, int imageByteOrder) -{ - #ifdef TEST - *logofs << "Unpack16To16: Unpacking " << end - out - << " bytes of colormapped data.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) out, (unsigned char *) data, end - out); - - return 1; -} - -int Unpack16To24(const unsigned char *data, unsigned char *out, - unsigned char *end, int imageByteOrder) - -{ - #ifdef TEST - *logofs << "Unpack16To24: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - unsigned short *data16 = (unsigned short *) data; - - while (out < end - 2) - { - if (*data16 == 0x0) - { - out[0] = 0x00; - out[1] = 0x00; - out[2] = 0x00; - } - else if (*data16 == 0xffff) - { - out[0] = 0xff; - out[1] = 0xff; - out[2] = 0xff; - } - else - { - #ifdef TEST - *logofs << "Unpack16To24: Pixel [" << *data16 << "]\n" - << logofs_flush; - #endif - - out[0] = ((*data16 >> 8) & 0xf8) | ((*data16 >> 13) & 0x07); - out[1] = ((*data16 >> 3) & 0xfc) | ((*data16 >> 9) & 0x03); - out[2] = ((*data16 << 3) & 0xf8) | ((*data16 >> 2) & 0x07); - } - - out += 3; - data16 += 1; - } - - return 1; -} - - -int Unpack16To32(const unsigned char *data, unsigned char *out, - unsigned char *end, int imageByteOrder) -{ - #ifdef TEST - *logofs << "Unpack16To32: Unpacking " << end - out - << " bytes of data.\n" - << logofs_flush; - #endif - - unsigned short *data16 = (unsigned short *) data; - unsigned int *out32 = (unsigned int *) out; - unsigned int *end32 = (unsigned int *) end; - - unsigned short pixel16; - unsigned int pixel32; - - while (out32 < end32) - { - - pixel16 = GetUINT((unsigned char *)data16, 0); - - if (pixel16 == 0x0) - { - PutULONG(0x0, (unsigned char *) out32, imageByteOrder); - } - else if (pixel16 == 0xffff) - { - PutULONG(0xffffff, (unsigned char *) out32, imageByteOrder); - } - else - { - pixel32 = ((((pixel16 >> 8) & 0xf8) | ((pixel16 >> 13) & 0x07)) << 16) | - ((((pixel16 >> 3) & 0xfc) | ((pixel16 >> 9) & 0x03)) << 8) | - (((pixel16 << 3) & 0xf8) | ((pixel16 >> 2) & 0x07)); - - PutULONG(pixel32, (unsigned char *) out32, imageByteOrder); - } - - out32++; - data16++; - } - return 1; -} - -int Unpack16(T_geometry *geometry, int src_depth, int src_width, int src_height, - unsigned char *src_data, int src_size, int dst_depth, int dst_width, - int dst_height, unsigned char *dst_data, int dst_size) -{ - int imageByteOrder = geometry -> image_byte_order; - - if (src_depth != 16) - { - #ifdef PANIC - *logofs << "Unpack16: PANIC! Cannot unpack colormapped image of source depth " - << src_depth << ".\n" << logofs_flush; - #endif - - return -1; - } - - int (*unpack)(const unsigned char *data, unsigned char *out, - unsigned char *end, int imageByteOrder); - - int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); - - switch (dst_bpp) - { - case 16: - { - unpack = Unpack16To16; - - break; - } - case 24: - { - unpack = Unpack16To24; - - break; - } - case 32: - { - unpack = Unpack16To32; - - break; - } - default: - { - #ifdef PANIC - *logofs << "Unpack16: PANIC! Bad destination bits per pixel " - << dst_bpp << ". Only 16/24/32 are supported.\n" - << logofs_flush; - #endif - - return -1; - } - } - - if (src_width == dst_width && src_height == dst_height) - { - unsigned char *dst_end = dst_data + dst_size; - - (*unpack)(src_data, dst_data, dst_end, imageByteOrder); - } - else if (src_width >= dst_width && src_height >= dst_height) - { - unsigned char *dst_end = dst_data; - - for (int y = 0; y < dst_height; y++) - { - dst_data = dst_end; - dst_end += RoundUp4(dst_width * dst_bpp / 8); - - (*unpack)(src_data, dst_data, dst_end, imageByteOrder); - - src_data += src_width * 2; - } - } - else - { - #ifdef PANIC - *logofs << "Unpack16: PANIC! Cannot unpack image. " - << "Destination area " << dst_width << "x" - << dst_height << " is not fully contained in " - << src_width << "x" << src_height << " source.\n" - << logofs_flush; - #endif - - return -1; - } - - return 1; -} - -int Unpack24To24(const unsigned char *data, - unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack124To24: Unpacking " << end - out - << " bytes of colormapped data.\n" - << logofs_flush; - #endif - - while (out < end) - { - *(out++) = *(data++); - } - - return 1; -} - -int Unpack24To32(const unsigned char *data, unsigned char *out, unsigned char *end) -{ - #ifdef TEST - *logofs << "Unpack24To32: Unpacking " << end - out - << " bytes of colormapped data.\n" - << logofs_flush; - #endif - - unsigned int *out32 = (unsigned int *) out; - unsigned int *end32 = (unsigned int *) end; - - while (out32 < end32) - { - if (data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x0) - { - *out32 = 0x0; - } - else if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) - { - *out32 = 0xffffff; - } - else - { - *out32 = (data[2] << 16) | (data[1] << 8) | data[0]; - } - - out32 += 1; - data += 3; - } - - return 1; -} - -int Unpack24(T_geometry *geometry, int src_depth, int src_width, int src_height, - unsigned char *src_data, int src_size, int dst_depth, int dst_width, - int dst_height, unsigned char *dst_data, int dst_size) - -{ - if (src_depth != 24) - { - #ifdef PANIC - *logofs << "Unpack24: PANIC! Cannot unpack colormapped image of source depth " - << src_depth << ".\n" << logofs_flush; - #endif - - return -1; - } - - int (*unpack)(const unsigned char *data, unsigned char *out, unsigned char *end); - - int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); - - switch (dst_bpp) - { - case 24: - { - unpack = Unpack24To24; - - break; - } - case 32: - { - unpack = Unpack24To32; - - break; - } - default: - { - #ifdef PANIC - *logofs << "Unpack24: PANIC! Bad destination bits per pixel " - << dst_bpp << ". Only 24/32 are supported.\n" - << logofs_flush; - #endif - - return -1; - } - } - - if (src_width == dst_width && src_height == dst_height) - { - unsigned char *dst_end = dst_data + dst_size; - - (*unpack)(src_data, dst_data, dst_end); - } - else if (src_width >= dst_width && src_height >= dst_height) - { - unsigned char *dst_end = dst_data; - - for (int y = 0; y < dst_height; y++) - { - dst_data = dst_end; - dst_end += RoundUp4(dst_width * dst_bpp / 8); - - (*unpack)(src_data, dst_data, dst_end); - - src_data += src_width * 3; - } - } - else - { - #ifdef PANIC - *logofs << "Unpack24: PANIC! Cannot unpack image. " - << "Destination area " << dst_width << "x" - << dst_height << " is not fully contained in " - << src_width << "x" << src_height << " source.\n" - << logofs_flush; - #endif - - return -1; - } - - return 1; -} - -int Unpack32To32(const T_colormask *colormask, const unsigned int *data, - unsigned int *out, unsigned int *end) -{ - #ifdef TEST - *logofs << "Unpack32To32: Unpacking " << end - out - << " bytes of data.\n" << logofs_flush; - #endif - - if (colormask -> correction_mask) - { - while (out < end) - { - if (*data == 0x00000000) - { - *out = 0x00000000; - } - else if (*data == 0xFFFFFFFF) - { - *out = 0xFFFFFFFF; - } - else - { - *out = *data | ((colormask -> correction_mask << 16) | - (colormask -> correction_mask << 8) | - colormask -> correction_mask); - } - - out += 1; - data += 1; - } - } - else - { - #ifdef TEST - *logofs << "Unpack32To32: Using bitwise copy due to null correction mask.\n" - << logofs_flush; - #endif - - memcpy((unsigned char *) out, (unsigned char *) data, end - out); - } - - return 1; -} diff --git a/nxcomp/Unpack.h b/nxcomp/Unpack.h deleted file mode 100644 index faaa41d82..000000000 --- a/nxcomp/Unpack.h +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Unpack_H -#define Unpack_H - -#include "NXpack.h" - -#include "Z.h" - -#define LSBFirst 0 -#define MSBFirst 1 - -#define SPLIT_PATTERN 0x88 - -typedef ColorMask T_colormask; - -// -// Pixel geometry of channel's display. -// - -typedef struct -{ - unsigned int depth1_bpp; - unsigned int depth4_bpp; - unsigned int depth8_bpp; - unsigned int depth16_bpp; - unsigned int depth24_bpp; - unsigned int depth32_bpp; - - unsigned int red_mask; - unsigned int green_mask; - unsigned int blue_mask; - - unsigned int image_byte_order; - unsigned int bitmap_bit_order; - unsigned int scanline_unit; - unsigned int scanline_pad; - -} T_geometry; - -// -// Colormap is used to remap colors -// from source to destination depth. -// - -typedef struct -{ - unsigned int entries; - unsigned int *data; - -} T_colormap; - -// -// Alpha channel data is added to 32 -// bits images at the time they are -// unpacked. -// - -typedef struct -{ - unsigned int entries; - unsigned char *data; - -} T_alpha; - -// -// The ZLIB stream structure used for -// the decompression. -// - -extern z_stream unpackStream; - -// -// Initialize the ZLIB stream used for -// decompression. -// - -void UnpackInit(); - -// -// Free the ZLIB stream. -// - -void UnpackDestroy(); - -// -// Get the destination bits per pixel -// based on the drawable depth. -// - -int UnpackBitsPerPixel(T_geometry *geometry, unsigned int depth); - -// -// Unpack the source data into the X -// bitmap. -// - -int Unpack8(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size); - -int Unpack16(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size); - -int Unpack24(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size); - -int Unpack8(T_geometry *geometry, T_colormap *colormap, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size); - -int Unpack15(T_geometry *geometry, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size); - -int Unpack16(T_geometry *geometry, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size); - -int Unpack24(T_geometry *geometry, int src_depth, int src_width, - int src_height, unsigned char *src_data, int src_size, int dst_depth, - int dst_width, int dst_height, unsigned char *dst_data, int dst_size); - -#endif /* Unpack_H */ diff --git a/nxcomp/Vars.c b/nxcomp/Vars.c deleted file mode 100644 index 685969677..000000000 --- a/nxcomp/Vars.c +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include "NXvars.h" - -/* - * Allocate here instances of variables and - * pointers declared in NXvars.h. - */ - -int _NXHandleDisplayError = 0; - -NXDisplayErrorPredicate _NXDisplayErrorFunction = NULL; - -int _NXUnsetLibraryPath = 0; - -NXLostSequenceHandler _NXLostSequenceFunction = NULL; - -NXDisplayBlockHandler _NXDisplayBlockFunction = NULL; -NXDisplayWriteHandler _NXDisplayWriteFunction = NULL; -NXDisplayFlushHandler _NXDisplayFlushFunction = NULL; -NXDisplayStatisticsHandler _NXDisplayStatisticsFunction = NULL; - -#ifdef __cplusplus -} -#endif diff --git a/nxcomp/Version.c b/nxcomp/Version.c deleted file mode 100644 index ff1793434..000000000 --- a/nxcomp/Version.c +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2015 Qindel Formacion y Servicios SL. */ -/* */ -/* This program is free software; you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License Version 2, as */ -/* published by the Free Software Foundation. */ -/* */ -/* This program is distributed in the hope that it will be useful, but */ -/* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- */ -/* BILITY 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, you can request a copy from Qindel */ -/* or write to the Free Software Foundation, Inc., 51 Franklin Street, */ -/* Fifth Floor, Boston, MA 02110-1301 USA. */ -/* */ -/* All rights reserved. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include "NX.h" - - -static int _NXVersionMajor = -1; -static int _NXVersionMinor = -1; -static int _NXVersionPatch = -1; -static int _NXVersionMaintenancePatch = -1; - - -const char* NXVersion() { - const char *version = VERSION; - return version; -} - -void _parseNXVersion() { - char version[32]; - int i; - strcpy(version, VERSION); - - char *value; - /* Reset values to 0 if undefined */ - _NXVersionMajor = _NXVersionMinor = _NXVersionPatch = _NXVersionMaintenancePatch = 0; - - -#define NXVERSIONSEPARATOR "." - value = strtok(version, NXVERSIONSEPARATOR); - - for (i = 0; value != NULL && i < 4; i++) - { - switch (i) - { - case 0: - _NXVersionMajor = atoi(value); - break; - - case 1: - _NXVersionMinor = atoi(value); - break; - - case 2: - _NXVersionPatch = atoi(value); - break; - - case 3: - _NXVersionMaintenancePatch = atoi(value); - break; - } - - value = strtok(NULL, NXVERSIONSEPARATOR); - } -} - -int NXMajorVersion() { - if (_NXVersionMajor == -1) - _parseNXVersion(); - return _NXVersionMajor; -} -int NXMinorVersion() { - if (_NXVersionMinor == -1) - _parseNXVersion(); - return _NXVersionMinor; -} -int NXPatchVersion() { - if (_NXVersionPatch == -1) - _parseNXVersion(); - return _NXVersionPatch; -} -int NXMaintenancePatchVersion() { - if (_NXVersionMaintenancePatch == -1) - _parseNXVersion(); - return _NXVersionMaintenancePatch; -} diff --git a/nxcomp/WriteBuffer.cpp b/nxcomp/WriteBuffer.cpp deleted file mode 100644 index 07d14fc30..000000000 --- a/nxcomp/WriteBuffer.cpp +++ /dev/null @@ -1,496 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include -#include -#include -#include - -#include "Misc.h" -#include "Control.h" - -#include "WriteBuffer.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -WriteBuffer::WriteBuffer() -{ - size_ = WRITE_BUFFER_DEFAULT_SIZE; - buffer_ = new unsigned char[size_]; - length_ = 0; - index_ = NULL; - - scratchLength_ = 0; - scratchBuffer_ = NULL; - scratchOwner_ = 1; - - initialSize_ = WRITE_BUFFER_DEFAULT_SIZE; - thresholdSize_ = WRITE_BUFFER_DEFAULT_SIZE << 1; - maximumSize_ = WRITE_BUFFER_DEFAULT_SIZE << 4; - - #ifdef VALGRIND - - memset(buffer_, '\0', size_); - - #endif -} - -WriteBuffer::~WriteBuffer() -{ - if (scratchOwner_ == 1 && - scratchBuffer_ != NULL) - { - delete [] scratchBuffer_; - } - - delete [] buffer_; -} - -void WriteBuffer::setSize(unsigned int initialSize, unsigned int thresholdSize, - unsigned int maximumSize) -{ - initialSize_ = initialSize; - thresholdSize_ = thresholdSize; - maximumSize_ = maximumSize; - - #ifdef TEST - *logofs << "WriteBuffer: Set buffer sizes to " - << initialSize_ << "/" << thresholdSize_ - << "/" << maximumSize_ << ".\n" - << logofs_flush; - #endif -} - -void WriteBuffer::partialReset() -{ - if (scratchBuffer_ != NULL) - { - if (scratchOwner_) - { - #ifdef DEBUG - *logofs << "WriteBuffer: Going to delete " - << scratchLength_ << " bytes from the " - << "scratch buffer.\n" << logofs_flush; - #endif - - delete [] scratchBuffer_; - } - - scratchLength_ = 0; - scratchBuffer_ = NULL; - scratchOwner_ = 1; - } - - length_ = 0; - index_ = NULL; - - #ifdef DEBUG - *logofs << "WriteBuffer: Performed partial reset with " - << size_ << " bytes in buffer.\n" - << logofs_flush; - #endif -} - -void WriteBuffer::fullReset() -{ - if (scratchBuffer_ != NULL) - { - if (scratchOwner_ == 1) - { - #ifdef DEBUG - *logofs << "WriteBuffer: Going to delete " - << scratchLength_ << " bytes from the " - << "scratch buffer.\n" << logofs_flush; - #endif - - delete [] scratchBuffer_; - } - - scratchLength_ = 0; - scratchBuffer_ = NULL; - scratchOwner_ = 1; - } - - length_ = 0; - index_ = NULL; - - if (size_ > initialSize_) - { - #ifdef TEST - *logofs << "WriteBuffer: Reallocating a new buffer of " - << initialSize_ << " bytes.\n" << logofs_flush; - #endif - - delete [] buffer_; - - size_ = initialSize_; - - buffer_ = new unsigned char[size_]; - - if (buffer_ == NULL) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't allocate memory for " - << "X messages in context [A].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "X messages in context [A].\n"; - - HandleAbort(); - } - - #ifdef VALGRIND - - memset(buffer_, '\0', size_); - - #endif - } - - #ifdef DEBUG - *logofs << "WriteBuffer: Performed full reset with " - << size_ << " bytes in buffer.\n" - << logofs_flush; - #endif -} - -unsigned char *WriteBuffer::addMessage(unsigned int numBytes) -{ - #ifdef DEBUG - *logofs << "WriteBuffer: Adding " << numBytes << " bytes to " - << length_ << " bytes already in buffer.\n" - << logofs_flush; - #endif - - if (numBytes > WRITE_BUFFER_OVERFLOW_SIZE) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't add a message of " - << numBytes << " bytes.\n" << logofs_flush; - - *logofs << "WriteBuffer: PANIC! Assuming error handling " - << "data in context [B].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't add a message of " - << numBytes << " bytes to write buffer.\n"; - - cerr << "Error" << ": Assuming error handling " - << "data in context [B].\n"; - - HandleAbort(); - } - else if (length_ + numBytes > size_) - { - unsigned int newSize = thresholdSize_; - - while (newSize < length_ + numBytes) - { - newSize <<= 1; - - if (newSize > maximumSize_) - { - newSize = length_ + numBytes + initialSize_; - } - } - - #ifdef TEST - *logofs << "WriteBuffer: Growing buffer from " - << size_ << " to " << newSize << " bytes.\n" - << logofs_flush; - #endif - - unsigned int indexOffset = 0; - - if (index_ && *index_) - { - indexOffset = *index_ - buffer_; - } - - size_ = newSize; - - unsigned char *newBuffer = new unsigned char[size_]; - - if (newBuffer == NULL) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't allocate memory for " - << "X messages in context [C].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "X messages in context [C].\n"; - - HandleAbort(); - } - - #ifdef TEST - if (newSize >= maximumSize_) - { - *logofs << "WriteBuffer: WARNING! Buffer grown to reach " - << "size of " << newSize << " bytes.\n" - << logofs_flush; - } - #endif - - #ifdef VALGRIND - - memset(newBuffer, '\0', size_); - - #endif - - memcpy(newBuffer, buffer_, length_); - - #ifdef DEBUG - *logofs << "WriteBuffer: Going to delete the " - << "old buffer with new size " << size_ - << ".\n" << logofs_flush; - #endif - - delete [] buffer_; - - buffer_ = newBuffer; - - if (index_ && *index_) - { - *index_ = buffer_ + indexOffset; - } - } - - unsigned char *result = buffer_ + length_; - - length_ += numBytes; - - #ifdef DEBUG - *logofs << "WriteBuffer: Bytes in buffer are " - << length_ << " while size is " << size_ - << ".\n" << logofs_flush; - #endif - - return result; -} - -unsigned char *WriteBuffer::removeMessage(unsigned int numBytes) -{ - #ifdef TEST - *logofs << "WriteBuffer: Removing " << numBytes - << " bytes from buffer.\n" << logofs_flush; - #endif - - if (numBytes > length_) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't remove " - << numBytes << " bytes with only " << length_ - << " bytes in buffer.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Buffer underflow handling " - << "write buffer in context [D].\n"; - - HandleAbort(); - } - - length_ -= numBytes; - - #ifdef TEST - *logofs << "WriteBuffer: Bytes in buffer are now " - << length_ << " while size is " - << size_ << ".\n" << logofs_flush; - #endif - - return (buffer_ + length_); -} - -unsigned char *WriteBuffer::addScratchMessage(unsigned int numBytes) -{ - if (numBytes > WRITE_BUFFER_OVERFLOW_SIZE) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't add a message of " - << numBytes << " bytes.\n" << logofs_flush; - - *logofs << "WriteBuffer: PANIC! Assuming error handling " - << "data in context [E].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't add a message of " - << numBytes << " bytes to write buffer.\n"; - - cerr << "Error" << ": Assuming error handling " - << "data in context [E].\n"; - - HandleAbort(); - } - else if (scratchBuffer_ != NULL) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't add a message of " - << numBytes << " bytes with " << scratchLength_ - << " bytes already in scratch buffer.\n" - << logofs_flush; - - *logofs << "WriteBuffer: PANIC! Assuming error handling " - << "data in context [F].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't add a message of " - << numBytes << " bytes with " << scratchLength_ - << " bytes already in scratch buffer.\n"; - - cerr << "Error" << ": Assuming error handling " - << "data in context [F].\n"; - - HandleAbort(); - } - - #ifdef DEBUG - *logofs << "WriteBuffer: Adding " << numBytes << " bytes " - << "to scratch buffer.\n" << logofs_flush; - #endif - - unsigned char *newBuffer = new unsigned char[numBytes]; - - if (newBuffer == NULL) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't allocate memory for " - << "X messages in context [G].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't allocate memory for " - << "X messages in context [G].\n"; - - HandleAbort(); - } - - #ifdef VALGRIND - - memset(newBuffer, '\0', numBytes); - - #endif - - scratchBuffer_ = newBuffer; - scratchOwner_ = 1; - scratchLength_ = numBytes; - - return newBuffer; -} - -unsigned char *WriteBuffer::addScratchMessage(unsigned char *newBuffer, unsigned int numBytes) -{ - if (numBytes > WRITE_BUFFER_OVERFLOW_SIZE) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't add a message of " - << numBytes << " bytes.\n" << logofs_flush; - - *logofs << "WriteBuffer: PANIC! Assuming error handling " - << "data in context [H].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't add a message of " - << numBytes << " bytes to write buffer.\n"; - - cerr << "Error" << ": Assuming error handling " - << "data in context [H].\n"; - - HandleAbort(); - } - else if (scratchBuffer_ != NULL) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't add a foreign " - << "message of " << numBytes << " bytes with " - << scratchLength_ << " bytes already in " - << "scratch buffer.\n" << logofs_flush; - - *logofs << "WriteBuffer: PANIC! Assuming error handling " - << "data in context [I].\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't add a foreign message of " - << numBytes << " bytes with " << scratchLength_ - << " bytes already in scratch buffer.\n"; - - cerr << "Error" << ": Assuming error handling " - << "data in context [I].\n"; - - HandleAbort(); - } - - #ifdef DEBUG - *logofs << "WriteBuffer: Adding " << numBytes << " bytes " - << "from a foreign message to scratch buffer.\n" - << logofs_flush; - #endif - - scratchBuffer_ = newBuffer; - scratchLength_ = numBytes; - scratchOwner_ = 0; - - return newBuffer; -} - -void WriteBuffer::removeScratchMessage() -{ - #ifdef TEST - - if (scratchLength_ == 0 || scratchBuffer_ == NULL) - { - #ifdef PANIC - *logofs << "WriteBuffer: PANIC! Can't remove non existent scratch message.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Can't remove non existent scratch message.\n"; - - HandleAbort(); - } - - *logofs << "WriteBuffer: Removing " << scratchLength_ - << " bytes from scratch buffer.\n" - << logofs_flush; - - #endif - - if (scratchOwner_ == 1) - { - #ifdef DEBUG - *logofs << "WriteBuffer: Going to delete " - << scratchLength_ << " bytes from the " - << "scratch buffer.\n" << logofs_flush; - #endif - - delete [] scratchBuffer_; - } - - scratchLength_ = 0; - scratchBuffer_ = NULL; - scratchOwner_ = 1; -} diff --git a/nxcomp/WriteBuffer.h b/nxcomp/WriteBuffer.h deleted file mode 100644 index ce408e210..000000000 --- a/nxcomp/WriteBuffer.h +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef WriteBuffer_H -#define WriteBuffer_H - -#include "Misc.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -#define WRITE_BUFFER_DEFAULT_SIZE 16384 - -// -// Adjust for the biggest reply that we could receive. -// This is likely to be a reply to a X_ListFonts where -// user has a large amount of installed fonts. -// - -#define WRITE_BUFFER_OVERFLOW_SIZE 4194304 - -class WriteBuffer -{ - public: - - WriteBuffer(); - - ~WriteBuffer(); - - void setSize(unsigned int initialSize, unsigned int thresholdSize, - unsigned int maximumSize); - - unsigned char *addMessage(unsigned int numBytes); - - unsigned char *removeMessage(unsigned int numBytes); - - unsigned char *addScratchMessage(unsigned int numBytes); - - // - // This form allows user to provide its own - // buffer as write buffer's scratch area. - // - - unsigned char *addScratchMessage(unsigned char *newBuffer, unsigned int numBytes); - - void removeScratchMessage(); - - void partialReset(); - - void fullReset(); - - unsigned char *getData() const - { - return buffer_; - } - - unsigned int getLength() const - { - return length_; - } - - unsigned int getAvailable() const - { - return (size_ - length_); - } - - unsigned char *getScratchData() const - { - return scratchBuffer_; - } - - unsigned int getScratchLength() const - { - return scratchLength_; - } - - unsigned int getTotalLength() const - { - return (length_ + scratchLength_); - } - - void registerPointer(unsigned char **pointer) - { - index_ = pointer; - } - - void unregisterPointer() - { - index_ = 0; - } - - private: - - unsigned int size_; - unsigned int length_; - - unsigned char *buffer_; - unsigned char **index_; - - unsigned int scratchLength_; - unsigned char *scratchBuffer_; - - int scratchOwner_; - - unsigned int initialSize_; - unsigned int thresholdSize_; - unsigned int maximumSize_; -}; - -#endif /* WriteBuffer_H */ diff --git a/nxcomp/XidCache.cpp b/nxcomp/XidCache.cpp deleted file mode 100644 index 0f83d388f..000000000 --- a/nxcomp/XidCache.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Control.h" - -#include "XidCache.h" - -XidCache::XidCache() -{ - for (int i = 0; i < 256; i++) - { - base_[i] = new IntCache(8); - } - - slot_ = 0; - last_ = 0; -} - -XidCache::~XidCache() -{ - for (int i = 0; i < 256; i++) - { - delete base_[i]; - } -} diff --git a/nxcomp/XidCache.h b/nxcomp/XidCache.h deleted file mode 100644 index 8a09ef9b1..000000000 --- a/nxcomp/XidCache.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef XidCache_H -#define XidCache_H - -#include "IntCache.h" - -class XidCache -{ - friend class EncodeBuffer; - friend class DecodeBuffer; - - public: - - XidCache(); - ~XidCache(); - - private: - - IntCache *base_[256]; - - unsigned int slot_; - unsigned int last_; -}; - -#endif /* XidCache_H */ diff --git a/nxcomp/Z.cpp b/nxcomp/Z.cpp deleted file mode 100644 index 35850b9d0..000000000 --- a/nxcomp/Z.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Z.h" -#include "Misc.h" - -int ZCompress(z_stream *stream, unsigned char *dest, unsigned int *destLen, - const unsigned char *source, unsigned int sourceLen) -{ - // - // Deal with the possible overflow. - // - - if (stream -> total_out & 0x80000000) - { - #ifdef TEST - *logofs << "ZCompress: Reset stream counters with " - << "total in " << stream -> total_in - << " and total out " << stream -> total_out - << ".\n" << logofs_flush; - #endif - - stream -> total_in = 0; - stream -> total_out = 0; - } - - unsigned int saveOut = stream -> total_out; - - stream -> next_in = (Bytef *) source; - stream -> avail_in = sourceLen; - - // - // Check if the source is bigger than - // 64K on 16-bit machine. - // - - #ifdef MAXSEG_64K - - if ((uLong) stream -> avail_in != sourceLen) return Z_BUF_ERROR; - - #endif - - stream -> next_out = dest; - stream -> avail_out = *destLen; - - #ifdef MAXSEG_64K - - if ((uLong) stream -> avail_out != *destLen) return Z_BUF_ERROR; - - #endif - - int result = deflate(stream, Z_FINISH); - - if (result != Z_STREAM_END) - { - deflateReset(stream); - - return (result == Z_OK ? Z_BUF_ERROR : result); - } - - *destLen = stream -> total_out - saveOut; - - result = deflateReset(stream); - - return result; -} - -int ZDecompress(z_stream *stream, unsigned char *dest, unsigned int *destLen, - const unsigned char *source, unsigned int sourceLen) -{ - stream -> next_in = (Bytef *) source; - stream -> avail_in = sourceLen; - - // - // Deal with the possible overflow. - // - - if (stream -> total_out & 0x80000000) - { - #ifdef TEST - *logofs << "ZDecompress: Reset stream counters with " - << "total in " << stream -> total_in - << " and total out " << stream -> total_out - << ".\n" << logofs_flush; - #endif - - stream -> total_in = 0; - stream -> total_out = 0; - } - - unsigned int saveOut = stream -> total_out; - - if (stream -> avail_in != sourceLen) - { - return Z_BUF_ERROR; - } - - stream -> next_out = dest; - stream -> avail_out = *destLen; - - if (stream -> avail_out != *destLen) - { - return Z_BUF_ERROR; - } - - int result = inflate(stream, Z_FINISH); - - if (result != Z_STREAM_END) - { - inflateReset(stream); - - return (result == Z_OK ? Z_BUF_ERROR : result); - } - - *destLen = stream -> total_out - saveOut; - - result = inflateReset(stream); - - return result; -} diff --git a/nxcomp/Z.h b/nxcomp/Z.h deleted file mode 100644 index 3a6d684c2..000000000 --- a/nxcomp/Z.h +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#ifndef Z_H -#define Z_H - -#include - -int ZCompress(z_stream *stream, unsigned char *dest, unsigned int *destLen, - const unsigned char *source, unsigned int sourceLen); - -int ZDecompress(z_stream *stream, unsigned char *dest, unsigned int *destLen, - const unsigned char *source, unsigned int sourceLen); - -#endif /* Z_H */ diff --git a/nxcomp/configure.ac b/nxcomp/configure.ac new file mode 100644 index 000000000..87087f32d --- /dev/null +++ b/nxcomp/configure.ac @@ -0,0 +1,83 @@ +# *************************************************************************** +# *** configure.ac for nxcomp *** +# *************************************************************************** + +m4_define([nxcomp_version], m4_esyscmd([tr -d '\n' < VERSION])) + +# Initialize Autoconf +AC_PREREQ(2.60) + +AC_INIT([libXcomp], [nxcomp_version], [https://github.com/ArcticaProject/nx-libs/issues]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_PROG_CXX +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz]) + +# Initialize libtool +AC_PROG_LIBTOOL + +COMP_VERSION=nxcomp_version +AC_SUBST([COMP_VERSION]) + +LT_COMP_VERSION=[`echo $COMP_VERSION | sed -r -e 's/^([0-9]+\.[0-9]+\.[0-9]+).*$/\1/' -e 's/\./:/g'`] +AC_SUBST([LT_COMP_VERSION]) + +PKG_CHECK_MODULES(JPEG, libjpeg) +PKG_CHECK_MODULES(PNG, libpng) +PKG_CHECK_MODULES(Z, zlib) + +# Upstream's pkg.m4 (since 0.27) offers this now, but define our own +# compatible version in case the local version of pkgconfig isn't new enough. +# https://bugs.freedesktop.org/show_bug.cgi?id=48743 +m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR], + [AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], + [install directory for nxcompshad.pc pkg-config file])], + [],[with_pkgconfigdir='$(libdir)/pkgconfig']) + AC_SUBST([pkgconfigdir], [${with_pkgconfigdir}])]) + +AC_LANG([C++]) +NX_COMPILER_BRAND +NX_COMPILER_FLAGS + +NX_BUILD_ON_CYGWIN32 +NX_BUILD_ON_AMD64 +NX_BUILD_ON_DARWIN +NX_BUILD_ON_SUN +NX_BUILD_ON_FreeBSD + +# Build PIC libraries. + +if test "$CYGWIN32" != yes -a "$DARWIN" != yes; then + CXXFLAGS="$CXXFLAGS -fPIC" + CFLAGS="$CFLAGS -fPIC" +fi + +# On FreeBSD search libraries and includes under /usr/local. + +if test "$FreeBSD" = yes; then + LIBS="$LIBS -L/usr/local/lib" + CPPFLAGS="$CPPFLAGS -I/usr/local/include" +fi + +NX_HAS_INADDRT + +# If in_addr_t is not defined use unsigned int. + +if test "$INADDRT" != yes ; then + echo -e "using unsigned int for type in_addr_t" + CPPFLAGS="$CPPFLAGS -DIN_ADDR_T=unsigned" +else + CPPFLAGS="$CPPFLAGS -DIN_ADDR_T=in_addr_t" +fi + +AC_CONFIG_FILES([ +Makefile +src/Makefile +nxcomp.pc +]) + +AC_OUTPUT diff --git a/nxcomp/configure.in b/nxcomp/configure.in deleted file mode 100644 index 8be604836..000000000 --- a/nxcomp/configure.in +++ /dev/null @@ -1,413 +0,0 @@ -dnl /**************************************************************************/ -dnl /* */ -dnl /* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -dnl /* Copyright (c) 2008-2014 Oleksandr Shneyder */ -dnl /* Copyright (c) 2014-2016 Ulrich Sibiller */ -dnl /* Copyright (c) 2014-2016 Mihai Moldovan */ -dnl /* Copyright (c) 2011-2016 Mike Gabriel */ -dnl /* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -dnl /* */ -dnl /* NXCOMP, NX protocol compression and NX extensions to this software */ -dnl /* are copyright of the aforementioned persons and companies. */ -dnl /* */ -dnl /* Redistribution and use of the present software is allowed according */ -dnl /* to terms specified in the file LICENSE.nxcomp which comes in the */ -dnl /* source distribution. */ -dnl /* */ -dnl /* All rights reserved. */ -dnl /* */ -dnl /* NOTE: This software has received contributions from various other */ -dnl /* contributors, only the core maintainers and supporters are listed as */ -dnl /* copyright holders. Please contact us, if you feel you should be listed */ -dnl /* as copyright holder, as well. */ -dnl /* */ -dnl /**************************************************************************/ - - -dnl Process this file with autoconf to produce a configure script. - -dnl Prolog - -AC_INIT(NX.h) -AC_PREREQ(2.13) - -pkgconfigdir=${libdir}/pkgconfig -AC_SUBST(pkgconfigdir) - -dnl Set our default compilation flags. - -if test "x$CXXFLAGS" = "x"; then - CXXFLAGS="-O3 -fno-rtti -fno-exceptions" -fi -if test "x$CFLAGS" = "x"; then - CFLAGS="$CFLAGS -O3" -fi - -dnl Reset default linking directives. - -LIBSTATIC="" -LIBSHARED="" - -dnl Prefer headers and libraries from nx-X11, if present. - -if test -d "../nx-X11/include" ; then - CXXFLAGS="$CXXFLAGS -I../nx-X11/exports/include" - CFLAGS="$CFLAGS -I../nx-X11/exports/include" - LIBS="$LIBS -L../nx-X11/exports/lib" -fi - -dnl Check whether --with-ipaq was given. - -if test "${with_ipaq}" = yes; then - echo -e "enabling IPAQ configuration" - CXX="arm-linux-c++" - CC="arm-linux-gcc" - unset ac_cv_prog_armcxx - unset ac_cv_prog_armcc - unset ac_cv_prog_CXXCPP - AC_CHECK_PROG([armcxx],["$CXX"],[yes],[no],[$PATH]) - AC_CHECK_PROG([armcc],["$CC"],[yes],[no],[$PATH]) - if test $armcxx = "yes" && test $armcc = "yes" ; then - ac_cv_prog_CXX="$CXX" - ac_cv_prog_CC="$CC" - else - AC_MSG_ERROR(Installation or configuration problem. Cannot find compiler for arm-linux.) - fi -else - unset ac_cv_prog_CXX - unset ac_cv_prog_CC - unset ac_cv_prog_CXXCPP -fi - -dnl Check for programs. - -AC_PROG_CXX -AC_PROG_CC -AC_LANG_CPLUSPLUS - -dnl Check whether option -Wno-deprecated -dnl is needed by GCC compiler. - -AC_MSG_CHECKING([whether compiler needs -Wno-deprecated]) -gcc_version=`${CC} --version | grep 'gcc (GCC) [[3-4]].' | head -n 1` -case "${gcc_version}" in - gcc*) - AC_MSG_RESULT([yes]) - CXXFLAGS="$CXXFLAGS -Wno-deprecated" - ;; - - *) - AC_MSG_RESULT([no]) - ;; -esac - -AC_MSG_CHECKING([whether compiler accepts -Wmissing-declarations]) -gcc_version=`${CC} --version | grep 'gcc (GCC) [[3-4]].' | head -n 1` -case "${gcc_version}" in - gcc*) - AC_MSG_RESULT([no]) - ;; - - *) - AC_MSG_RESULT([yes]) - CXXFLAGS="$CXXFLAGS -Wmissing-declarations" - ;; -esac - -dnl Check for BSD compatible install. - -AC_PROG_INSTALL - -dnl Check for extra header files. - -AC_PATH_XTRA - -dnl Custom addition. - -ac_help="$ac_help - --with-symbols add the -g flag to produce the debug symbols - --with-use-malloc add the __USE_MALLOC flag to avoid the STL allocators - --with-info define INFO at compile time to get basic log output - --with-valgrind clean up allocated buffers to avoid valgrind warnings - --with-version use this version for produced libraries - - --with-static-png enable static linking of PNG library - --with-static-jpeg enable static linking of JPEG library - --with-static-z enable static linking of Z library" - -dnl Check to see if we're running under Cygwin32. - -AC_DEFUN(nxconf_CYGWIN32, -[AC_CACHE_CHECK(for Cygwin32 environment, nxconf_cv_cygwin32, -[AC_TRY_COMPILE(,[return __CYGWIN32__;], -nxconf_cv_cygwin32=yes, nxconf_cv_cygwin32=no) -rm -f conftest*]) -CYGWIN32= -test "$nxconf_cv_cygwin32" = yes && CYGWIN32=yes]) -nxconf_CYGWIN32 - -dnl Check whether we're building on a AMD64. - -AC_DEFUN(nxconf_AMD64, -[AC_CACHE_CHECK(for Amd64 environment, nxconf_cv_amd64, -[AC_TRY_COMPILE(,[return (__amd64__ || __x86_64__);], -nxconf_cv_amd64=yes, nxconf_cv_amd64=no) -rm -f conftest*]) -AMD64= -test "$nxconf_cv_amd64" = yes && AMD64=yes]) -nxconf_AMD64 - -dnl Check for Darwin environment. - -AC_DEFUN(nxconf_DARWIN, -[AC_CACHE_CHECK(for Darwin environment, nxconf_cv_darwin, -[AC_TRY_COMPILE(,[return __APPLE__;], -nxconf_cv_darwin=yes, nxconf_cv_darwin=no) -rm -f conftest*]) -DARWIN= -test "$nxconf_cv_darwin" = yes && DARWIN=yes]) -nxconf_DARWIN - -dnl Check to see if we're running under Solaris. - -AC_DEFUN(nxconf_SUN, -[AC_CACHE_CHECK(for Solaris environment, nxconf_cv_sun, -[AC_TRY_COMPILE(,[return __sun;], -nxconf_cv_sun=yes, nxconf_cv_sun=no) -rm -f conftest*]) -SUN= -test "$nxconf_cv_sun" = yes && SUN=yes]) -nxconf_SUN - -dnl Check to see if we're running under FreeBSD. - -AC_DEFUN(nxconf_FreeBSD, -[AC_CACHE_CHECK(for FreeBSD environment, nxconf_cv_freebsd, -[AC_TRY_COMPILE(,[return __FreeBSD__;], -nxconf_cv_freebsd=yes, nxconf_cv_freebsd=no) -rm -f conftest*]) -FreeBSD= -test "$nxconf_cv_freebsd" = yes && FreeBSD=yes]) -nxconf_FreeBSD - -dnl Build PIC libraries. - -if test "$CYGWIN32" != yes -a "$DARWIN" != yes; then - CXXFLAGS="$CXXFLAGS -fPIC" - CFLAGS="$CFLAGS -fPIC" -fi - -dnl Solaris requires the socket and gcc_s libs explicitly linked. -dnl Note also that headers from default /usr/openwin/include/X11 -dnl cause a warning due to pragma in Xmd.h. - -if test "$SUN" = yes; then - LIBS="$LIBS -L/usr/sfw/lib -lsocket " - CXXFLAGS="$CXXFLAGS -I/usr/sfw/include" - CFLAGS="$CFLAGS -I/usr/sfw/include" -fi - -dnl On FreeBSD search libraries and includes under /usr/local. - -if test "$FreeBSD" = yes; then - LIBS="$LIBS -L/usr/local/lib" - CXXFLAGS="$CXXFLAGS -I/usr/local/include" - CFLAGS="$CFLAGS -I/usr/local/include" -fi - -dnl Under Darwin we don't have support for -soname option and -dnl we need the -dynamiclib flag. Under Solaris, instead, we need -dnl the options -G -h. - -if test "$DARWIN" = yes; then - LDFLAGS="$LDFLAGS -dynamiclib" -elif test "$SUN" = yes; then - LDFLAGS="$LDFLAGS -G -h \$(LIBLOAD)" -else - LDFLAGS="$LDFLAGS -Wl,-soname,\$(LIBLOAD)" -fi - -dnl Check to see if in_addr_t is defined. -dnl Could use a specific configure test. - -AC_DEFUN(nxconf_INADDRT, -[AC_CACHE_CHECK(for in_addr_t, nxconf_cv_inaddrt, -[AC_TRY_COMPILE([#include ],[in_addr_t t; t = 1; return t;], -nxconf_cv_inaddrt=yes, nxconf_cv_inaddrt=no) -rm -f conftest*]) -INADDRT= -test "$nxconf_cv_inaddrt" = yes && INADDRT=yes]) -nxconf_INADDRT - -dnl If in_addr_t is not defined use unsigned int. - -if test "$INADDRT" != yes ; then - echo -e "using unsigned int for type in_addr_t" - CXXFLAGS="$CXXFLAGS -DIN_ADDR_T=unsigned" - CFLAGS="$CFLAGS -DIN_ADDR_T=unsigned" -else - CXXFLAGS="$CXXFLAGS -DIN_ADDR_T=in_addr_t" - CFLAGS="$CFLAGS -DIN_ADDR_T=in_addr_t" -fi - -dnl Check whether --with-version was given. - -AC_SUBST(LIBVERSION) -AC_SUBST(VERSION) -if test "${with_version}" = yes; then - VERSION=${ac_option} -else - VERSION=`cat VERSION` -fi -echo -e "compiling version ${VERSION}" - -LIBVERSION=`echo ${VERSION} | cut -d '.' -f 1` - -CXXFLAGS="$CXXFLAGS -DVERSION=\\\"${VERSION}\\\"" -CFLAGS="$CFLAGS -DVERSION=\\\"${VERSION}\\\"" - -dnl Check whether --with-static-png was given and -dnl add -lpng or libpng.a to linking. - -if test "${with_static_png}" = yes; then - echo -e "enabling static linking of PNG library" - if test "$SUN" = yes && test -f "/usr/sfw/lib/libpng.a"; then - LIBSTATIC="$LIBSTATIC /usr/sfw/lib/libpng.a" - else - if test -f "/usr/lib/libpng.a" ; then - LIBSTATIC="$LIBSTATIC /usr/lib/libpng.a" - else - if test -f "/usr/local/lib/libpng.a" ; then - echo -e "assuming libpng.a in /usr/local/lib" - LIBSTATIC="$LIBSTATIC /usr/local/lib/libpng.a" - else - echo -e "Warning: assuming libpng.a in the local path" - LIBSTATIC="$LIBSTATIC libpng.a" - fi - fi - fi -else - echo -e "enabling dynamic linking of PNG library" - LIBSHARED="$LIBSHARED -lpng" -fi - -dnl Check whether --with-static-jpeg was given and -dnl add -ljpeg or libjpeg.a to linking. - -if test "${with_static_jpeg}" = yes; then - echo -e "enabling static linking of JPEG library" - if test "$SUN" = yes && test -f "/usr/sfw/lib/libjpeg.a"; then - LIBSTATIC="$LIBSTATIC /usr/sfw/lib/libjpeg.a" - else - if test -f "/usr/lib/libjpeg.a" ; then - LIBSTATIC="$LIBSTATIC /usr/lib/libjpeg.a" - else - if test -f "/usr/local/lib/libjpeg.a" ; then - echo -e "assuming libjpeg.a in /usr/local/lib" - LIBSTATIC="$LIBSTATIC /usr/local/lib/libjpeg.a" - else - echo -e "Warning: assuming libjpeg.a in the local path" - LIBSTATIC="$LIBSTATIC libjpeg.a" - fi - fi - fi -else - echo -e "enabling dynamic linking of JPEG library" - LIBSHARED="$LIBSHARED -ljpeg" -fi - -dnl Check whether --with-static-z was given and -dnl add -lz or libz.a to linking. - -if test "${with_static_z}" = yes; then - echo -e "enabling static linking of Z library" - if test "$SUN" = yes && test -f "/usr/sfw/lib/libz.a"; then - LIBSTATIC="$LIBSTATIC /usr/sfw/lib/libz.a" - else - if test -f "/usr/lib/libz.a" ; then - LIBSTATIC="$LIBSTATIC /usr/lib/libz.a" - else - if test -f "/usr/local/lib/libz.a" ; then - echo -e "assuming libz.a in /usr/local/lib" - LIBSTATIC="$LIBSTATIC /usr/local/lib/libz.a" - else - echo -e "Warning: assuming libz.a in the local path" - LIBSTATIC="$LIBSTATIC libz.a" - fi - fi - fi -else - echo -e "enabling dynamic linking of Z library" - LIBSHARED="$LIBSHARED -lz" -fi - -dnl Finally compose the LIB variable. - -if test "$DARWIN" = yes ; then - LIBS="$LIBS $LIBSTATIC $LIBSHARED" -elif test "$SUN" = yes ; then - LIBS="$LIBS $LIBSTATIC $LIBSHARED" -else - LIBS="$LIBS $LIBSTATIC -shared $LIBSHARED" -fi - -dnl Check whether --with-symbols or --without-symbols was -dnl given and set the required optimization level. - -if test "${with_symbols}" = yes; then - echo -e "enabling production of debug symbols" - CXXFLAGS="-g $CXXFLAGS" - CFLAGS="-g $CFLAGS" -else - echo -e "disabling production of debug symbols" -fi - -dnl Check whether --with-use-malloc or --without-use-malloc -dnl was given. - -if test "${with_use_malloc}" = yes; then - echo -e "disabling use of the STL allocators" - CXXFLAGS="$CXXFLAGS -D__USE_MALLOC" -else - echo -e "enabling use of the STL allocators" -fi - -dnl Check whether --with-info or --without-info was given. - -if test "${with_info}" = yes; then - echo -e "enabling info output in the log file" - CXXFLAGS="$CXXFLAGS -DINFO" - CFLAGS="$CFLAGS -DINFO" -else - echo -e "disabling info output in the log file" -fi - -dnl Check whether --with-valgrind or --without-valgrind was given. - -if test "${with_valgrind}" = yes; then - echo -e "enabling valgrind memory checker workarounds" - CXXFLAGS="$CXXFLAGS -DVALGRIND" - CFLAGS="$CFLAGS -DVALGRIND" -else - echo -e "disabling valgrind memory checker workarounds" -fi - -dnl Find makedepend somewhere. - -AC_SUBST(MAKEDEPEND) -MAKEDEPEND="$(which makedepend)" - -dnl Determine what to build based on the platform. -dnl Override the LIBS settings on Cygwin32 so that -dnl we always link with the exact set of libraries. - -AC_SUBST(ALL) - -if test "$CYGWIN32" = yes; then - ALL="\$(LIBCYGARCHIVE) \$(LIBCYGSHARED) \$(LIBARCHIVE)" - LIBS="-lstdc++ -lpng -ljpeg -lz" -else - ALL="\$(LIBFULL) \$(LIBLOAD) \$(LIBSHARED) \$(LIBARCHIVE)" -fi - -AC_OUTPUT(Makefile nxcomp.pc) diff --git a/nxcomp/include/MD5.h b/nxcomp/include/MD5.h new file mode 100644 index 000000000..698c995d8 --- /dev/null +++ b/nxcomp/include/MD5.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.h is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Removed support for non-ANSI compilers; removed + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); + added conditionalization for C++ compilation from Martin + Purschke . + 1999-05-03 lpd Original version. + */ + +#ifndef md5_INCLUDED +# define md5_INCLUDED + +/* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ + +typedef unsigned char md5_byte_t; /* 8-bit byte */ +typedef unsigned int md5_word_t; /* 32-bit word */ + +/* Define the state of the MD5 Algorithm. */ +typedef struct md5_state_s { + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ +} md5_state_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Initialize the algorithm. */ +void md5_init(md5_state_t *pms); + +/* Append a string to the message. */ +void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); + +/* Finish the message and return the digest. */ +void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* md5_INCLUDED */ diff --git a/nxcomp/include/NX.h b/nxcomp/include/NX.h new file mode 100644 index 000000000..7ec79b4b1 --- /dev/null +++ b/nxcomp/include/NX.h @@ -0,0 +1,471 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef NX_H +#define NX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include + +#define NX_FD_ANY -1 + +#define NX_MODE_ANY -1 +#define NX_MODE_CLIENT 1 +#define NX_MODE_SERVER 2 + +#define NX_DISPLAY_ANY NULL + +#define NX_SIGNAL_ANY -1 +#define NX_SIGNAL_ENABLE 1 +#define NX_SIGNAL_DISABLE 2 +#define NX_SIGNAL_RAISE 3 +#define NX_SIGNAL_FORWARD 4 + +#define NX_POLICY_IMMEDIATE 1 +#define NX_POLICY_DEFERRED 2 + +#define NX_ALERT_REMOTE 0 +#define NX_ALERT_LOCAL 1 + +#define NX_HANDLER_FLUSH 0 +#define NX_HANDLER_STATISTICS 1 + +#define NX_STATISTICS_PARTIAL 0 +#define NX_STATISTICS_TOTAL 1 + +#define NX_CHANNEL_X11 0 +#define NX_CHANNEL_CUPS 1 +#define NX_CHANNEL_SMB 2 +#define NX_CHANNEL_MEDIA 3 +#define NX_CHANNEL_HTTP 4 +#define NX_CHANNEL_FONT 5 +#define NX_CHANNEL_SLAVE 6 + +#define NX_FILE_SESSION 0 +#define NX_FILE_ERRORS 1 +#define NX_FILE_OPTIONS 2 +#define NX_FILE_STATS 3 + +/* + * The following are the new interfaces to the NX transport. The + * NX proxy software is now intended to be run as a library of a + * higher level communication manager (nxssh, nxhttp, nxrtp, etc, + * not only nxproxy). This is a work-in-progress, so expect these + * interfaces to change in future. At the present moment, as an + * example, there is no provision for creating and managing mul- + * tiple proxy connections. + */ + +/* + * Attach a NX transport to the provided descriptor. This should be + * done after having created a pair of connected sockets. + */ + +extern int NXTransCreate(int fd, int mode, const char *options); + +/* + * Tell the proxy to use the second descriptor as its own end of + * the internal connection to the NX agent. The NX agent will use + * the first descriptor. Setting an agent connection will have the + * effect of disabling further X client connections and, if it is + * possible, will trigger the use of the memory-to-memory transport. + */ + +extern int NXTransAgent(int fd[2]); + +/* + * Prepare the file sets and the timeout for a later execution of + * the select(). The masks and the timeout must persist across all + * the calls, so if you don't need any of the values, it is requi- + * red that you create empty masks and a default timeout. To save + * a check at each run, all the functions below assume that valid + * pointers are passed. + */ + +extern int NXTransPrepare(int *maxfds, fd_set *readfds, + fd_set *writefds, struct timeval *timeout); + +/* + * Call select() to find out the descriptors in the sets having + * pending data. + */ + +extern int NXTransSelect(int *result, int *error, int *maxfds, fd_set *readfds, + fd_set *writefds, struct timeval *timeout); + +/* + * Perform the required I/O on all the NX descriptors having pen- + * ding data. This can include reading and writing to the NX chan- + * nels, encoding and decoding the proxy data or managing any of + * the other NX resources. + */ + +extern int NXTransExecute(int *result, int *error, int *maxfds, fd_set *readfds, + fd_set *writefds, struct timeval *timeout); + +/* + * Run an empty loop, giving to the NX transport a chance to check + * its descriptors. + */ + +extern int NXTransContinue(struct timeval *timeout); + +/* + * Perform I/O on the given descriptors. If memory-to-memory trans- + * port has been activated and the descriptor is recognized as a + * valid agent connection, then the functions will read and write + * the data directly to the proxy buffer, otherwise the correspond- + * ing network operation will be performed. + */ + +extern int NXTransRead(int fd, char *data, int size); +extern int NXTransWrite(int fd, char *data, int size); +extern int NXTransReadable(int fd, int *readable); + +extern int NXTransReadVector(int fd, struct iovec *iovdata, int iovsize); +extern int NXTransWriteVector(int fd, struct iovec *iovdata, int iovsize); + +extern int NXTransClose(int fd); + +/* + * Return true if the NX transport is running. The fd parameter can + * be either the local descriptor attached to the NX transport or + * NX_FD_ANY. + */ + +extern int NXTransRunning(int fd); + +/* + * Close down the NX transport and free all the allocated resources. + * The fd parameter can be either the local descriptor or NX_FD_ANY. + * This must be explicitly called by the agent before the proxy can + * start the tear down procedure. + */ + +extern int NXTransDestroy(int fd); + +/* + * Tell to the proxy how to handle the standard POSIX signals. For + * example, given the SIGINT signal, the caller can specify any of + * the following actions: + * + * NX_SIGNAL_ENABLE: A signal handler will have to be installed by + * the library, so that it can be intercepted by + * the proxy. + * + * NX_SIGNAL_DISABLE: The signal will be handled by the caller and, + * eventually, forwarded to the proxy by calling + * NXTransSignal() explicitly. + * + * NX_SIGNAL_RAISE: The signal must be handled now, as if it had + * been delivered by the operating system. This + * function can be called by the agent with the + * purpose of propagating a signal to the proxy. + * + * NX_SIGNAL_FORWARD: A signal handler will have to be installed by + * the library but the library will have to call + * the original signal handler when the signal + * is received. + * + * As a rule of thumb, agents should let the proxy handle SIGUSR1 + * and SIGUSR2, used for producing the NX protocol statistics, and + * SIGHUP, used for disconnecting the NX transport. + * + * The following signals are blocked by default upon creation of the + * NX transport: + * + * SIGCHLD These signals should be always put under the control + * SIGUSR1 of the proxy. If agents are intercepting them, agents + * SIGUSR2 should later call NXTransSignal(..., NX_SIGNAL_RAISE) + * SIGHUP to forward the signal to the proxy. As an alternative + * they can specify a NX_SIGNAL_FORWARD action, so they, + * in turn, can be notified about the signal. This can + * be especially useful for SIGCHLD. + * + * SIGINT These signals should be intercepted by agents. Agents + * SIGTERM should ensure that NXTransDestroy() is called before + * exiting, to give the proxy a chance to shut down the + * NX transport. + * + * SIGPIPE This signal is blocked by the proxy, but not used to + * implement any functionality. It can be handled by the + * NX agent without affecting the proxy. + * + * SIGALRM This is now used by the proxy and agents should not + * redefine it. Agents can use the signal to implement + * their own timers but should not interleave calls to + * the NX transport and should restore the old handler + * when the timeout is raised. + * + * SIGVTALRM These signals are not used but may be used in future + * SIGWINCH versions of the library. + * SIGIO + * SIGTSTP + * SIGTTIN + * SIGTTOU + * + * By calling NXTransSignal(..., NX_SIGNAL_DISABLE) nxcomp will res- + * tore the signal handler that was saved at the time the proxy hand- + * ler was installed. This means that you should call the function + * just after the XOpenDisplay() or any other function used to init- + * ialize the NX transport. + */ + +extern int NXTransSignal(int signal, int action); + +/* + * Return a value between 0 and 9 indicating the congestion level + * based on the tokens still available. A value of 9 means that + * the link is congested and no further data can be sent. + */ + +extern int NXTransCongestion(int fd); + +/* + * Let the application to be notified by the proxy when an event oc- + * curs. The parameter, as set at the time the handler is installed, + * is passed each time to the callback function. The parameter is + * presumably the display pointer, given that at the present moment + * the NX transport doesn't have access to the display structure and + * so wouldn't be able to determine the display to pass to the call- + * back function. + * + * NX_HANDLER_FLUSH: The handler function is called when some + * more data has been written to the proxy + * link. + * + * The data is the number of bytes written. + * + * NX_HANDLER_STATISTICS: This handler is called to let the agent + * include arbitrary data in the transport + * statistics. The parameter, in this case, + * is a pointer to a pointer to a null term- + * inated string. The pointer is set at the + * time the handler is registered. The point- + * ed string will have to be filled by the + * agent with its statistics data. + * + * The data can be NX_STATISTICS_PARTIAL or NX_STATISTICS_TOTAL. The + * agent can refer to the value by using the NXStatisticsPartial and + * NXStatisticsTotal constants defined in NXvars.h. + * + * Note that these interfaces are used by Xlib and nxcompext. Agents + * should never call these interfaces directly, but use the nxcompext + * wrapper. + */ + +extern int NXTransHandler(int fd, int type, void (*handler)(void *parameter, + int reason), void *parameter); + +/* + * Set the policy to be used by the NX transport to write data to the + * proxy link: + * + * NX_POLICY_IMMEDIATE: When set to immediate, the proxy will try to + * write the data just after having encoded it. + * + * NX_POLICY_DEFERRED: When policy is set to deferred, data will be + * accumulated in a buffer and written to the + * remote proxy when NXTransFlush() is called by + * the agent. + */ + +extern int NXTransPolicy(int fd, int type); + +/* + * Query the number of bytes that have been accumulated for a deferred + * flush. + */ + +extern int NXTransFlushable(int fd); + +/* + * Tell to the NX transport to write all the accumulated data to the + * remote proxy. + */ + +extern int NXTransFlush(int fd); + +/* + * Create a new channel of the given type. It returns 1 on success, + * 0 if the NX transport is not running, or -1 in the case of error. + * On success, the descriptor provided by the caller can be later + * used for the subsequent I/O. The type parameter not only tells to + * the proxy the remote port where the channel has to be connected, + * but also gives a hint about the type of data that will be carried + * by the channel, so that the proxy can try to optimize the traffic + * on the proxy link. + * + * NX_CHANNEL_X: The channel will carry X traffic and it + * will be connected to the remote X display. + * + * NX_CHANNEL_CUPS: The channel will carry CUPS/IPP protocol. + * + * NX_CHANNEL_SMB: The channel will carry SMB/CIFS protocol. + * + * NX_CHANNEL_MEDIA: The channel will transport audio or other + * multimedia data. + * + * NX_CHANNEL_HTTP: The channel will carry HTTP protocol. + * + * NX_CHANNEL_FONT: The channel will forward a X font server + * connection. + * + * Only a proxy running at the NX server/X client side will be able + * to create a X, CUPS, SMB, MEDIA and HTTP channel. A proxy running + * at the NX client/X server side can create font server connections. + * The channel creation will also fail if the remote end has not been + * set up to forward the connection. + * + * To create a new channel the agent will have to set up a socketpair + * and pass to the proxy one of the socket descriptors. + * + * Example: + * + * #include + * #include + * + * int fds[2]; + * + * if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) + * { + * ... + * } + * else + * { + * // + * // Use fds[0] locally and let the + * // proxy use fds[1]. + * // + * + * if (NXTransChannel(NX_FD_ANY, fds[1], NX_CHANNEL_X) <= 0) + * { + * ... + * } + * + * // + * // The agent can now use fds[0] in + * // read(), write() and select() + * // system calls. + * // + * + * ... + * } + * + * Note that all the I/O on the descriptor should be non-blocking, to + * give a chance to the NX transport to run in the background and handle + * the data that will be fed to the agent's side of the socketpair. This + * will happen automatically, as long as the agent uses the XSelect() + * version of the select() function (as it is normal whenever performing + * Xlib I/O). In all the other cases, like presumably in the agent's main + * loop, the agent will have to loop through NXTransPrepare(), NXTrans- + * Select() and NXTransExecute() functions explicitly, adding to the sets + * the descriptors that are awaited by the agent. Please check the imple- + * mentation of _XSelect() in nx-X11/lib/X11/XlibInt.c for an example. + */ + +extern int NXTransChannel(int fd, int channelfd, int type); + +/* + * Return the name of the files used by the proxy for the current session. + * + * The type parameter can be: + * + * NX_FILE_SESSION: Usually the file 'session' in the user's session + * directory. + * + * NX_FILE_ERRORS: The file used for the diagnostic output. Usually + * the file 'errors' in the session directory. + * + * NX_FILE_OPTIONS: The file containing the NX options, if any. + * + * NX_FILE_STATS: The file used for the statistics output. + * + * The returned string is allocated in static memory. The caller should + * copy the string upon returning from the function, without freeing the + * pointer. + */ + +extern const char *NXTransFile(int type); + +/* + * Return the time in milliseconds elapsed since the last call to this + * same function. + */ + +extern long NXTransTime(void); + +/* + * Other interfaces to the internal transport functions. + */ + +extern int NXTransProxy(int fd, int mode, const char *display); + +extern int NXTransClient(const char *display); + +extern int NXTransDialog(const char *caption, const char *message, + const char *window, const char *type, int local, + const char *display); + +extern int NXTransAlert(int code, int local); + +extern int NXTransWatchdog(int timeout); + +extern int NXTransKeeper(int caches, int images, const char *root); + +extern void NXTransExit(int code) __attribute__((noreturn)); + +extern int NXTransParseCommandLine(int argc, const char **argv); +extern int NXTransParseEnvironment(const char *env, int force); + +extern void NXTransCleanup(void) __attribute__((noreturn)); + +/* + * Cleans up the global and local state + * (the same way as NXTransCleanup does) + * but does not exit the process + * Needed for IOS platform + */ +extern void NXTransCleanupForReconnect(void); + +extern const char* NXVersion(void); +extern int NXMajorVersion(void); +extern int NXMinorVersion(void); +extern int NXPatchVersion(void); +extern int NXMaintenancePatchVersion(void); + +#ifdef __cplusplus +} +#endif + +#endif /* NX_H */ diff --git a/nxcomp/include/NXalert.h b/nxcomp/include/NXalert.h new file mode 100644 index 000000000..dca2f44ca --- /dev/null +++ b/nxcomp/include/NXalert.h @@ -0,0 +1,276 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef NXalert_H +#define NXalert_H + +#define ALERT_CAPTION_PREFIX "NX - " + +#define INTERNAL_ERROR_ALERT 1 +#define INTERNAL_ERROR_ALERT_TYPE "error" +#define INTERNAL_ERROR_ALERT_STRING \ +"\ +An unrecoverable internal error was detected.\n\ +Press OK to terminate the current session.\n\ +" + +#define CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT 2 +#define CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT_TYPE "yesno" +#define CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT_STRING \ +"\ +One of the applications currently in use is not responding.\n\ +Do you want to terminate the current session?\n\ +" + +#define CLOSE_DEAD_X_CONNECTION_SERVER_ALERT 3 +#define CLOSE_DEAD_X_CONNECTION_SERVER_ALERT_TYPE "yesno" +#define CLOSE_DEAD_X_CONNECTION_SERVER_ALERT_STRING \ +"\ +One of the applications did not behave correctly and caused\n\ +the X server to stop responding in a timely fashion. Do you\n\ +want to terminate the current session?\n\ +" + +#define CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT 4 +#define CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT_TYPE NULL +#define CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT_STRING NULL + +#define CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT 5 +#define CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT_TYPE "yesno" +#define CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT_STRING \ +"\ +No response received from the remote server.\n\ +Do you want to terminate the current session?\n\ +" + +#define RESTART_DEAD_PROXY_CONNECTION_CLIENT_ALERT 6 +#define RESTART_DEAD_PROXY_CONNECTION_CLIENT_ALERT_TYPE NULL +#define RESTART_DEAD_PROXY_CONNECTION_CLIENT_ALERT_STRING NULL + +#define RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT 7 +#define RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT_TYPE "yesno" +#define RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT_STRING \ +"\ +Connection with remote server was shut down. NX will try\n\ +to establish a new server connection. Session could have\n\ +been left in a unusable state. Do you want to terminate\n\ +the session?\n\ +" + +#define CLOSE_UNRESPONSIVE_X_SERVER_ALERT 8 +#define CLOSE_UNRESPONSIVE_X_SERVER_ALERT_TYPE "panic" +#define CLOSE_UNRESPONSIVE_X_SERVER_ALERT_STRING \ +"\ +You pressed the key sequence CTRL+ALT+SHIFT+ESC.\n\ +This is probably because your X server has become\n\ +unresponsive. Session will be terminated in 30\n\ +seconds unless you abort the procedure by pressing\n\ +the Cancel button.\n\ +" + +#define WRONG_PROXY_VERSION_ALERT 9 +#define WRONG_PROXY_VERSION_ALERT_TYPE "ok" +#define WRONG_PROXY_VERSION_ALERT_STRING \ +"\ +Local NX libraries version " VERSION " do not match the NX\n\ +version of the remote server. Please check the error\n\ +log on the server to find out which client version you\n\ +need to install to be able to access this server.\n\ +" + +#define FAILED_PROXY_CONNECTION_CLIENT_ALERT 10 +#define FAILED_PROXY_CONNECTION_CLIENT_ALERT_TYPE NULL +#define FAILED_PROXY_CONNECTION_CLIENT_ALERT_STRING NULL + +#define FAILED_PROXY_CONNECTION_SERVER_ALERT 11 +#define FAILED_PROXY_CONNECTION_SERVER_ALERT_TYPE "yesno" +#define FAILED_PROXY_CONNECTION_SERVER_ALERT_STRING \ +"\ +Could not yet establish the connection to the remote\n\ +proxy. Do you want to terminate the current session?\n\ +" + +#define MISSING_PROXY_CACHE_ALERT 12 +#define MISSING_PROXY_CACHE_ALERT_TYPE "ok" +#define MISSING_PROXY_CACHE_ALERT_STRING \ +"\ +NX was unable to negotiate a cache for this session.\n\ +This may happen if this is the first time you run a\n\ +session on this server or if cache was corrupted or\n\ +produced by an incompatible NX version.\n\ +" + +#define ABORT_PROXY_CONNECTION_ALERT 13 +#define ABORT_PROXY_CONNECTION_ALERT_TYPE "ok" +#define ABORT_PROXY_CONNECTION_ALERT_STRING \ +"\ +The connection with the remote server was shut down.\n\ +Please check the state of your network connection.\n\ +" + +/* + * The one below is a special alert, used to close + * a previous alert that is running on the given + * side. This can be used to get rid of a message + * that has ceased to hold true. + */ + +#define DISPLACE_MESSAGE_ALERT 14 +#define DISPLACE_MESSAGE_ALERT_TYPE NULL +#define DISPLACE_MESSAGE_ALERT_STRING NULL + +/* + * These are the other alert messages that were + * added in the 1.5.0 release. The first is never + * shown and is intended just for testing. + */ + +#define GREETING_MESSAGE_ALERT 15 +#define GREETING_MESSAGE_ALERT_TYPE "ok" +#define GREETING_MESSAGE_ALERT_STRING \ +"\ +Welcome to NX from the NoMachine team. We really\n\ +hope you will enjoy this wonderful software as much\n\ +as we had fun making it ;-).\n\ +" + +/* + * These alerts are intended to notify the user + * of the reason why the agent failed to resume + * the session. + */ + +#define START_RESUME_SESSION_ALERT 16 +#define START_RESUME_SESSION_ALERT_TYPE "ok" +#define START_RESUME_SESSION_ALERT_STRING \ +"\ +You appear to run your NX session across a slow network\n\ +connection. Resuming the session may require some time.\n\ +Please wait.\ +" + +#define FAILED_RESUME_DISPLAY_ALERT 17 +#define FAILED_RESUME_DISPLAY_ALERT_TYPE "error" +#define FAILED_RESUME_DISPLAY_ALERT_STRING \ +"\ +Failed to open the display. Can't resume the NX\n\ +session on this display.\n\ +" + +#define FAILED_RESUME_DISPLAY_BROKEN_ALERT 18 +#define FAILED_RESUME_DISPLAY_BROKEN_TYPE "error" +#define FAILED_RESUME_DISPLAY_BROKEN_STRING \ +"\ +The display connection was broken while trying to\n\ +resume the session. Please, check your network\n\ +connection and try again.\n\ +" + +#define FAILED_RESUME_VISUALS_ALERT 19 +#define FAILED_RESUME_VISUALS_ALERT_TYPE "error" +#define FAILED_RESUME_VISUALS_ALERT_STRING \ +"\ +Failed to restore all the required visuals.\n\ +Can't resume the NX session on this display.\n\ +" + +#define FAILED_RESUME_COLORMAPS_ALERT 20 +#define FAILED_RESUME_COLORMAPS_ALERT_TYPE "error" +#define FAILED_RESUME_COLORMAPS_ALERT_STRING \ +"\ +The number of available colormaps is different\n\ +on the new display. Can't resume the NX session\n\ +on this display.\n\ +" + +#define FAILED_RESUME_PIXMAPS_ALERT 21 +#define FAILED_RESUME_PIXMAPS_ALERT_TYPE "error" +#define FAILED_RESUME_PIXMAPS_ALERT_STRING \ +"\ +Failed to restore all the required pixmap formats.\n\ +Can't resume the NX session on this display.\n\ +" + +#define FAILED_RESUME_DEPTHS_ALERT 22 +#define FAILED_RESUME_DEPTHS_ALERT_TYPE "error" +#define FAILED_RESUME_DEPTHS_ALERT_STRING \ +"\ +Failed to restore all the required screen depths.\n\ +Can't resume the NX session on this display.\n\ +" + +#define FAILED_RESUME_RENDER_ALERT 23 +#define FAILED_RESUME_RENDER_ALERT_TYPE "error" +#define FAILED_RESUME_RENDER_ALERT_STRING \ +"\ +The render extension is missing or an incompatible\n\ +version was detected on your X server. Can't resume\n\ +the NX session on this display.\n\ +" + +#define FAILED_RESUME_FONTS_ALERT 24 +#define FAILED_RESUME_FONTS_ALERT_TYPE "error" +#define FAILED_RESUME_FONTS_ALERT_STRING \ +"\ +One or more of the fonts that are in use by the\n\ +session are missing. Can't resume the NX session\n\ +on this display.\n\ +" + +#define ABORT_PROXY_NEGOTIATION_ALERT 62 +#define ABORT_PROXY_NEGOTIATION_ALERT_TYPE "ok" +#define ABORT_PROXY_NEGOTIATION_ALERT_STRING \ +"\ +The remote proxy closed the connection while negotiating\n\ +the session. This may be due to the wrong authentication\n\ +credentials passed to the server.\n\ +" + +#define ABORT_PROXY_SHUTDOWN_ALERT 64 +#define ABORT_PROXY_SHUTDOWN_ALERT_TYPE "ok" +#define ABORT_PROXY_SHUTDOWN_ALERT_STRING \ +"\ +No response received from the remote proxy while\n\ +waiting for the session shutdown.\n\ +" + +#define FAILED_XDMCP_CONNECTION_ALERT 65 +#define FAILED_XDMCP_CONNECTION_ALERT_TYPE "ok" +#define FAILED_XDMCP_CONNECTION_ALERT_STRING \ +"\ +The XDM host that was contacted by the NX server doesn't\n\ +seem to be able to start the session. Please check your\n\ +server configuration.\n\ +" + +/* + * Used to handle the backward compatibility. + * Update the numbers if you add a new alert. + */ + +#define LAST_PROTO_STEP_6_ALERT 63 +#define LAST_PROTO_STEP_7_ALERT 65 + +#endif /* NXalert_H */ diff --git a/nxcomp/include/NXpack.h b/nxcomp/include/NXpack.h new file mode 100644 index 000000000..3eade6855 --- /dev/null +++ b/nxcomp/include/NXpack.h @@ -0,0 +1,141 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef NXpack_H +#define NXpack_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MASK_METHOD_LIMIT 10 + +#define NO_MASK 0 + +#define MASK_8_COLORS 1 +#define MASK_64_COLORS 2 +#define MASK_256_COLORS 3 +#define MASK_512_COLORS 4 +#define MASK_4K_COLORS 5 +#define MASK_32K_COLORS 6 +#define MASK_64K_COLORS 7 +#define MASK_256K_COLORS 8 +#define MASK_2M_COLORS 9 +#define MASK_16M_COLORS 10 + +#define PACK_METHOD_LIMIT 128 + +#define NO_PACK 0 + +#define PACK_MASKED_8_COLORS 1 +#define PACK_MASKED_64_COLORS 2 +#define PACK_MASKED_256_COLORS 3 +#define PACK_MASKED_512_COLORS 4 +#define PACK_MASKED_4K_COLORS 5 +#define PACK_MASKED_32K_COLORS 6 +#define PACK_MASKED_64K_COLORS 7 +#define PACK_MASKED_256K_COLORS 8 +#define PACK_MASKED_2M_COLORS 9 +#define PACK_MASKED_16M_COLORS 10 + +#define PACK_RAW_8_BITS 3 +#define PACK_RAW_16_BITS 7 +#define PACK_RAW_24_BITS 10 + +#define PACK_COLORMAP_256_COLORS 11 + +#define PACK_JPEG_8_COLORS 26 +#define PACK_JPEG_64_COLORS 27 +#define PACK_JPEG_256_COLORS 28 +#define PACK_JPEG_512_COLORS 29 +#define PACK_JPEG_4K_COLORS 30 +#define PACK_JPEG_32K_COLORS 31 +#define PACK_JPEG_64K_COLORS 32 +#define PACK_JPEG_256K_COLORS 33 +#define PACK_JPEG_2M_COLORS 34 +#define PACK_JPEG_16M_COLORS 35 + +#define PACK_PNG_8_COLORS 37 +#define PACK_PNG_64_COLORS 38 +#define PACK_PNG_256_COLORS 39 +#define PACK_PNG_512_COLORS 40 +#define PACK_PNG_4K_COLORS 41 +#define PACK_PNG_32K_COLORS 42 +#define PACK_PNG_64K_COLORS 43 +#define PACK_PNG_256K_COLORS 44 +#define PACK_PNG_2M_COLORS 45 +#define PACK_PNG_16M_COLORS 46 + +#define PACK_RGB_16M_COLORS 63 +#define PACK_RLE_16M_COLORS 64 + +#define PACK_ALPHA 65 +#define PACK_COLORMAP 66 + +#define PACK_BITMAP_16M_COLORS 67 + +/* + * Not really pack methods. These values + * allow dynamic selection of the pack + * method by the agent. + */ + +#define PACK_NONE 0 +#define PACK_LOSSY 253 +#define PACK_LOSSLESS 254 +#define PACK_ADAPTIVE 255 + +/* + * Reduce the number of colors in the + * image by applying a mask. + */ + +typedef struct +{ + unsigned int color_mask; + unsigned int correction_mask; + unsigned int white_threshold; + unsigned int black_threshold; + +} ColorMask; + +extern const ColorMask Mask8TrueColor; +extern const ColorMask Mask64TrueColor; +extern const ColorMask Mask512TrueColor; +extern const ColorMask Mask4KTrueColor; +extern const ColorMask Mask32KTrueColor; +extern const ColorMask Mask256KTrueColor; +extern const ColorMask Mask2MTrueColor; +extern const ColorMask Mask16MTrueColor; + +const ColorMask *MethodColorMask(unsigned int method); + +int MethodBitsPerPixel(unsigned int method); + +#ifdef __cplusplus +} +#endif + +#endif /* NXpack_H */ diff --git a/nxcomp/include/NXproto.h b/nxcomp/include/NXproto.h new file mode 100644 index 000000000..7b988bdbf --- /dev/null +++ b/nxcomp/include/NXproto.h @@ -0,0 +1,447 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef NXproto_H +#define NXproto_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * Force the size to match the wire protocol. + */ + +#define Drawable CARD32 +#define GContext CARD32 + +#define sz_xNXGetControlParametersReq 4 +#define sz_xNXGetCleanupParametersReq 4 +#define sz_xNXGetImageParametersReq 4 +#define sz_xNXGetUnpackParametersReq 8 +#define sz_xNXGetShmemParametersReq 16 +#define sz_xNXGetFontParametersReq 4 +#define sz_xNXSetExposeParametersReq 8 +#define sz_xNXSetCacheParametersReq 8 +#define sz_xNXStartSplitReq 8 +#define sz_xNXEndSplitReq 4 +#define sz_xNXCommitSplitReq 12 +#define sz_xNXSetUnpackGeometryReq 24 +#define sz_xNXSetUnpackColormapReq 16 +#define sz_xNXSetUnpackAlphaReq 16 +#define sz_xNXPutPackedImageReq 40 +#define sz_xNXFreeUnpackReq 4 +#define sz_xNXFinishSplitReq 4 +#define sz_xNXAbortSplitReq 4 +#define sz_xNXFreeSplitReq 4 + +#define sz_xGetControlParametersReply 32 +#define sz_xGetCleanupParametersReply 32 +#define sz_xGetImageParametersReply 32 +#define sz_xGetUnpackParametersReply 32 +#define sz_xGetShmemParametersReply 32 + +#define LINK_TYPE_LIMIT 5 + +#define LINK_TYPE_NONE 0 +#define LINK_TYPE_MODEM 1 +#define LINK_TYPE_ISDN 2 +#define LINK_TYPE_ADSL 3 +#define LINK_TYPE_WAN 4 +#define LINK_TYPE_LAN 5 + +/* + * NX Replies. + */ + +/* + * The following reply has 4 new boolean + * fields in the last protocol version. + */ + +typedef struct _NXGetControlParametersReply { + BYTE type; /* Is X_Reply. */ + CARD8 linkType; + CARD16 sequenceNumber B16; + CARD32 length B32; /* Is 0. */ + CARD8 localMajor; + CARD8 localMinor; + CARD8 localPatch; + CARD8 remoteMajor; + CARD8 remoteMinor; + CARD8 remotePatch; + CARD16 splitTimeout B16; + CARD16 motionTimeout B16; + CARD8 splitMode; + CARD8 pad1; + CARD32 splitSize B32; + CARD8 packMethod; + CARD8 packQuality; + CARD8 dataLevel; + CARD8 streamLevel; + CARD8 deltaLevel; + CARD8 loadCache; + CARD8 saveCache; + CARD8 startupCache; +} xNXGetControlParametersReply; + +typedef struct _NXGetCleanupParametersReply { + BYTE type; /* Is X_Reply. */ + BYTE pad; + CARD16 sequenceNumber B16; + CARD32 length B32; /* Is 0. */ + BOOL cleanGet; + BOOL cleanAlloc; + BOOL cleanFlush; + BOOL cleanSend; + BOOL cleanImages; + BYTE pad1, pad2, pad3; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xNXGetCleanupParametersReply; + +typedef struct _NXGetImageParametersReply { + BYTE type; /* Is X_Reply. */ + BYTE pad; + CARD16 sequenceNumber B16; + CARD32 length B32; /* Is 0. */ + BOOL imageSplit; + BOOL imageMask; + BOOL imageFrame; + CARD8 imageMaskMethod; + CARD8 imageSplitMethod; + BYTE pad1, pad2, pad3; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xNXGetImageParametersReply; + +/* + * Data is made of PACK_METHOD_LIMIT values of + * type BOOL telling which unpack capabilities + * are implemented in proxy. + */ + +typedef struct _NXGetUnpackParametersReply { + BYTE type; /* Is X_Reply. */ + BYTE pad; + CARD16 sequenceNumber B16; + CARD32 length B32; /* Is PACK_METHOD_LIMIT / 4 from NXpack.h. */ + CARD8 entries; /* Is PACK_METHOD_LIMIT. */ + BYTE pad1, pad2, pad3; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xNXGetUnpackParametersReply; + +typedef struct _NXGetShmemParametersReply { + BYTE type; /* Is X_Reply. */ + CARD8 stage; /* As in the corresponding request. */ + CARD16 sequenceNumber B16; + CARD32 length B32; /* Is 0. */ + BOOL clientEnabled; /* SHM on path agent to proxy. */ + BOOL serverEnabled; /* SHM on path proxy to X server. */ + BYTE pad1, pad2; /* Previous values can be checked */ + CARD32 clientSize B32; /* at end of stage 2. */ + CARD32 serverSize B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xNXGetShmemParametersReply; + +typedef struct _NXGetFontParametersReply { + BYTE type; /* Is X_Reply. */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* Is length of path string + 1 / 4. */ + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xNXGetFontParametersReply; + +/* + * NX Requests. + */ + +typedef struct _NXGetControlParametersReq { + CARD8 reqType; + BYTE pad; + CARD16 length B16; +} xNXGetControlParametersReq; + +typedef struct _NXGetCleanupParametersReq { + CARD8 reqType; + BYTE pad; + CARD16 length B16; +} xNXGetCleanupParametersReq; + +typedef struct _NXGetImageParametersReq { + CARD8 reqType; + BYTE pad; + CARD16 length B16; +} xNXGetImageParametersReq; + +typedef struct _NXGetUnpackParametersReq { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD8 entries; + BYTE pad1, pad2, pad3; +} xNXGetUnpackParametersReq; + +typedef struct _NXGetShmemParametersReq { + CARD8 reqType; + CARD8 stage; /* It is between 0 and 2. */ + CARD16 length B16; + BOOL enableClient; /* X client side support is */ + BOOL enableServer; /* not implemented yet. */ + BYTE pad1, pad2; + CARD32 clientSegment; /* XID identifying the shared */ + CARD32 serverSegment; /* memory segments. */ +} xNXGetShmemParametersReq; + +typedef struct _NXGetFontParametersReq { + CARD8 reqType; + CARD8 pad; + CARD16 length B16; +} xNXGetFontParametersReq; + +/* + * The available split modes. + */ + +#define NXSplitModeDefault 0 +#define NXSplitModeAsync 1 +#define NXSplitModeSync 2 + +typedef struct _NXStartSplitReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; + CARD8 mode; + BYTE pad1, pad2, pad3; +} xNXStartSplitReq; + +typedef struct _NXEndSplitReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; +} xNXEndSplitReq; + +typedef struct _NXCommitSplitReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; + CARD8 propagate; + CARD8 request; + BYTE pad1, pad2; + CARD32 position B32; +} xNXCommitSplitReq; + +typedef struct _NXFinishSplitReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; +} xNXFinishSplitReq; + +typedef struct _NXAbortSplitReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; +} xNXAbortSplitReq; + +typedef struct _NXFreeSplitReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; +} xNXFreeSplitReq; + +typedef struct _NXSetExposeParametersReq { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + BOOL expose; + BOOL graphicsExpose; + BOOL noExpose; + BYTE pad1; +} xNXSetExposeParametersReq; + +typedef struct _NXSetCacheParametersReq { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + BOOL enableCache; + BOOL enableSplit; + BOOL enableSave; + BOOL enableLoad; +} xNXSetCacheParametersReq; + +typedef struct _NXSetUnpackGeometryReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; + CARD8 depth1Bpp; + CARD8 depth4Bpp; + CARD8 depth8Bpp; + CARD8 depth16Bpp; + CARD8 depth24Bpp; + CARD8 depth32Bpp; + BYTE pad1, pad2; + CARD32 redMask B32; + CARD32 greenMask B32; + CARD32 blueMask B32; +} xNXSetUnpackGeometryReq; + +typedef struct _NXSetUnpackColormapReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; + CARD8 method; + BYTE pad1, pad2, pad3; + CARD32 srcLength B32; + CARD32 dstLength B32; +} xNXSetUnpackColormapReq; + +typedef struct _NXSetUnpackAlphaReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; + CARD8 method; + BYTE pad1, pad2, pad3; + CARD32 srcLength B32; + CARD32 dstLength B32; +} xNXSetUnpackAlphaReq; + +typedef struct _NXPutPackedImageReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + CARD8 method; + CARD8 format; + CARD8 srcDepth; + CARD8 dstDepth; + CARD32 srcLength B32; + CARD32 dstLength B32; + INT16 srcX B16, srcY B16; + CARD16 srcWidth B16, srcHeight B16; + INT16 dstX B16, dstY B16; + CARD16 dstWidth B16, dstHeight B16; +} xNXPutPackedImageReq; + +typedef struct _NXFreeUnpackReq { + CARD8 reqType; + CARD8 resource; + CARD16 length B16; +} xNXFreeUnpackReq; + +/* + * The X_NXSplitData and X_NXSplitEvent opcodes + * are used internally and are ignored if coming + * from the agent. + */ + +#define X_NXInternalGenericData 0 +#define X_NXInternalGenericReply 1 +#define X_NXInternalGenericRequest 255 + +#define X_NXInternalShapeExtension 128 +#define X_NXInternalRenderExtension 129 + +#define X_NXFirstOpcode 230 +#define X_NXLastOpcode 252 + +#define X_NXGetControlParameters 230 +#define X_NXGetCleanupParameters 231 +#define X_NXGetImageParameters 232 +#define X_NXGetUnpackParameters 233 +#define X_NXStartSplit 234 +#define X_NXEndSplit 235 +#define X_NXSplitData 236 +#define X_NXCommitSplit 237 +#define X_NXSetExposeParameters 240 +#define X_NXSetUnpackGeometry 241 +#define X_NXSetUnpackColormap 242 +#define X_NXPutPackedImage 243 +#define X_NXSplitEvent 244 +#define X_NXGetShmemParameters 245 +#define X_NXSetUnpackAlpha 246 +#define X_NXFreeUnpack 247 +#define X_NXFinishSplit 248 +#define X_NXAbortSplit 249 +#define X_NXFreeSplit 250 +#define X_NXGetFontParameters 251 +#define X_NXSetCacheParameters 252 + +/* + * The following events are received by the agent + * in the form of a ClientMessage with the value + * 0 in fields atom and window. The format is + * always 32. Event specific data starts at byte + * offset 12. + * + * These events are sent by the NX transport to + * notify the agent about the result of a split + * operation. + */ + +#define NXNoSplitNotify 1 +#define NXStartSplitNotify 2 +#define NXCommitSplitNotify 3 +#define NXEndSplitNotify 4 +#define NXEmptySplitNotify 5 + +/* + * Notifications of collect events. These events + * don't come from the NX transport but are put + * back in client's event queue by NXlib. + */ + +#define NXCollectImageNotify 8 +#define NXCollectPropertyNotify 9 +#define NXCollectGrabPointerNotify 10 +#define NXCollectInputFocusNotify 11 + +#undef Drawable +#undef GContext + +#ifdef __cplusplus +} +#endif + +#endif /* NXproto_H */ diff --git a/nxcomp/include/NXvars.h b/nxcomp/include/NXvars.h new file mode 100644 index 000000000..f514000d7 --- /dev/null +++ b/nxcomp/include/NXvars.h @@ -0,0 +1,201 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef NXvars_H +#define NXvars_H + +/* + * This can be included by the proxy or another + * layer that doesn't use Xlib. + */ + +#if !defined(_XLIB_H_) && !defined(_XKBSRV_H_) + +#define NeedFunctionPrototypes 1 + +#define Display void + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Display flush policies. + */ + +#define NXPolicyImmediate 1 +#define NXPolicyDeferred 2 + +/* + * Type of flush. + */ + +#define NXFlushBuffer 0 +#define NXFlushLink 1 + +/* + * Type of statistics. + */ + +#define NXStatisticsPartial 0 +#define NXStatisticsTotal 1 + +/* + * Reason why the display is blocking. + */ + +#define NXBlockRead 1 +#define NXBlockWrite 2 + +/* + * Set if the client is interested in ignoring + * the display error and continue with the exe- + * cution of the program. By default the usual + * Xlib behaviour is gotten, and the library + * will call an exit(). + */ + +extern int _NXHandleDisplayError; + +/* + * The function below is called whenever Xlib is + * going to perform an I/O operation. The funct- + * ion can be redefined to include additional + * checks aimed at detecting if the display needs + * to be closed, for example because of an event + * or a signal mandating the end of the session. + * In this way the client program can regain the + * control before Xlib blocks waiting for input + * from the network. + */ + +typedef int (*NXDisplayErrorPredicate)( +#if NeedFunctionPrototypes + Display* /* display */, + int /* reason */ +#endif +); + +extern NXDisplayErrorPredicate _NXDisplayErrorFunction; + +/* + * This is called when Xlib is going to block + * waiting for the display to become readable or + * writable. The client can use the hook to run + * any arbitrary operation that may require some + * time to complete. The user should not try to + * read or write to the display inside the call- + * back routine. + */ + +typedef void (*NXDisplayBlockHandler)( +#if NeedFunctionPrototypes + Display* /* display */, + int /* reason */ +#endif +); + +extern NXDisplayBlockHandler _NXDisplayBlockFunction; + +/* + * Used to notify the program when more data + * is written to the socket. + */ + +typedef void (*NXDisplayWriteHandler)( +#if NeedFunctionPrototypes + Display* /* display */, + int /* length */ +#endif +); + +extern NXDisplayWriteHandler _NXDisplayWriteFunction; + +/* + * This callback is used to notify the agent + * that the proxy link has been flushed. + */ + +typedef void (*NXDisplayFlushHandler)( +#if NeedFunctionPrototypes + Display* /* display */, + int /* length */ +#endif +); + +extern NXDisplayFlushHandler _NXDisplayFlushFunction; + +/* + * Used by the NX transport to get an arbitrary + * string to add to its protocol statistics. + */ + +typedef void (*NXDisplayStatisticsHandler)( +#if NeedFunctionPrototypes + Display* /* display */, + char* /* buffer */, + int /* size */ +#endif +); + +extern NXDisplayStatisticsHandler _NXDisplayStatisticsFunction; + +/* + * Let users redefine the function printing an + * error message in the case of a out-of-order + * sequence number. + */ + +typedef void (*NXLostSequenceHandler)( +#if NeedFunctionPrototypes + Display* /* display */, + unsigned long /* newseq */, + unsigned long /* lastseq */, + unsigned int /* type */ +#endif +); + +extern NXLostSequenceHandler _NXLostSequenceFunction; + +/* + * Let the X server run the children processes + * (as for example the keyboard initialization + * utilities) by using the native system libra- + * ries, instead of the libraries shipped with + * the NX environment. If set, the Popen() in + * the X server will remove the LD_LIBRARY_PATH + * setting from the environment before calling + * the execl() function in the child process. + */ + +extern int _NXUnsetLibraryPath; + +#ifdef __cplusplus +} +#endif + +#endif /* NXvars_H */ diff --git a/nxcomp/install-sh b/nxcomp/install-sh deleted file mode 100755 index 58719246f..000000000 --- a/nxcomp/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/nxcomp/m4/nx-macros.m4 b/nxcomp/m4/nx-macros.m4 new file mode 120000 index 000000000..813e9b041 --- /dev/null +++ b/nxcomp/m4/nx-macros.m4 @@ -0,0 +1 @@ +../../m4/nx-macros.m4 \ No newline at end of file diff --git a/nxcomp/mkinstalldirs b/nxcomp/mkinstalldirs deleted file mode 100755 index 936cf3407..000000000 --- a/nxcomp/mkinstalldirs +++ /dev/null @@ -1,34 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Last modified: 1995-03-05 -# Public domain - -errstatus=0 - -for file in ${1+"$@"} ; do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d in ${1+"$@"} ; do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" 1>&2 - mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$? - fi - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus diff --git a/nxcomp/nxcomp.pc.in b/nxcomp/nxcomp.pc.in index f0963aa17..26206d857 100644 --- a/nxcomp/nxcomp.pc.in +++ b/nxcomp/nxcomp.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: nxcomp Description: NX Compression Library -Version: @VERSION@ +Version: @COMP_VERSION@ #libjepg does not provide a pkgconfig-file, zlib does not provide it for older versions #Requires: libjpeg zlib Requires: libpng diff --git a/nxcomp/src/ActionCache.cpp b/nxcomp/src/ActionCache.cpp new file mode 100644 index 000000000..783b1724e --- /dev/null +++ b/nxcomp/src/ActionCache.cpp @@ -0,0 +1,51 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Control.h" + +#include "ActionCache.h" + +ActionCache::ActionCache() +{ + for (int i = 0; i < 256; i++) + { + base_[i] = new IntCache(8); + } + + slot_ = 0; + last_ = 0; +} + +ActionCache::~ActionCache() +{ + for (int i = 0; i < 256; i++) + { + delete base_[i]; + } +} diff --git a/nxcomp/src/ActionCache.h b/nxcomp/src/ActionCache.h new file mode 100644 index 000000000..2aedd4a07 --- /dev/null +++ b/nxcomp/src/ActionCache.h @@ -0,0 +1,49 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ActionCache_H +#define ActionCache_H + +#include "IntCache.h" + +class ActionCache +{ + friend class EncodeBuffer; + friend class DecodeBuffer; + + public: + + ActionCache(); + ~ActionCache(); + + private: + + IntCache *base_[256]; + + unsigned int slot_; + unsigned short last_; +}; + +#endif /* ActionCache_H */ diff --git a/nxcomp/src/Agent.cpp b/nxcomp/src/Agent.cpp new file mode 100644 index 000000000..e55620601 --- /dev/null +++ b/nxcomp/src/Agent.cpp @@ -0,0 +1,84 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Agent.h" +#include "Proxy.h" + +extern Proxy *proxy; + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +Agent::Agent(int fd[2]) +{ + remoteFd_ = fd[0]; + localFd_ = fd[1]; + + transport_ = new AgentTransport(localFd_); + + if (transport_ == NULL) + { + #ifdef PANIC + *logofs << "Agent: PANIC! Can't create the memory-to-memory transport " + << "for FD#" << localFd_ << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't create the memory-to-memory transport " + << "for FD#" << localFd_ << ".\n"; + + HandleCleanup(); + } + + FD_ZERO(&saveRead_); + FD_ZERO(&saveWrite_); + + canRead_ = 0; + + #ifdef DEBUG + *logofs << "Agent: Created agent object at " << this + << ".\n" << logofs_flush; + #endif +} + +Agent::~Agent() +{ + delete transport_; + + #ifdef DEBUG + *logofs << "Agent: Deleted agent object at " << this + << ".\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/Agent.h b/nxcomp/src/Agent.h new file mode 100644 index 000000000..3e1a50ae5 --- /dev/null +++ b/nxcomp/src/Agent.h @@ -0,0 +1,263 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Agent_H +#define Agent_H + +#include + +#include +#include +#include + +#include "Misc.h" +#include "Transport.h" +#include "Proxy.h" + +extern Proxy *proxy; + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +class Agent +{ + public: + + // + // Must be created by passing the fake descriptor that + // will be used for simulating socket communication + // betwen the agent and the proxy. I/O will take place + // by copying data to the agent's read and write buf- + // fers. + // + + Agent(int fd[2]); + + ~Agent(); + + AgentTransport *getTransport() const + { + return transport_; + } + + void saveReadMask(fd_set *readSet) + { + saveRead_ = *readSet; + } + + void saveWriteMask(fd_set *writeSet) + { + saveWrite_ = *writeSet; + } + + void clearReadMask(fd_set *readSet) + { + FD_CLR(remoteFd_, readSet); + FD_CLR(localFd_, readSet); + } + + void clearWriteMask(fd_set *writeSet) + { + FD_CLR(remoteFd_, writeSet); + FD_CLR(localFd_, writeSet); + } + + void setLocalRead(fd_set *readSet, int *result) + { + (*result)++; + + FD_SET(localFd_, readSet); + } + + void setRemoteRead(fd_set *readSet, int *result) + { + (*result)++; + + FD_SET(remoteFd_, readSet); + } + + void setRemoteWrite(fd_set *writeSet, int *result) + { + (*result)++; + + FD_SET(remoteFd_, writeSet); + } + + fd_set *getSavedReadMask() + { + return &saveRead_; + } + + fd_set *getSavedWriteMask() + { + return &saveWrite_; + } + + int getRemoteFd() const + { + return remoteFd_; + } + + int getLocalFd() const + { + return localFd_; + } + + int getProxyFd() const + { + return proxy -> getFd(); + } + + int isValid() const + { + return (transport_ != NULL); + } + + int localReadable() + { + return (transport_ -> readable() != 0); + } + + // + // Check if we can process more data from + // the agent descriptor and cache the result + // to avoid multiple calls. This must be + // always called before querying the other + // functions. + // + + void saveChannelState() + { + canRead_ = (proxy != NULL ? proxy -> canRead(localFd_) : 0); + } + + int remoteCanRead(const fd_set * const readSet) + { + // OS X 10.5 requires the second argument to be non-const, so copy readSet. + // It's safe though, as FD_ISSET does not operate on it. + fd_set readWorkSet = *readSet; + + #if defined(TEST) || defined(INFO) + *logofs << "Agent: remoteCanRead() is " << + (FD_ISSET(remoteFd_, &readWorkSet) && transport_ -> dequeuable() != 0) + << " with FD_ISSET() " << (int) FD_ISSET(remoteFd_, &readWorkSet) + << " and dequeuable " << transport_ -> dequeuable() + << ".\n" << logofs_flush; + #endif + + return (FD_ISSET(remoteFd_, &readWorkSet) && + transport_ -> dequeuable() != 0); + } + + int remoteCanWrite(const fd_set * const writeSet) + { + // OS X 10.5 requires the second argument to be non-const, so copy writeSet. + // It's safe though, as FD_ISSET does not operate on it. + fd_set writeWorkSet = *writeSet; + + #if defined(TEST) || defined(INFO) + *logofs << "Agent: remoteCanWrite() is " << + (FD_ISSET(remoteFd_, &writeWorkSet) && transport_ -> + queuable() != 0 && canRead_ == 1) << " with FD_ISSET() " + << (int) FD_ISSET(remoteFd_, &writeWorkSet) << " queueable " + << transport_ -> queuable() << " channel can read " + << canRead_ << ".\n" << logofs_flush; + #endif + + return (FD_ISSET(remoteFd_, &writeWorkSet) && + transport_ -> queuable() != 0 && + canRead_ == 1); + } + + int localCanRead() + { + #if defined(TEST) || defined(INFO) + *logofs << "Agent: localCanRead() is " << + (transport_ -> readable() != 0 && canRead_ == 1) + << " with readable " << transport_ -> readable() + << " channel can read " << canRead_ << ".\n" + << logofs_flush; + #endif + + return (transport_ -> readable() != 0 && + canRead_ == 1); + } + + int proxyCanRead() + { + #if defined(TEST) || defined(INFO) + *logofs << "Agent: proxyCanRead() is " << proxy -> canRead() + << ".\n" << logofs_flush; + #endif + + return (proxy -> canRead()); + } + + int proxyCanRead(const fd_set * const readSet) + { + // OS X 10.5 requires the second argument to be non-const, so copy readSet. + // It's safe though, as FD_ISSET does not operate on it. + fd_set readWorkSet = *readSet; + + #if defined(TEST) || defined(INFO) + *logofs << "Agent: proxyCanRead() is " + << ((int) FD_ISSET(proxy -> getFd(), &readWorkSet)) + << ".\n" << logofs_flush; + #endif + + return (FD_ISSET(proxy -> getFd(), &readWorkSet)); + } + + int enqueueData(const char *data, const int size) const + { + return transport_ -> enqueue(data, size); + } + + int dequeueData(char *data, int size) const + { + return transport_ -> dequeue(data, size); + } + + int dequeuableData() const + { + return transport_ -> dequeuable(); + } + + private: + + int remoteFd_; + int localFd_; + + fd_set saveRead_; + fd_set saveWrite_; + + int canRead_; + + AgentTransport *transport_; +}; + +#endif /* Agent_H */ diff --git a/nxcomp/src/Alpha.cpp b/nxcomp/src/Alpha.cpp new file mode 100644 index 000000000..6157e21e5 --- /dev/null +++ b/nxcomp/src/Alpha.cpp @@ -0,0 +1,138 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Unpack.h" +#include "Alpha.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +int UnpackAlpha(unsigned char method, unsigned char *src_data, int src_size, + unsigned char *dst_data, int dst_size) +{ + if (*src_data == 0) + { + if (dst_size != src_size - 1) + { + #ifdef TEST + *logofs << "UnpackAlpha: PANIC! Invalid destination size " + << dst_size << " with source " << src_size + << ".\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef TEST + *logofs << "UnpackAlpha: Expanding " << src_size - 1 + << " bytes of plain alpha data.\n" << logofs_flush; + #endif + + memcpy(dst_data, src_data + 1, src_size - 1); + + return 1; + } + + unsigned int check_size = dst_size; + + int result = ZDecompress(&unpackStream, dst_data, &check_size, + src_data + 1, src_size - 1); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "UnpackAlpha: PANIC! Failure decompressing alpha data. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decompressing alpha data. " + << "Error is '" << zError(result) << "'.\n"; + + return -1; + } + else if (check_size != (unsigned int) dst_size) + { + #ifdef PANIC + *logofs << "UnpackAlpha: PANIC! Size mismatch in alpha data. " + << "Resulting size is " << check_size << " with " + << "expected size " << dst_size << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Size mismatch in alpha data. " + << "Resulting size is " << check_size << " with " + << "expected size " << dst_size << ".\n"; + + return -1; + } + + #ifdef TEST + *logofs << "UnpackAlpha: Decompressed " << src_size - 1 + << " bytes to " << dst_size << " bytes of alpha data.\n" + << logofs_flush; + #endif + + return 1; +} + +int UnpackAlpha(T_alpha *alpha, unsigned char *dst_data, + int dst_size, int big_endian) +{ + unsigned int count = dst_size >> 2; + + unsigned int i; + + int shift; + + if (count != alpha -> entries) + { + #ifdef WARNING + *logofs << "UnpackAlpha: WARNING! Not applying the alpha with " + << count << " elements needed and " << alpha -> entries + << " available.\n" << logofs_flush; + #endif + + return 0; + } + + shift = (big_endian == 1 ? 0 : 3); + + for (i = 0; i < count; i++) + { + *(dst_data + shift) = *(alpha -> data + i); + + dst_data += 4; + } + + return 1; +} diff --git a/nxcomp/src/Alpha.h b/nxcomp/src/Alpha.h new file mode 100644 index 000000000..ea5068812 --- /dev/null +++ b/nxcomp/src/Alpha.h @@ -0,0 +1,35 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Alpha_H +#define Alpha_H + +int UnpackAlpha(unsigned char method, unsigned char *src_data, int src_size, + unsigned char *dst_data, int dst_size); + +int UnpackAlpha(T_alpha *alpha, unsigned char *dst_data, + int dst_size, int big_endian); + +#endif /* Aplha_H */ diff --git a/nxcomp/src/Auth.cpp b/nxcomp/src/Auth.cpp new file mode 100644 index 000000000..d42c0556d --- /dev/null +++ b/nxcomp/src/Auth.cpp @@ -0,0 +1,671 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Auth.h" + +#include "Misc.h" +#include "Control.h" +#include "Timestamp.h" +#include "Pipe.h" + +#define DEFAULT_STRING_LIMIT 512 + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Store the provided cookie as our 'fake' cookie, then +// read the 'real' cookie from the current X authority +// file. +// + +Auth::Auth(char *display, char *cookie) +{ + display_ = NULL; + + file_ = NULL; + + last_ = nullTimestamp(); + + fakeCookie_ = NULL; + realCookie_ = NULL; + + fakeData_ = NULL; + realData_ = NULL; + + dataSize_ = 0; + + generatedCookie_ = 0; + + if (display == NULL || *display == '\0' || cookie == NULL || + *cookie == '\0' || strlen(cookie) != 32) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Can't create the X authorization data " + << "with cookie '" << cookie << "' and display '" + << display << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't create the X authorization data " + << "with cookie '" << cookie << "' and display '" + << display << "'.\n"; + + return; + } + + #ifdef TEST + *logofs << "Auth: Creating X authorization data with cookie '" + << cookie << "' and display '" << display << "'.\n" + << logofs_flush; + #endif + + // + // Get a local copy of all parameters. + // + + display_ = new char[strlen(display) + 1]; + file_ = new char[DEFAULT_STRING_LIMIT]; + + fakeCookie_ = new char[strlen(cookie) + 1]; + realCookie_ = new char[DEFAULT_STRING_LIMIT]; + + if (display_ == NULL || file_ == NULL || + fakeCookie_ == NULL || realCookie_ == NULL) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Cannot allocate memory for the X " + << "authorization data.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot allocate memory for the X " + << "authorization data.\n"; + + return; + } + + strcpy(display_, display); + + *file_ = '\0'; + + strcpy(fakeCookie_, cookie); + + *realCookie_ = '\0'; + + // + // Get the real cookie from the authorization file. + // + + updateCookie(); +} + +Auth::~Auth() +{ + delete [] display_; + delete [] file_; + + delete [] fakeCookie_; + delete [] realCookie_; + + delete [] fakeData_; + delete [] realData_; +} + +// +// At the present moment the cookie is read only once, +// at the time the instance is initialized. If the auth +// file changes along the life of the session, the old +// cookie will be used. This works with X servers beca- +// use of an undocumented "feature". See nx-X11. +// + +int Auth::updateCookie() +{ + if (isTimestamp(last_) == 0) + { + #ifdef TEST + *logofs << "Auth: Reading the X authorization file " + << "with last update at " << strMsTimestamp(last_) + << ".\n" << logofs_flush; + #endif + + if (getCookie() == 1 && validateCookie() == 1) + { + // + // It should rather be the modification time + // the auth file, so we can read it again if + // the file is changed. + // + + #ifdef TEST + *logofs << "Auth: Setting last X authorization file " + << "update at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + last_ = getTimestamp(); + + return 1; + } + + #ifdef PANIC + *logofs << "Auth: PANIC! Cannot read the cookie from the X " + << "authorization file.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot read the cookie from the X " + << "authorization file.\n"; + + return -1; + } + + #ifdef TEST + *logofs << "Auth: WARNING! Skipping check on the X " + << "authorization file.\n" << logofs_flush; + #endif + + return 0; +} + +int Auth::getCookie() +{ + // + // Check the name of the auth file that we are going to use. + // It can be either the value of the XAUTHORITY environment + // or the default .Xauthority file in the user's home. + // + + char *environment; + + environment = getenv("XAUTHORITY"); + + if (environment != NULL && *environment != '\0') + { + strncpy(file_, environment, DEFAULT_STRING_LIMIT - 1); + } + else + { + snprintf(file_, DEFAULT_STRING_LIMIT - 1, "%s/.Xauthority", + control -> HomePath); + } + + *(file_ + DEFAULT_STRING_LIMIT - 1) = '\0'; + + #ifdef TEST + *logofs << "Auth: Using X authorization file '" << file_ + << "'.\n" << logofs_flush; + #endif + + // + // Use the nxauth command on Windows and the Mac, xauth + // on all the other platforms. On Windows we assume that + // the nxauth command is located under bin in the client + // installation directory. On Mac OS X we assume that the + // command is located directly in the client installation + // directory, to make bundle shipping easier. On all the + // other platforms we use the default xauth command that + // is in our path. + // + + char command[DEFAULT_STRING_LIMIT]; + + #if defined(__CYGWIN32__) + + snprintf(command, DEFAULT_STRING_LIMIT - 1, + "%s/bin/nxauth", control -> SystemPath); + + *(command + DEFAULT_STRING_LIMIT - 1) = '\0'; + + #elif defined(__APPLE__) + + snprintf(command, DEFAULT_STRING_LIMIT - 1, + "%s/nxauth", control -> SystemPath); + + *(command + DEFAULT_STRING_LIMIT - 1) = '\0'; + + #else + + strcpy(command, "xauth"); + + #endif + + #ifdef TEST + *logofs << "Auth: Using X auth command '" << command + << "'.\n" << logofs_flush; + #endif + + // + // The SSH code forces using the unix:n port when passing localhost:n. + // This is probably because localhost:n can fail to return a valid + // entry on machines where the hostname for localhost doesn't match + // exactly the 'localhost' string. For example, on a freshly installed + // Fedora Core 3 I get a 'localhost.localdomain/unix:0' entry. Query- + // ing 'xauth list localhost:0' results in an empty result, while the + // query 'xauth list unix:0' works as expected. Note anyway that if + // the cookie for the TCP connection on 'localhost' is set to a dif- + // ferent cookie than the one for the Unix connections, both SSH and + // NX will match the wrong cookie and session will fail. + // + + char line[DEFAULT_STRING_LIMIT]; + + if (strncmp(display_, "localhost:", 10) == 0) + { + snprintf(line, DEFAULT_STRING_LIMIT, "unix:%s", display_ + 10); + } + else + { + snprintf(line, DEFAULT_STRING_LIMIT, "%.200s", display_); + } + + const char *parameters[256]; + + parameters[0] = command; + parameters[1] = command; + parameters[2] = "-f"; + parameters[3] = file_; + parameters[4] = "list"; + parameters[5] = line; + parameters[6] = NULL; + + #ifdef TEST + *logofs << "Auth: Executing command "; + + for (int i = 0; i < 256 && parameters[i] != NULL; i++) + { + *logofs << "[" << parameters[i] << "]"; + } + + *logofs << ".\n" << logofs_flush; + #endif + + // + // Use the popen() function to read the result + // of the command. We would better use our own + // implementation. + // + + FILE *data = Popen((char *const *) parameters, "r"); + + int result = -1; + + if (data == NULL) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Failed to execute the X auth command.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to execute the X auth command.\n"; + + goto AuthGetCookieResult; + } + + if (fgets(line, DEFAULT_STRING_LIMIT, data) == NULL) + { + #ifdef WARNING + *logofs << "Auth: WARNING! Failed to read data from the X " + << "auth command.\n" << logofs_flush; + #endif + + #ifdef TEST + cerr << "Warning" << ": Failed to read data from the X " + << "auth command.\n"; + #endif + + #ifdef PANIC + *logofs << "Auth: WARNING! Generating a fake cookie for " + << "X authentication.\n" << logofs_flush; + #endif + + #ifdef TEST + cerr << "Warning" << ": Generating a fake cookie for " + << "X authentication.\n"; + #endif + + generateCookie(realCookie_); + } + else + { + #ifdef TEST + *logofs << "Auth: Checking cookie in string '" << line + << "'.\n" << logofs_flush; + #endif + + // + // Skip the hostname in the authority entry + // just in case it includes some white spaces. + // + + char *cookie = NULL; + + cookie = index(line, ':'); + + if (cookie == NULL) + { + cookie = line; + } + + if (sscanf(cookie, "%*s %*s %511s", realCookie_) != 1) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Failed to identify the cookie " + << "in string '" << line << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to identify the cookie " + << "in string '" << line << "'.\n"; + + goto AuthGetCookieResult; + } + + #ifdef TEST + *logofs << "Auth: Got cookie '" << realCookie_ + << "' from file '" << file_ << "'.\n" + << logofs_flush; + #endif + } + + result = 1; + +AuthGetCookieResult: + + if (data != NULL) + { + Pclose(data); + } + + return result; +} + +int Auth::validateCookie() +{ + unsigned int length = strlen(realCookie_); + + if (length > DEFAULT_STRING_LIMIT / 2 - 1 || + strlen(fakeCookie_) != length) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Size mismatch between cookies '" + << realCookie_ << "' and '" << fakeCookie_ << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Size mismatch between cookies '" + << realCookie_ << "' and '" << fakeCookie_ << "'.\n"; + + goto AuthValidateCookieError; + } + + // + // The length of the resulting data will be + // half the size of the Hex cookie. + // + + length = length / 2; + + fakeData_ = new char[length]; + realData_ = new char[length]; + + if (fakeData_ == NULL || realData_ == NULL) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Cannot allocate memory for the binary X " + << "authorization data.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot allocate memory for the binary X " + << "authorization data.\n"; + + goto AuthValidateCookieError; + } + + // + // Translate the real cookie from Hex data + // to its binary representation. + // + + unsigned int value; + + for (unsigned int i = 0; i < length; i++) + { + if (sscanf(realCookie_ + 2 * i, "%2x", &value) != 1) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Bad X authorization data in real " + << "cookie '" << realCookie_ << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Bad X authorization data in real cookie '" + << realCookie_ << "'.\n"; + + goto AuthValidateCookieError; + } + + realData_[i] = value; + + if (sscanf(fakeCookie_ + 2 * i, "%2x", &value) != 1) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Bad X authorization data in fake " + << "cookie '" << fakeCookie_ << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Bad X authorization data in fake cookie '" + << fakeCookie_ << "'.\n"; + + goto AuthValidateCookieError; + } + + fakeData_[i] = value; + } + + dataSize_ = length; + + #ifdef TEST + *logofs << "Auth: Validated real cookie '" + << realCookie_ << "' and fake cookie '" << fakeCookie_ + << "' with data with size " << dataSize_ << ".\n" + << logofs_flush; + + *logofs << "Auth: Ready to accept incoming connections.\n" + << logofs_flush; + #endif + + return 1; + +AuthValidateCookieError: + + delete [] fakeData_; + delete [] realData_; + + fakeData_ = NULL; + realData_ = NULL; + + dataSize_ = 0; + + return -1; +} + +int Auth::checkCookie(unsigned char *buffer) +{ + if (isValid() != 1) + { + #ifdef PANIC + *logofs << "Auth: PANIC! Attempt to check the X cookie with " + << "invalid authorization data.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Attempt to check the X cookie with " + << "invalid authorization data.\n"; + + return -1; + } + + const char *protoName = "MIT-MAGIC-COOKIE-1"; + int protoSize = strlen(protoName); + + int matchedProtoSize; + int matchedDataSize; + + if (buffer[0] == 0x42) + { + // + // Byte order is MSB first. + // + + matchedProtoSize = 256 * buffer[6] + buffer[7]; + matchedDataSize = 256 * buffer[8] + buffer[9]; + } + else if (buffer[0] == 0x6c) + { + // + // Byte order is LSB first. + // + + matchedProtoSize = buffer[6] + 256 * buffer[7]; + matchedDataSize = buffer[8] + 256 * buffer[9]; + } + else + { + #ifdef WARNING + *logofs << "Auth: WARNING! Bad X connection data in the buffer.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Bad X connection data in the buffer.\n"; + + return -1; + } + + // + // Check if both the authentication protocol + // and the fake cookie match our data. + // + + int protoOffset = 12; + + #ifdef TEST + *logofs << "Auth: Received a protocol size of " + << matchedProtoSize << " bytes.\n" + << logofs_flush; + #endif + + if (matchedProtoSize != protoSize || + memcmp(buffer + protoOffset, protoName, protoSize) != 0) + { + #ifdef WARNING + *logofs << "Auth: WARNING! Protocol mismatch or no X " + << "authentication data.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Protocol mismatch or no X " + << "authentication data.\n"; + + return -1; + } + + int dataOffset = protoOffset + ((matchedProtoSize + 3) & ~3); + + #ifdef TEST + *logofs << "Auth: Received a data size of " + << matchedDataSize << " bytes.\n" + << logofs_flush; + #endif + + if (matchedDataSize != dataSize_ || + memcmp(buffer + dataOffset, fakeData_, dataSize_) != 0) + { + #ifdef WARNING + *logofs << "Auth: WARNING! Cookie mismatch in the X " + << "authentication data.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Cookie mismatch in the X " + << "authentication data.\n"; + + return -1; + } + + // + // Everything is OK. Replace the fake data. + // + + #ifdef TEST + *logofs << "Auth: Replacing fake X authentication data " + << "with the real data.\n" << logofs_flush; + #endif + + memcpy(buffer + dataOffset, realData_, dataSize_); + + return 1; +} + +void Auth::generateCookie(char *cookie) +{ + // + // Code is from the SSH implementation, except that + // we use a much weaker random number generator. + // This is not critical, anyway, as this is just a + // fake cookie. The X server doesn't have a cookie + // for the display, so it will ignore the value we + // feed to it. + // + + T_timestamp timer = getTimestamp(); + + srand((unsigned int) timer.tv_usec); + + unsigned int data = rand(); + + for (int i = 0; i < 16; i++) + { + if (i % 4 == 0) + { + data = rand(); + } + + snprintf(cookie + 2 * i, 3, "%02x", data & 0xff); + + data >>= 8; + } + + generatedCookie_ = 1; + + #ifdef TEST + *logofs << "Auth: Generated X cookie string '" + << cookie << "'.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/Auth.h b/nxcomp/src/Auth.h new file mode 100644 index 000000000..d51d9a26f --- /dev/null +++ b/nxcomp/src/Auth.h @@ -0,0 +1,127 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Auth_H +#define Auth_H + +#include "Timestamp.h" + +// +// Handle the forwarding of authorization credentials +// to the X server by replacing the fake cookie with +// the real cookie as it is read from the auth file. +// At the moment only the MIT-MAGIC-COOKIE-1 cookies +// are recognized. The implementation is based on the +// corresponding code found in the SSH client. +// + +class Auth +{ + public: + + // + // Must be created by passing the fake cookie that + // will be forwarded by the remote end and with the + // real X display that is going to be used for the + // session. + // + + Auth(char *display, char *cookie); + + ~Auth(); + + int isValid() + { + return (isTimestamp(last_) == 1 && fakeCookie_ != NULL && + *fakeCookie_ != '\0' && realCookie_ != NULL && + *realCookie_ != '\0' && fakeData_ != NULL && + realData_ != NULL && dataSize_ != 0); + } + + int isFake() const + { + return generatedCookie_; + } + + // + // Method called in the channel class to find if the + // provided cookie matches the fake one. If the data + // matches, the fake cookie is replaced with the real + // one. + // + + int checkCookie(unsigned char *buffer); + + protected: + + // + // Update the real cookie for the display. If called + // a further time, check if the auth file is changed + // and get the new cookie. + // + + int updateCookie(); + + // + // Find out which authorization file is to be used + // and query the cookie for the current display. + // + + int getCookie(); + + // + // Extract the binary data from the cookies so that + // data can be directly compared at the time it is + // taken from the X request. + // + + int validateCookie(); + + // + // Generate a fake random cookie and copy it to the + // provided string. + // + + void generateCookie(char *cookie); + + private: + + char *display_; + char *file_; + + T_timestamp last_; + + char *fakeCookie_; + char *realCookie_; + + char *fakeData_; + char *realData_; + + int dataSize_; + + int generatedCookie_; +}; + +#endif /* Auth_H */ diff --git a/nxcomp/src/Bitmap.cpp b/nxcomp/src/Bitmap.cpp new file mode 100644 index 000000000..c89df53e3 --- /dev/null +++ b/nxcomp/src/Bitmap.cpp @@ -0,0 +1,118 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Bitmap.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +int UnpackBitmap(T_geometry *geometry, unsigned char method, unsigned char *src_data, + int src_size, int dst_bpp, int dst_width, int dst_height, + unsigned char *dst_data, int dst_size) +{ + if (dst_bpp != 32) + { + #ifdef TEST + *logofs << "UnpackBitmap: Nothing to do with " + << "image of " << dst_bpp << " bits per plane " + << "and size " << src_size << ".\n" + << logofs_flush; + #endif + + if (src_size != dst_size) + { + #ifdef PANIC + *logofs << "UnpackBitmap: PANIC! Size mismatch with " + << src_size << " bytes in the source and " + << dst_size << " in the destination.\n" + << logofs_flush; + #endif + + return -1; + } + + memcpy(dst_data, src_data, src_size); + + return 1; + } + else if (src_size != dst_width * dst_height * 3 || + dst_size != dst_width * dst_height * 4) + { + #ifdef PANIC + *logofs << "UnpackBitmap: PANIC! Size mismatch with " + << src_size << " bytes in the source and " + << dst_size << " in the destination.\n" + << logofs_flush; + #endif + + return -1; + } + + /* + * Insert the 4th byte in the bitmap. + */ + + unsigned char *next_src = src_data; + unsigned char *next_dst = dst_data; + + if (geometry -> image_byte_order == LSBFirst) + { + while (next_src < src_data + src_size) + { + *next_dst++ = *next_src++; + *next_dst++ = *next_src++; + *next_dst++ = *next_src++; + + next_dst++; + } + } + else + { + while (next_src < src_data + src_size) + { + next_dst++; + + *next_dst++ = *next_src++; + *next_dst++ = *next_src++; + *next_dst++ = *next_src++; + } + } + + #ifdef TEST + *logofs << "UnpackBitmap: Unpacked " << src_size + << " bytes to a buffer of " << dst_size + << " with " << dst_bpp << " bits per plane.\n" + << logofs_flush; + #endif + + return 1; +} diff --git a/nxcomp/src/Bitmap.h b/nxcomp/src/Bitmap.h new file mode 100644 index 000000000..8143e3125 --- /dev/null +++ b/nxcomp/src/Bitmap.h @@ -0,0 +1,36 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Bitmap_H +#define Bitmap_H + +#include "Unpack.h" + +int UnpackBitmap(T_geometry *geometry, unsigned char method, + unsigned char *src_data, int src_size, int dst_bpp, + int dst_width, int dst_height, unsigned char *dst_data, + int dst_size); + +#endif /* Bitmap_H */ diff --git a/nxcomp/src/BlockCache.cpp b/nxcomp/src/BlockCache.cpp new file mode 100644 index 000000000..161145e3d --- /dev/null +++ b/nxcomp/src/BlockCache.cpp @@ -0,0 +1,81 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "BlockCache.h" + + +int BlockCache::compare(unsigned int size, const unsigned char *data, + int overwrite) +{ + int match = 0; + if (size == size_) + { + match = 1; + for (unsigned int i = 0; i < size_; i++) + if (data[i] != buffer_[i]) + { + match = 0; + break; + } + } + if (!match && overwrite) + set(size, data); + return match; +} + + +void BlockCache::set(unsigned int size, const unsigned char *data) +{ + if (size_ < size) + { + delete[]buffer_; + buffer_ = new unsigned char[size]; + } + size_ = size; + memcpy(buffer_, data, size); + checksum_ = checksum(size, data); +} + + +unsigned int BlockCache::checksum(unsigned int size, const unsigned char *data) +{ + unsigned int sum = 0; + unsigned int shift = 0; + const unsigned char *next = data; + for (unsigned int i = 0; i < size; i++) + { + unsigned int value = (unsigned int) *next++; + sum += (value << shift); + shift++; + if (shift == 8) + shift = 0; + } + return sum; +} diff --git a/nxcomp/src/BlockCache.h b/nxcomp/src/BlockCache.h new file mode 100644 index 000000000..48e586966 --- /dev/null +++ b/nxcomp/src/BlockCache.h @@ -0,0 +1,67 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef BlockCache_H +#define BlockCache_H + + +// Cache to hold an arbitrary-length block of bytes + +class BlockCache +{ + public: + BlockCache():buffer_(0), size_(0), checksum_(0) + { + } + ~BlockCache() + { + delete[]buffer_; + } + int compare(unsigned int size, const unsigned char *data, + int overwrite = 1); + void set(unsigned int size, const unsigned char *data); + + unsigned int getLength() const + { + return size_; + } + unsigned int getChecksum() const + { + return checksum_; + } + const unsigned char *getData() const + { + return buffer_; + } + + static unsigned int checksum(unsigned int size, const unsigned char *data); + +private: + unsigned char *buffer_; + unsigned int size_; + unsigned int checksum_; +}; + +#endif /* BlockCache_H */ diff --git a/nxcomp/src/BlockCacheSet.cpp b/nxcomp/src/BlockCacheSet.cpp new file mode 100644 index 000000000..1dd6361dc --- /dev/null +++ b/nxcomp/src/BlockCacheSet.cpp @@ -0,0 +1,147 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "BlockCacheSet.h" + + +BlockCacheSet::BlockCacheSet(unsigned int numCaches): + caches_(new BlockCache *[numCaches]), size_(numCaches), + length_(0) +{ + for (unsigned int i = 0; i < numCaches; i++) + caches_[i] = new BlockCache(); +} + + +BlockCacheSet::~BlockCacheSet() +{ + // + // TODO: There is still a strange segfault occurring + // at random time under Cygwin, when proxy is being + // shutdown. Problem appeared just after upgrading + // to the latest version of the Cygwin DLL. A stack + // trace, obtained at the last minute, reveals that + // failure happens in this destructor. + // + + #ifndef __CYGWIN32__ + + for (unsigned int i = 0; i < size_; i++) + delete caches_[i]; + delete[]caches_; + + #endif /* ifdef __CYGWIN32__ */ +} + + +int +BlockCacheSet::lookup(unsigned int dataLength, const unsigned char *data, + unsigned int &index) +{ + unsigned int checksum = BlockCache::checksum(dataLength, data); + for (unsigned int i = 0; i < length_; i++) + if ((caches_[i]->getChecksum() == checksum) && + (caches_[i]->compare(dataLength, data, 0))) + { + // match + index = i; + if (i) + { + BlockCache *save = caches_[i]; + unsigned int target = (i >> 1); + do + { + caches_[i] = caches_[i - 1]; + i--; + } + while (i > target); + caches_[target] = save; + } + return 1; + } + // no match + unsigned int insertionPoint = (length_ >> 1); + unsigned int start; + if (length_ >= size_) + start = size_ - 1; + else + { + start = length_; + length_++; + } + BlockCache *save = caches_[start]; + for (unsigned int k = start; k > insertionPoint; k--) + caches_[k] = caches_[k - 1]; + caches_[insertionPoint] = save; + save->set(dataLength, data); + return 0; +} + + +void +BlockCacheSet::get(unsigned index, unsigned int &size, + const unsigned char *&data) +{ + size = caches_[index]->getLength(); + data = caches_[index]->getData(); + if (index) + { + BlockCache *save = caches_[index]; + unsigned int target = (index >> 1); + do + { + caches_[index] = caches_[index - 1]; + index--; + } + while (index > target); + caches_[target] = save; + } +} + + + +void +BlockCacheSet::set(unsigned int dataLength, const unsigned char *data) +{ + unsigned int insertionPoint = (length_ >> 1); + unsigned int start; + if (length_ >= size_) + start = size_ - 1; + else + { + start = length_; + length_++; + } + BlockCache *save = caches_[start]; + for (unsigned int k = start; k > insertionPoint; k--) + caches_[k] = caches_[k - 1]; + caches_[insertionPoint] = save; + save->set(dataLength, data); +} diff --git a/nxcomp/src/BlockCacheSet.h b/nxcomp/src/BlockCacheSet.h new file mode 100644 index 000000000..97273b0e0 --- /dev/null +++ b/nxcomp/src/BlockCacheSet.h @@ -0,0 +1,49 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef BlockCacheSet_H +#define BlockCacheSet_H + +#include "BlockCache.h" + + +class BlockCacheSet +{ + public: + BlockCacheSet(unsigned int numCaches); + ~BlockCacheSet(); + + int lookup(unsigned int size, const unsigned char *data, + unsigned int &index); + void get(unsigned int index, unsigned int &size, const unsigned char *&data); + void set(unsigned int size, const unsigned char *data); + + private: + BlockCache ** caches_; + unsigned int size_; + unsigned int length_; +}; + +#endif /* BlockCacheSet_H */ diff --git a/nxcomp/src/ChangeGC.cpp b/nxcomp/src/ChangeGC.cpp new file mode 100644 index 000000000..e92178f27 --- /dev/null +++ b/nxcomp/src/ChangeGC.cpp @@ -0,0 +1,184 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ChangeGC.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int ChangeGCStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ChangeGCMessage *changeGC = (ChangeGCMessage *) message; + + // + // Here is the fingerprint. + // + + changeGC -> gcontext = GetULONG(buffer + 4, bigEndian); + changeGC -> value_mask = GetULONG(buffer + 8, bigEndian); + + // + // Clear the unused bytes carried in the + // payload to increase the effectiveness + // of the caching algorithm. + // + + if ((int) size > dataOffset) + { + #ifdef DEBUG + *logofs << name() << ": Removing unused bytes from the " + << "data payload.\n" << logofs_flush; + #endif + + changeGC -> value_mask &= (1 << 23) - 1; + + unsigned int mask = 0x1; + unsigned char *source = (unsigned char *) buffer + CHANGEGC_DATA_OFFSET; + unsigned long value = 0; + + for (unsigned int i = 0; i < 23; i++) + { + if (changeGC -> value_mask & mask) + { + value = GetULONG(source, bigEndian); + + value &= (0xffffffff >> (32 - CREATEGC_FIELD_WIDTH[i])); + + PutULONG(value, source, bigEndian); + + source += 4; + } + + mask <<= 1; + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ChangeGCStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ChangeGCMessage *changeGC = (ChangeGCMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(changeGC -> gcontext, buffer + 4, bigEndian); + PutULONG(changeGC -> value_mask, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void ChangeGCStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + ChangeGCMessage *changeGC = (ChangeGCMessage *) message; + + *logofs << name() << ": Identity gcontext " << changeGC -> gcontext + << ", mask " << changeGC -> value_mask << ", size " + << changeGC -> size_ << ".\n" << logofs_flush; + #endif +} + +void ChangeGCStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +/* + md5_append(md5_state_, buffer + 4, 8); +*/ + md5_append(md5_state_, buffer + 8, 4); +} + +void ChangeGCStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + ChangeGCMessage *changeGC = (ChangeGCMessage *) message; + ChangeGCMessage *cachedChangeGC = (ChangeGCMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << changeGC -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(changeGC -> gcontext, clientCache -> gcCache); + + cachedChangeGC -> gcontext = changeGC -> gcontext; +} + +void ChangeGCStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + ChangeGCMessage *changeGC = (ChangeGCMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + changeGC -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << changeGC -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/ChangeGC.h b/nxcomp/src/ChangeGC.h new file mode 100644 index 000000000..9cac90e66 --- /dev/null +++ b/nxcomp/src/ChangeGC.h @@ -0,0 +1,185 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ChangeGC_H +#define ChangeGC_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define CHANGEGC_ENABLE_CACHE 1 +#define CHANGEGC_ENABLE_DATA 0 +#define CHANGEGC_ENABLE_SPLIT 0 +#define CHANGEGC_ENABLE_COMPRESS 0 + +#define CHANGEGC_DATA_LIMIT 144 +#define CHANGEGC_DATA_OFFSET 12 + +#define CHANGEGC_CACHE_SLOTS 3000 +#define CHANGEGC_CACHE_THRESHOLD 3 +#define CHANGEGC_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class ChangeGCMessage : public Message +{ + friend class ChangeGCStore; + + public: + + ChangeGCMessage() + { + } + + ~ChangeGCMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int gcontext; + unsigned int value_mask; +}; + +class ChangeGCStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + ChangeGCStore() : MessageStore() + { + enableCache = CHANGEGC_ENABLE_CACHE; + enableData = CHANGEGC_ENABLE_DATA; + enableSplit = CHANGEGC_ENABLE_SPLIT; + enableCompress = CHANGEGC_ENABLE_COMPRESS; + + dataLimit = CHANGEGC_DATA_LIMIT; + dataOffset = CHANGEGC_DATA_OFFSET; + + cacheSlots = CHANGEGC_CACHE_SLOTS; + cacheThreshold = CHANGEGC_CACHE_THRESHOLD; + cacheLowerThreshold = CHANGEGC_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~ChangeGCStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "ChangeGC"; + } + + virtual unsigned char opcode() const + { + return X_ChangeGC; + } + + virtual unsigned int storage() const + { + return sizeof(ChangeGCMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new ChangeGCMessage(); + } + + virtual Message *create(const Message &message) const + { + return new ChangeGCMessage((const ChangeGCMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (ChangeGCMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; +}; + +#endif /* ChangeGC_H */ diff --git a/nxcomp/src/ChangeProperty.cpp b/nxcomp/src/ChangeProperty.cpp new file mode 100644 index 000000000..74814c2ea --- /dev/null +++ b/nxcomp/src/ChangeProperty.cpp @@ -0,0 +1,191 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ChangeProperty.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int ChangePropertyStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; + + changeProperty -> mode = *(buffer + 1); + changeProperty -> format = *(buffer + 16); + + changeProperty -> window = GetULONG(buffer + 4, bigEndian); + changeProperty -> property = GetULONG(buffer + 8, bigEndian); + changeProperty -> type = GetULONG(buffer + 12, bigEndian); + changeProperty -> length = GetULONG(buffer + 20, bigEndian); + + // + // Cleanup the padding bytes. + // + + unsigned int uiFormat; + unsigned int uiLengthInBytes; + + if ((int) size > CHANGEPROPERTY_DATA_OFFSET) + { + uiFormat = *(buffer + 16); + + uiLengthInBytes = changeProperty -> length; + + #ifdef DEBUG + *logofs << name() << ": length " << uiLengthInBytes + << ", format " << uiFormat << ", size " + << size << ".\n" << logofs_flush; + #endif + + if (uiFormat == 16) + { + uiLengthInBytes <<= 1; + } + else if (uiFormat == 32) + { + uiLengthInBytes <<= 2; + } + + unsigned char *end = ((unsigned char *) buffer) + size; + unsigned char *pad = ((unsigned char *) buffer) + CHANGEPROPERTY_DATA_OFFSET + uiLengthInBytes; + + CleanData((unsigned char *) pad, end - pad); + } + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ChangePropertyStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; + + *(buffer + 1) = changeProperty -> mode; + *(buffer + 16) = changeProperty -> format; + + PutULONG(changeProperty -> window, buffer + 4, bigEndian); + PutULONG(changeProperty -> property, buffer + 8, bigEndian); + PutULONG(changeProperty -> type, buffer + 12, bigEndian); + PutULONG(changeProperty -> length, buffer + 20, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void ChangePropertyStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; + + *logofs << name() << ": Identity mode " << (unsigned int) changeProperty -> mode << ", format " + << (unsigned int) changeProperty -> format << ", window " << changeProperty -> window + << ", property " << changeProperty -> property << ", type " << changeProperty -> type + << ", length " << changeProperty -> length << ", size " << changeProperty -> size_ + << ".\n" << logofs_flush; + + #endif +} + +void ChangePropertyStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 16, 1); + + md5_append(md5_state_, buffer + 8, 4); + md5_append(md5_state_, buffer + 12, 4); + md5_append(md5_state_, buffer + 20, 4); +} + +void ChangePropertyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; + ChangePropertyMessage *cachedChangeProperty = (ChangePropertyMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << changeProperty -> window + << " as window field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(changeProperty -> window, clientCache -> windowCache); + + cachedChangeProperty -> window = changeProperty -> window; +} + +void ChangePropertyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> windowCache); + + changeProperty -> window = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << changeProperty -> window + << " as window field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/ChangeProperty.h b/nxcomp/src/ChangeProperty.h new file mode 100644 index 000000000..c06ce10fc --- /dev/null +++ b/nxcomp/src/ChangeProperty.h @@ -0,0 +1,189 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ChangeProperty_H +#define ChangeProperty_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define CHANGEPROPERTY_ENABLE_CACHE 1 +#define CHANGEPROPERTY_ENABLE_DATA 0 +#define CHANGEPROPERTY_ENABLE_SPLIT 0 +#define CHANGEPROPERTY_ENABLE_COMPRESS 0 + +#define CHANGEPROPERTY_DATA_LIMIT 28688 +#define CHANGEPROPERTY_DATA_OFFSET 24 + +#define CHANGEPROPERTY_CACHE_SLOTS 2000 +#define CHANGEPROPERTY_CACHE_THRESHOLD 2 +#define CHANGEPROPERTY_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class ChangePropertyMessage : public Message +{ + friend class ChangePropertyStore; + + public: + + ChangePropertyMessage() + { + } + + ~ChangePropertyMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char mode; + unsigned char format; + unsigned int window; + unsigned int property; + unsigned int type; + unsigned int length; +}; + +class ChangePropertyStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + ChangePropertyStore() : MessageStore() + { + enableCache = CHANGEPROPERTY_ENABLE_CACHE; + enableData = CHANGEPROPERTY_ENABLE_DATA; + enableSplit = CHANGEPROPERTY_ENABLE_SPLIT; + enableCompress = CHANGEPROPERTY_ENABLE_COMPRESS; + + dataLimit = CHANGEPROPERTY_DATA_LIMIT; + dataOffset = CHANGEPROPERTY_DATA_OFFSET; + + cacheSlots = CHANGEPROPERTY_CACHE_SLOTS; + cacheThreshold = CHANGEPROPERTY_CACHE_THRESHOLD; + cacheLowerThreshold = CHANGEPROPERTY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~ChangePropertyStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "ChangeProperty"; + } + + virtual unsigned char opcode() const + { + return X_ChangeProperty; + } + + virtual unsigned int storage() const + { + return sizeof(ChangePropertyMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new ChangePropertyMessage(); + } + + virtual Message *create(const Message &message) const + { + return new ChangePropertyMessage((const ChangePropertyMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (ChangePropertyMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* ChangeProperty_H */ diff --git a/nxcomp/src/Channel.cpp b/nxcomp/src/Channel.cpp new file mode 100644 index 000000000..24a422e37 --- /dev/null +++ b/nxcomp/src/Channel.cpp @@ -0,0 +1,2039 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Channel.h" + +#include "List.h" +#include "Proxy.h" +#include "Statistics.h" + +#include "StaticCompressor.h" + +#include "NXalert.h" + +extern Proxy *proxy; + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Log the operations related to splits. +// + +#undef SPLIT + +#undef COUNT + +#define COUNT_MAJOR_OPCODE 154 + +#undef MONITOR + +#define MONITOR_MAJOR_OPCODE 154 +#define MONITOR_MINOR_OPCODE 23 + +#undef CLEAR + +#define CLEAR_MAJOR_OPCODE 154 +#define CLEAR_MINOR_OPCODE 23 + +// +// Define this to know how many messages +// are allocated and deallocated. +// + +#undef REFERENCES + +// +// Set to the descriptor of the first X +// channel successfully connected. +// + +int Channel::firstClient_ = -1; + +// +// Port used for font server connections. +// + +int Channel::fontPort_ = -1; + +// +// This is used for reference count. +// + +#ifdef REFERENCES + +int Channel::references_ = 0; + +#endif + +Channel::Channel(Transport *transport, StaticCompressor *compressor) + + : transport_(transport), compressor_(compressor) +{ + fd_ = transport_ -> fd(); + + finish_ = 0; + closing_ = 0; + drop_ = 0; + congestion_ = 0; + priority_ = 0; + + alert_ = 0; + + firstRequest_ = 1; + firstReply_ = 1; + + enableCache_ = 1; + enableSplit_ = 1; + enableSave_ = 1; + enableLoad_ = 1; + + // + // Must be set by proxy. + // + + opcodeStore_ = NULL; + + clientStore_ = NULL; + serverStore_ = NULL; + + clientCache_ = NULL; + serverCache_ = NULL; + + #ifdef REFERENCES + *logofs << "Channel: Created new Channel at " + << this << " out of " << ++references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +Channel::~Channel() +{ + if (firstClient_ == fd_) + { + firstClient_ = -1; + } + + #ifdef REFERENCES + *logofs << "Channel: Deleted Channel at " + << this << " out of " << --references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +int Channel::handleEncode(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, + MessageStore *store, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + #ifdef MONITOR + + static float totalMessages = 0; + static float totalBits = 0; + + int bits; + int diff; + + bits = encodeBuffer.getBits(); + + #endif + + // + // Check if message can be differentially + // encoded using a similar message in the + // message store. + // + + #ifdef COUNT + + if (*(buffer) == COUNT_MAJOR_OPCODE) + { + if (*(buffer) < 128) + { + *logofs << "handleEncode: Handling OPCODE#" << (unsigned int) *(buffer) + << ".\n" << logofs_flush; + } + else + { + *logofs << "handleEncode: Handling OPCODE#" << (unsigned int) *(buffer) + << " MINOR#" << (unsigned int) *(buffer + 1) << ".\n" + << logofs_flush; + } + } + + #endif + + #ifdef CLEAR + + if (*(buffer) == CLEAR_MAJOR_OPCODE && + (CLEAR_MINOR_OPCODE == -1 || *(buffer + 1) == CLEAR_MINOR_OPCODE)) + { + *((unsigned char *) buffer) = X_NoOperation; + + *((unsigned char *) buffer + 1) = '\0'; + + CleanData((unsigned char *) buffer + 4, size - 4); + } + + #endif + + if (handleEncodeCached(encodeBuffer, channelCache, + store, buffer, size) == 1) + { + #ifdef MONITOR + + diff = encodeBuffer.getBits() - bits; + + if (*(buffer) == MONITOR_MAJOR_OPCODE && + (MONITOR_MINOR_OPCODE == -1 || *(buffer + 1) == MONITOR_MINOR_OPCODE)) + { + totalMessages++; + + totalBits += diff; + + *logofs << "handleEncode: Handled cached OPCODE#" << (unsigned int) *(buffer) + << " MINOR#" << (unsigned int) *(buffer + 1) << ". " << size + << " bytes in, " << diff << " bits (" << ((float) diff) / 8 + << " bytes) out. Average " << totalBits / totalMessages + << "/1.\n" << logofs_flush; + } + + #endif + + // + // Let the channel update the split store + // and notify the agent in the case of a + // cache hit. + // + + if (store -> enableSplit) + { + handleSplit(encodeBuffer, store, store -> lastAction, + store -> lastHit, opcode, buffer, size); + } + + return 1; + } + + // + // A similar message could not be found in + // cache or message must be discarded. Must + // transmit the message using the field by + // field differential encoding. + // + + handleEncodeIdentity(encodeBuffer, channelCache, + store, buffer, size, bigEndian_); + + // + // Check if message has a distinct data part. + // + + if (store -> enableData) + { + // + // If message split was requested by agent then send data + // out-of-band, dividing it in small chunks. Until message + // is completely transferred, keep in the split store a + // dummy version of the message, with data replaced with a + // pattern. + // + // While data is being transferred, agent should have put + // the resource (for example its client) asleep. It can + // happen, though, that a different client would reference + // the same message. We cannot issue a cache hit for images + // being split (such images are put in store in 'incomplete' + // state), so we need to handle this case. + // + + if (store -> enableSplit == 1) + { + // + // Let the channel decide what to do with the + // message. If the split can't take place be- + // cause the split store is full, the channel + // will tell the remote side that the data is + // going to follow. + // + + if (handleSplit(encodeBuffer, store, store -> lastAction, + (store -> lastAction == IS_ADDED ? store -> lastAdded : 0), + opcode, buffer, size) == 1) + { + #ifdef MONITOR + + diff = encodeBuffer.getBits() - bits; + + if (*(buffer) == MONITOR_MAJOR_OPCODE && + (MONITOR_MINOR_OPCODE == -1 || *(buffer + 1) == MONITOR_MINOR_OPCODE)) + { + totalMessages++; + + totalBits += diff; + + *logofs << "handleEncode: Handled split OPCODE#" << (unsigned int) *(buffer) + << " MINOR#" << (unsigned int) *(buffer + 1) << ". " << size + << " bytes in, " << diff << " bits (" << ((float) diff) / 8 + << " bytes) out. Average " << totalBits / totalMessages + << "/1.\n" << logofs_flush; + } + + #endif + + return 0; + } + } + + // + // The split did not take place and we are going + // to transfer the data part. Check if the static + // compression of the data section is enabled. + // This is the case of all messages not having a + // special differential encoding or messages that + // we want to store in cache in compressed form. + // + + unsigned int offset = store -> identitySize(buffer, size); + + if (store -> enableCompress) + { + unsigned char *data = NULL; + unsigned int dataSize = 0; + + int compressed = handleCompress(encodeBuffer, opcode, offset, + buffer, size, data, dataSize); + if (compressed < 0) + { + return -1; + } + else if (compressed > 0) + { + // + // Update the size of the message according + // to the result of the data compression. + // + + handleUpdate(store, size - offset, dataSize); + } + } + else + { + handleCopy(encodeBuffer, opcode, offset, buffer, size); + } + } + + #ifdef MONITOR + + diff = encodeBuffer.getBits() - bits; + + if (*(buffer) == MONITOR_MAJOR_OPCODE && + (MONITOR_MINOR_OPCODE == -1 || *(buffer + 1) == MONITOR_MINOR_OPCODE)) + { + totalMessages++; + + totalBits += diff; + + *logofs << "handleEncode: Handled OPCODE#" << (unsigned int) *(buffer) + << " MINOR#" << (unsigned int) *(buffer + 1) << ". " << size + << " bytes in, " << diff << " bits (" << ((float) diff) / 8 + << " bytes) out. Average " << totalBits / totalMessages + << "/1.\n" << logofs_flush; + } + + #endif + + return 0; +} + +int Channel::handleDecode(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, + MessageStore *store, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + // + // Check first if the message is in the + // message store. + // + + unsigned int split = 0; + + if (handleDecodeCached(decodeBuffer, channelCache, + store, buffer, size) == 1) + { + // + // Let the channel update the split store + // in the case of a message being cached. + // + + if (store -> enableSplit == 1) + { + // Since ProtoStep7 (#issue 108) + #ifdef DEBUG + *logofs << "handleDecode: " << store -> name() + << ": Checking if the message was split.\n" + << logofs_flush; + #endif + + decodeBuffer.decodeBoolValue(split); + + if (split == 1) + { + handleSplit(decodeBuffer, store, store -> lastAction, + store -> lastHit, opcode, buffer, size); + + handleCleanAndNullRequest(opcode, buffer, size); + } + } + + return 1; + } + + // + // Decode the full identity. + // + + handleDecodeIdentity(decodeBuffer, channelCache, store, buffer, + size, bigEndian_, &writeBuffer_); + + // + // Check if the message has a distinct + // data part. + // + + if (store -> enableData) + { + // + // Check if message has been split. + // + + if (store -> enableSplit) + { + #ifdef DEBUG + *logofs << "handleDecode: " << store -> name() + << ": Checking if the message was split.\n" + << logofs_flush; + #endif + + decodeBuffer.decodeBoolValue(split); + + if (split == 1) + { + // + // If the message was added to the store, + // create the entry without the data part. + // + + handleSaveSplit(store, buffer, size); + + handleSplit(decodeBuffer, store, store -> lastAction, + (store -> lastAction == IS_ADDED ? store -> lastAdded : 0), + opcode, buffer, size); + + handleCleanAndNullRequest(opcode, buffer, size); + + return 0; + } + } + + // + // Decode the data part. + // + + unsigned int offset = store -> identitySize(buffer, size); + + if (store -> enableCompress) + { + const unsigned char *data = NULL; + unsigned int dataSize = 0; + + int decompressed = handleDecompress(decodeBuffer, opcode, offset, + buffer, size, data, dataSize); + if (decompressed < 0) + { + return -1; + } + else if (decompressed > 0) + { + // + // The message has been transferred + // in compressed format. + // + + handleSave(store, buffer, size, data, dataSize); + + if (store -> enableSplit) + { + if (split == 1) + { + handleSplit(decodeBuffer, store, store -> lastAction, + (store -> lastAction == IS_ADDED ? store -> lastAdded : 0), + opcode, buffer, size); + + handleCleanAndNullRequest(opcode, buffer, size); + } + } + + return 0; + } + } + else + { + // + // Static compression of the data part + // was not enabled for this message. + // + + handleCopy(decodeBuffer, opcode, offset, buffer, size); + } + } + + // + // The message doesn't have a data part + // or the data was not compressed. + // + + handleSave(store, buffer, size); + + if (store -> enableSplit) + { + if (split == 1) + { + handleSplit(decodeBuffer, store, store -> lastAction, + (store -> lastAction == IS_ADDED ? store -> lastAdded : 0), + opcode, buffer, size); + + handleCleanAndNullRequest(opcode, buffer, size); + } + } + + return 0; +} + +int Channel::handleEncodeCached(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, + MessageStore *store, const unsigned char *buffer, + const unsigned int size) +{ + if (control -> LocalDeltaCompression == 0 || + enableCache_ == 0 || store -> enableCache == 0) + { + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeActionValue(is_discarded, + store -> lastActionCache); + + store -> lastAction = is_discarded; + + return 0; + } + + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() + << ": Going to handle a new message of this class.\n" + << logofs_flush; + #endif + + // + // Check if the estimated size of cache is greater + // than the requested limit. If it is the case make + // some room by deleting one or more messages. + // + + int position; + + while (mustCleanStore(store) == 1 && canCleanStore(store) == 1) + { + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() + << ": Trying to reduce size of message store.\n" + << logofs_flush; + #endif + + position = store -> clean(use_checksum); + + if (position == nothing) + { + #ifdef TEST + *logofs << "handleEncodeCached: " << store -> name() + << ": WARNING! No message found to be " + << "actually removed.\n" << logofs_flush; + #endif + + break; + } + + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() + << ": Message at position " << position + << " will be removed.\n" << logofs_flush; + #endif + + // + // Encode the position of message to + // be discarded. + // + + store -> lastRemoved = position; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeActionValue(is_removed, store -> lastRemoved, + store -> lastActionCache); + + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() << ": Going to " + << "clean up message at position " << position << ".\n" + << logofs_flush; + #endif + + store -> remove(position, use_checksum, discard_data); + + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() << ": There are " + << store -> getSize() << " messages in the store out of " + << store -> cacheSlots << " slots.\n" << logofs_flush; + + *logofs << "handleEncodeCached: " << store -> name() + << ": Size of store is " << store -> getLocalStorageSize() + << " bytes locally and " << store -> getRemoteStorageSize() + << " bytes remotely.\n" << logofs_flush; + + *logofs << "handleEncodeCached: " << store -> name() + << ": Size of total cache is " << store -> getLocalTotalStorageSize() + << " bytes locally and " << store -> getRemoteTotalStorageSize() + << " bytes remotely.\n" << logofs_flush; + #endif + } + + #ifdef DEBUG + + if (mustCleanStore(store) == 1 && canCleanStore(store) == 0) + { + *logofs << "handleEncodeCached: " << store -> name() + << ": Store would need a clean but operation will be delayed.\n" + << logofs_flush; + + *logofs << "handleEncodeCached: " << store -> name() << ": There are " + << store -> getSize() << " messages in the store out of " + << store -> cacheSlots << " slots.\n" << logofs_flush; + + *logofs << "handleEncodeCached: " << store -> name() + << ": Size of store is " << store -> getLocalStorageSize() + << " bytes locally and " << store -> getRemoteStorageSize() + << " bytes remotely.\n" << logofs_flush; + + *logofs << "handleEncodeCached: " << store -> name() + << ": Size of total cache is " << store -> getLocalTotalStorageSize() + << " bytes locally and " << store -> getRemoteTotalStorageSize() + << " bytes remotely.\n" << logofs_flush; + } + + #endif + + // + // If 'on the wire' size of message exceeds the + // allowed limit then avoid to store it in the + // cache. + // + + if (store -> validateMessage(buffer, size) == 0) + { + #ifdef TEST + *logofs << "handleEncodeCached: " << store -> name() + << ": Message with size " << size << " ignored.\n" + << logofs_flush; + #endif + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeActionValue(is_discarded, + store -> lastActionCache); + + store -> lastAction = is_discarded; + + return 0; + } + + // + // Fill the message object with the + // received data. + // + + Message *message = store -> getTemporary(); + + if (message == NULL) + { + #ifdef PANIC + *logofs << "handleEncodeCached: " << store -> name() + << ": PANIC! Can't allocate memory for " + << "a new message.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "a new message in context [D].\n"; + + HandleCleanup(); + } + + // + // As we are at encoding side, it is enough to store the + // checksum for the object while data can be erased. Both + // the identity and the data will never be sent through + // the wire again as long as they are stored in the cache + // at the decoding side. The split parameter is always + // set to 0 as the data will not be stored in any case. + // + + store -> parse(message, 0, buffer, size, use_checksum, + discard_data, bigEndian_); + + #ifdef DUMP + + store -> dump(message); + + #endif + + // + // Search the object in the message + // store. If found get the position. + // + + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() + << ": Searching object of size " << size + << " in the cache.\n" << logofs_flush; + #endif + + int added; + int locked; + + position = store -> findOrAdd(message, use_checksum, + discard_data, added, locked); + + if (position == nothing) + { + #ifdef WARNING + *logofs << "handleEncodeCached: " << store -> name() + << ": WARNING! Can't store object in the cache.\n" + << logofs_flush; + #endif + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeActionValue(is_discarded, + store -> lastActionCache); + + store -> lastAction = is_discarded; + + return 0; + } + else if (locked == 1) + { + // + // We can't issue a cache hit. Encoding identity + // differences while message it's being split + // would later result in agent to commit a wrong + // version of message. + // + + #ifdef WARNING + *logofs << "handleEncodeCached: " << store -> name() + << ": WARNING! Message of size " << store -> plainSize(position) + << " at position " << position << " is locked.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Message of size " << store -> plainSize(position) + << " at position " << position << " is locked.\n"; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeActionValue(is_discarded, + store -> lastActionCache); + + store -> lastAction = is_discarded; + + return 0; + } + else if (added == 1) + { + store -> resetTemporary(); + + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() << ": Message of size " + << store -> plainSize(position) << " has been stored at position " + << position << ".\n" << logofs_flush; + + *logofs << "handleEncodeCached: " << store -> name() << ": There are " + << store -> getSize() << " messages in the store out of " + << store -> cacheSlots << " slots.\n" << logofs_flush; + + *logofs << "handleEncodeCached: " << store -> name() + << ": Size of store is " << store -> getLocalStorageSize() + << " bytes locally and " << store -> getRemoteStorageSize() + << " bytes remotely.\n" << logofs_flush; + + *logofs << "handleEncodeCached: " << store -> name() + << ": Size of total cache is " << store -> getLocalTotalStorageSize() + << " bytes locally and " << store -> getRemoteTotalStorageSize() + << " bytes remotely.\n" << logofs_flush; + #endif + + // + // Inform the decoding side that message + // must be inserted in cache and encode + // the position where the insertion took + // place. + // + + store -> lastAction = IS_ADDED; + + store -> lastAdded = position; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeActionValue(IS_ADDED, store -> lastAdded, + store -> lastActionCache); + + return 0; + } + else + { + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() + << ": Cache hit. Found object at position " + << position << ".\n" << logofs_flush; + #endif + + // + // Must abort the connection if the + // the position is invalid. + // + + Message *cachedMessage = store -> get(position); + + // + // Increase the rating of the cached + // message. + // + + store -> touch(cachedMessage); + + #ifdef DEBUG + *logofs << "handleEncodeCached: " << store -> name() << ": Hits for " + << "object at position " << position << " are now " + << store -> getTouches(position) << ".\n" + << logofs_flush; + #endif + + // + // Send to the decoding side position + // where object can be found in cache. + // + + store -> lastAction = IS_HIT; + + store -> lastHit = position; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeActionValue(IS_HIT, store -> lastHit, + store -> lastActionCache); + + // + // Send the field by field differences in + // respect to the original message stored + // in cache. + // + + store -> updateIdentity(encodeBuffer, message, cachedMessage, channelCache); + + return 1; + } +} + +void Channel::handleUpdateAdded(MessageStore *store, unsigned int dataSize, + unsigned int compressedDataSize) +{ + #ifdef TEST + + if (store -> lastAction != IS_ADDED) + { + #ifdef PANIC + *logofs << "handleUpdateAdded: " << store -> name() + << ": PANIC! Function called for action '" + << store -> lastAction << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Update function called for " + << "store '" << store -> name() << "' with " + << "action '" << store -> lastAction + << "'.\n"; + + HandleCleanup(); + } + + #endif + + #ifdef DEBUG + *logofs << "handleUpdateAdded: " << store -> name() << ": Updating " + << "object at position " << store -> lastAdded << " of size " + << store -> plainSize(store -> lastAdded) << " (" << dataSize + << "/" << compressedDataSize << ").\n" << logofs_flush; + #endif + + store -> updateData(store -> lastAdded, dataSize, compressedDataSize); + + #ifdef DEBUG + *logofs << "handleUpdateAdded: " << store -> name() << ": There are " + << store -> getSize() << " messages in the store out of " + << store -> cacheSlots << " slots.\n" << logofs_flush; + + *logofs << "handleUpdateAdded: " << store -> name() + << ": Size of store is " << store -> getLocalStorageSize() + << " bytes locally and " << store -> getRemoteStorageSize() + << " bytes remotely.\n" << logofs_flush; + + *logofs << "handleUpdateAdded: " << store -> name() + << ": Size of total cache is " << store -> getLocalTotalStorageSize() + << " bytes locally and " << store -> getRemoteTotalStorageSize() + << " bytes remotely.\n" << logofs_flush; + #endif +} + +int Channel::handleDecodeCached(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, + MessageStore *store, unsigned char *&buffer, + unsigned int &size) +{ + // + // Create a new message object and + // fill it with received data. + // + + #ifdef DEBUG + *logofs << "handleDecodeCached: " << store -> name() + << ": Going to handle a new message of this class.\n" + << logofs_flush; + #endif + + // + // Decode bits telling how to handle + // this message. + // + + unsigned char action; + unsigned short int position; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeActionValue(action, position, + store -> lastActionCache); + + // + // Clean operations must always come + // before any operation on message. + // + + while (action == is_removed) + { + // Since ProtoStep7 (#issue 108) + store -> lastRemoved = position; + + #ifdef DEBUG + + if (store -> get(store -> lastRemoved)) + { + *logofs << "handleDecodeCached: " << store -> name() << ": Cleaning up " + << "object at position " << store -> lastRemoved + << " of size " << store -> plainSize(store -> lastRemoved) + << " (" << store -> plainSize(store -> lastRemoved) << "/" + << store -> compressedSize(store -> lastRemoved) << ").\n" + << logofs_flush; + } + + #endif + + // + // If the message can't be found we + // will abort the connection. + // + + store -> remove(store -> lastRemoved, discard_checksum, use_data); + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeActionValue(action, position, + store -> lastActionCache); + } + + // + // If it's a cache hit, the position + // where object can be found follows. + // + + if ((T_store_action) action == IS_HIT) + { + // Since ProtoStep7 (#issue 108) + store -> lastHit = position; + + // + // Get data from the cache at given position. + // + + #ifdef DEBUG + + if (store -> get(store -> lastHit)) + { + *logofs << "handleDecodeCached: " << store -> name() << ": Retrieving " + << "object at position " << store -> lastHit + << " of size " << store -> plainSize(store -> lastHit) + << " (" << store -> plainSize(store -> lastHit) << "/" + << store -> compressedSize(store -> lastHit) << ").\n" + << logofs_flush; + } + + #endif + + // + // Must abort the connection if the + // the position is invalid. + // + + Message *message = store -> get(store -> lastHit); + + // + // Make room for the outgoing message. + // + + size = store -> plainSize(store -> lastHit); + + buffer = writeBuffer_.addMessage(size); + + #ifdef DEBUG + *logofs << "handleDecodeCached: " << store -> name() + << ": Prepared an outgoing buffer of " + << size << " bytes.\n" << logofs_flush; + #endif + + // + // Decode the variant part. Pass client + // or server cache to the message store. + // + + store -> updateIdentity(decodeBuffer, message, channelCache); + + // + // Write each field in the outgoing buffer. + // + + store -> unparse(message, buffer, size, bigEndian_); + + #ifdef DUMP + + store -> dump(message); + + #endif + + store -> lastAction = IS_HIT; + + return 1; + } + else if ((T_store_action) action == IS_ADDED) + { + // Since ProtoStep7 (#issue 108) + store -> lastAdded = position; + + #ifdef DEBUG + *logofs << "handleDecodeCached: " << store -> name() + << ": Message will be later stored at position " + << store -> lastAdded << ".\n" << logofs_flush; + #endif + + store -> lastAction = IS_ADDED; + + return 0; + } + else + { + #ifdef DEBUG + *logofs << "handleDecodeCached: " << store -> name() + << ": Message will be later discarded.\n" + << logofs_flush; + #endif + + store -> lastAction = is_discarded; + + return 0; + } +} + +void Channel::handleSaveAdded(MessageStore *store, int split, unsigned char *buffer, + unsigned int size, const unsigned char *compressedData, + const unsigned int compressedDataSize) +{ + #ifdef TEST + + if (store -> lastAction != IS_ADDED) + { + #ifdef PANIC + *logofs << "handleSaveAdded: " << store -> name() + << ": PANIC! Function called for action '" + << store -> lastAction << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Save function called for " + << "store '" << store -> name() << "' with " + << "action '" << store -> lastAction + << "'.\n"; + + HandleCleanup(); + } + + #endif + + Message *message = store -> getTemporary(); + + if (message == NULL) + { + #ifdef PANIC + *logofs << "handleSaveAdded: " << store -> name() + << ": PANIC! Can't access temporary storage " + << "for message at position " << store -> lastAdded + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't access temporary storage " + << "for message at position " << store -> lastAdded + << ".\n"; + + HandleCleanup(); + } + + if (compressedData == NULL) + { + // + // If the data part has been split + // avoid to copy it into the message. + // + + store -> parse(message, split, buffer, size, discard_checksum, + use_data, bigEndian_); + } + else + { + store -> parse(message, buffer, size, compressedData, + compressedDataSize, discard_checksum, + use_data, bigEndian_); + } + + if (store -> add(message, store -> lastAdded, + discard_checksum, use_data) == nothing) + { + #ifdef PANIC + *logofs << "handleSaveAdded: " << store -> name() + << ": PANIC! Can't store message in the cache " + << "at position " << store -> lastAdded << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't store message of type " + << store -> name() << "in the cache at position " + << store -> lastAdded << ".\n"; + + HandleCleanup(); + } + else + { + store -> resetTemporary(); + + #ifdef DEBUG + *logofs << "handleSaveAdded: " << store -> name() << ": Stored " + << (compressedData == NULL ? "plain" : "compressed") + << " object at position " << store -> lastAdded + << " of size " << store -> plainSize(store -> lastAdded) + << " (" << store -> plainSize(store -> lastAdded) << "/" + << store -> compressedSize(store -> lastAdded) << ").\n" + << logofs_flush; + #endif + } + + #ifdef DEBUG + *logofs << "handleSaveAdded: " << store -> name() + << ": Size of store is " << store -> getLocalStorageSize() + << " bytes locally and " << store -> getRemoteStorageSize() + << " bytes remotely.\n" << logofs_flush; + + *logofs << "handleSaveAdded: " << store -> name() + << ": Size of total cache is " << store -> getLocalTotalStorageSize() + << " bytes locally and " << store -> getRemoteTotalStorageSize() + << " bytes remotely.\n" << logofs_flush; + #endif +} + +int Channel::handleWait(int timeout) +{ + #ifdef TEST + *logofs << "handleWait: Going to wait for more data " + << "on FD#" << fd_ << " at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + T_timestamp startTs = getNewTimestamp(); + + T_timestamp nowTs = startTs; + + int readable; + int remaining; + + for (;;) + { + remaining = timeout - diffTimestamp(startTs, nowTs); + + if (transport_ -> blocked() == 1) + { + #ifdef WARNING + *logofs << "handleWait: WARNING! Having to drain with " + << "channel " << "for FD#" << fd_ << " blocked.\n" + << logofs_flush; + #endif + + handleDrain(0, remaining); + + continue; + } + + if (remaining <= 0) + { + #ifdef TEST + *logofs << "handleWait: Timeout raised while waiting " + << "for more data for FD#" << fd_ << " at " + << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + return 0; + } + + #ifdef TEST + *logofs << "handleWait: Waiting " << remaining << " Ms " + << "for a new message on FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + readable = transport_ -> wait(remaining); + + if (readable > 0) + { + #ifdef TEST + *logofs << "handleWait: WARNING! Encoding more data " + << "for FD#" << fd_ << " at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + if (proxy -> handleAsyncRead(fd_) < 0) + { + return -1; + } + + return 1; + } + else if (readable == -1) + { + return -1; + } + + nowTs = getNewTimestamp(); + } +} + +int Channel::handleDrain(int limit, int timeout) +{ + #ifdef TEST + *logofs << "handleDrain: Going to drain FD#" << fd_ + << " with a limit of " << limit << " bytes " + << "at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + T_timestamp startTs = getNewTimestamp(); + + T_timestamp nowTs = startTs; + + int drained; + int remaining; + + int result; + + for (;;) + { + remaining = timeout - diffTimestamp(startTs, nowTs); + + if (remaining <= 0) + { + #ifdef TEST + *logofs << "handleDrain: Timeout raised while draining " + << "FD#" << fd_ << " at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + result = 0; + + goto ChannelDrainEnd; + } + + #ifdef TEST + *logofs << "handleDrain: Trying to write to FD#" + << fd_ << " with " << remaining << " Ms " + << "remaining.\n" << logofs_flush; + #endif + + drained = transport_ -> drain(limit, remaining); + + if (drained == 1) + { + #ifdef TEST + *logofs << "handleDrain: Transport for FD#" << fd_ + << " drained to " << transport_ -> length() + << " bytes at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + result = 1; + + goto ChannelDrainEnd; + } + else if (drained == 0 && transport_ -> readable() > 0) + { + #ifdef TEST + *logofs << "handleDrain: WARNING! Encoding more data " + << "for FD#" << fd_ << " at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + if (proxy -> handleAsyncRead(fd_) < 0) + { + goto ChannelDrainError; + } + } + else if (drained == -1) + { + goto ChannelDrainError; + } + + nowTs = getNewTimestamp(); + + if (diffTimestamp(startTs, nowTs) >= control -> ChannelTimeout) + { + int seconds = (remaining + control -> LatencyTimeout * 10) / 1000; + + #ifdef WARNING + *logofs << "handleDrain: WARNING! Could not drain FD#" + << fd_ << " within " << seconds << " seconds.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Can't write to connection on FD#" + << fd_ << " since " << seconds << " seconds.\n"; + + if (alert_ == 0) + { + if (control -> ProxyMode == proxy_client) + { + alert_ = CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT; + } + else + { + alert_ = CLOSE_DEAD_X_CONNECTION_SERVER_ALERT; + } + + HandleAlert(alert_, 1); + } + } + } + +ChannelDrainEnd: + + // + // Maybe we drained the channel and are + // now out of the congestion state. + // + + handleCongestion(); + + return result; + +ChannelDrainError: + + finish_ = 1; + + return -1; +} + +int Channel::handleCongestion() +{ + // + // Send a begin congestion control code + // if the local end of the channel does + // not consume its data. + // + + if (isCongested() == 1) + { + if (congestion_ == 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleCongestion: Sending congestion for FD#" + << fd_ << " with length " << transport_ -> length() + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + congestion_ = 1; + + // + // Use the callback to send the control + // code immediately. + // + + if (proxy -> handleAsyncCongestion(fd_) < 0) + { + finish_ = 1; + + return -1; + } + } + } + else + { + // + // If the channel was in congestion state + // send an end congestion control code. + // + + if (congestion_ == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleCongestion: Sending decongestion for FD#" + << fd_ << " with length " << transport_ -> length() + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + congestion_ = 0; + + if (proxy -> handleAsyncDecongestion(fd_) < 0) + { + finish_ = 1; + + return -1; + } + } + + // + // Remove the "channel unresponsive" + // dialog. + // + + if (alert_ != 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleCongestion: Displacing the dialog " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + HandleAlert(DISPLACE_MESSAGE_ALERT, 1); + } + } + + return 1; +} + +int Channel::handleFlush(T_flush type, int bufferLength, int scratchLength) +{ + if (finish_ == 1) + { + #ifdef TEST + *logofs << "handleFlush: Not flushing data for " + << "finishing channel for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + writeBuffer_.fullReset(); + + return -1; + } + + #ifdef TEST + *logofs << "handleFlush: Flushing " << bufferLength + << " + " << scratchLength << " bytes " + << "to FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + // + // Check if the channel has data available. + // Recent Linux kernels are very picky. + // They require that we read often or they + // assume that the process is non-interact- + // ive. + // + + int result = 0; + + if (handleAsyncEvents() < 0) + { + goto ChannelFlushError; + } + + // + // Write the data in the main buffer first, + // followed by the data in the scratch buffer. + // + + if (bufferLength > 0) + { + result = transport_ -> write(write_immediate, + writeBuffer_.getData(), bufferLength); + } + + if (result >= 0 && scratchLength > 0) + { + result = transport_ -> write(write_immediate, + writeBuffer_.getScratchData(), scratchLength); + } + + if (type == flush_if_any) + { + writeBuffer_.fullReset(); + } + else + { + writeBuffer_.partialReset(); + } + + // + // If we failed to write to the X connection then + // set the finish flag. The caller should continue + // to handle all the remaining messages or it will + // corrupt the decode buffer. At the real end, an + // error will be propagated to the upper layers + // which will perform any needed cleanup. + // + + if (result < 0) + { + goto ChannelFlushError; + } + + // + // Reset transport buffers. + // + + transport_ -> partialReset(); + + // + // Check if the X server has generated + // any event in response to our data. + // + + if (handleAsyncEvents() < 0) + { + goto ChannelFlushError; + } + + // + // Check if the channel has entered in + // congestion state and, in this case, + // send an immediate congestion control + // code to the remote. + // + + handleCongestion(); + + // + // We could optionally drain the output + // buffer if this is X11 channel. + // + // if (isCongested() == 1 && isReliable() == 1) + // { + // if (handleDrain(0, control -> ChannelTimeout) < 0) + // { + // goto ChannelFlushError; + // } + // } + // + + return 1; + +ChannelFlushError: + + finish_ = 1; + + return -1; +} + +int Channel::handleFlush() +{ + #ifdef TEST + *logofs << "handleFlush: Flushing " + << transport_ -> length() << " bytes to FD#" + << fd_ << " with descriptor writable.\n" + << logofs_flush; + #endif + + // + // Check if there is anything to read + // before anf after having written to + // the socket. + // + + if (handleAsyncEvents() < 0) + { + goto ChannelFlushError; + } + + if (transport_ -> flush() < 0) + { + #ifdef TEST + *logofs << "handleFlush: Failure detected " + << "flushing data to FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + goto ChannelFlushError; + } + + if (handleAsyncEvents() < 0) + { + goto ChannelFlushError; + } + + // + // Reset channel's transport buffers. + // + + transport_ -> partialReset(); + + // + // Check if the channel went out of the + // congestion state. + // + + handleCongestion(); + + return 1; + +ChannelFlushError: + + finish_ = 1; + + return -1; +} + +void Channel::handleResetAlert() +{ + if (alert_ != 0) + { + #ifdef TEST + *logofs << "handleResetAlert: The channel alert '" + << alert_ << "' was displaced.\n" + << logofs_flush; + #endif + + alert_ = 0; + } +} + +int Channel::handleCompress(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned int offset, const unsigned char *buffer, + const unsigned int size, unsigned char *&compressedData, + unsigned int &compressedDataSize) +{ + if (size <= offset) + { + #ifdef DEBUG + *logofs << "handleCompress: Not compressing data for FD#" << fd_ + << " as offset is " << offset << " with data size " + << size << ".\n" << logofs_flush; + #endif + + return 0; + } + + #ifdef DEBUG + *logofs << "handleCompress: Compressing data for FD#" << fd_ + << " with data size " << size << " and offset " + << offset << ".\n" << logofs_flush; + #endif + + // + // It is responsibility of the compressor to + // mark the buffer as such if the compression + // couldn't take place. + // + + if (compressor_ -> compressBuffer(buffer + offset, size - offset, compressedData, + compressedDataSize, encodeBuffer) <= 0) + { + #ifdef DEBUG + *logofs << "handleCompress: Sent " << size - offset + << " bytes of plain data for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + return 0; + } + else + { + #ifdef DEBUG + *logofs << "handleCompress: Sent " << compressedDataSize + << " bytes of compressed data for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + return 1; + } +} + +int Channel::handleDecompress(DecodeBuffer &decodeBuffer, const unsigned char opcode, + const unsigned int offset, unsigned char *buffer, + const unsigned int size, const unsigned char *&compressedData, + unsigned int &compressedDataSize) +{ + if (size <= offset) + { + return 0; + } + + int result = compressor_ -> decompressBuffer(buffer + offset, size - offset, + compressedData, compressedDataSize, + decodeBuffer); + if (result < 0) + { + #ifdef PANIC + *logofs << "handleDecompress: PANIC! Failed to decompress " + << size - offset << " bytes of data for FD#" << fd_ + << " with OPCODE#" << (unsigned int) opcode << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Data decompression failed for OPCODE#" + << (unsigned int) opcode << ".\n"; + + return -1; + } + else if (result == 0) + { + #ifdef DEBUG + *logofs << "handleDecompress: Received " << size - offset + << " bytes of plain data for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + return 0; + } + else + { + #ifdef DEBUG + *logofs << "handleDecompress: Received " << compressedDataSize + << " bytes of compressed data for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + return 1; + } +} + +int Channel::handleCleanAndNullRequest(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size) +{ + #ifdef TEST + *logofs << "handleCleanAndNullRequest: Removing the previous data " + << "and sending an X_NoOperation " << "for FD#" << fd_ + << " due to OPCODE#" << (unsigned int) opcode << " (" + << DumpOpcode(opcode) << ").\n" << logofs_flush; + #endif + + writeBuffer_.removeMessage(size - 4); + + size = 4; + opcode = X_NoOperation; + + return 1; +} + +int Channel::handleNullRequest(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size) +{ + #ifdef TEST + *logofs << "handleNullRequest: Sending an X_NoOperation for FD#" + << fd_ << " due to OPCODE#" << (unsigned int) opcode + << " (" << DumpOpcode(opcode) << ").\n" + << logofs_flush; + #endif + + size = 4; + buffer = writeBuffer_.addMessage(size); + opcode = X_NoOperation; + + return 1; +} + +void Channel::handleSplitStoreError(int resource) +{ + if (resource < 0 || resource >= CONNECTIONS_LIMIT) + { + #ifdef PANIC + *logofs << "handleSplitStoreError: PANIC! Resource " + << resource << " is out of range with limit " + << "set to " << CONNECTIONS_LIMIT << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Resource " << resource + << " is out of range with limit set to " + << CONNECTIONS_LIMIT << ".\n"; + + HandleCleanup(); + } + else + { + #ifdef PANIC + *logofs << "handleSplitStoreError: PANIC! Cannot " + << "allocate the split store for resource " + << resource << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot allocate the " + << "split store for resource " << resource + << ".\n"; + + HandleCleanup(); + } +} + +void Channel::handleSplitStoreAlloc(List *list, int resource) +{ + if (resource < 0 || resource >= CONNECTIONS_LIMIT) + { + handleSplitStoreError(resource); + } + + if (clientStore_ -> getSplitStore(resource) == NULL) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitStoreAlloc: Allocating a new " + << "split store for resource " << resource + << ".\n" << logofs_flush; + #endif + + SplitStore *splitStore = clientStore_ -> createSplitStore(resource); + + if (splitStore == NULL) + { + handleSplitStoreError(resource); + } + + list -> add(resource); + } + #if defined(TEST) || defined(SPLIT) + else + { + // + // Old proxy versions only use a single + // split store. + // + + if (resource != 0) + { + *logofs << "handleSplitStoreAlloc: WARNING! A split " + << "store for resource " << resource + << " already exists.\n" << logofs_flush; + } + } + #endif +} + +void Channel::handleSplitStoreRemove(List *list, int resource) +{ + if (resource < 0 || resource >= CONNECTIONS_LIMIT) + { + handleSplitStoreError(resource); + } + + SplitStore *splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore != NULL) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitStoreRemove: Deleting the " + << "split store for resource " << resource + << ".\n" << logofs_flush; + #endif + + clientStore_ -> destroySplitStore(resource); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitStoreRemove: Deleting resource " + << resource << " from the list " << ".\n" + << logofs_flush; + #endif + + list -> remove(resource); + } + #if defined(TEST) || defined(SPLIT) + else + { + *logofs << "handleSplitStoreRemove: WARNING! A split " + << "store for resource " << resource + << " does not exist.\n" << logofs_flush; + } + #endif +} + +Split *Channel::handleSplitCommitRemove(int request, int resource, int position) +{ + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitCommitRemove: SPLIT! Checking split " + << "commit with resource " << resource << " request " + << request << " and position " << position + << ".\n" << logofs_flush; + #endif + + // + // Remove the split from the split queue. + // + + CommitStore *commitStore = clientStore_ -> getCommitStore(); + + Split *split = commitStore -> pop(); + + if (split == NULL) + { + #ifdef PANIC + *logofs << "handleSplitCommitRemove: PANIC! Can't " + << "find the split in the commit queue.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't find the " + << "split in the commit queue.\n"; + + HandleCleanup(); + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitCommitRemove: SPLIT! Element from " + << "the queue has resource " << split -> getResource() + << " request " << split -> getRequest() << " and " + << "position " << split -> getPosition() + << ".\n" << logofs_flush; + #endif + + // Since ProtoStep7 (#issue 108) + if (resource != split -> getResource() || + request != split -> getRequest() || + position != split -> getPosition()) + { + #ifdef PANIC + *logofs << "handleSplitCommitRemove: PANIC! The data in " + << "the split doesn't match the commit request.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": The data in the split doesn't " + << "match the commit request.\n"; + + return NULL; + } + + #if defined(TEST) || defined(SPLIT) + + commitStore -> dump(); + + #endif + + return split; +} + +int Channel::setReferences() +{ + #ifdef TEST + *logofs << "Channel: Initializing the static " + << "members for the base class.\n" + << logofs_flush; + #endif + + firstClient_ = -1; + + fontPort_ = -1; + + #ifdef REFERENCES + + references_ = 0; + + #endif + + return 1; +} + +int Channel::setOpcodes(OpcodeStore *opcodeStore) +{ + opcodeStore_ = opcodeStore; + + #ifdef TEST + *logofs << "setOpcodes: Propagated opcodes store to channel " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + return 1; +} + +int Channel::setStores(ClientStore *clientStore, ServerStore *serverStore) +{ + clientStore_ = clientStore; + serverStore_ = serverStore; + + #ifdef TEST + *logofs << "setStores: Propagated message stores to channel " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + return 1; +} + +int Channel::setCaches(ClientCache *clientCache, ServerCache *serverCache) +{ + clientCache_ = clientCache; + serverCache_ = serverCache; + + #ifdef TEST + *logofs << "setCaches: Propagated encode caches to channel " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + return 1; +} diff --git a/nxcomp/src/Channel.h b/nxcomp/src/Channel.h new file mode 100644 index 000000000..93b022630 --- /dev/null +++ b/nxcomp/src/Channel.h @@ -0,0 +1,664 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Channel_H +#define Channel_H + +#include "Transport.h" + +#include "WriteBuffer.h" + +#include "OpcodeStore.h" + +#include "ClientStore.h" +#include "ServerStore.h" + +#include "ClientCache.h" +#include "ServerCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Forward declaration of referenced classes. +// + +class List; + +class StaticCompressor; + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Define this to log a line when a channel +// is created or destroyed. +// + +#undef REFERENCES + +// +// Type of traffic carried by channel. +// + +typedef enum +{ + channel_none = -1, + channel_x11, + channel_cups, + channel_smb, + channel_media, + channel_http, + channel_font, + channel_slave, + channel_last_tag + +} T_channel_type; + +// +// Type of notification event to be sent +// by proxy to the X channel. +// + +typedef enum +{ + notify_no_split, + notify_start_split, + notify_commit_split, + notify_end_split, + notify_empty_split, + +} T_notification_type; + +class Channel +{ + public: + + // + // Maximum number of X connections supported. + // + + static const int CONNECTIONS_LIMIT = 256; + + Channel(Transport *transport, StaticCompressor *compressor); + + virtual ~Channel(); + + // + // Read any X message available on the X + // connection and encode it to the encode + // buffer. + // + + virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, + unsigned int length) = 0; + + // + // Decode any X message encoded in the + // proxy message and write it to the X + // connection. + // + + virtual int handleWrite(const unsigned char *message, unsigned int length) = 0; + + // + // Other methods to be implemented in + // client, server and generic channel + // classes. + // + + virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, + T_store_action action, int position, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) = 0; + + virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, + T_store_action action, int position, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) = 0; + + virtual int handleSplit(EncodeBuffer &encodeBuffer) = 0; + + virtual int handleSplit(DecodeBuffer &decodeBuffer) = 0; + + virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split) = 0; + + virtual int handleSplitEvent(DecodeBuffer &decodeBuffer) = 0; + + virtual int handleMotion(EncodeBuffer &encodeBuffer) = 0; + + virtual int handleCompletion(EncodeBuffer &encodeBuffer) = 0; + + virtual int handleConfiguration() = 0; + + virtual int handleFinish() = 0; + + // + // Interleave reads of the available + // events while writing data to the + // channel socket. + // + + virtual int handleAsyncEvents() = 0; + + // + // Handle the channel tear down. + // + + int handleClosing() + { + closing_ = 1; + + return 1; + } + + int handleDrop() + { + drop_ = 1; + + return 1; + } + + // + // Try to read more data from the socket. In + // the meanwhile flush any enqueued data if + // the channel is blocked. Return as soon as + // more data has been read or the timeout has + // been exceeded. + // + + int handleWait(int timeout); + + // + // Drain the output buffer while handling the + // data that may become readable. + // + + int handleDrain(int timeout, int limit); + + // + // Flush any remaining data in the transport + // buffer. + // + + int handleFlush(); + + // + // Called when the loop has replaced or + // closed a previous alert. + // + + void handleResetAlert(); + + // + // Initialize all the static members. + // + + static int setReferences(); + + // + // Set pointer to object mapping opcodes + // of NX specific messages. + // + + int setOpcodes(OpcodeStore *opcodeStore); + + // + // Update pointers to message stores in + // channels. + // + + int setStores(ClientStore *clientStore, ServerStore *serverStore); + + // + // The same for channels caches. + // + + int setCaches(ClientCache *clientCache, ServerCache *serverCache); + + // + // Set the port used for tunneling of the + // font server connections. + // + + void setPorts(int fontPort) + { + fontPort_ = fontPort; + } + + // + // Check if there are pending split + // to send to the remote side. + // + + virtual int needSplit() const = 0; + + // + // Check if there are motion events + // to flush. + // + + virtual int needMotion() const = 0; + + // + // Return the type of traffic carried + // by this channel. + // + + virtual T_channel_type getType() const = 0; + + // + // Check if the channel has been marked + // as closing down. + // + + int getFinish() const + { + return finish_; + } + + int getClosing() + { + return closing_; + } + + int getDrop() + { + return drop_; + } + + int getCongestion() + { + return congestion_; + } + + protected: + + int handleFlush(T_flush type) + { + // + // We could write the data immediately if there + // is already something queued to the low level + // TCP buffers. + // + // if (... || transport_ -> queued() > 0) + // { + // ... + // } + // + + if (writeBuffer_.getScratchLength() > 0 || + (type == flush_if_any && writeBuffer_.getLength() > 0) || + writeBuffer_.getLength() >= (unsigned int) + control -> TransportFlushBufferSize) + { + return handleFlush(type, writeBuffer_.getLength(), + writeBuffer_.getScratchLength()); + } + + return 0; + } + + // + // Actually flush the data to the + // channel descriptor. + // + + int handleFlush(T_flush type, int bufferLength, int scratchLength); + + // + // Handle the congestion changes. + // + + int handleCongestion(); + + // + // Encode and decode X messages. + // + + int handleEncode(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, + MessageStore *store, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + int handleDecode(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, + MessageStore *store, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + // + // Encode the message based on its + // message store. + // + + int handleEncodeCached(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, + MessageStore *store, const unsigned char *buffer, + const unsigned int size); + + int handleDecodeCached(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, + MessageStore *store, unsigned char *&buffer, + unsigned int &size); + + int handleEncodeIdentity(EncodeBuffer &encodeBuffer, ChannelCache *channelCache, + MessageStore *store, const unsigned char *buffer, + const unsigned int size, int bigEndian) + { + return (store -> encodeIdentity(encodeBuffer, buffer, size, + bigEndian, channelCache)); + } + + int handleDecodeIdentity(DecodeBuffer &decodeBuffer, ChannelCache *channelCache, + MessageStore *store, unsigned char *&buffer, + unsigned int &size, int bigEndian, + WriteBuffer *writeBuffer) + { + return (store -> decodeIdentity(decodeBuffer, buffer, size, bigEndian, + writeBuffer, channelCache)); + } + + // + // Other utility functions used by + // the encoding and decoding methods. + // + + void handleCopy(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned int offset, const unsigned char *buffer, + const unsigned int size) + { + if (size > offset) + { + encodeBuffer.encodeMemory(buffer + offset, size - offset); + } + } + + void handleCopy(DecodeBuffer &decodeBuffer, const unsigned char opcode, + const unsigned int offset, unsigned char *buffer, + const unsigned int size) + { + if (size > offset) + { + memcpy(buffer + offset, decodeBuffer.decodeMemory(size - offset), size - offset); + } + } + + void handleUpdate(MessageStore *store, const unsigned int dataSize, + const unsigned int compressedDataSize) + { + if (store -> lastAction == IS_ADDED) + { + handleUpdateAdded(store, dataSize, compressedDataSize); + } + } + + void handleSave(MessageStore *store, unsigned char *buffer, unsigned int size, + const unsigned char *compressedData = NULL, + const unsigned int compressedDataSize = 0) + { + if (store -> lastAction == IS_ADDED) + { + handleSaveAdded(store, 0, buffer, size, compressedData, compressedDataSize); + } + } + + void handleSaveSplit(MessageStore *store, unsigned char *buffer, + unsigned int size) + { + if (store -> lastAction == IS_ADDED) + { + return handleSaveAdded(store, 1, buffer, size, 0, 0); + } + } + + void handleUpdateAdded(MessageStore *store, const unsigned int dataSize, + const unsigned int compressedDataSize); + + void handleSaveAdded(MessageStore *store, int split, unsigned char *buffer, + unsigned int size, const unsigned char *compressedData, + const unsigned int compressedDataSize); + + // + // Compress the data part of a message + // using ZLIB or another compressor + // and send it over the network. + // + + int handleCompress(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned int offset, const unsigned char *buffer, + const unsigned int size, unsigned char *&compressedData, + unsigned int &compressedDataSize); + + int handleDecompress(DecodeBuffer &decodeBuffer, const unsigned char opcode, + const unsigned int offset, unsigned char *buffer, + const unsigned int size, const unsigned char *&compressedData, + unsigned int &compressedDataSize); + + // + // Send an X_NoOperation to the X server. + // The second version also removes any + // previous data in the write buffer. + // + + int handleNullRequest(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size); + + int handleCleanAndNullRequest(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size); + + // + // X11 channels are considered to be in + // congestion state when there was a + // blocking write and, since then, the + // local end didn't consume all the data. + // + + virtual int isCongested() + { + return (transport_ -> getType() != + transport_agent && transport_ -> length() > + control -> TransportFlushBufferSize); + } + + virtual int isReliable() + { + return 1; + } + + // + // Determine how to handle allocation + // of new messages in the message + // stores. + // + + int mustCleanStore(MessageStore *store) + { + return (store -> getRemoteTotalStorageSize() > control -> + RemoteTotalStorageSize || store -> getLocalTotalStorageSize() > + control -> LocalTotalStorageSize || (store -> getRemoteStorageSize() > + (control -> RemoteTotalStorageSize / 100 * store -> + cacheThreshold)) || (store -> getLocalStorageSize() > + (control -> LocalTotalStorageSize / 100 * store -> + cacheThreshold))); + } + + int canCleanStore(MessageStore *store) + { + return ((store -> getSize() > 0 && (store -> getRemoteStorageSize() > + (control -> RemoteTotalStorageSize / 100 * store -> + cacheLowerThreshold))) || (store -> getLocalStorageSize() > + (control -> LocalTotalStorageSize / 100 * store -> + cacheLowerThreshold))); + } + + protected: + + // + // Set up the split stores. + // + + void handleSplitStoreError(int resource); + + void handleSplitStoreAlloc(List *list, int resource); + void handleSplitStoreRemove(List *list, int resource); + + Split *handleSplitCommitRemove(int request, int resource, int position); + + void validateSize(const char *name, int input, int output, + int offset, int size) + { + if (size < offset || size > control -> MaximumMessageSize || + size != (int) RoundUp4(input) + offset || + output > control -> MaximumMessageSize) + { + *logofs << "Channel: PANIC! Invalid size " << size + << " for " << name << " output with data " + << input << "/" << output << "/" << offset + << "/" << size << ".\n" << logofs_flush; + + cerr << "Error" << ": Invalid size " << size + << " for " << name << " output.\n"; + + HandleAbort(); + } + } + + // + // Is the X client big endian? + // + + int bigEndian() const + { + return bigEndian_; + } + + int bigEndian_; + + // + // Other X server's features + // saved at session startup. + // + + unsigned int imageByteOrder_; + unsigned int bitmapBitOrder_; + unsigned int scanlineUnit_; + unsigned int scanlinePad_; + + int firstRequest_; + int firstReply_; + + // + // Use this class for IO operations. + // + + Transport *transport_; + + // + // The static compressor is created by the + // proxy and shared among channels. + // + + StaticCompressor *compressor_; + + // + // Map NX operations to opcodes. Propagated + // by proxy to all channels on the same X + // server. + // + + OpcodeStore *opcodeStore_; + + // + // Also stores are shared between channels. + // + + ClientStore *clientStore_; + ServerStore *serverStore_; + + // + // Caches are specific for each channel. + // + + ClientCache *clientCache_; + ServerCache *serverCache_; + + // + // Data going to X connection. + // + + WriteBuffer writeBuffer_; + + // + // Other data members. + // + + int fd_; + + int finish_; + int closing_; + int drop_; + int congestion_; + int priority_; + + int alert_; + + // + // It will be set to the descriptor of the + // first X channel that is successfully con- + // nected and will print an info message on + // standard error. + // + + static int firstClient_; + + // + // Port used for font server connections. + // + + static int fontPort_; + + // + // Track which cache operations have been + // enabled by the agent. + // + + int enableCache_; + int enableSplit_; + int enableSave_; + int enableLoad_; + + // + // Keep track of object creation and + // deletion. + // + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +#endif /* Channel_H */ diff --git a/nxcomp/src/ChannelCache.cpp b/nxcomp/src/ChannelCache.cpp new file mode 100644 index 000000000..f30f18bc1 --- /dev/null +++ b/nxcomp/src/ChannelCache.cpp @@ -0,0 +1,68 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ChannelCache.h" + +const unsigned int CONFIGUREWINDOW_FIELD_WIDTH[7] = +{ + 16, // x + 16, // y + 16, // width + 16, // height + 16, // border width + 29, // sibling window + 3 // stack mode +}; + +const unsigned int CREATEGC_FIELD_WIDTH[23] = +{ + 4, // function + 32, // plane mask + 32, // foreground + 32, // background + 16, // line width + 2, // line style + 2, // cap style + 2, // join style + 2, // fill style + 1, // fill rule + 29, // tile + 29, // stipple + 16, // tile/stipple x origin + 16, // tile/stipple y origin + 29, // font + 1, // subwindow mode + 1, // graphics exposures + 16, // clip x origin + 16, // clip y origin + 29, // clip mask + 16, // card offset + 8, // dashes + 1 // arc mode +}; diff --git a/nxcomp/src/ChannelCache.h b/nxcomp/src/ChannelCache.h new file mode 100644 index 000000000..6a29c3847 --- /dev/null +++ b/nxcomp/src/ChannelCache.h @@ -0,0 +1,61 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ChannelCache_H +#define ChannelCache_H + +// +// Sizes of optional fields for ConfigureWindow +// request. +// + +extern const unsigned int CONFIGUREWINDOW_FIELD_WIDTH[7]; + +// +// Sizes of optional fields for CreateGC request. +// + +extern const unsigned int CREATEGC_FIELD_WIDTH[23]; + +// +// This is just needed to provide a pointer +// to the base cache class in encoding and +// decoding procedures of message stores. +// + +class ChannelCache +{ + public: + + ChannelCache() + { + } + + ~ChannelCache() + { + } +}; + +#endif /* ChannelCache_H */ diff --git a/nxcomp/src/ChannelEndPoint.cpp b/nxcomp/src/ChannelEndPoint.cpp new file mode 100644 index 000000000..921615bae --- /dev/null +++ b/nxcomp/src/ChannelEndPoint.cpp @@ -0,0 +1,349 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "ChannelEndPoint.h" + +#include "NXalert.h" + +ChannelEndPoint::ChannelEndPoint(const char *spec) + : defaultTCPPort_(0), defaultTCPInterface_(0), + defaultUnixPath_(NULL), spec_(NULL) { + setSpec(spec); +} + +ChannelEndPoint::~ChannelEndPoint() +{ + char *unixPath = NULL; + + if (getUnixPath(&unixPath)) + { + struct stat st; + lstat(unixPath, &st); + if(S_ISSOCK(st.st_mode)) + unlink(unixPath); + } +} + +void +ChannelEndPoint::setSpec(const char *spec) { + if (spec_) free(spec_); + + if (spec && strlen(spec)) + { + spec_ = strdup(spec); + isUnix_ = getUnixPath(); + isTCP_ = getTCPHostAndPort(); + } + else + { + spec_ = NULL; + isUnix_ = false; + isTCP_ = false; + } +} + +void +ChannelEndPoint::setSpec(long port) { + if (port >= 0) { + char tmp[20]; + sprintf(tmp, "%ld", port); + setSpec(tmp); + } + else { + disable(); + } +} + +void +ChannelEndPoint::setSpec(const char *hostName, long port) { + int length; + + if (spec_) free(spec_); + isUnix_ = false; + isTCP_ = false; + + if (hostName && strlen(hostName) && port >= 1) + { + length = snprintf(NULL, 0, "tcp:%s:%ld", hostName, port); + spec_ = (char *)calloc(length + 1, sizeof(char)); + snprintf(spec_, length+1, "tcp:%s:%ld", hostName, port); + isTCP_ = true; + } + else setSpec((char*)NULL); +} + +bool +ChannelEndPoint::getSpec(char **socketUri) const { + + if (socketUri) *socketUri = NULL; + + char *unixPath = NULL; + char *hostName = NULL; + long port = -1; + + char *newSocketUri = NULL; + int length = -1; + + if (getUnixPath(&unixPath)) + { + length = snprintf(NULL, 0, "unix:%s", unixPath); + } + else if (getTCPHostAndPort(&hostName, &port)) + { + length = snprintf(NULL, 0, "tcp:%s:%ld", hostName, port); + } + + if (length > 0) + { + newSocketUri = (char *)calloc(length + 1, sizeof(char)); + if (isUnixSocket()) + snprintf(newSocketUri, length+1, "unix:%s", unixPath); + else + snprintf(newSocketUri, length+1, "tcp:%s:%ld", hostName, port); + + if (socketUri) + *socketUri = strdup(newSocketUri); + } + + free(newSocketUri); + free(unixPath); + free(hostName); + + if (NULL != *socketUri) + return true; + + return false; +} + +void +ChannelEndPoint::setDefaultTCPPort(long port) { + defaultTCPPort_ = port; +} + +void +ChannelEndPoint::setDefaultTCPInterface(int publicInterface) { + defaultTCPInterface_ = publicInterface; +} + +void +ChannelEndPoint::setDefaultUnixPath(char *path) { + if (defaultUnixPath_) free(defaultUnixPath_); + + if (path && strlen(path)) + defaultUnixPath_ = strdup(path); + else + defaultUnixPath_ = NULL; +} + +void +ChannelEndPoint::disable() { + setSpec("0"); +} + +bool +ChannelEndPoint::getPort(long *port) const { + if (port) *port = 0; + long p = -1; + if (spec_) { + char *end; + p = strtol(spec_, &end, 10); + if ((end == spec_) || (*end != '\0')) + return false; + } + + if (port) *port = p; + return true; +} + +bool +ChannelEndPoint::getUnixPath(char **unixPath) const { + + if (unixPath) *unixPath = 0; + + long p; + char *path = NULL; + + if (getPort(&p)) { + if (p != 1) return false; + } + else if (spec_ && (strncmp("unix:", spec_, 5) == 0)) { + path = spec_ + 5; + } + else + return false; + + if (!path || (*path == '\0')) { + path = defaultUnixPath_; + if (!path) + return false; + } + + if (unixPath) + *unixPath = strdup(path); + + return true; +} + +bool +ChannelEndPoint::isUnixSocket() const { + return isUnix_; +} + +// FIXME!!! +static const char * +getComputerName() { + // + // Strangely enough, under some Windows OSes SMB + // service doesn't bind to localhost. Fall back + // to localhost if can't find computer name in + // the environment. In future we should try to + // bind to localhost and then try the other IPs. + // + + const char *hostname = NULL; + + #ifdef __CYGWIN32__ + + hostname = getenv("COMPUTERNAME"); + + #endif + + if (hostname == NULL) + { + hostname = "localhost"; + } + + return hostname; +} + +bool +ChannelEndPoint::getTCPHostAndPort(char **host, long *port) const { + long p; + char *h = NULL; + ssize_t h_len; + + if (host) *host = NULL; + if (port) *port = 0; + + if (getPort(&p)) { + h_len = 0; + } + else if (spec_ && (strncmp("tcp:", spec_, 4) == 0)) { + h = spec_ + 4; + char *colon = strrchr(h, ':'); + if (colon) { + char *end; + h_len = colon++ - h; + p = strtol(colon, &end, 10); + if ((end == colon) || (*end != '\0')) + return false; + } + else { + h_len = strlen(h); + p = 1; + } + } + else + return false; + + if (p == 1) p = defaultTCPPort_; + if (p < 1) return false; + + if (port) + *port = p; + + if (host) + *host = ( h_len + ? strndup(h, h_len) + : strdup(defaultTCPInterface_ ? getComputerName() : "localhost")); + + return true; +} + +bool +ChannelEndPoint::isTCPSocket() const { + return isTCP_; +} + +long ChannelEndPoint::getTCPPort() const { + long port; + if (getTCPHostAndPort(NULL, &port)) return port; + return -1; +} + +bool +ChannelEndPoint::enabled() const { + return (isUnixSocket() || isTCPSocket()); +} + +bool +ChannelEndPoint::validateSpec() { + isTCP_ = getTCPHostAndPort(); + isUnix_ = getUnixPath(); + return ( getPort() || isUnix_ || isTCP_ ); +} + +ChannelEndPoint &ChannelEndPoint::operator=(const ChannelEndPoint &other) { + char *old; + defaultTCPPort_ = other.defaultTCPPort_; + defaultTCPInterface_ = other.defaultTCPInterface_; + old = defaultUnixPath_; + defaultUnixPath_ = (other.defaultUnixPath_ ? strdup(other.defaultUnixPath_) : NULL); + free(old); + old = spec_; + spec_ = (other.spec_ ? strdup(other.spec_) : NULL); + free(old); + isUnix_ = getUnixPath(); + isTCP_ = getTCPHostAndPort(); + return *this; +} + +std::ostream& operator<<(std::ostream& os, const ChannelEndPoint& endPoint) { + if (endPoint.enabled()) { + char* endPointSpec = NULL; + if (endPoint.getSpec(&endPointSpec)) + { + os << endPointSpec; + free(endPointSpec); + } + else + os << "(invalid)"; + } + else + { + os << "(disabled)"; + } + return os; +} diff --git a/nxcomp/src/ChannelEndPoint.h b/nxcomp/src/ChannelEndPoint.h new file mode 100644 index 000000000..4c0c728f3 --- /dev/null +++ b/nxcomp/src/ChannelEndPoint.h @@ -0,0 +1,71 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ChannelEndPoint_H +#define ChannelEndPoint_H + +#include +#include + +class ChannelEndPoint +{ + private: + long defaultTCPPort_; + int defaultTCPInterface_; // 0=localhost, otherwise IP of public interface. + char *defaultUnixPath_; + char *spec_; + bool isUnix_; + bool isTCP_; + + bool getPort(long *port = NULL) const; + + public: + ChannelEndPoint(const char *spec = NULL); + ~ChannelEndPoint(); + ChannelEndPoint &operator=(const ChannelEndPoint &other); + + bool enabled() const; + bool disabled() { return !enabled(); } + void disable(); + void setSpec(const char *spec); + void setSpec(long port); + void setSpec(const char *hostName, long port); + bool getSpec(char **socketUri) const; + void setDefaultTCPPort(long port); + void setDefaultTCPInterface(int publicInterface); + void setDefaultUnixPath(char *path); + + bool getUnixPath(char **path = NULL) const; + bool isUnixSocket() const; + bool getTCPHostAndPort(char **hostname = NULL, long *port = NULL) const; + long getTCPPort() const; + bool isTCPSocket() const; + + bool validateSpec(); +}; + +std::ostream& operator<<(std::ostream& os, const ChannelEndPoint& endPoint); + +#endif diff --git a/nxcomp/src/ChannelStore.h b/nxcomp/src/ChannelStore.h new file mode 100644 index 000000000..53bb60f73 --- /dev/null +++ b/nxcomp/src/ChannelStore.h @@ -0,0 +1,54 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ChannelStore_H +#define ChannelStore_H + +// +// One message store for each opcode. +// + +#define CHANNEL_STORE_OPCODE_LIMIT 256 + +// +// One split store for each resource. +// + +#define CHANNEL_STORE_RESOURCE_LIMIT 256 + +class ChannelStore +{ + public: + + ChannelStore() + { + } + + virtual ~ChannelStore() + { + } +}; + +#endif /* ChannelStore_H */ diff --git a/nxcomp/src/CharCache.cpp b/nxcomp/src/CharCache.cpp new file mode 100644 index 000000000..ed0e5a02a --- /dev/null +++ b/nxcomp/src/CharCache.cpp @@ -0,0 +1,73 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "CharCache.h" + +int CharCache::lookup(unsigned char value, unsigned int &index) +{ + for (unsigned int i = 0; i < length_; i++) + if (value == buffer_[i]) + { + index = i; + if (i) + { + unsigned int target = (i >> 1); + do + { + buffer_[i] = buffer_[i - 1]; + i--; + } + while (i > target); + buffer_[target] = value; + } + return 1; + } + insert(value); + return 0; +} + +void CharCache::insert(unsigned char value) +{ + unsigned int insertionPoint = 0; + if (2 >= length_) + insertionPoint = length_; + else + insertionPoint = 2; + unsigned int start; + if (length_ >= 7) + start = 7 - 1; + else + { + start = length_; + length_++; + } + for (unsigned int k = start; k > insertionPoint; k--) + buffer_[k] = buffer_[k - 1]; + buffer_[insertionPoint] = value; +} diff --git a/nxcomp/src/CharCache.h b/nxcomp/src/CharCache.h new file mode 100644 index 000000000..b8891d2df --- /dev/null +++ b/nxcomp/src/CharCache.h @@ -0,0 +1,91 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef CharCache_H +#define CharCache_H + +// +// CharCache is a counterpart of IntCache that is +// optimized for use in compressing text composed +// of 8-bit characters. +// + +class CharCache +{ + public: + + CharCache() : length_(0) + { + } + + ~CharCache() + { + } + + unsigned int getSize() const + { + return (unsigned int) length_; + } + + int lookup(unsigned char value, unsigned int &index); + + // + // This can be inlined as it is only + // called by decodeCachedValue(). + // + + unsigned int get(unsigned int index) + { + unsigned char result = buffer_[index]; + + if (index != 0) + { + unsigned int i = index; + unsigned int target = (i >> 1); + + do + { + buffer_[i] = buffer_[i - 1]; + + i--; + } + while (i > target); + + buffer_[target] = result; + } + + return (unsigned int) result; + } + + void insert(unsigned char value); + + private: + + unsigned char length_; + + unsigned char buffer_[7]; +}; + +#endif /* CharCache_H */ diff --git a/nxcomp/src/Children.cpp b/nxcomp/src/Children.cpp new file mode 100644 index 000000000..49ab13352 --- /dev/null +++ b/nxcomp/src/Children.cpp @@ -0,0 +1,1059 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "NX.h" + +#include "Misc.h" + +#include "Types.h" +#include "Timestamp.h" + +#include "Control.h" +#include "Statistics.h" +#include "Proxy.h" + +#include "Keeper.h" +#include "Fork.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#define DISPLAY_LENGTH_LIMIT 256 +#define DEFAULT_STRING_LIMIT 512 + +// +// These are from the main loop. +// + +extern Keeper *keeper; + +extern int (*handler)(int); + +extern int useUnixSocket; + +extern int lastDialog; +extern int lastWatchdog; +extern int lastKeeper; + +extern void CleanupListeners(); +extern void CleanupSockets(); +extern void CleanupAgent(); +extern void CleanupGlobal(); + +extern void InstallSignals(); + +extern char *GetClientPath(); + +extern int CheckParent(const char *name, const char *type, + int parent); + +#ifdef __sun +extern char **environ; +#endif + +// +// Close all the unused descriptors and +// install any signal handler that might +// have been disabled in the main process. +// + +static void SystemCleanup(const char *name); + +// +// Release all objects allocated in the +// heap. + +static void MemoryCleanup(const char *name); + +// +// Remove 'name' from the environment. +// + +static int UnsetEnv(const char *name); + +static int NXTransKeeperHandler(int signal); +static void NXTransKeeperCheck(); + + +// +// Start a nxclient process in dialog mode. +// + +int NXTransDialog(const char *caption, const char *message, + const char *window, const char *type, int local, + const char* display) +{ + // + // Be sure log file is valid. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + int pid; + + #ifdef TEST + *logofs << "NXTransDialog: Going to fork with NX pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + pid = Fork(); + + if (pid != 0) + { + if (pid < 0) + { + #ifdef TEST + *logofs << "NXTransDialog: WARNING! Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + } + #ifdef TEST + else + { + *logofs << "NXTransDialog: Created NX dialog process " + << "with pid '" << pid << "'.\n" + << logofs_flush; + } + #endif + + return pid; + } + + #ifdef TEST + *logofs << "NXTransDialog: Executing child with pid '" + << getpid() << "' and parent '" << getppid() + << "'.\n" << logofs_flush; + #endif + + SystemCleanup("NXTransDialog"); + + // + // Copy the client command before + // freeing up the control class. + // + + char command[DEFAULT_STRING_LIMIT]; + + if (control != NULL) + { + strcpy(command, control -> ClientPath); + } + else + { + char *path = GetClientPath(); + + strcpy(command, path); + + delete [] path; + } + + // + // Get rid of the unused resources. + // + + MemoryCleanup("NXTransDialog"); + + #ifdef TEST + *logofs << "NXTransDialog: Running external NX dialog with caption '" + << caption << "' message '" << message << "' type '" + << type << "' local '" << local << "' display '" + << display << "'.\n" + << logofs_flush; + #endif + + int pulldown = (strcmp(type, "pulldown") == 0); + + char parent[DEFAULT_STRING_LIMIT]; + + snprintf(parent, DEFAULT_STRING_LIMIT, "%d", getppid()); + + parent[DEFAULT_STRING_LIMIT - 1] = '\0'; + + UnsetEnv("LD_LIBRARY_PATH"); + + for (int i = 0; i < 2; i++) + { + if (local != 0) + { + if (pulldown) + { + execlp(command, command, "--dialog", type, "--caption", caption, + "--window", window, "--local", "--parent", parent, + "--display", display, NULL); + } + else + { + execlp(command, command, "--dialog", type, "--caption", caption, + "--message", message, "--local", "--parent", parent, + "--display", display, NULL); + } + } + else + { + if (pulldown) + { + execlp(command, command, "--dialog", type, "--caption", caption, + "--window", window, "--parent", parent, + "--display", display, NULL); + } + else + { + execlp(command, command, "--dialog", type, "--caption", caption, + "--message", message, "--parent", parent, + "--display", display, NULL); + } + } + + #ifdef WARNING + *logofs << "NXTransDialog: WARNING! Couldn't start '" + << command << "'. " << "Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Couldn't start '" << command + << "'. Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + // + // Retry by looking for the default name + // in the default NX path. + // + + if (i == 0) + { + + strcpy(command, "nxclient"); + + char newPath[DEFAULT_STRING_LIMIT]; + + strcpy(newPath, "/usr/NX/bin:/opt/NX/bin:/usr/local/NX/bin:"); + + #ifdef __APPLE__ + + strcat(newPath, "/Applications/NX Client for OSX.app/Contents/MacOS:"); + + #endif + + #ifdef __CYGWIN32__ + + strcat(newPath, ".:"); + + #endif + + int newLength = strlen(newPath); + + char *oldPath = getenv("PATH"); + + strncpy(newPath + newLength, oldPath, DEFAULT_STRING_LIMIT - newLength - 1); + + newPath[DEFAULT_STRING_LIMIT - 1] = '\0'; + + #ifdef WARNING + *logofs << "NXTransDialog: WARNING! Trying with path '" + << newPath << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Trying with path '" << newPath + << "'.\n"; + + // + // Solaris doesn't seem to have + // function setenv(). + // + + #ifdef __sun + + char newEnv[DEFAULT_STRING_LIMIT + 5]; + + sprintf(newEnv,"PATH=%s", newPath); + + putenv(newEnv); + + #else + + setenv("PATH", newPath, 1); + + #endif + + } + } + + // + // Hopefully useless. + // + + exit(0); +} + +// +// Start a nxclient process in dialog mode. +// + +int NXTransClient(const char* display) +{ + // + // Be sure log file is valid. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + int pid; + + #ifdef TEST + *logofs << "NXTransClient: Going to fork with NX pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + pid = Fork(); + + if (pid != 0) + { + if (pid < 0) + { + #ifdef TEST + *logofs << "NXTransClient: WARNING! Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + } + #ifdef TEST + else + { + *logofs << "NXTransClient: Created NX client process " + << "with pid '" << pid << "'.\n" + << logofs_flush; + } + #endif + + return pid; + } + + #ifdef TEST + *logofs << "NXTransClient: Executing child with pid '" + << getpid() << "' and parent '" << getppid() + << "'.\n" << logofs_flush; + #endif + + SystemCleanup("NXTransClient"); + + // + // Copy the client command before + // freeing up the control class. + // + + char command[DEFAULT_STRING_LIMIT]; + + if (control != NULL) + { + strcpy(command, control -> ClientPath); + } + else + { + char *path = GetClientPath(); + + strcpy(command, path); + + delete [] path; + } + + // + // Get rid of unused resources. + // + + MemoryCleanup("NXTransClient"); + + #ifdef TEST + *logofs << "NXTransClient: Running external NX client with display '" + << display << "'.\n" << logofs_flush; + #endif + + // + // Provide the display in the environment. + // + + char newDisplay[DISPLAY_LENGTH_LIMIT]; + + #ifdef __sun + + snprintf(newDisplay, DISPLAY_LENGTH_LIMIT - 1, "DISPLAY=%s", display); + + newDisplay[DISPLAY_LENGTH_LIMIT - 1] = '\0'; + + putenv(newDisplay); + + #else + + strncpy(newDisplay, display, DISPLAY_LENGTH_LIMIT - 1); + + newDisplay[DISPLAY_LENGTH_LIMIT - 1] = '\0'; + + setenv("DISPLAY", newDisplay, 1); + + #endif + + UnsetEnv("LD_LIBRARY_PATH"); + + for (int i = 0; i < 2; i++) + { + execlp(command, command, NULL); + + #ifdef WARNING + *logofs << "NXTransClient: WARNING! Couldn't start '" + << command << "'. Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Couldn't start '" << command + << "'. Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + // + // Retry by looking for the default name + // in the default NX path. + // + + if (i == 0) + { + + strcpy(command, "nxclient"); + + char newPath[DEFAULT_STRING_LIMIT]; + + strcpy(newPath, "/usr/NX/bin:/opt/NX/bin:/usr/local/NX/bin:"); + + #ifdef __APPLE__ + + strcat(newPath, "/Applications/NX Client for OSX.app/Contents/MacOS:"); + + #endif + + #ifdef __CYGWIN32__ + + strcat(newPath, ".:"); + + #endif + + int newLength = strlen(newPath); + + char *oldPath = getenv("PATH"); + + strncpy(newPath + newLength, oldPath, DEFAULT_STRING_LIMIT - newLength - 1); + + newPath[DEFAULT_STRING_LIMIT - 1] = '\0'; + + #ifdef WARNING + *logofs << "NXTransClient: WARNING! Trying with path '" + << newPath << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Trying with path '" << newPath + << "'.\n"; + + // + // Solaris doesn't seem to have + // function setenv(). + // + + #ifdef __sun + + char newEnv[DEFAULT_STRING_LIMIT + 5]; + + sprintf(newEnv,"PATH=%s", newPath); + + putenv(newEnv); + + #else + + setenv("PATH", newPath, 1); + + #endif + } + + } + // + // Hopefully useless. + // + + exit(0); +} + +// +// Wait until the timeout is expired. +// The timeout is expressed in milli- +// seconds. +// + +int NXTransWatchdog(int timeout) +{ + // + // Be sure log file is valid. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + int pid; + + #ifdef TEST + *logofs << "NXTransWatchdog: Going to fork with NX pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + pid = Fork(); + + if (pid != 0) + { + if (pid < 0) + { + #ifdef TEST + *logofs << "NXTransWatchdog: WARNING! Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + } + #ifdef TEST + else + { + *logofs << "NXTransWatchdog: Created NX watchdog process " + << "with pid '" << pid << "'.\n" << logofs_flush; + } + #endif + + return pid; + } + + int parent = getppid(); + + #ifdef TEST + *logofs << "NXTransWatchdog: Executing child with pid '" + << getpid() << "' and parent '" << parent + << "'.\n" << logofs_flush; + #endif + + SystemCleanup("NXTransWatchdog"); + + // + // Get rid of unused resources. + // + + MemoryCleanup("NXTransWatchdog"); + + // + // Run until the timeout is expired + // or forever, if no timeout is + // provided. + // + + T_timestamp startTs = getTimestamp(); + + int diffTs = 0; + + for (;;) + { + // + // Complain if the parent is dead. + // + + if (CheckParent("NXTransWatchdog", "watchdog", parent) == 0) + { + #ifdef TEST + *logofs << "NXTransWatchdog: Exiting with no parent " + << "running.\n" << logofs_flush; + #endif + + HandleCleanup(); + } + + if (timeout > 0) + { + if (diffTs >= timeout) + { + #ifdef TEST + *logofs << "NXTransWatchdog: Timeout of " << timeout + << " Ms raised in watchdog.\n" << logofs_flush; + #endif + + // + // We will just exit. Our parent should be + // monitoring us and detect that the process + // is gone. + // + + HandleCleanup(); + } + } + + if (timeout > 0) + { + #ifdef TEST + *logofs << "NXTransWatchdog: Waiting for the timeout " + << "with " << timeout - diffTs << " Ms to run.\n" + << logofs_flush; + #endif + + usleep((timeout - diffTs) * 1000); + + diffTs = diffTimestamp(startTs, getNewTimestamp()); + } + else + { + #ifdef TEST + *logofs << "NXTransWatchdog: Waiting for a signal.\n" + << logofs_flush; + #endif + + sleep(10); + } + } + + // + // Hopefully useless. + // + + exit(0); +} + +int NXTransKeeperHandler(int signal) +{ + if (keeper != NULL) + { + switch (signal) + { + case SIGTERM: + case SIGINT: + case SIGHUP: + { + #ifdef TEST + *logofs << "NXTransKeeperHandler: Requesting giveup " + << "because of signal " << signal << " ,'" + << DumpSignal(signal) << "'.\n" + << logofs_flush; + #endif + + keeper -> setSignal(signal); + + return 0; + } + } + } + + return 1; +} + +void NXTransKeeperCheck() +{ + if (CheckParent("NXTransKeeper", "keeper", + keeper -> getParent()) == 0 || keeper -> getSignal() != 0) + { + #ifdef TEST + *logofs << "NXTransKeeperCheck: Exiting because of signal " + << "or no parent running.\n" << logofs_flush; + #endif + + HandleCleanup(); + } +} + +int NXTransKeeper(int caches, int images, const char *root) +{ + // + // Be sure log file is valid. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + if (caches == 0 && images == 0) + { + #ifdef TEST + *logofs << "NXTransKeeper: No NX cache house-keeping needed.\n" + << logofs_flush; + #endif + + return 0; + } + + int pid; + + #ifdef TEST + *logofs << "NXTransKeeper: Going to fork with NX pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + pid = Fork(); + + if (pid != 0) + { + if (pid < 0) + { + #ifdef TEST + *logofs << "NXTransKeeper: WARNING! Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + } + #ifdef TEST + else + { + *logofs << "NXTransKeeper: Created NX keeper process " + << "with pid '" << pid << "'.\n" + << logofs_flush; + } + #endif + + return pid; + } + + int parent = getppid(); + + #ifdef TEST + *logofs << "NXTransKeeper: Executing child with pid '" + << getpid() << "' and parent '" << parent + << "'.\n" << logofs_flush; + #endif + + SystemCleanup("NXTransKeeper"); + + #ifdef TEST + *logofs << "NXTransKeeper: Going to run with caches " << caches + << " images " << images << " and root " << root + << " at " << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + // + // Create the house-keeper class. + // + + int timeout = control -> KeeperTimeout; + + keeper = new Keeper(caches, images, root, 100, parent); + + handler = NXTransKeeperHandler; + + if (keeper == NULL) + { + #ifdef PANIC + *logofs << "NXTransKeeper: PANIC! Failed to create the keeper object.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to create the keeper object.\n"; + + HandleCleanup(); + } + + // + // Get rid of unused resources. Root path + // must be copied in keeper's constructor + // before control is deleted. + // + + MemoryCleanup("NXTransKeeper"); + + // + // Decrease the priority of this process. + // + // The following applies to Cygwin: "Cygwin processes can be + // set to IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, HIGH_- + // PRIORITY_CLASS, or REALTIME_PRIORITY_CLASS with the nice + // call. If you pass a positive number to nice(), then the + // priority level will decrease by one (within the above list + // of priorities). A negative number would make it increase + // by one. It is not possible to change it by more than one + // at a time without making repeated calls". + // + + if (nice(5) < 0 && errno != 0) + { + #ifdef WARNING + *logofs << "NXTransKeeper: WARNING! Failed to renice process to +5. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Failed to renice process to +5. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + } + + // + // Delay a bit the first run to give + // a boost to the session startup. + // + + #ifdef TEST + *logofs << "NXTransKeeper: Going to sleep for " + << timeout / 20 << " Ms.\n" << logofs_flush; + #endif + + usleep(timeout / 20 * 1000); + + NXTransKeeperCheck(); + + // + // The house keeping of the persistent + // caches is performed only once. + // + + if (caches != 0) + { + #ifdef TEST + *logofs << "NXTransKeeper: Going to cleanup the NX cache " + << "directories at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + keeper -> cleanupCaches(); + + #ifdef TEST + *logofs << "NXTransKeeper: Completed cleanup of NX cache " + << "directories at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + } + #ifdef TEST + else + { + *logofs << "NXTransKeeper: Nothing to do for the " + << "persistent caches.\n" << logofs_flush; + } + #endif + + if (images == 0) + { + #ifdef TEST + *logofs << "NXTransKeeper: Nothing to do for the " + << "persistent images.\n" << logofs_flush; + #endif + + HandleCleanup(); + } + + // + // Take care of the persisten image cache. + // Run a number of iterations and then exit, + // so we can keep the memory consumption + // low. The parent will check our exit code + // and will eventually restart us. + // + + for (int iterations = 0; iterations < 100; iterations++) + { + #ifdef TEST + *logofs << "NXTransKeeper: Running iteration " << iterations + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + NXTransKeeperCheck(); + + #ifdef TEST + *logofs << "NXTransKeeper: Going to cleanup the NX images " + << "directories at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + if (keeper -> cleanupImages() < 0) + { + #ifdef TEST + *logofs << "NXTransKeeper: Exiting because of error " + << "handling the image cache.\n" << logofs_flush; + #endif + + HandleCleanup(); + } + + #ifdef TEST + *logofs << "NXTransKeeper: Completed cleanup of NX images " + << "directories at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + NXTransKeeperCheck(); + + #ifdef TEST + *logofs << "NXTransKeeper: Going to sleep for " << timeout + << " Ms.\n" << logofs_flush; + #endif + + usleep(timeout * 1000); + } + + HandleCleanup(2); + + // + // Hopefully useless. + // + + exit(0); +} + +void SystemCleanup(const char *name) +{ + #ifdef TEST + *logofs << name << ": Performing system cleanup in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + // + // Reinstall signals that might + // have been restored by agents. + // + + InstallSignals(); +} + +void MemoryCleanup(const char *name) +{ + #ifdef TEST + *logofs << name << ": Performing memory cleanup in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + DisableSignals(); + + // + // Prevent deletion of unix socket + // and lock file. + // + + useUnixSocket = 0; + + // + // Don't let cleanup kill other + // children. + // + + lastDialog = 0; + lastWatchdog = 0; + lastKeeper = 0; + + CleanupListeners(); + + CleanupSockets(); + + CleanupGlobal(); + + EnableSignals(); +} + +int UnsetEnv(const char *name) +{ + int result; + + #ifdef __sun + + char **pEnv = environ; + + int nameLen = strlen(name) + 1; + + char *varName = new char[nameLen + 1]; + + strcpy(varName, name); + + strcat(varName, "="); + + pEnv = environ; + + while (*pEnv != NULL) + { + if (!strncmp(varName, *pEnv, nameLen)) + { + break; + } + + *pEnv++; + } + + while (*pEnv != NULL) + { + *pEnv = *(pEnv + 1); + + pEnv++; + } + + result = 0; + + #else + + #ifdef __APPLE__ + + unsetenv(name); + result = 0; + + #else + + result = unsetenv(name); + + #endif + + #endif + + return result; +} diff --git a/nxcomp/src/ClearArea.cpp b/nxcomp/src/ClearArea.cpp new file mode 100644 index 000000000..0cb152d95 --- /dev/null +++ b/nxcomp/src/ClearArea.cpp @@ -0,0 +1,125 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ClearArea.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int ClearAreaStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ClearAreaMessage *clearArea = (ClearAreaMessage *) message; + + // + // Here is the fingerprint. + // + + clearArea -> exposures = *(buffer + 1); + + clearArea -> window = GetULONG(buffer + 4, bigEndian); + + clearArea -> x = GetUINT(buffer + 8, bigEndian); + clearArea -> y = GetUINT(buffer + 10, bigEndian); + clearArea -> width = GetUINT(buffer + 12, bigEndian); + clearArea -> height = GetUINT(buffer + 14, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ClearAreaStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ClearAreaMessage *clearArea = (ClearAreaMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = clearArea -> exposures; + + PutULONG(clearArea -> window, buffer + 4, bigEndian); + + PutUINT(clearArea -> x, buffer + 8, bigEndian); + PutUINT(clearArea -> y, buffer + 10, bigEndian); + PutUINT(clearArea -> width, buffer + 12, bigEndian); + PutUINT(clearArea -> height, buffer + 14, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void ClearAreaStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + ClearAreaMessage *clearArea = (ClearAreaMessage *) message; + + *logofs << name() << ": Identity exposures " << (unsigned int) clearArea -> exposures + << ", window " << clearArea -> window << ", x " << clearArea -> x + << ", y " << clearArea -> y << ", width " << clearArea -> width + << ", height " << clearArea -> height << ", size " << clearArea -> size_ + << ".\n"; + + #endif +} + +void ClearAreaStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 4, 4); + md5_append(md5_state_, buffer + 8, 2); + md5_append(md5_state_, buffer + 10, 2); + md5_append(md5_state_, buffer + 12, 2); + md5_append(md5_state_, buffer + 14, 2); +} diff --git a/nxcomp/src/ClearArea.h b/nxcomp/src/ClearArea.h new file mode 100644 index 000000000..8067edffd --- /dev/null +++ b/nxcomp/src/ClearArea.h @@ -0,0 +1,182 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ClearArea_H +#define ClearArea_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define CLEARAREA_ENABLE_CACHE 1 +#define CLEARAREA_ENABLE_DATA 0 +#define CLEARAREA_ENABLE_SPLIT 0 +#define CLEARAREA_ENABLE_COMPRESS 0 + +#define CLEARAREA_DATA_LIMIT 0 +#define CLEARAREA_DATA_OFFSET 16 + +#define CLEARAREA_CACHE_SLOTS 3000 +#define CLEARAREA_CACHE_THRESHOLD 5 +#define CLEARAREA_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class ClearAreaMessage : public Message +{ + friend class ClearAreaStore; + + public: + + ClearAreaMessage() + { + } + + ~ClearAreaMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char exposures; + unsigned int window; + unsigned short x; + unsigned short y; + unsigned short width; + unsigned short height; +}; + +class ClearAreaStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + ClearAreaStore() : MessageStore() + { + enableCache = CLEARAREA_ENABLE_CACHE; + enableData = CLEARAREA_ENABLE_DATA; + enableSplit = CLEARAREA_ENABLE_SPLIT; + enableCompress = CLEARAREA_ENABLE_COMPRESS; + + dataLimit = CLEARAREA_DATA_LIMIT; + dataOffset = CLEARAREA_DATA_OFFSET; + + cacheSlots = CLEARAREA_CACHE_SLOTS; + cacheThreshold = CLEARAREA_CACHE_THRESHOLD; + cacheLowerThreshold = CLEARAREA_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~ClearAreaStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "ClearArea"; + } + + virtual unsigned char opcode() const + { + return X_ClearArea; + } + + virtual unsigned int storage() const + { + return sizeof(ClearAreaMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new ClearAreaMessage(); + } + + virtual Message *create(const Message &message) const + { + return new ClearAreaMessage((const ClearAreaMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (ClearAreaMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* ClearArea_H */ diff --git a/nxcomp/src/ClientCache.cpp b/nxcomp/src/ClientCache.cpp new file mode 100644 index 000000000..47bb7db1d --- /dev/null +++ b/nxcomp/src/ClientCache.cpp @@ -0,0 +1,392 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ClientCache.h" + +ClientCache::ClientCache() : + + freeGCCache(16), freeDrawableCache(16), freeWindowCache(16), + + cursorCache(16), colormapCache(16), visualCache(16), lastFont(0), + + changePropertyPropertyCache(16), changePropertyTypeCache(16), + changePropertyData32Cache(16), + + configureWindowBitmaskCache(4), + + convertSelectionRequestorCache(16), + convertSelectionLastTimestamp(0), + + copyPlaneBitPlaneCache(8), + + createGCBitmaskCache(8), + + createPixmapIdCache(16), createPixmapLastId(0), + createPixmapXCache(8), createPixmapYCache(8), + + createWindowBitmaskCache(8), + + fillPolyNumPointsCache(8), fillPolyIndex(0), + + getSelectionOwnerSelectionCache(8), + + grabButtonEventMaskCache(8), grabButtonConfineCache(8), + grabButtonModifierCache(8), + + grabKeyboardLastTimestamp(0), + + imageTextLengthCache(8), + imageTextLastX(0), imageTextLastY(0), + imageTextCacheX(8), imageTextCacheY(8), + + polySegmentCacheX(8), polySegmentCacheY(8), polySegmentCacheIndex(0), + + polyTextLastX(0), polyTextLastY(0), polyTextCacheX(8), + polyTextCacheY(8), polyTextFontCache(8), + + putImageWidthCache(8), putImageHeightCache(8), putImageLastX(0), + putImageLastY(0), putImageXCache(8), putImageYCache(8), + + getImagePlaneMaskCache(8), + + queryColorsLastPixel(0), + + setClipRectanglesXCache(8), setClipRectanglesYCache(8), + + setDashesLengthCache(8), setDashesOffsetCache(8), + + setSelectionOwnerCache(8), setSelectionOwnerTimestampCache(8), + + translateCoordsSrcCache(8), translateCoordsDstCache(8), + translateCoordsXCache(8), translateCoordsYCache(8), + + sendEventMaskCache(16), sendEventLastSequence(0), + sendEventIntDataCache(16), + + putPackedImageSrcLengthCache(16), putPackedImageDstLengthCache(16), + + // + // RenderExtension requests. + // + + renderFreePictureCache(16), + + renderGlyphSetCache(16), + renderFreeGlyphSetCache(16), + + renderIdCache(8), + + renderLengthCache(16), renderFormatCache(16), + renderValueMaskCache(8), renderNumGlyphsCache(8), + + renderXCache(16), renderYCache(16), + renderLastX(0), renderLastY(0), + + renderWidthCache(16), renderHeightCache(16), + + renderLastId(0), + + renderGlyphXCache(16), renderGlyphYCache(16), + renderGlyphX(0), renderGlyphY(0), + + renderLastCompositeGlyphsData(0), + + setCacheParametersCache(8), + + lastIdCache(16), lastId(0) + +{ + unsigned int i; + + for (i = 0; i < 3; i++) + { + allocColorRGBCache[i] = new IntCache(8); + + convertSelectionAtomCache[i] = new IntCache(8); + } + + for (i = 0; i < 4; i++) + { + clearAreaGeomCache[i] = new IntCache(8); + } + + for (i = 0; i < 7; i++) + { + configureWindowAttrCache[i] = new IntCache(8); + } + + for (i = 0; i < 6; i++) + { + copyAreaGeomCache[i] = new IntCache(8); + copyPlaneGeomCache[i] = new IntCache(8); + } + + for (i = 0; i < 23; i++) + { + if (CREATEGC_FIELD_WIDTH[i] > 16) + { + createGCAttrCache[i] = new IntCache(16); + } + else + { + createGCAttrCache[i] = new IntCache(CREATEGC_FIELD_WIDTH[i]); + } + } + + for (i = 0; i < 6; i++) + { + createWindowGeomCache[i] = new IntCache(8); + } + + for (i = 0; i < 15; i++) + { + createWindowAttrCache[i] = new IntCache(8); + } + + for (i = 0; i < 10; i++) + { + fillPolyXRelCache[i] = new IntCache(8); + fillPolyXAbsCache[i] = new IntCache(8); + fillPolyYRelCache[i] = new IntCache(8); + fillPolyYAbsCache[i] = new IntCache(8); + } + + for (i = 0; i < 8; i++) + { + fillPolyRecentX[i] = 0; + fillPolyRecentY[i] = 0; + } + + for (i = 0; i < 4; i++) + { + polyFillRectangleCacheX[i] = new IntCache(8); + polyFillRectangleCacheY[i] = new IntCache(8); + polyFillRectangleCacheWidth[i] = new IntCache(8); + polyFillRectangleCacheHeight[i] = new IntCache(8); + } + + for (i = 0; i < 2; i++) + { + polyLineCacheX[i] = new IntCache(8); + polyLineCacheY[i] = new IntCache(8); + } + + for (i = 0; i < 2; i++) + { + polyPointCacheX[i] = new IntCache(8); + polyPointCacheY[i] = new IntCache(8); + } + + for (i = 0; i < 4; i++) + { + polyRectangleGeomCache[i] = new IntCache(8); + } + + for (i = 0; i < 2; i++) + { + polySegmentLastX[i] = 0; + polySegmentLastY[i] = 0; + } + + for (i = 0; i < 4; i++) + { + setClipRectanglesGeomCache[i] = new IntCache(8); + } + + for (i = 0; i < 2; i++) + { + polyFillArcCacheX[i] = new IntCache(8); + polyFillArcCacheY[i] = new IntCache(8); + polyFillArcCacheWidth[i] = new IntCache(8); + polyFillArcCacheHeight[i] = new IntCache(8); + polyFillArcCacheAngle1[i] = new IntCache(8); + polyFillArcCacheAngle2[i] = new IntCache(8); + } + + for (i = 0; i < 2; i++) + { + polyArcCacheX[i] = new IntCache(8); + polyArcCacheY[i] = new IntCache(8); + polyArcCacheWidth[i] = new IntCache(8); + polyArcCacheHeight[i] = new IntCache(8); + polyArcCacheAngle1[i] = new IntCache(8); + polyArcCacheAngle2[i] = new IntCache(8); + } + + for (i = 0; i < 8; i++) + { + shapeDataCache[i] = new IntCache(8); + } + + for (i = 0; i < 8; i++) + { + genericRequestDataCache[i] = new IntCache(8); + } + + for (i = 0; i < 16; i++) + { + renderDataCache[i] = new IntCache(16); + } + + for (i = 0; i < 16; i++) + { + renderCompositeGlyphsDataCache[i] = new IntCache(16); + } + + for (i = 0; i < 3; i++) + { + renderCompositeDataCache[i] = new IntCache(16); + } +} + + +ClientCache::~ClientCache() +{ + unsigned int i; + + for (i = 0; i < 3; i++) + { + delete allocColorRGBCache[i]; + delete convertSelectionAtomCache[i]; + } + + for (i = 0; i < 4; i++) + { + delete clearAreaGeomCache[i]; + } + + for (i = 0; i < 7; i++) + { + delete configureWindowAttrCache[i]; + } + + for (i = 0; i < 6; i++) + { + delete copyAreaGeomCache[i]; + delete copyPlaneGeomCache[i]; + } + + for (i = 0; i < 23; i++) + { + delete createGCAttrCache[i]; + } + + for (i = 0; i < 6; i++) + { + delete createWindowGeomCache[i]; + } + + for (i = 0; i < 15; i++) + { + delete createWindowAttrCache[i]; + } + + for (i = 0; i < 10; i++) + { + delete fillPolyXRelCache[i]; + delete fillPolyXAbsCache[i]; + delete fillPolyYRelCache[i]; + delete fillPolyYAbsCache[i]; + } + + for (i = 0; i < 4; i++) + { + delete polyFillRectangleCacheX[i]; + delete polyFillRectangleCacheY[i]; + delete polyFillRectangleCacheWidth[i]; + delete polyFillRectangleCacheHeight[i]; + } + + for (i = 0; i < 2; i++) + { + delete polyLineCacheX[i]; + delete polyLineCacheY[i]; + } + + for (i = 0; i < 2; i++) + { + delete polyPointCacheX[i]; + delete polyPointCacheY[i]; + } + + for (i = 0; i < 4; i++) + { + delete polyRectangleGeomCache[i]; + } + + for (i = 0; i < 4; i++) + { + delete setClipRectanglesGeomCache[i]; + } + + for (i = 0; i < 2; i++) + { + delete polyFillArcCacheX[i]; + delete polyFillArcCacheY[i]; + delete polyFillArcCacheWidth[i]; + delete polyFillArcCacheHeight[i]; + delete polyFillArcCacheAngle1[i]; + delete polyFillArcCacheAngle2[i]; + } + + for (i = 0; i < 2; i++) + { + delete polyArcCacheX[i]; + delete polyArcCacheY[i]; + delete polyArcCacheWidth[i]; + delete polyArcCacheHeight[i]; + delete polyArcCacheAngle1[i]; + delete polyArcCacheAngle2[i]; + } + + for (i = 0; i < 8; i++) + { + delete shapeDataCache[i]; + } + + for (i = 0; i < 8; i++) + { + delete genericRequestDataCache[i]; + } + + for (i = 0; i < 16; i++) + { + delete renderDataCache[i]; + } + + for (i = 0; i < 16; i++) + { + delete renderCompositeGlyphsDataCache[i]; + } + + for (i = 0; i < 3; i++) + { + delete renderCompositeDataCache[i]; + } +} diff --git a/nxcomp/src/ClientCache.h b/nxcomp/src/ClientCache.h new file mode 100644 index 000000000..ed3361097 --- /dev/null +++ b/nxcomp/src/ClientCache.h @@ -0,0 +1,417 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ClientCache_H +#define ClientCache_H + +#include "Misc.h" + +#include "IntCache.h" +#include "CharCache.h" +#include "OpcodeCache.h" +#include "XidCache.h" +#include "FreeCache.h" + +#include "ChannelCache.h" + +class ClientCache : public ChannelCache +{ + public: + + ClientCache(); + + ~ClientCache(); + + // + // Opcode prediction caches. + // + + OpcodeCache opcodeCache; + + // + // GC and drawables caches. + // + + XidCache gcCache; + FreeCache freeGCCache; + + XidCache drawableCache; + FreeCache freeDrawableCache; + + XidCache windowCache; + FreeCache freeWindowCache; + + // + // General-purpose caches. + // + + IntCache cursorCache; + IntCache colormapCache; + IntCache visualCache; + CharCache depthCache; + CharCache resourceCache; + CharCache methodCache; + + unsigned int lastFont; + + // + // AllocColor request. + // + + IntCache *allocColorRGBCache[3]; + + // + // ChangeProperty request. + // + + CharCache changePropertyFormatCache; + IntCache changePropertyPropertyCache; + IntCache changePropertyTypeCache; + IntCache changePropertyData32Cache; + + // + // ClearArea request. + // + + IntCache *clearAreaGeomCache[4]; + + // + // ConfigureWindow request. + // + + IntCache configureWindowBitmaskCache; + IntCache *configureWindowAttrCache[7]; + + // + // ConvertSelection request. + // + + IntCache convertSelectionRequestorCache; + IntCache* convertSelectionAtomCache[3]; + unsigned int convertSelectionLastTimestamp; + + // + // CopyArea request. + // + + IntCache *copyAreaGeomCache[6]; + + // + // CopyPlane request. + // + + IntCache *copyPlaneGeomCache[6]; + IntCache copyPlaneBitPlaneCache; + + // + // CreateGC request. + // + + IntCache createGCBitmaskCache; + IntCache *createGCAttrCache[23]; + + // + // CreatePixmap request. + // + + IntCache createPixmapIdCache; + unsigned int createPixmapLastId; + IntCache createPixmapXCache; + IntCache createPixmapYCache; + + // + // CreateWindow request. + // + + IntCache *createWindowGeomCache[6]; + IntCache createWindowBitmaskCache; + IntCache *createWindowAttrCache[15]; + + // + // FillPoly request. + // + + IntCache fillPolyNumPointsCache; + IntCache *fillPolyXRelCache[10]; + IntCache *fillPolyXAbsCache[10]; + IntCache *fillPolyYRelCache[10]; + IntCache *fillPolyYAbsCache[10]; + unsigned int fillPolyRecentX[8]; + unsigned int fillPolyRecentY[8]; + unsigned int fillPolyIndex; + + // + // GetSelectionOwner request. + // + + IntCache getSelectionOwnerSelectionCache; + + // + // GrabButton request (also used for GrabPointer). + // + + IntCache grabButtonEventMaskCache; + IntCache grabButtonConfineCache; + CharCache grabButtonButtonCache; + IntCache grabButtonModifierCache; + + // + // GrabKeyboard request. + // + + unsigned int grabKeyboardLastTimestamp; + + // + // ImageText8/16 request. + // + + IntCache imageTextLengthCache; + unsigned int imageTextLastX; + unsigned int imageTextLastY; + IntCache imageTextCacheX; + IntCache imageTextCacheY; + + // + // PolyFillRectangle request. + // + + IntCache *polyFillRectangleCacheX[4]; + IntCache *polyFillRectangleCacheY[4]; + IntCache *polyFillRectangleCacheWidth[4]; + IntCache *polyFillRectangleCacheHeight[4]; + + // + // PolyLine request. + // + + IntCache *polyLineCacheX[2]; + IntCache *polyLineCacheY[2]; + + // + // PolyPoint request. + // + + IntCache *polyPointCacheX[2]; + IntCache *polyPointCacheY[2]; + + // + // PolyRectangle request. + // + + IntCache *polyRectangleGeomCache[4]; + + // + // PolySegment request. + // + + IntCache polySegmentCacheX; + IntCache polySegmentCacheY; + unsigned int polySegmentLastX[2]; + unsigned int polySegmentLastY[2]; + unsigned int polySegmentCacheIndex; + + // + // PolyText8/16 request. + // + + unsigned int polyTextLastX; + unsigned int polyTextLastY; + IntCache polyTextCacheX; + IntCache polyTextCacheY; + IntCache polyTextFontCache; + CharCache polyTextDeltaCache; + + // + // PutImage request. + // + + IntCache putImageWidthCache; + IntCache putImageHeightCache; + unsigned int putImageLastX; + unsigned int putImageLastY; + IntCache putImageXCache; + IntCache putImageYCache; + CharCache putImageLeftPadCache; + + // + // GetImage request. + // + + IntCache getImagePlaneMaskCache; + + // + // QueryColors request. + // + + unsigned int queryColorsLastPixel; + + // + // SetClipRectangles request. + // + + IntCache setClipRectanglesXCache; + IntCache setClipRectanglesYCache; + IntCache *setClipRectanglesGeomCache[4]; + + // + // SetDashes request. + // + + IntCache setDashesLengthCache; + IntCache setDashesOffsetCache; + CharCache setDashesDashCache_[2]; + + // + // SetSelectionOwner request. + // + + IntCache setSelectionOwnerCache; + IntCache setSelectionOwnerTimestampCache; + + // + // TranslateCoords request. + // + + IntCache translateCoordsSrcCache; + IntCache translateCoordsDstCache; + IntCache translateCoordsXCache; + IntCache translateCoordsYCache; + + // + // SendEvent request. + // + + IntCache sendEventMaskCache; + CharCache sendEventCodeCache; + CharCache sendEventByteDataCache; + unsigned int sendEventLastSequence; + IntCache sendEventIntDataCache; + CharCache sendEventEventCache; + + // + // PolyFillArc request. + // + + IntCache *polyFillArcCacheX[2]; + IntCache *polyFillArcCacheY[2]; + IntCache *polyFillArcCacheWidth[2]; + IntCache *polyFillArcCacheHeight[2]; + IntCache *polyFillArcCacheAngle1[2]; + IntCache *polyFillArcCacheAngle2[2]; + + // + // PolyArc request. + // + + IntCache *polyArcCacheX[2]; + IntCache *polyArcCacheY[2]; + IntCache *polyArcCacheWidth[2]; + IntCache *polyArcCacheHeight[2]; + IntCache *polyArcCacheAngle1[2]; + IntCache *polyArcCacheAngle2[2]; + + // + // PutPackedImage request. + // + + IntCache putPackedImageSrcLengthCache; + IntCache putPackedImageDstLengthCache; + + // + // Shape extension requests. + // + + CharCache shapeOpcodeCache; + IntCache *shapeDataCache[8]; + + // + // Generic requests. + // + + CharCache genericRequestOpcodeCache; + IntCache *genericRequestDataCache[8]; + + // + // Render extension requests. + // + + OpcodeCache renderOpcodeCache; + + CharCache renderOpCache; + + XidCache renderSrcPictureCache; + XidCache renderMaskPictureCache; + XidCache renderDstPictureCache; + FreeCache renderFreePictureCache; + + IntCache renderGlyphSetCache; + FreeCache renderFreeGlyphSetCache; + + IntCache renderIdCache; + IntCache renderLengthCache; + IntCache renderFormatCache; + IntCache renderValueMaskCache; + IntCache renderNumGlyphsCache; + + IntCache renderXCache; + IntCache renderYCache; + + unsigned int renderLastX; + unsigned int renderLastY; + + IntCache renderWidthCache; + IntCache renderHeightCache; + + unsigned int renderLastId; + + IntCache *renderDataCache[16]; + + IntCache renderGlyphXCache; + IntCache renderGlyphYCache; + + unsigned int renderGlyphX; + unsigned int renderGlyphY; + + IntCache *renderCompositeGlyphsDataCache[16]; + unsigned int renderLastCompositeGlyphsData; + + IntCache *renderCompositeDataCache[3]; + + // + // SetCacheParameters request. + // + + IntCache setCacheParametersCache; + + // + // Encode new XID values based + // on the last value encoded. + // + + IntCache lastIdCache; + unsigned int lastId; +}; + +#endif /* ClientCache_H */ diff --git a/nxcomp/src/ClientChannel.cpp b/nxcomp/src/ClientChannel.cpp new file mode 100644 index 000000000..2a182e49f --- /dev/null +++ b/nxcomp/src/ClientChannel.cpp @@ -0,0 +1,7881 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "NXproto.h" +#include "NXrender.h" + +#include "ClientChannel.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "StaticCompressor.h" + +#include "Statistics.h" +#include "Proxy.h" + +#include "PutImage.h" +#include "PutPackedImage.h" + +extern Proxy *proxy; + +// +// Set the verbosity level. You also +// need to define OPCODES in Misc.cpp +// if you want literals instead of +// opcodes' numbers. +// + +#define PANIC +#define WARNING +#undef OPCODES +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Log the important tracepoints related +// to writing packets to the peer proxy. +// + +#undef FLUSH + +// +// Log the operations related to splits. +// + +#undef SPLIT + +// +// Define this to trace the invocations +// of the agent's callbacks. +// + +#undef CALLBACK + +// +// By defining this, a simple procedure is activated at +// startup which just allocates and deallocates plenty +// of cache objects. This is used to help determine the +// current memory requirements. +// + +#undef MEMORY + +// +// Inspects target of common X operations. +// + +#undef TARGETS + +#ifdef TARGETS + +#include +#include + +typedef set < unsigned int, less > T_windows; +typedef set < unsigned int, less > T_pixmaps; +typedef map < unsigned int, unsigned int, less > T_gcontexts; + +T_windows windows; +T_pixmaps pixmaps; +T_gcontexts gcontexts; + +#endif + +// +// Define this to log when a channel +// is created or destroyed. +// + +#undef REFERENCES + +// +// Here are the static members. +// + +#ifdef REFERENCES + +int ClientChannel::references_ = 0; + +#endif + +ClientChannel::ClientChannel(Transport *transport, StaticCompressor *compressor) + + : Channel(transport, compressor), readBuffer_(transport_, this) +{ + // + // Sequence number of the next message + // being encoded or decoded. + // + + clientSequence_ = 0; + serverSequence_ = 0; + + // + // Current sequence known by NX agent. + // + + lastSequence_ = 0; + + // + // This is used to test the synchronous + // flush in the proxy. + // + + lastRequest_ = 0; + + // + // Store information about the images + // being streamed. + // + + splitState_.resource = nothing; + splitState_.pending = 0; + splitState_.commit = 0; + splitState_.mode = split_none; + + // + // Number of outstanding tainted replies. + // + + taintCounter_ = 0; + + #ifdef MEMORY + + *logofs << "ClientChannel: Created 1 ClientCache and 1 ServerCache. " + << "You have 30 seconds to check the allocated size.\n" + << logofs_flush; + + sleep(30); + + ClientCache *clientCacheTestArray[100]; + ServerCache *serverCacheTestArray[100]; + + for (int i = 0; i < 100; i++) + { + clientCacheTestArray[i] = new ClientCache(); + } + + *logofs << "ClientChannel: Created further 100 ClientCache. " + << "You have 30 seconds to check the allocated size.\n" + << logofs_flush; + + sleep(30); + + for (int i = 0; i < 100; i++) + { + serverCacheTestArray[i] = new ServerCache(); + } + + *logofs << "ClientChannel: Created further 100 ServerCache. " + << "You have 30 seconds to check the allocated size.\n" + << logofs_flush; + + sleep(30); + + for (int i = 0; i < 100; i++) + { + delete clientCacheTestArray[i]; + delete serverCacheTestArray[i]; + } + + *logofs << "ClientChannel: Deleted 100 ClientCache and 100 ServerCache. " + << "You have 30 seconds to check the allocated size.\n" + << logofs_flush; + + sleep(30); + + #endif + + #ifdef REFERENCES + *logofs << "ClientChannel: Created new object at " + << this << " for FD#" << fd_ << " out of " + << ++references_ << " allocated channels.\n" + << logofs_flush; + #endif +} + +ClientChannel::~ClientChannel() +{ + #ifdef REFERENCES + *logofs << "ClientChannel: Deleted object at " + << this << " for FD#" << fd_ << " out of " + << --references_ << " allocated channels.\n" + << logofs_flush; + #endif +} + +// +// Beginning of handleRead(). +// + +int ClientChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, + unsigned int length) +{ + #ifdef TEST + *logofs << "handleRead: Called for FD#" << fd_ + << " with " << encodeBuffer.getLength() + << " bytes already encoded.\n" + << logofs_flush; + #endif + + // + // Pointer to located message and + // its size in bytes. + // + + const unsigned char *inputMessage; + unsigned int inputLength; + + // + // Set when message is found in + // cache. + // + + int hit; + + // + // Check if we can borrow the buffer + // from the caller. + // + + if (message != NULL && length != 0) + { + readBuffer_.readMessage(message, length); + } + else + { + // + // Get the data from the transport. + // + + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: Trying to read from FD#" + << fd_ << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + int result = readBuffer_.readMessage(); + + #ifdef DEBUG + *logofs << "handleRead: Read result on FD#" << fd_ + << " is " << result << ".\n" + << logofs_flush; + #endif + + if (result < 0) + { + // + // Let the proxy close the channel. + // + + return -1; + } + else if (result == 0) + { + #if defined(TEST) || defined(INFO) + + *logofs << "handleRead: PANIC! No data read from FD#" + << fd_ << " while encoding messages.\n" + << logofs_flush; + + HandleCleanup(); + + #endif + + return 0; + } + } + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "handleRead: Encoding messages for FD#" << fd_ + << " with " << readBuffer_.getLength() << " bytes " + << "in the buffer.\n" << logofs_flush; + #endif + + // + // Extract any complete message which + // is available in the buffer. + // + + if (proxy -> handleAsyncSwitch(fd_) < 0) + { + return -1; + } + + while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) + { + hit = 0; + + if (firstRequest_) + { + // + // Need to add the length of the first + // request as it was not present in + // previous versions. + // + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeValue(inputLength, 8); + + for (unsigned int i = 0; i < inputLength; i++) + { + encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8); + } + + firstRequest_ = 0; + + #if defined(TEST) || defined(OPCODES) + + int bits = encodeBuffer.diffBits(); + + *logofs << "handleRead: Handled first request. " << inputLength + << " bytes in, " << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + #endif + + priority_++; + } + else + { + // + // First of all we get the opcode. + // + + unsigned char inputOpcode = *inputMessage; + + #if defined(TEST) || defined(INFO) + + // + // This is used to test the synchronous + // flush in the parent proxy. + // + + lastRequest_ = inputOpcode; + + #endif + + // + // Check if the request is supported by the + // remote. If not, only handle it locally and + // taint the opcode as a X_NoOperation. Also + // try to short-circuit some replies at this + // side. XSync requests, for example, weight + // for half of the total round-trips. + // + + if (handleTaintRequest(inputOpcode, inputMessage, + inputLength) < 0) + { + return -1; + } + + encodeBuffer.encodeOpcodeValue(inputOpcode, clientCache_ -> opcodeCache); + + // + // Update the current sequence. + // + + clientSequence_++; + clientSequence_ &= 0xffff; + + #ifdef DEBUG + *logofs << "handleRead: Last client sequence number for FD#" + << fd_ << " is " << clientSequence_ << ".\n" + << logofs_flush; + #endif + + // + // If differential compression is disabled + // then use the most simple encoding. + // + + if (control -> LocalDeltaCompression == 0) + { + int result = handleFastReadRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength); + if (result < 0) + { + return -1; + } + else if (result > 0) + { + continue; + } + } + + // + // Go to the message's specific encoding. + // + + switch (inputOpcode) + { + case X_AllocColor: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, + clientCache_ -> colormapCache); + const unsigned char *nextSrc = inputMessage + 8; + unsigned int colorData[3]; + for (unsigned int i = 0; i < 3; i++) + { + unsigned int value = GetUINT(nextSrc, bigEndian_); + encodeBuffer.encodeCachedValue(value, 16, + *(clientCache_ -> allocColorRGBCache[i]), 4); + colorData[i] = value; + nextSrc += 2; + } + + sequenceQueue_.push(clientSequence_, inputOpcode, + colorData[0], colorData[1], colorData[2]); + + priority_++; + } + break; + case X_ReparentWindow: + { + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, bigEndian_), + clientCache_ -> windowCache); + encodeBuffer.encodeValue(GetUINT(inputMessage + 12, bigEndian_), 16, 11); + encodeBuffer.encodeValue(GetUINT(inputMessage + 14, bigEndian_), 16, 11); + } + break; + case X_ChangeProperty: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ChangeProperty); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + unsigned char format = inputMessage[16]; + encodeBuffer.encodeCachedValue(format, 8, + clientCache_ -> changePropertyFormatCache); + unsigned int dataLength = GetULONG(inputMessage + 20, bigEndian_); + encodeBuffer.encodeValue(dataLength, 32, 6); + encodeBuffer.encodeValue(inputMessage[1], 2); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, + clientCache_ -> changePropertyPropertyCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 29, + clientCache_ -> changePropertyTypeCache, 9); + const unsigned char *nextSrc = inputMessage + 24; + if (format == 8) + { + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, dataLength); + } + else if (format == 32) + { + for (unsigned int i = 0; i < dataLength; i++) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 32, + clientCache_ -> changePropertyData32Cache); + nextSrc += 4; + } + } + else + { + for (unsigned int i = 0; i < dataLength; i++) + { + encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16); + nextSrc += 2; + } + } + } + break; + case X_SendEvent: + { + // + // TODO: This can be improved. In the worst + // cases, it appears to provide a poor 1.6:1 + // ratio. + // + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_SendEvent); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + unsigned int window = GetULONG(inputMessage + 4, bigEndian_); + + if (window == 0 || window == 1) + { + encodeBuffer.encodeBoolValue(1); + encodeBuffer.encodeBoolValue(window); + } + else + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeXidValue(window, clientCache_ -> windowCache); + } + + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 32, + clientCache_ -> sendEventMaskCache, 9); + encodeBuffer.encodeCachedValue(*(inputMessage + 12), 8, + clientCache_ -> sendEventCodeCache); + encodeBuffer.encodeCachedValue(*(inputMessage + 13), 8, + clientCache_ -> sendEventByteDataCache); + + unsigned int newSeq = GetUINT(inputMessage + 14, bigEndian_); + unsigned int diffSeq = newSeq - clientCache_ -> sendEventLastSequence; + clientCache_ -> sendEventLastSequence = newSeq; + encodeBuffer.encodeValue(diffSeq, 16, 4); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), 32, + clientCache_ -> sendEventIntDataCache); + + for (unsigned int i = 20; i < 44; i++) + { + encodeBuffer.encodeCachedValue((unsigned int) inputMessage[i], 8, + clientCache_ -> sendEventEventCache); + } + } + break; + case X_ChangeWindowAttributes: + { + encodeBuffer.encodeValue((inputLength - 12) >> 2, 4); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + unsigned int bitmask = GetULONG(inputMessage + 8, bigEndian_); + encodeBuffer.encodeCachedValue(bitmask, 15, + clientCache_ -> createWindowBitmaskCache); + const unsigned char *nextSrc = inputMessage + 12; + unsigned int mask = 0x1; + for (unsigned int j = 0; j < 15; j++) + { + if (bitmask & mask) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 32, + *clientCache_ -> createWindowAttrCache[j]); + nextSrc += 4; + } + mask <<= 1; + } + } + break; + case X_ClearArea: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_ClearArea target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_ClearArea target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_ClearArea target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ClearArea); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + const unsigned char *nextSrc = inputMessage + 8; + for (unsigned int i = 0; i < 4; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *clientCache_ -> clearAreaGeomCache[i], 8); + nextSrc += 2; + } + } + break; + case X_CloseFont: + { + unsigned int font = GetULONG(inputMessage + 4, bigEndian_); + encodeBuffer.encodeValue(font - clientCache_ -> lastFont, 29, 5); + clientCache_ -> lastFont = font; + } + break; + case X_ConfigureWindow: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ConfigureWindow); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + unsigned int bitmask = GetUINT(inputMessage + 8, bigEndian_); + encodeBuffer.encodeCachedValue(bitmask, 7, + clientCache_ -> configureWindowBitmaskCache); + unsigned int mask = 0x1; + const unsigned char *nextSrc = inputMessage + 12; + for (unsigned int i = 0; i < 7; i++) + { + if (bitmask & mask) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), + CONFIGUREWINDOW_FIELD_WIDTH[i], + *clientCache_ -> configureWindowAttrCache[i], 8); + nextSrc += 4; + } + mask <<= 1; + } + } + break; + case X_ConvertSelection: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, + clientCache_ -> convertSelectionRequestorCache, 9); + const unsigned char* nextSrc = inputMessage + 8; + for (unsigned int i = 0; i < 3; i++) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29, + *(clientCache_ -> convertSelectionAtomCache[i]), 9); + nextSrc += 4; + } + unsigned int timestamp = GetULONG(nextSrc, bigEndian_); + encodeBuffer.encodeValue(timestamp - + clientCache_ -> convertSelectionLastTimestamp, 32, 4); + clientCache_ -> convertSelectionLastTimestamp = timestamp; + } + break; + case X_CopyArea: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_CopyArea source id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_CopyArea source id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_CopyArea source id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + t_id = GetULONG(inputMessage + 8, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_CopyArea target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_CopyArea target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_CopyArea target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_CopyArea); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 12, + bigEndian_), clientCache_ -> gcCache); + const unsigned char *nextSrc = inputMessage + 16; + for (unsigned int i = 0; i < 6; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *clientCache_ -> copyAreaGeomCache[i], 8); + nextSrc += 2; + } + } + break; + case X_CopyGC: + { + #ifdef TARGETS + + unsigned int s_g_id = GetULONG(inputMessage + 4, bigEndian_); + unsigned int d_g_id = GetULONG(inputMessage + 8, bigEndian_); + + *logofs << "handleRead: X_CopyGC source gcontext id is " << s_g_id + << " destination gcontext id is " << d_g_id << ".\n" + << logofs_flush; + + #endif + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> gcCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, + bigEndian_), 23, clientCache_ -> createGCBitmaskCache); + } + break; + case X_CopyPlane: + { + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 12, + bigEndian_), clientCache_ -> gcCache); + const unsigned char *nextSrc = inputMessage + 16; + for (unsigned int i = 0; i < 6; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *clientCache_ -> copyPlaneGeomCache[i], 8); + nextSrc += 2; + } + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 28, bigEndian_), 32, + clientCache_ -> copyPlaneBitPlaneCache, 10); + } + break; + case X_CreateGC: + { + #ifdef TARGETS + + unsigned int g_id = GetULONG(inputMessage + 4, bigEndian_); + unsigned int t_id = GetULONG(inputMessage + 8, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_CreateGC id " << g_id + << " target id is pixmap " << t_id + << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_CreateGC id " << g_id + << " target id is window " << t_id + << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_CreateGC id " << g_id + << " target id is unrecognized.\n" + << logofs_flush; + } + + gcontexts.insert(T_gcontexts::value_type(g_id, t_id)); + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_CreateGC); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeNewXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> lastId, clientCache_ -> lastIdCache, + clientCache_ -> gcCache, + clientCache_ -> freeGCCache); + + const unsigned char *nextSrc = inputMessage + 8; + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> drawableCache); + nextSrc += 4; + unsigned int bitmask = GetULONG(nextSrc, bigEndian_); + nextSrc += 4; + encodeBuffer.encodeCachedValue(bitmask, 23, + clientCache_ -> createGCBitmaskCache); + unsigned int mask = 0x1; + for (unsigned int i = 0; i < 23; i++) + { + if (bitmask & mask) + { + unsigned int value = GetULONG(nextSrc, bigEndian_); + nextSrc += 4; + unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i]; + if (fieldWidth <= 4) + { + encodeBuffer.encodeValue(value, fieldWidth); + } + else + { + encodeBuffer.encodeCachedValue(value, fieldWidth, + *clientCache_ -> createGCAttrCache[i]); + } + } + mask <<= 1; + } + } + break; + case X_ChangeGC: + { + #ifdef TARGETS + + unsigned int g_id = GetULONG(inputMessage + 4, bigEndian_); + + T_gcontexts::iterator i = gcontexts.find(g_id); + + if (i != gcontexts.end()) + { + unsigned int t_id = i -> second; + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_ChangeGC gcontext id is " << g_id + << " target id is pixmap " << t_id << ".\n" + << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_ChangeGC gcontext id is " << g_id + << " target id is window " << t_id << ".\n" + << logofs_flush; + } + else + { + *logofs << "handleRead: X_ChangeGC gcontext is " << g_id + << " target id is unrecognized.\n" + << logofs_flush; + } + } + else + { + *logofs << "handleRead: X_ChangeGC gcontext id " << g_id + << " is unrecognized.\n" << logofs_flush; + } + + gcontexts.erase(g_id); + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ChangeGC); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> gcCache); + const unsigned char *nextSrc = inputMessage + 8; + unsigned int bitmask = GetULONG(nextSrc, bigEndian_); + nextSrc += 4; + encodeBuffer.encodeCachedValue(bitmask, 23, + clientCache_ -> createGCBitmaskCache); + unsigned int mask = 0x1; + for (unsigned int i = 0; i < 23; i++) + { + if (bitmask & mask) + { + unsigned int value = GetULONG(nextSrc, bigEndian_); + nextSrc += 4; + unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i]; + if (fieldWidth <= 4) + { + encodeBuffer.encodeValue(value, fieldWidth); + } + else + { + encodeBuffer.encodeCachedValue(value, fieldWidth, + *clientCache_ -> createGCAttrCache[i]); + } + } + mask <<= 1; + } + } + break; + case X_CreatePixmap: + { + #ifdef TARGETS + + *logofs << "handleRead: X_CreatePixmap depth " << (unsigned) inputMessage[1] + << ", pixmap id " << GetULONG(inputMessage + 4, bigEndian_) + << ", drawable " << GetULONG(inputMessage + 8, bigEndian_) + << ", width " << GetUINT(inputMessage + 12, bigEndian_) + << ", height " << GetUINT(inputMessage + 14, bigEndian_) + << ", size " << GetUINT(inputMessage + 2, bigEndian_) << 2 + << ".\n" << logofs_flush; + + unsigned int p_id = GetULONG(inputMessage + 4, bigEndian_); + unsigned short p_sx = GetUINT(inputMessage + 12, bigEndian_); + unsigned short p_sy = GetUINT(inputMessage + 14, bigEndian_); + + *logofs << "handleRead: X_CreatePixmap id is " << p_id + << " width is " << p_sx << " height is " << p_sy + << ".\n" << logofs_flush; + + if (p_sx * p_sy <= 64 * 64) + { + *logofs << "handleRead: X_CreatePixmap id " << p_id << " of size " + << p_sx << "x" << p_sy << "=" << p_sx * p_sy + << " will be painted at client side.\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_CreatePixmap id " << p_id << " of size " + << p_sx << "x" << p_sy << "=" << p_sx * p_sy + << " will be painted at server side.\n" << logofs_flush; + } + + pixmaps.insert(p_id); + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_CreatePixmap); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + } + break; + case X_CreateWindow: + { + #ifdef TARGETS + + unsigned int w_id = GetULONG(inputMessage + 4, bigEndian_); + + *logofs << "handleRead: X_CreateWindow id is " << w_id + << ".\n" << logofs_flush; + + windows.insert(w_id); + + #endif + + unsigned bitmask = GetULONG(inputMessage + 28, bigEndian_); + encodeBuffer.encodeCachedValue((unsigned int) inputMessage[1], 8, + clientCache_ -> depthCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, bigEndian_), + clientCache_ -> windowCache); + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeNewXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> lastId, clientCache_ -> lastIdCache, + clientCache_ -> windowCache, + clientCache_ -> freeWindowCache); + + const unsigned char *nextSrc = inputMessage + 12; + for (unsigned int i = 0; i < 6; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *clientCache_ -> createWindowGeomCache[i], 8); + nextSrc += 2; + } + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 24, + bigEndian_), 29, clientCache_ -> visualCache); + encodeBuffer.encodeCachedValue(bitmask, 15, + clientCache_ -> createWindowBitmaskCache); + nextSrc = inputMessage + 32; + unsigned int mask = 0x1; + for (unsigned int j = 0; j < 15; j++) + { + if (bitmask & mask) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 32, + *clientCache_ -> createWindowAttrCache[j]); + nextSrc += 4; + } + mask <<= 1; + } + } + break; + case X_DeleteProperty: + { + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + encodeBuffer.encodeValue(GetULONG(inputMessage + 8, bigEndian_), 29, 9); + } + break; + case X_FillPoly: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_FillPoly target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_FillPoly target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_FillPoly target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_FillPoly); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + unsigned int numPoints = ((inputLength - 16) >> 2); + + // Since ProtoStep10 (#issue 108) + encodeBuffer.encodeCachedValue(numPoints, 16, + clientCache_ -> fillPolyNumPointsCache, 4); + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, bigEndian_), + clientCache_ -> gcCache); + encodeBuffer.encodeValue((unsigned int) inputMessage[12], 2); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[13]); + int relativeCoordMode = (inputMessage[13] != 0); + const unsigned char *nextSrc = inputMessage + 16; + unsigned int pointIndex = 0; + + for (unsigned int i = 0; i < numPoints; i++) + { + if (relativeCoordMode) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *clientCache_ -> fillPolyXRelCache[pointIndex], 8); + nextSrc += 2; + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *clientCache_ -> fillPolyYRelCache[pointIndex], 8); + nextSrc += 2; + } + else + { + unsigned int x = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + unsigned int y = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + unsigned int j; + for (j = 0; j < 8; j++) + if ((x == clientCache_ -> fillPolyRecentX[j]) && + (y == clientCache_ -> fillPolyRecentY[j])) + break; + if (j < 8) + { + encodeBuffer.encodeBoolValue(1); + encodeBuffer.encodeValue(j, 3); + } + else + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeCachedValue(x, 16, + *clientCache_ -> fillPolyXAbsCache[pointIndex], 8); + encodeBuffer.encodeCachedValue(y, 16, + *clientCache_ -> fillPolyYAbsCache[pointIndex], 8); + clientCache_ -> fillPolyRecentX[clientCache_ -> fillPolyIndex] = x; + clientCache_ -> fillPolyRecentY[clientCache_ -> fillPolyIndex] = y; + clientCache_ -> fillPolyIndex++; + if (clientCache_ -> fillPolyIndex == 8) + clientCache_ -> fillPolyIndex = 0; + } + } + + if (++pointIndex == 10) pointIndex = 0; + } + } + break; + case X_FreeColors: + { + unsigned int numPixels = GetUINT(inputMessage + 2, bigEndian_) - 3; + encodeBuffer.encodeValue(numPixels, 16, 4); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, + clientCache_ -> colormapCache); + encodeBuffer.encodeValue(GetULONG(inputMessage + 8, bigEndian_), 32, 4); + const unsigned char *nextSrc = inputMessage + 12; + while (numPixels) + { + encodeBuffer.encodeValue(GetULONG(nextSrc, bigEndian_), 32, 8); + nextSrc += 4; + numPixels--; + } + } + break; + case X_FreeCursor: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, clientCache_ -> cursorCache, 9); + } + break; + case X_FreeGC: + { + #ifdef TARGETS + + unsigned int g_id = GetULONG(inputMessage + 4, bigEndian_); + + T_gcontexts::iterator i = gcontexts.find(g_id); + + if (i != gcontexts.end()) + { + unsigned int t_id = i -> second; + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_FreeGC gcontext id is " << g_id + << " target id is pixmap " << t_id << ".\n" + << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_FreeGC gcontext id is " << g_id + << " target id is window " << t_id << ".\n" + << logofs_flush; + } + else + { + *logofs << "handleRead: X_FreeGC gcontext id is " << g_id + << " target id is unrecognized.\n" + << logofs_flush; + } + } + else + { + *logofs << "handleRead: X_FreeGC gcontext id " << g_id + << " is unrecognized.\n" << logofs_flush; + } + + gcontexts.erase(g_id); + + #endif + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeFreeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> freeGCCache); + } + break; + case X_FreePixmap: + { + #ifdef TARGETS + + unsigned int p_id = GetULONG(inputMessage + 4, bigEndian_); + + *logofs << "handleRead: X_FreePixmap id is " << p_id << ".\n" << logofs_flush; + + pixmaps.erase(p_id); + + #endif + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeFreeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> freeDrawableCache); + } + break; + case X_GetAtomName: + { + encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 29, 9); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GetGeometry: + { + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> drawableCache); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GetInputFocus: + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GetModifierMapping: + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GetKeyboardMapping: + { + encodeBuffer.encodeValue((unsigned int) inputMessage[4], 8); + encodeBuffer.encodeValue((unsigned int) inputMessage[5], 8); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GetProperty: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_GetProperty); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + unsigned int property = GetULONG(inputMessage + 8, bigEndian_); + + sequenceQueue_.push(clientSequence_, inputOpcode, property); + + priority_++; + + hit = 1; + + break; + } + + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + unsigned int property = GetULONG(inputMessage + 8, bigEndian_); + encodeBuffer.encodeValue(property, 29, 9); + encodeBuffer.encodeValue(GetULONG(inputMessage + 12, bigEndian_), 29, 9); + encodeBuffer.encodeValue(GetULONG(inputMessage + 16, bigEndian_), 32, 2); + encodeBuffer.encodeValue(GetULONG(inputMessage + 20, bigEndian_), 32, 8); + + sequenceQueue_.push(clientSequence_, inputOpcode, property); + + priority_++; + } + break; + case X_GetSelectionOwner: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, + clientCache_ -> getSelectionOwnerSelectionCache, 9); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GrabButton: + { + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, + clientCache_ -> grabButtonEventMaskCache); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[10]); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[11]); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 29, + clientCache_ -> grabButtonConfineCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), 29, + clientCache_ -> cursorCache, 9); + encodeBuffer.encodeCachedValue(inputMessage[20], 8, + clientCache_ -> grabButtonButtonCache); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 22, bigEndian_), 16, + clientCache_ -> grabButtonModifierCache); + } + break; + case X_GrabPointer: + { + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, + clientCache_ -> grabButtonEventMaskCache); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[10]); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[11]); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, + bigEndian_), 29, + clientCache_ -> grabButtonConfineCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, + bigEndian_), 29, clientCache_ -> cursorCache, 9); + + unsigned int timestamp = GetULONG(inputMessage + 20, bigEndian_); + encodeBuffer.encodeValue(timestamp - + clientCache_ -> grabKeyboardLastTimestamp, 32, 4); + clientCache_ -> grabKeyboardLastTimestamp = timestamp; + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GrabKeyboard: + { + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + unsigned int timestamp = GetULONG(inputMessage + 8, bigEndian_); + encodeBuffer.encodeValue(timestamp - + clientCache_ -> grabKeyboardLastTimestamp, 32, 4); + clientCache_ -> grabKeyboardLastTimestamp = timestamp; + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[12]); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[13]); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GrabServer: + case X_UngrabServer: + case X_NoOperation: + { + } + break; + case X_PolyText8: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PolyText8 target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PolyText8 target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PolyText8 target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyText8); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + unsigned int x = GetUINT(inputMessage + 12, bigEndian_); + int xDiff = x - clientCache_ -> polyTextLastX; + clientCache_ -> polyTextLastX = x; + encodeBuffer.encodeCachedValue(xDiff, 16, + clientCache_ -> polyTextCacheX); + unsigned int y = GetUINT(inputMessage + 14, bigEndian_); + int yDiff = y - clientCache_ -> polyTextLastY; + clientCache_ -> polyTextLastY = y; + encodeBuffer.encodeCachedValue(yDiff, 16, + clientCache_ -> polyTextCacheY); + const unsigned char *end = inputMessage + inputLength - 1; + const unsigned char *nextSrc = inputMessage + 16; + while (nextSrc < end) + { + unsigned int textLength = (unsigned int) *nextSrc++; + encodeBuffer.encodeBoolValue(1); + encodeBuffer.encodeValue(textLength, 8); + if (textLength == 255) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, 1), 29, + clientCache_ -> polyTextFontCache); + nextSrc += 4; + } + else + { + encodeBuffer.encodeCachedValue(*nextSrc++, 8, + clientCache_ -> polyTextDeltaCache); + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, textLength); + nextSrc += textLength; + } + } + encodeBuffer.encodeBoolValue(0); + } + break; + case X_PolyText16: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PolyText16 target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PolyText16 target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PolyText16 target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyText16); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + unsigned int x = GetUINT(inputMessage + 12, bigEndian_); + int xDiff = x - clientCache_ -> polyTextLastX; + clientCache_ -> polyTextLastX = x; + encodeBuffer.encodeCachedValue(xDiff, 16, + clientCache_ -> polyTextCacheX); + unsigned int y = GetUINT(inputMessage + 14, bigEndian_); + int yDiff = y - clientCache_ -> polyTextLastY; + clientCache_ -> polyTextLastY = y; + encodeBuffer.encodeCachedValue(yDiff, 16, + clientCache_ -> polyTextCacheY); + const unsigned char *end = inputMessage + inputLength - 1; + const unsigned char *nextSrc = inputMessage + 16; + while (nextSrc < end) + { + unsigned int textLength = (unsigned int) *nextSrc++; + encodeBuffer.encodeBoolValue(1); + encodeBuffer.encodeValue(textLength, 8); + if (textLength == 255) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, 1), 29, + clientCache_ -> polyTextFontCache); + nextSrc += 4; + } + else + { + encodeBuffer.encodeCachedValue(*nextSrc++, 8, + clientCache_ -> polyTextDeltaCache); + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, textLength * 2); + nextSrc += textLength * 2; + } + } + encodeBuffer.encodeBoolValue(0); + } + break; + case X_ImageText8: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_ImageText8 target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_ImageText8 target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_ImageText8 target id " + << t_id << " is unrecognized.\n" + << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ImageText8); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + unsigned int textLength = (unsigned int) inputMessage[1]; + encodeBuffer.encodeCachedValue(textLength, 8, + clientCache_ -> imageTextLengthCache, 4); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + unsigned int x = GetUINT(inputMessage + 12, bigEndian_); + int xDiff = x - clientCache_ -> imageTextLastX; + clientCache_ -> imageTextLastX = x; + encodeBuffer.encodeCachedValue(xDiff, 16, + clientCache_ -> imageTextCacheX); + unsigned int y = GetUINT(inputMessage + 14, bigEndian_); + int yDiff = y - clientCache_ -> imageTextLastY; + clientCache_ -> imageTextLastY = y; + encodeBuffer.encodeCachedValue(yDiff, 16, + clientCache_ -> imageTextCacheY); + const unsigned char *nextSrc = inputMessage + 16; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, textLength); + } + break; + case X_ImageText16: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_ImageText16 target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_ImageText16 target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_ImageText16 target id " + << t_id << " is unrecognized.\n" + << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ImageText16); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + unsigned int textLength = (unsigned int) inputMessage[1]; + encodeBuffer.encodeCachedValue(textLength, 8, + clientCache_ -> imageTextLengthCache, 4); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + unsigned int x = GetUINT(inputMessage + 12, bigEndian_); + int xDiff = x - clientCache_ -> imageTextLastX; + clientCache_ -> imageTextLastX = x; + encodeBuffer.encodeCachedValue(xDiff, 16, + clientCache_ -> imageTextCacheX); + unsigned int y = GetUINT(inputMessage + 14, bigEndian_); + int yDiff = y - clientCache_ -> imageTextLastY; + clientCache_ -> imageTextLastY = y; + encodeBuffer.encodeCachedValue(yDiff, 16, + clientCache_ -> imageTextCacheY); + const unsigned char *nextSrc = inputMessage + 16; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, textLength * 2); + } + break; + case X_InternAtom: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_InternAtom); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + // + // Set the priority, also if doing so will + // penalize all the well written clients + // using XInternAtoms() to pipeline multi- + // ple replies. + // + + priority_++; + + hit = 1; + + break; + } + + unsigned int nameLength = GetUINT(inputMessage + 4, bigEndian_); + encodeBuffer.encodeValue(nameLength, 16, 6); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + const unsigned char *nextSrc = inputMessage + 8; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, nameLength); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_ListExtensions: + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_ListFonts: + { + unsigned int textLength = GetUINT(inputMessage + 6, bigEndian_); + encodeBuffer.encodeValue(textLength, 16, 6); + encodeBuffer.encodeValue(GetUINT(inputMessage + 4, bigEndian_), 16, 6); + const unsigned char* nextSrc = inputMessage + 8; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, textLength); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_LookupColor: + case X_AllocNamedColor: + { + unsigned int textLength = GetUINT(inputMessage + 8, bigEndian_); + encodeBuffer.encodeValue(textLength, 16, 6); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, clientCache_ -> colormapCache); + const unsigned char *nextSrc = inputMessage + 12; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, textLength); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_MapWindow: + case X_UnmapWindow: + case X_MapSubwindows: + case X_GetWindowAttributes: + case X_DestroyWindow: + case X_DestroySubwindows: + case X_QueryPointer: + case X_QueryTree: + { + #ifdef TARGETS + + if (inputOpcode == X_DestroyWindow) + { + unsigned int w_id = GetULONG(inputMessage + 4, bigEndian_); + + *logofs << "handleRead: X_DestroyWindow id is " + << w_id << ".\n" << logofs_flush; + + windows.erase(w_id); + } + + #endif + + if (inputOpcode == X_DestroyWindow) + { + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeFreeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> freeWindowCache); + } + else + { + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> windowCache); + } + + if ((inputOpcode == X_QueryPointer) || + (inputOpcode == X_GetWindowAttributes) || + (inputOpcode == X_QueryTree)) + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + } + break; + case X_OpenFont: + { + unsigned int nameLength = GetUINT(inputMessage + 8, bigEndian_); + encodeBuffer.encodeValue(nameLength, 16, 7); + unsigned int font = GetULONG(inputMessage + 4, bigEndian_); + encodeBuffer.encodeValue(font - clientCache_ -> lastFont, 29, 5); + clientCache_ -> lastFont = font; + const unsigned char *nextSrc = inputMessage + 12; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, nameLength); + } + break; + case X_PolyFillRectangle: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PolyFillRectangle target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PolyFillRectangle target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PolyFillRectangle target id " + << t_id << " is unrecognized.\n" + << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyFillRectangle); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0; + unsigned int lastWidth = 0, lastHeight = 0; + + // + // TODO: Could send the size at the beginning + // instead of a bool at each iteration. + // + + for (unsigned int i = 12; i < inputLength;) + { + unsigned int x = GetUINT(inputMessage + i, bigEndian_); + unsigned int newX = x; + x -= lastX; + lastX = newX; + encodeBuffer.encodeCachedValue(x, 16, + *clientCache_ -> polyFillRectangleCacheX[index], 8); + i += 2; + unsigned int y = GetUINT(inputMessage + i, bigEndian_); + unsigned int newY = y; + y -= lastY; + lastY = newY; + encodeBuffer.encodeCachedValue(y, 16, + *clientCache_ -> polyFillRectangleCacheY[index], 8); + i += 2; + unsigned int width = GetUINT(inputMessage + i, bigEndian_); + unsigned int newWidth = width; + width -= lastWidth; + lastWidth = newWidth; + encodeBuffer.encodeCachedValue(width, 16, + *clientCache_ -> polyFillRectangleCacheWidth[index], 8); + i += 2; + unsigned int height = GetUINT(inputMessage + i, bigEndian_); + unsigned int newHeight = height; + height -= lastHeight; + lastHeight = newHeight; + encodeBuffer.encodeCachedValue(height, 16, + *clientCache_ -> polyFillRectangleCacheHeight[index], 8); + i += 2; + + if (++index == 4) index = 0; + + encodeBuffer.encodeBoolValue((i < inputLength) ? 1 : 0); + } + } + break; + case X_PolyFillArc: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PolyFillArc target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PolyFillArc target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PolyFillArc target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyFillArc); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0; + unsigned int lastWidth = 0, lastHeight = 0; + unsigned int lastAngle1 = 0, lastAngle2 = 0; + + // + // TODO: Could send the size at the beginning + // instead of a bool at each iteration. + // + + for (unsigned int i = 12; i < inputLength;) + { + unsigned int x = GetUINT(inputMessage + i, bigEndian_); + unsigned int newX = x; + x -= lastX; + lastX = newX; + encodeBuffer.encodeCachedValue(x, 16, + *clientCache_ -> polyFillArcCacheX[index], 8); + i += 2; + unsigned int y = GetUINT(inputMessage + i, bigEndian_); + unsigned int newY = y; + y -= lastY; + lastY = newY; + encodeBuffer.encodeCachedValue(y, 16, + *clientCache_ -> polyFillArcCacheY[index], 8); + i += 2; + unsigned int width = GetUINT(inputMessage + i, bigEndian_); + unsigned int newWidth = width; + width -= lastWidth; + lastWidth = newWidth; + encodeBuffer.encodeCachedValue(width, 16, + *clientCache_ -> polyFillArcCacheWidth[index], 8); + i += 2; + unsigned int height = GetUINT(inputMessage + i, bigEndian_); + unsigned int newHeight = height; + height -= lastHeight; + lastHeight = newHeight; + encodeBuffer.encodeCachedValue(height, 16, + *clientCache_ -> polyFillArcCacheHeight[index], 8); + i += 2; + unsigned int angle1 = GetUINT(inputMessage + i, bigEndian_); + unsigned int newAngle1 = angle1; + angle1 -= lastAngle1; + lastAngle1 = newAngle1; + encodeBuffer.encodeCachedValue(angle1, 16, + *clientCache_ -> polyFillArcCacheAngle1[index], 8); + i += 2; + unsigned int angle2 = GetUINT(inputMessage + i, bigEndian_); + unsigned int newAngle2 = angle2; + angle2 -= lastAngle2; + lastAngle2 = newAngle2; + encodeBuffer.encodeCachedValue(angle2, 16, + *clientCache_ -> polyFillArcCacheAngle2[index], 8); + i += 2; + + if (++index == 2) index = 0; + + encodeBuffer.encodeBoolValue((i < inputLength) ? 1 : 0); + } + } + break; + case X_PolyArc: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PolyArc target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PolyArc target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PolyArc target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyArc); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0; + unsigned int lastWidth = 0, lastHeight = 0; + unsigned int lastAngle1 = 0, lastAngle2 = 0; + + // + // TODO: Could send the size at the beginning + // instead of a bool at each iteration. + // + + for (unsigned int i = 12; i < inputLength;) + { + unsigned int x = GetUINT(inputMessage + i, bigEndian_); + unsigned int newX = x; + x -= lastX; + lastX = newX; + encodeBuffer.encodeCachedValue(x, 16, + *clientCache_ -> polyArcCacheX[index], 8); + i += 2; + unsigned int y = GetUINT(inputMessage + i, bigEndian_); + unsigned int newY = y; + y -= lastY; + lastY = newY; + encodeBuffer.encodeCachedValue(y, 16, + *clientCache_ -> polyArcCacheY[index], 8); + i += 2; + unsigned int width = GetUINT(inputMessage + i, bigEndian_); + unsigned int newWidth = width; + width -= lastWidth; + lastWidth = newWidth; + encodeBuffer.encodeCachedValue(width, 16, + *clientCache_ -> polyArcCacheWidth[index], 8); + i += 2; + unsigned int height = GetUINT(inputMessage + i, bigEndian_); + unsigned int newHeight = height; + height -= lastHeight; + lastHeight = newHeight; + encodeBuffer.encodeCachedValue(height, 16, + *clientCache_ -> polyArcCacheHeight[index], 8); + i += 2; + unsigned int angle1 = GetUINT(inputMessage + i, bigEndian_); + unsigned int newAngle1 = angle1; + angle1 -= lastAngle1; + lastAngle1 = newAngle1; + encodeBuffer.encodeCachedValue(angle1, 16, + *clientCache_ -> polyArcCacheAngle1[index], 8); + i += 2; + unsigned int angle2 = GetUINT(inputMessage + i, bigEndian_); + unsigned int newAngle2 = angle2; + angle2 -= lastAngle2; + lastAngle2 = newAngle2; + encodeBuffer.encodeCachedValue(angle2, 16, + *clientCache_ -> polyArcCacheAngle2[index], 8); + i += 2; + + if (++index == 2) index = 0; + + encodeBuffer.encodeBoolValue((i < inputLength) ? 1 : 0); + } + } + break; + case X_PolyPoint: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PolyPoint target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PolyPoint target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PolyPoint target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyPoint); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeValue(GetUINT(inputMessage + 2, bigEndian_) - 3, 16, 4); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, bigEndian_), + clientCache_ -> gcCache); + const unsigned char *nextSrc = inputMessage + 12; + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0; + + for (unsigned int i = 12; i < inputLength; i += 4) + { + unsigned int x = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + unsigned int tmp = x; + x -= lastX; + lastX = tmp; + encodeBuffer.encodeCachedValue(x, 16, + *clientCache_ -> polyPointCacheX[index], 8); + unsigned int y = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + tmp = y; + y -= lastY; + lastY = tmp; + encodeBuffer.encodeCachedValue(y, 16, + *clientCache_ -> polyPointCacheY[index], 8); + + if (++index == 2) index = 0; + } + } + break; + case X_PolyLine: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PolyLine target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PolyLine target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PolyLine target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyLine); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeValue(GetUINT(inputMessage + 2, bigEndian_) - 3, 16, 4); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + const unsigned char *nextSrc = inputMessage + 12; + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0; + + for (unsigned int i = 12; i < inputLength; i += 4) + { + unsigned int x = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + unsigned int tmp = x; + x -= lastX; + lastX = tmp; + encodeBuffer.encodeCachedValue(x, 16, + *clientCache_ -> polyLineCacheX[index], 8); + unsigned int y = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + tmp = y; + y -= lastY; + lastY = tmp; + encodeBuffer.encodeCachedValue(y, 16, + *clientCache_ -> polyLineCacheY[index], 8); + + if (++index == 2) index = 0; + } + } + break; + case X_PolyRectangle: + { + encodeBuffer.encodeValue((GetUINT(inputMessage + 2, + bigEndian_) - 3) >> 1, 16, 3); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + const unsigned char *end = inputMessage + inputLength; + const unsigned char *nextSrc = inputMessage + 12; + while (nextSrc < end) + { + for (unsigned int i = 0; i < 4; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *clientCache_ -> polyRectangleGeomCache[i], 8); + nextSrc += 2; + } + } + } + break; + case X_PolySegment: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PolySegment target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PolySegment target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PolySegment target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolySegment); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + encodeBuffer.encodeValue((GetUINT(inputMessage + 2, + bigEndian_) - 3) >> 1, 16, 4); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 8, + bigEndian_), clientCache_ -> gcCache); + const unsigned char *end = inputMessage + inputLength; + const unsigned char *nextSrc = inputMessage + 12; + // unsigned int index = 0; + // unsigned int lastX1, lastY1, lastX2, lastY2; + while (nextSrc < end) + { + unsigned int x = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + unsigned int xDiff0 = + x - clientCache_ -> polySegmentLastX[0]; + unsigned int xDiff1 = + x - clientCache_ -> polySegmentLastX[1]; + int xDiff0Abs = (int) xDiff0; + if (xDiff0Abs < 0) + xDiff0Abs = -xDiff0Abs; + int xDiff1Abs = (int) xDiff1; + if (xDiff1Abs < 0) + xDiff1Abs = -xDiff1Abs; + + unsigned int y = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + unsigned int yDiff0 = + y - clientCache_ -> polySegmentLastY[0]; + unsigned int yDiff1 = + y - clientCache_ -> polySegmentLastY[1]; + int yDiff0Abs = (int) yDiff0; + if (yDiff0Abs < 0) + yDiff0Abs = -yDiff0Abs; + int yDiff1Abs = (int) yDiff1; + if (yDiff1Abs < 0) + yDiff1Abs = -yDiff1Abs; + + int diff0 = xDiff0Abs + yDiff0Abs; + int diff1 = xDiff1Abs + yDiff1Abs; + if (diff0 < diff1) + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeCachedValue(xDiff0, 16, + clientCache_ -> polySegmentCacheX, 6); + encodeBuffer.encodeCachedValue(yDiff0, 16, + clientCache_ -> polySegmentCacheY, 6); + } + else + { + encodeBuffer.encodeBoolValue(1); + encodeBuffer.encodeCachedValue(xDiff1, 16, + clientCache_ -> polySegmentCacheX, 6); + encodeBuffer.encodeCachedValue(yDiff1, 16, + clientCache_ -> polySegmentCacheY, 6); + } + + clientCache_ -> polySegmentLastX[clientCache_ -> polySegmentCacheIndex] = x; + clientCache_ -> polySegmentLastY[clientCache_ -> polySegmentCacheIndex] = y; + + clientCache_ -> polySegmentCacheIndex = + clientCache_ -> polySegmentCacheIndex == 1 ? 0 : 1; + } + } + break; + case X_PutImage: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_PutImage target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_PutImage target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_PutImage target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PutImage); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + } + break; + case X_QueryBestSize: + { + encodeBuffer.encodeValue((unsigned int)inputMessage[1], 2); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + encodeBuffer.encodeValue(GetUINT(inputMessage + 8, bigEndian_), 16, 8); + encodeBuffer.encodeValue(GetUINT(inputMessage + 10, bigEndian_), 16, 8); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_QueryColors: + { + // Differential encoding. + encodeBuffer.encodeBoolValue(1); + + unsigned int numColors = ((inputLength - 8) >> 2); + encodeBuffer.encodeValue(numColors, 16, 5); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, + clientCache_ -> colormapCache); + const unsigned char *nextSrc = inputMessage + 8; + unsigned int predictedPixel = clientCache_ -> queryColorsLastPixel; + for (unsigned int i = 0; i < numColors; i++) + { + unsigned int pixel = GetULONG(nextSrc, bigEndian_); + nextSrc += 4; + if (pixel == predictedPixel) + encodeBuffer.encodeBoolValue(1); + else + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeValue(pixel, 32, 9); + } + if (i == 0) + clientCache_ -> queryColorsLastPixel = pixel; + predictedPixel = pixel + 1; + } + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_QueryExtension: + { + #ifdef TEST + + char data[256]; + + int length = GetUINT(inputMessage + 4, bigEndian_); + + if (length > 256) + { + length = 256; + } + + strncpy(data, (char *) inputMessage + 8, length); + + *(data + length) = '\0'; + + *logofs << "handleRead: Going to query extension '" + << data << "' for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + unsigned int nameLength = GetUINT(inputMessage + 4, bigEndian_); + encodeBuffer.encodeValue(nameLength, 16, 6); + const unsigned char *nextSrc = inputMessage + 8; + + for (; nameLength; nameLength--) + { + encodeBuffer.encodeValue((unsigned int) *nextSrc++, 8); + } + + unsigned int extension = 0; + + if (strncmp((char *) inputMessage + 8, "SHAPE", 5) == 0) + { + extension = X_NXInternalShapeExtension; + } + else if (strncmp((char *) inputMessage + 8, "RENDER", 6) == 0) + { + extension = X_NXInternalRenderExtension; + } + + sequenceQueue_.push(clientSequence_, inputOpcode, extension); + + priority_++; + } + break; + case X_QueryFont: + { + unsigned int font = GetULONG(inputMessage + 4, bigEndian_); + encodeBuffer.encodeValue(font - clientCache_ -> lastFont, 29, 5); + clientCache_ -> lastFont = font; + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_SetClipRectangles: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_SetClipRectangles); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + hit = 1; + + break; + } + + unsigned int numRectangles = ((inputLength - 12) >> 3); + + // Since ProtoStep9 (#issue 108) + encodeBuffer.encodeValue(numRectangles, 15, 4); + + encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> gcCache); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, + clientCache_ -> setClipRectanglesXCache, 8); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 10, bigEndian_), 16, + clientCache_ -> setClipRectanglesYCache, 8); + const unsigned char *nextSrc = inputMessage + 12; + for (unsigned int i = 0; i < numRectangles; i++) + { + for (unsigned int j = 0; j < 4; j++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *clientCache_ -> setClipRectanglesGeomCache[j], 8); + nextSrc += 2; + } + } + } + break; + case X_SetDashes: + { + unsigned int numDashes = GetUINT(inputMessage + 10, bigEndian_); + encodeBuffer.encodeCachedValue(numDashes, 16, + clientCache_ -> setDashesLengthCache, 5); + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, bigEndian_), + clientCache_ -> gcCache); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, + clientCache_ -> setDashesOffsetCache, 5); + const unsigned char *nextSrc = inputMessage + 12; + for (unsigned int i = 0; i < numDashes; i++) + encodeBuffer.encodeCachedValue(*nextSrc++, 8, + clientCache_ -> setDashesDashCache_[i & 1], 5); + } + break; + case X_SetSelectionOwner: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, + clientCache_ -> setSelectionOwnerCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, + clientCache_ -> getSelectionOwnerSelectionCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 32, + clientCache_ -> setSelectionOwnerTimestampCache, 9); + } + break; + case X_TranslateCoords: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_TranslateCoords source id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_TranslateCoords source id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_TranslateCoords source id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + t_id = GetULONG(inputMessage + 8, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_TranslateCoords target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_TranslateCoords target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_TranslateCoords target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_TranslateCoords); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + + hit = 1; + + break; + } + + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, + clientCache_ -> translateCoordsSrcCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, + clientCache_ -> translateCoordsDstCache, 9); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 12, bigEndian_), 16, + clientCache_ -> translateCoordsXCache, 8); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 14, bigEndian_), 16, + clientCache_ -> translateCoordsYCache, 8); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GetImage: + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_GetImage source id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_GetImage source id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_GetImage source id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_GetImage); + + if (handleEncodeCached(encodeBuffer, clientCache_, messageStore, + inputMessage, inputLength)) + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + + hit = 1; + + break; + } + + // Format. + encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2); + // Drawable. + encodeBuffer.encodeXidValue(GetULONG(inputMessage + 4, + bigEndian_), clientCache_ -> drawableCache); + // X. + unsigned int x = GetUINT(inputMessage + 8, bigEndian_); + int xDiff = x - clientCache_ -> putImageLastX; + clientCache_ -> putImageLastX = x; + encodeBuffer.encodeCachedValue(xDiff, 16, + clientCache_ -> putImageXCache, 8); + // Y. + unsigned int y = GetUINT(inputMessage + 10, bigEndian_); + int yDiff = y - clientCache_ -> putImageLastY; + clientCache_ -> putImageLastY = y; + encodeBuffer.encodeCachedValue(yDiff, 16, + clientCache_ -> putImageYCache, 8); + // Width. + unsigned int width = GetUINT(inputMessage + 12, bigEndian_); + encodeBuffer.encodeCachedValue(width, 16, + clientCache_ -> putImageWidthCache, 8); + // Height. + unsigned int height = GetUINT(inputMessage + 14, bigEndian_); + encodeBuffer.encodeCachedValue(height, 16, + clientCache_ -> putImageHeightCache, 8); + // Plane mask. + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), 32, + clientCache_ -> getImagePlaneMaskCache, 5); + + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GetPointerMapping: + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + case X_GetKeyboardControl: + { + sequenceQueue_.push(clientSequence_, inputOpcode); + + priority_++; + } + break; + default: + { + if (inputOpcode == opcodeStore_ -> renderExtension) + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXInternalRenderExtension); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + } + else if (inputOpcode == opcodeStore_ -> shapeExtension) + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXInternalShapeExtension); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + } + else if (inputOpcode == opcodeStore_ -> putPackedImage) + { + #ifdef TARGETS + + unsigned int t_id = GetULONG(inputMessage + 4, bigEndian_); + + if (pixmaps.find(t_id) != pixmaps.end()) + { + *logofs << "handleRead: X_NXPutPackedImage target id is pixmap " + << t_id << ".\n" << logofs_flush; + } + else if (windows.find(t_id) != windows.end()) + { + *logofs << "handleRead: X_NXPutPackedImage target id is window " + << t_id << ".\n" << logofs_flush; + } + else + { + *logofs << "handleRead: X_NXPutPackedImage target id " << t_id + << " is unrecognized.\n" << logofs_flush; + } + + #endif + + #ifdef DEBUG + *logofs << "handleRead: Encoding packed image request for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + // + // The field carries the destination data + // length. We add the request's size of + // the final X_PutImage. + // + + unsigned int outputLength = GetULONG(inputMessage + 20, bigEndian_) + 24; + + statistics -> addPackedBytesIn(inputLength); + + statistics -> addPackedBytesOut(outputLength); + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXPutPackedImage); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + } + else if (inputOpcode == opcodeStore_ -> setUnpackColormap) + { + #ifdef DEBUG + *logofs << "handleRead: Encoding set unpack colormap request " + << "for FD#" << fd_ << " with size " << inputLength + << ".\n" << logofs_flush; + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXSetUnpackColormap); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + } + else if (inputOpcode == opcodeStore_ -> setUnpackAlpha) + { + #ifdef DEBUG + *logofs << "handleRead: Encoding set unpack alpha request " + << "for FD#" << fd_ << " with size " << inputLength + << ".\n" << logofs_flush; + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXSetUnpackAlpha); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + } + else if (inputOpcode == opcodeStore_ -> setUnpackGeometry) + { + #ifdef DEBUG + *logofs << "handleRead: Encoding set unpack geometry request " + << "for FD#" << fd_ << " with size " << inputLength + << ".\n" << logofs_flush; + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXSetUnpackGeometry); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + } + else if (inputOpcode == opcodeStore_ -> startSplit) + { + if (handleStartSplitRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + else if (inputOpcode == opcodeStore_ -> endSplit) + { + if (handleEndSplitRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + else if (inputOpcode == opcodeStore_ -> commitSplit) + { + if (handleCommitSplitRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + else if (inputOpcode == opcodeStore_ -> abortSplit) + { + if (handleAbortSplitRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + else if (inputOpcode == opcodeStore_ -> finishSplit) + { + if (handleFinishSplitRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + else if (inputOpcode == opcodeStore_ -> freeSplit) + { + #ifdef DEBUG + *logofs << "handleRead: Encoding free split request " + << "for FD#" << fd_ << " with size " << inputLength + << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(*(inputMessage + 1), 8, + clientCache_ -> resourceCache); + } + else if (inputOpcode == opcodeStore_ -> freeUnpack) + { + #ifdef DEBUG + *logofs << "handleRead: Encoding free unpack request " + << "for FD#" << fd_ << " with size " << inputLength + << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(*(inputMessage + 1), 8, + clientCache_ -> resourceCache); + } + else if (inputOpcode == opcodeStore_ -> getControlParameters) + { + #ifdef DEBUG + *logofs << "handleRead: Encoding get control parameters " + << "request for FD#" << fd_ << " with size " + << inputLength << ".\n" << logofs_flush; + #endif + + // + // Add the reply to the write buffer. If found + // to contain a message, it it will be flushed + // to the X client before leaving the loop. + // + + unsigned char *reply = writeBuffer_.addMessage(32); + + *(reply + 0) = X_Reply; + + PutUINT(clientSequence_, reply + 2, bigEndian_); + + PutULONG(0, reply + 4, bigEndian_); + + // + // Save the sequence number we used + // to auto-generate this reply. + // + + lastSequence_ = clientSequence_; + + #ifdef TEST + *logofs << "handleRead: Registered " << lastSequence_ + << " as last auto-generated sequence number.\n" + << logofs_flush; + #endif + + *(reply + 1) = control -> LinkMode; + + *(reply + 8) = control -> LocalVersionMajor; + *(reply + 9) = control -> LocalVersionMinor; + *(reply + 10) = control -> LocalVersionPatch; + + *(reply + 11) = control -> RemoteVersionMajor; + *(reply + 12) = control -> RemoteVersionMinor; + *(reply + 13) = control -> RemoteVersionPatch; + + PutUINT(control -> SplitTimeout, reply + 14, bigEndian_); + PutUINT(control -> MotionTimeout, reply + 16, bigEndian_); + + *(reply + 18) = control -> SplitMode; + + PutULONG(control -> SplitDataThreshold, reply + 20, bigEndian_); + + *(reply + 24) = control -> PackMethod; + *(reply + 25) = control -> PackQuality; + + *(reply + 26) = control -> LocalDataCompressionLevel; + *(reply + 27) = control -> LocalStreamCompressionLevel; + *(reply + 28) = control -> LocalDeltaCompression; + + *(reply + 29) = (control -> LocalDeltaCompression == 1 && + control -> PersistentCacheEnableLoad == 1); + *(reply + 30) = (control -> LocalDeltaCompression == 1 && + control -> PersistentCacheEnableSave == 1); + *(reply + 31) = (control -> LocalDeltaCompression == 1 && + control -> PersistentCacheEnableLoad == 1 && + control -> PersistentCacheName != NULL); + + if (handleFlush(flush_if_any) < 0) + { + return -1; + } + } + else if (inputOpcode == opcodeStore_ -> getCleanupParameters) + { + #ifdef WARNING + *logofs << "handleRead: WARNING! Encoding fake get cleanup " + << "parameters request for FD#" << fd_ << " with size " + << inputLength << ".\n" << logofs_flush; + #endif + } + else if (inputOpcode == opcodeStore_ -> getImageParameters) + { + #ifdef WARNING + *logofs << "handleRead: WARNING! Encoding fake get cleanup " + << "parameters request for FD#" << fd_ << " with size " + << inputLength << ".\n" << logofs_flush; + #endif + } + else if (inputOpcode == opcodeStore_ -> getUnpackParameters) + { + #ifdef DEBUG + *logofs << "handleRead: Encoding get unpack parameters " + << "request for FD#" << fd_ << " with size " + << inputLength << ".\n" << logofs_flush; + #endif + + sequenceQueue_.push(clientSequence_, inputOpcode); + } + else if (inputOpcode == opcodeStore_ -> getShmemParameters) + { + if (handleShmemRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + else if (inputOpcode == opcodeStore_ -> setExposeParameters) + { + // + // Enable or disable expose events + // coming from the real server. + // + + encodeBuffer.encodeBoolValue(*(inputMessage + 4)); + encodeBuffer.encodeBoolValue(*(inputMessage + 5)); + encodeBuffer.encodeBoolValue(*(inputMessage + 6)); + } + else if (inputOpcode == opcodeStore_ -> setCacheParameters) + { + if (handleCacheRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + else if (inputOpcode == opcodeStore_ -> getFontParameters) + { + if (handleFontRequest(encodeBuffer, inputOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + else + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXInternalGenericRequest); + + hit = handleEncode(encodeBuffer, clientCache_, messageStore, + inputOpcode, inputMessage, inputLength); + + // + // Don't flush if the opcode is unrecognized. + // We may optionally flush it is an extension + // but would penalize the well written clients. + // + // if (inputOpcode > 127) + // { + // priority_++; + // } + // + } + } + } // End of switch on opcode. + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + + const char *cacheString = (hit ? "cached " : ""); + + *logofs << "handleRead: Handled " << cacheString << "request OPCODE#" + << (unsigned int) inputOpcode << " (" << DumpOpcode(inputOpcode) + << ")" << " for FD#" << fd_ << " sequence " << clientSequence_ + << ". " << inputLength << " bytes in, " << bits << " bits (" + << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; + + #endif + + if (hit) + { + statistics -> addCachedRequest(inputOpcode); + } + + statistics -> addRequestBits(inputOpcode, inputLength << 3, bits); + + if (inputOpcode == opcodeStore_ -> renderExtension) + { + if (hit) + { + statistics -> addRenderCachedRequest(*(inputMessage + 1)); + } + + statistics -> addRenderRequestBits(*(inputMessage + 1), inputLength << 3, bits); + } + + } // End if (firstRequest_)... else ... + + } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != 0) ... + + // + // Check if we need to flush because of + // prioritized data. + // + + if (priority_ > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: WARNING! Requesting flush " + << "because of " << priority_ << " prioritized " + << "messages for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + if (proxy -> handleAsyncPriority() < 0) + { + return -1; + } + + // + // Reset the priority flag. + // + + priority_ = 0; + } + + // + // Flush if we exceeded the token length. + // + + if (proxy -> canAsyncFlush() == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: WARNING! Requesting flush " + << "because of token length exceeded.\n" + << logofs_flush; + #endif + + if (proxy -> handleAsyncFlush() < 0) + { + return -1; + } + } + + #if defined(TEST) || defined(INFO) + + if (transport_ -> pending() != 0 || + readBuffer_.checkMessage() != 0) + { + *logofs << "handleRead: PANIC! Buffer for X descriptor FD#" + << fd_ << " has " << transport_ -> pending() + << " bytes to read.\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + // + // Reset the read buffer. + // + + readBuffer_.fullReset(); + + return 1; +} + +// +// End of handleRead(). +// + +// +// Beginning of handleWrite(). +// + +int ClientChannel::handleWrite(const unsigned char *message, unsigned int length) +{ + #ifdef TEST + *logofs << "handleWrite: Called for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + // + // Create the buffer from which to + // decode messages. + // + + DecodeBuffer decodeBuffer(message, length); + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "handleWrite: Decoding messages for FD#" << fd_ + << " with " << length << " bytes in the buffer.\n" + << logofs_flush; + #endif + + if (firstReply_) + { + #ifdef TEST + *logofs << "handleWrite: First reply detected.\n" << logofs_flush; + #endif + + unsigned int outputOpcode; + + decodeBuffer.decodeValue(outputOpcode, 8); + unsigned int secondByte; + decodeBuffer.decodeValue(secondByte, 8); + unsigned int major; + decodeBuffer.decodeValue(major, 16); + unsigned int minor; + decodeBuffer.decodeValue(minor, 16); + unsigned int extraLength; + decodeBuffer.decodeValue(extraLength, 16); + unsigned int outputLength = 8 + (extraLength << 2); + + unsigned char *outputMessage = writeBuffer_.addMessage(outputLength); + *outputMessage = (unsigned char) outputOpcode; + outputMessage[1] = (unsigned char) secondByte; + PutUINT(major, outputMessage + 2, bigEndian_); + PutUINT(minor, outputMessage + 4, bigEndian_); + PutUINT(extraLength, outputMessage + 6, bigEndian_); + unsigned char *nextDest = outputMessage + 8; + unsigned int cached; + decodeBuffer.decodeBoolValue(cached); + + if (cached) + { + memcpy(nextDest, ServerCache::lastInitReply.getData(), outputLength - 8); + } + else + { + for (unsigned i = 8; i < outputLength; i++) + { + unsigned int nextByte; + decodeBuffer.decodeValue(nextByte, 8); + *nextDest++ = (unsigned char) nextByte; + } + + ServerCache::lastInitReply.set(outputLength - 8, outputMessage + 8); + } + + imageByteOrder_ = outputMessage[30]; + bitmapBitOrder_ = outputMessage[31]; + scanlineUnit_ = outputMessage[32]; + scanlinePad_ = outputMessage[33]; + + firstReply_ = 0; + + } // End of if (firstReply_) + + // + // This was previously in a 'else' block. + // Due to the way the first request was + // handled, we could not decode multiple + // messages in the first frame. + // + + { // Start of the decoding block. + + #ifdef DEBUG + *logofs << "handleWrite: Starting loop on opcodes.\n" + << logofs_flush; + #endif + + unsigned char outputOpcode; + + // + // NX client needs this line to consider + // the initialization phase successfully + // completed. + // + + if (firstClient_ == -1) + { + cerr << "Info" << ": Established X client connection.\n" ; + + firstClient_ = fd_; + } + + while (decodeBuffer.decodeOpcodeValue(outputOpcode, serverCache_ -> opcodeCache, 1)) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoded a new OPCODE#" + << (unsigned int) outputOpcode << ".\n" + << logofs_flush; + #endif + + unsigned char *outputMessage = NULL; + unsigned int outputLength = 0; + + // + // General-purpose temp variables + // for decoding ints and chars. + // + + unsigned int value = 0; + unsigned char cValue = 0; + + // + // Check first if we need to abort any split, + // then if this is a reply, finally if it is + // en event or error. + // + + if (outputOpcode == opcodeStore_ -> splitEvent) + { + // + // It's an abort split, not a normal + // burst of proxy data. + // + + handleSplitEvent(decodeBuffer); + + continue; + } + else if (outputOpcode == X_Reply) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoding sequence number of reply.\n" + << logofs_flush; + #endif + + unsigned int sequenceNum; + unsigned int sequenceDiff; + + decodeBuffer.decodeCachedValue(sequenceDiff, 16, + serverCache_ -> replySequenceCache, 7); + + sequenceNum = (serverSequence_ + sequenceDiff) & 0xffff; + + serverSequence_ = sequenceNum; + + #ifdef DEBUG + *logofs << "handleWrite: Last server sequence number for FD#" + << fd_ << " is " << serverSequence_ << " with " + << "difference " << sequenceDiff << ".\n" + << logofs_flush; + #endif + + // + // In case of reply we can follow the X server and + // override any event's sequence number generated + // by this side. + // + + #ifdef TEST + *logofs << "handleWrite: Updating last event's sequence " + << lastSequence_ << " to reply's sequence number " + << serverSequence_ << " for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + lastSequence_ = serverSequence_; + + unsigned short int requestSequenceNum; + unsigned char requestOpcode; + + #ifdef DEBUG + + requestSequenceNum = 0; + requestOpcode = 0; + + *logofs << "handleWrite: Peek of sequence number returns "; + + *logofs << sequenceQueue_.peek(requestSequenceNum, requestOpcode); + + *logofs << " with sequence " << requestSequenceNum << " and opcode " + << (unsigned int) requestOpcode << ".\n" << logofs_flush; + + #endif + + if (sequenceQueue_.peek(requestSequenceNum, requestOpcode) == 1 && + (requestSequenceNum == sequenceNum)) + { + unsigned int requestData[3]; + + sequenceQueue_.pop(requestSequenceNum, requestOpcode, + requestData[0], requestData[1], requestData[2]); + + #ifdef DEBUG + *logofs << "handleWrite: Identified reply to OPCODE#" + << (unsigned int) requestOpcode << ".\n" + << logofs_flush; + #endif + + // + // Is differential encoding disabled? + // + + if (control -> RemoteDeltaCompression == 0) + { + int result = handleFastWriteReply(decodeBuffer, requestOpcode, + outputMessage, outputLength); + if (result < 0) + { + return -1; + } + else if (result > 0) + { + continue; + } + } + + switch (requestOpcode) + { + case X_AllocColor: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + unsigned char *nextDest = outputMessage + 8; + for (unsigned int i = 0; i < 3; i++) + { + decodeBuffer.decodeBoolValue(value); + if (value) + { + PutUINT(requestData[i], nextDest, bigEndian_); + } + else + { + decodeBuffer.decodeValue(value, 16, 6); + PutUINT(requestData[i] + value, nextDest, bigEndian_); + } + nextDest += 2; + } + decodeBuffer.decodeValue(value, 32, 9); + PutULONG(value, outputMessage + 16, bigEndian_); + } + break; + case X_GetAtomName: + { + unsigned int nameLength; + decodeBuffer.decodeValue(nameLength, 16, 6); + outputLength = RoundUp4(nameLength) + 32; + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(nameLength, outputMessage + 8, bigEndian_); + unsigned char* nextDest = outputMessage + 32; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, nameLength); + } + break; + case X_GetGeometry: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(cValue, 8, + serverCache_ -> depthCache); + outputMessage[1] = cValue; + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> getGeometryRootCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + for (unsigned int i = 0; i < 5; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *serverCache_ -> getGeometryGeomCache[i], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + } + break; + case X_GetInputFocus: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 2); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> getInputFocusWindowCache); + PutULONG(value, outputMessage + 8, bigEndian_); + } + break; + case X_GetKeyboardMapping: + { + decodeBuffer.decodeBoolValue(value); + if (value) + { + unsigned int dataLength = + ServerCache::getKeyboardMappingLastMap.getLength(); + outputLength = 32 + dataLength; + outputMessage = writeBuffer_.addMessage(outputLength); + outputMessage[1] = + ServerCache::getKeyboardMappingLastKeysymsPerKeycode; + memcpy(outputMessage + 32, + ServerCache::getKeyboardMappingLastMap.getData(), + dataLength); + break; + } + unsigned int numKeycodes; + decodeBuffer.decodeValue(numKeycodes, 8); + unsigned int keysymsPerKeycode; + decodeBuffer.decodeValue(keysymsPerKeycode, 8, 4); + ServerCache::getKeyboardMappingLastKeysymsPerKeycode = + keysymsPerKeycode; + outputLength = 32 + numKeycodes * keysymsPerKeycode * 4; + outputMessage = writeBuffer_.addMessage(outputLength); + outputMessage[1] = (unsigned char) keysymsPerKeycode; + unsigned char *nextDest = outputMessage + 32; + unsigned char previous = 0; + for (unsigned int count = numKeycodes * keysymsPerKeycode; + count; --count) + { + decodeBuffer.decodeBoolValue(value); + if (value) + PutULONG((unsigned int) NoSymbol, nextDest, bigEndian_); + else + { + unsigned int keysym; + decodeBuffer.decodeCachedValue(keysym, 24, + serverCache_ -> getKeyboardMappingKeysymCache, 9); + decodeBuffer.decodeCachedValue(cValue, 8, + serverCache_ -> getKeyboardMappingLastByteCache, 5); + previous += cValue; + PutULONG((keysym << 8) | previous, nextDest, bigEndian_); + } + nextDest += 4; + } + ServerCache::getKeyboardMappingLastMap.set(outputLength - 32, + outputMessage + 32); + } + break; + case X_GetModifierMapping: + { + unsigned int keycodesPerModifier; + decodeBuffer.decodeValue(keycodesPerModifier, 8); + outputLength = 32 + (keycodesPerModifier << 3); + outputMessage = writeBuffer_.addMessage(outputLength); + outputMessage[1] = (unsigned char) keycodesPerModifier; + unsigned char *nextDest = outputMessage + 32; + decodeBuffer.decodeBoolValue(value); + if (value) + { + memcpy(outputMessage + 32, + ServerCache::getModifierMappingLastMap.getData(), + ServerCache::getModifierMappingLastMap.getLength()); + break; + } + for (unsigned int count = outputLength - 32; count; count--) + { + decodeBuffer.decodeBoolValue(value); + if (value) + *nextDest++ = 0; + else + { + decodeBuffer.decodeValue(value, 8); + *nextDest++ = value; + } + } + ServerCache::getModifierMappingLastMap.set(outputLength - 32, + outputMessage + 32); + } + break; + case X_GetProperty: + { + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_GetProperty); + + handleDecode(decodeBuffer, serverCache_, messageStore, + requestOpcode, outputMessage, outputLength); + } + break; + case X_GetSelectionOwner: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> getSelectionOwnerCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + } + break; + case X_GetWindowAttributes: + { + outputLength = 44; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 2); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> visualCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> getWindowAttributesClassCache, 3); + PutUINT(value, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(cValue, 8, + serverCache_ -> getWindowAttributesBitGravityCache); + outputMessage[14] = cValue; + decodeBuffer.decodeCachedValue(cValue, 8, + serverCache_ -> getWindowAttributesWinGravityCache); + outputMessage[15] = cValue; + decodeBuffer.decodeCachedValue(value, 32, + serverCache_ -> getWindowAttributesPlanesCache, 9); + PutULONG(value, outputMessage + 16, bigEndian_); + decodeBuffer.decodeCachedValue(value, 32, + serverCache_ -> getWindowAttributesPixelCache, 9); + PutULONG(value, outputMessage + 20, bigEndian_); + decodeBuffer.decodeBoolValue(value); + outputMessage[24] = (unsigned char) value; + decodeBuffer.decodeBoolValue(value); + outputMessage[25] = (unsigned char) value; + decodeBuffer.decodeValue(value, 2); + outputMessage[26] = (unsigned char) value; + decodeBuffer.decodeBoolValue(value); + outputMessage[27] = (unsigned char) value; + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> colormapCache, 9); + PutULONG(value, outputMessage + 28, bigEndian_); + decodeBuffer.decodeCachedValue(value, 32, + serverCache_ -> getWindowAttributesAllEventsCache); + PutULONG(value, outputMessage + 32, bigEndian_); + decodeBuffer.decodeCachedValue(value, 32, + serverCache_ -> getWindowAttributesYourEventsCache); + PutULONG(value, outputMessage + 36, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> getWindowAttributesDontPropagateCache); + PutUINT(value, outputMessage + 40, bigEndian_); + } + break; + case X_GrabKeyboard: + case X_GrabPointer: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 3); + outputMessage[1] = (unsigned char) value; + } + break; + case X_InternAtom: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 29, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + } + break; + case X_ListExtensions: + { + decodeBuffer.decodeValue(value, 32, 8); + outputLength = 32 + (value << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + unsigned int numExtensions; + decodeBuffer.decodeValue(numExtensions, 8); + outputMessage[1] = (unsigned char) numExtensions; + unsigned char *nextDest = outputMessage + 32; + for (; numExtensions; numExtensions--) + { + unsigned int length; + decodeBuffer.decodeValue(length, 8); + *nextDest++ = (unsigned char) length; + for (; length; length--) + { + decodeBuffer.decodeValue(value, 8); + *nextDest++ = value; + } + } + } + break; + case X_ListFonts: + { + // + // Differential compression can achieve a 12:1 to 14:1 + // ratio, while the best ZLIB compression can achieve + // a mere 4:1 to 5:1. In the first case, though, the + // huge amount of data constituting the message would + // be stored uncompressed at the remote side. We need + // to find a compromise. The solution is to use diffe- + // rential compression at startup and ZLIB compression + // later on. + // + + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_ListFonts); + + if (handleDecodeCached(decodeBuffer, serverCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + decodeBuffer.decodeValue(value, 32, 8); + outputLength = 32 + (value << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + unsigned int numFonts; + decodeBuffer.decodeValue(numFonts, 16, 6); + PutUINT(numFonts, outputMessage + 8, bigEndian_); + + // Differential or plain data compression? + decodeBuffer.decodeBoolValue(value); + + if (value) + { + unsigned char* nextDest = outputMessage + 32; + for (; numFonts; numFonts--) + { + unsigned int length; + decodeBuffer.decodeValue(length, 8); + *nextDest++ = (unsigned char)length; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, length); + nextDest += length; + } + + handleSave(messageStore, outputMessage, outputLength); + } + else + { + const unsigned char *compressedData = NULL; + unsigned int compressedDataSize = 0; + + int decompressed = handleDecompress(decodeBuffer, requestOpcode, messageStore -> dataOffset, + outputMessage, outputLength, compressedData, + compressedDataSize); + if (decompressed < 0) + { + return -1; + } + else if (decompressed > 0) + { + handleSave(messageStore, outputMessage, outputLength, + compressedData, compressedDataSize); + } + else + { + handleSave(messageStore, outputMessage, outputLength); + } + } + } + break; + case X_LookupColor: + case X_AllocNamedColor: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + unsigned char *nextDest = outputMessage + 8; + if (requestOpcode == X_AllocNamedColor) + { + decodeBuffer.decodeValue(value, 32, 9); + PutULONG(value, nextDest, bigEndian_); + nextDest += 4; + } + unsigned int count = 3; + do + { + decodeBuffer.decodeValue(value, 16, 9); + PutUINT(value, nextDest, bigEndian_); + unsigned int visualColor; + decodeBuffer.decodeValue(visualColor, 16, 5); + visualColor += value; + visualColor &= 0xffff; + PutUINT(visualColor, nextDest + 6, bigEndian_); + nextDest += 2; + } + while (--count); + } + break; + case X_QueryBestSize: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 16, 8); + PutUINT(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeValue(value, 16, 8); + PutUINT(value, outputMessage + 10, bigEndian_); + } + break; + case X_QueryColors: + { + // Differential or plain data compression? + decodeBuffer.decodeBoolValue(value); + + if (value) + { + decodeBuffer.decodeBoolValue(value); + if (value) + { + unsigned int numColors = + serverCache_ -> queryColorsLastReply.getLength() / 6; + outputLength = 32 + (numColors << 3); + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(numColors, outputMessage + 8, bigEndian_); + const unsigned char *nextSrc = + serverCache_ -> queryColorsLastReply.getData(); + unsigned char *nextDest = outputMessage + 32; + for (; numColors; numColors--) + { + for (unsigned int i = 0; i < 6; i++) + *nextDest++ = *nextSrc++; + nextDest += 2; + } + } + else + { + unsigned int numColors; + decodeBuffer.decodeValue(numColors, 16, 5); + outputLength = 32 + (numColors << 3); + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(numColors, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 32; + for (unsigned int c = 0; c < numColors; c++) + { + for (unsigned int i = 0; i < 3; i++) + { + decodeBuffer.decodeValue(value, 16); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + } + serverCache_ -> queryColorsLastReply.set(numColors * 6, + outputMessage + 32); + const unsigned char *nextSrc = nextDest - 1; + nextDest = outputMessage + 32 + ((numColors - 1) << 3) + 5; + for (; numColors > 1; numColors--) + { + for (unsigned int i = 0; i < 6; i++) + *nextDest-- = *nextSrc--; + nextDest -= 2; + } + } + } + else + { + // Reply length. + unsigned int numColors; + decodeBuffer.decodeValue(numColors, 16, 5); + outputLength = 32 + (numColors << 3); + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(numColors, outputMessage + 8, bigEndian_); + + const unsigned char *compressedData = NULL; + unsigned int compressedDataSize = 0; + + int decompressed = handleDecompress(decodeBuffer, requestOpcode, 32, + outputMessage, outputLength, compressedData, + compressedDataSize); + if (decompressed < 0) + { + return -1; + } + } + } + break; + case X_QueryExtension: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeBoolValue(value); + outputMessage[8] = (unsigned char) value; + decodeBuffer.decodeValue(value, 8); + outputMessage[9] = (unsigned char) value; + decodeBuffer.decodeValue(value, 8); + outputMessage[10] = (unsigned char) value; + decodeBuffer.decodeValue(value, 8); + outputMessage[11] = (unsigned char) value; + + // + // We use a predefined opcode to address + // extensions' message stores, while real + // opcodes are used for communication with + // X server and clients. + // + + if (requestData[0] == X_NXInternalShapeExtension) + { + opcodeStore_ -> shapeExtension = outputMessage[9]; + + #ifdef TEST + *logofs << "handleWrite: Shape extension opcode for FD#" << fd_ + << " is " << (unsigned int) opcodeStore_ -> shapeExtension + << ".\n" << logofs_flush; + #endif + } + else if (requestData[0] == X_NXInternalRenderExtension) + { + opcodeStore_ -> renderExtension = outputMessage[9]; + + #ifdef TEST + *logofs << "handleWrite: Render extension opcode for FD#" << fd_ + << " is " << (unsigned int) opcodeStore_ -> renderExtension + << ".\n" << logofs_flush; + #endif + } + } + break; + case X_QueryFont: + { + // + // Use differential compression at startup and plain + // data compression later. Check X_ListFonts message + // for an explaination. + // + + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_QueryFont); + + if (handleDecodeCached(decodeBuffer, serverCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + // Differential or plain data compression? + decodeBuffer.decodeBoolValue(value); + + if (value) + { + unsigned int numProperties; + unsigned int numCharInfos; + decodeBuffer.decodeValue(numProperties, 16, 8); + decodeBuffer.decodeValue(numCharInfos, 32, 10); + outputLength = 60 + numProperties * 8 + numCharInfos * 12; + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(numProperties, outputMessage + 46, bigEndian_); + PutULONG(numCharInfos, outputMessage + 56, bigEndian_); + handleDecodeCharInfo(decodeBuffer, outputMessage + 8); + handleDecodeCharInfo(decodeBuffer, outputMessage + 24); + decodeBuffer.decodeValue(value, 16, 9); + PutUINT(value, outputMessage + 40, bigEndian_); + decodeBuffer.decodeValue(value, 16, 9); + PutUINT(value, outputMessage + 42, bigEndian_); + decodeBuffer.decodeValue(value, 16, 9); + PutUINT(value, outputMessage + 44, bigEndian_); + decodeBuffer.decodeBoolValue(value); + outputMessage[48] = (unsigned char) value; + decodeBuffer.decodeValue(value, 8); + outputMessage[49] = (unsigned char) value; + decodeBuffer.decodeValue(value, 8); + outputMessage[50] = (unsigned char) value; + decodeBuffer.decodeBoolValue(value); + outputMessage[51] = (unsigned char) value; + decodeBuffer.decodeValue(value, 16, 9); + PutUINT(value, outputMessage + 52, bigEndian_); + decodeBuffer.decodeValue(value, 16, 9); + PutUINT(value, outputMessage + 54, bigEndian_); + unsigned char *nextDest = outputMessage + 60; + decodeBuffer.decodeBoolValue(value); + + int end = 0; + + if (value == 1) + { + unsigned int index; + decodeBuffer.decodeValue(index, 4); + unsigned int length; + const unsigned char *data; + ServerCache::queryFontFontCache.get(index, length, data); + memcpy(nextDest, data, length); + + end = 1; + } + + if (end == 0) + { + unsigned char *saveDest = nextDest; + unsigned int length = numProperties * 8 + numCharInfos * 12; + for (; numProperties; numProperties--) + { + decodeBuffer.decodeValue(value, 32, 9); + PutULONG(value, nextDest, bigEndian_); + decodeBuffer.decodeValue(value, 32, 9); + PutULONG(value, nextDest + 4, bigEndian_); + nextDest += 8; + } + for (; numCharInfos; numCharInfos--) + { + handleDecodeCharInfo(decodeBuffer, nextDest); + + nextDest += 12; + } + ServerCache::queryFontFontCache.set(length, saveDest); + } + + handleSave(messageStore, outputMessage, outputLength); + } + else + { + // Reply length. + unsigned int replyLength; + decodeBuffer.decodeValue(replyLength, 32, 16); + outputLength = 32 + (replyLength << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + + const unsigned char *compressedData = NULL; + unsigned int compressedDataSize = 0; + + int decompressed = handleDecompress(decodeBuffer, requestOpcode, messageStore -> dataOffset, + outputMessage, outputLength, compressedData, + compressedDataSize); + if (decompressed < 0) + { + return -1; + } + else if (decompressed > 0) + { + handleSave(messageStore, outputMessage, outputLength, + compressedData, compressedDataSize); + } + else + { + handleSave(messageStore, outputMessage, outputLength); + } + } + } + break; + case X_QueryPointer: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeBoolValue(value); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> queryPointerRootCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> queryPointerChildCache, 9); + PutULONG(value, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyRootXCache, 8); + serverCache_ -> motionNotifyLastRootX += value; + PutUINT(serverCache_ -> motionNotifyLastRootX, outputMessage + 16, + bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyRootYCache, 8); + serverCache_ -> motionNotifyLastRootY += value; + PutUINT(serverCache_ -> motionNotifyLastRootY, outputMessage + 18, + bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyEventXCache, 8); + PutUINT(serverCache_ -> motionNotifyLastRootX + value, + outputMessage + 20, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyEventYCache, 8); + PutUINT(serverCache_ -> motionNotifyLastRootY + value, + outputMessage + 22, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyStateCache); + PutUINT(value, outputMessage + 24, bigEndian_); + } + break; + case X_QueryTree: + { + unsigned int children; + decodeBuffer.decodeValue(children, 16, 8); + + outputLength = 32 + (children << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + + PutULONG(outputLength, outputMessage + 4, bigEndian_); + + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> queryTreeWindowCache); + + PutULONG(value, outputMessage + 8, bigEndian_); + + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> queryTreeWindowCache); + + PutULONG(value, outputMessage + 12, bigEndian_); + + unsigned char *next = outputMessage + 32; + + PutUINT(children, outputMessage + 16, bigEndian_); + + for (unsigned int i = 0; i < children; i++) + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> queryTreeWindowCache); + + PutULONG(value, next + (i * 4), bigEndian_); + } + } + break; + case X_TranslateCoords: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeBoolValue(value); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> translateCoordsChildCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> translateCoordsXCache, 8); + PutUINT(value, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> translateCoordsYCache, 8); + PutUINT(value, outputMessage + 14, bigEndian_); + } + break; + case X_GetImage: + { + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_GetImage); + + if (handleDecodeCached(decodeBuffer, serverCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + // Depth. + decodeBuffer.decodeCachedValue(cValue, 8, + serverCache_ -> depthCache); + // Reply length. + unsigned int replyLength; + decodeBuffer.decodeValue(replyLength, 32, 9); + outputLength = 32 + (replyLength << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + outputMessage[1] = (unsigned char) cValue; + // Visual. + unsigned int visual; + decodeBuffer.decodeCachedValue(visual, 29, + serverCache_ -> visualCache); + PutULONG(visual, outputMessage + 8, bigEndian_); + + // Since ProtoStep8 (#issue 108) + handleCopy(decodeBuffer, requestOpcode, messageStore -> + dataOffset, outputMessage, outputLength); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_GetPointerMapping: + { + unsigned int nextByte; + decodeBuffer.decodeValue(nextByte, 8, 4); + unsigned int replyLength; + decodeBuffer.decodeValue(replyLength, 32, 4); + outputLength = 32 + (replyLength << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + outputMessage[1] = (unsigned char) nextByte; + unsigned char *nextDest = outputMessage + 32; + for (unsigned int i = 32; i < outputLength; i++) + { + decodeBuffer.decodeValue(nextByte, 8, 4); + *nextDest++ = (unsigned char) nextByte; + } + } + break; + case X_GetKeyboardControl: + { + unsigned int nextByte; + decodeBuffer.decodeValue(nextByte, 8, 2); + unsigned int replyLength; + decodeBuffer.decodeValue(replyLength, 32, 8); + outputLength = 32 + (replyLength << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + outputMessage[1] = (unsigned char) nextByte; + unsigned char *nextDest = outputMessage + 8; + for (unsigned int i = 8; i < outputLength; i++) + { + decodeBuffer.decodeValue(nextByte, 8, 4); + *nextDest++ = (unsigned char) nextByte; + } + } + break; + default: + { + if (requestOpcode == opcodeStore_ -> getUnpackParameters) + { + #ifdef TEST + *logofs << "handleWrite: Received get unpack parameters reply " + << "OPCODE#" << (unsigned int) opcodeStore_ -> getUnpackParameters + << ".\n" << logofs_flush; + #endif + + outputLength = 32 + PACK_METHOD_LIMIT; + + outputMessage = writeBuffer_.addMessage(outputLength); + + unsigned int method; + + // + // Let agent use only the unpack methods + // implemented at both sides. + // + + for (int i = 0; i < PACK_METHOD_LIMIT; i++) + { + decodeBuffer.decodeBoolValue(method); + + control -> RemoteUnpackMethods[i] = method; + + *(outputMessage + 32 + i) = + (control -> LocalUnpackMethods[i] == 1 && + method == 1); + } + } + else if (requestOpcode == opcodeStore_ -> getShmemParameters) + { + if (handleShmemReply(decodeBuffer, requestOpcode, + outputMessage, outputLength) < 0) + { + return -1; + } + } + else if (requestOpcode == opcodeStore_ -> getFontParameters) + { + if (handleFontReply(decodeBuffer, requestOpcode, + outputMessage, outputLength) < 0) + { + return -1; + } + } + else + { + #ifdef PANIC + *logofs << "handleWrite: PANIC! No matching request for " + << "reply with sequence number " << sequenceNum + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": No matching request for " + << "reply with sequence number " << sequenceNum + << ".\n"; + + return -1; + } + } + } + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleWrite: Handled reply to OPCODE#" + << (unsigned) requestOpcode << " (" << DumpOpcode(requestOpcode) + << ")" << " for FD#" << fd_ << " with sequence " << serverSequence_ + << ". Output size is " << outputLength << ".\n" << logofs_flush; + #endif + + statistics -> addRepliedRequest(requestOpcode); + } + else // End of if (sequenceQueue_.peek() && ...) + { + // + // Reply didn't match any request opcode. + // Check again if differential encoding + // is disabled. + // + + #ifdef DEBUG + *logofs << "handleWrite: Identified generic reply.\n" + << logofs_flush; + #endif + + requestOpcode = X_Reply; + + if (control -> RemoteDeltaCompression == 0) + { + int result = handleFastWriteReply(decodeBuffer, requestOpcode, + outputMessage, outputLength); + if (result < 0) + { + return -1; + } + else if (result > 0) + { + continue; + } + } + + // + // All replies whose opcode is not pushed in + // sequence number queue are cached together. + // Among such replies are those to extension + // requests. + // + + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_NXInternalGenericReply); + + handleDecode(decodeBuffer, serverCache_, messageStore, + requestOpcode, outputMessage, outputLength); + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleWrite: Handled generic reply for FD#" << fd_ + << " with sequence " << serverSequence_ << ". Output size is " + << outputLength << ".\n" << logofs_flush; + #endif + + statistics -> addRepliedRequest(requestOpcode); + + } // End of if (sequenceQueue_.peek() && ...) else ... + + // + // If any output was produced then write opcode, + // sequence number and size to the buffer. + // + + if (outputLength > 0) + { + *outputMessage = outputOpcode; + + PutUINT(serverSequence_, outputMessage + 2, bigEndian_); + + PutULONG((outputLength - 32) >> 2, outputMessage + 4, bigEndian_); + } + + } // End of if (outputOpcode == 1)... + else + { + // + // It's an event or error. + // + + unsigned int sequenceNum; + unsigned int sequenceDiff; + + decodeBuffer.decodeCachedValue(sequenceDiff, 16, + serverCache_ -> eventSequenceCache, 7); + + sequenceNum = (serverSequence_ + sequenceDiff) & 0xffff; + + serverSequence_ = sequenceNum; + + #ifdef DEBUG + *logofs << "handleWrite: Last server sequence number for FD#" + << fd_ << " is " << serverSequence_ << " with " + << "difference " << sequenceDiff << ".\n" + << logofs_flush; + #endif + + // + // Check if this is an error that matches + // a sequence number for which we were + // expecting a reply. + // + + if (outputOpcode == X_Error) + { + unsigned short int errorSequenceNum; + unsigned char errorOpcode; + + if (sequenceQueue_.peek(errorSequenceNum, errorOpcode) && + ((unsigned) errorSequenceNum == serverSequence_)) + { + // + // Remove the queued sequence of the reply. + // + + #ifdef TEST + *logofs << "handleWrite: WARNING! Removing reply to OPCODE#" + << (unsigned) errorOpcode << " sequence " + << errorSequenceNum << " for FD#" << fd_ + << " due to error.\n" << logofs_flush; + #endif + + sequenceQueue_.pop(errorSequenceNum, errorOpcode); + + // + // Send to the client the current sequence + // number, not the number that matched the + // reply. Because we are generating replies + // at our side, Xlib can incur in a sequence + // lost if the error comes after the auto- + // generated reply. + // + + if (control -> SessionMode == session_proxy) + { + #ifdef TEST + *logofs << "handleWrite: Updating last event's sequence " + << lastSequence_ << " to X server's error sequence " + << "number " << serverSequence_ << " for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + lastSequence_ = serverSequence_; + } + } + + // + // In case of errors always send to client the + // original X server's sequence associated to + // the failing request. + // + + if (control -> SessionMode != session_proxy) + { + #ifdef TEST + *logofs << "handleWrite: Updating last event's sequence " + << lastSequence_ << " to X server's error sequence " + << "number " << serverSequence_ << " for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + lastSequence_ = serverSequence_; + } + } + + // + // Check if by producing events at client side we + // have modified the events' sequence numbering. + // In this case taint the original sequence to + // comply with the last one known by client. + // + +/* +FIXME: Recover the sequence number if the proxy + is not connected to an agent. +*/ + if (serverSequence_ > lastSequence_ || + control -> SessionMode != session_proxy) + { + #ifdef DEBUG + *logofs << "handleWrite: Updating last event's sequence " + << lastSequence_ << " to X server's sequence number " + << serverSequence_ << " for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + lastSequence_ = serverSequence_; + } + #ifdef DEBUG + else if (serverSequence_ < lastSequence_) + { + // + // Use our last auto-generated sequence. + // + + *logofs << "handleWrite: Tainting sequence number " + << serverSequence_ << " to last event's sequence " + << lastSequence_ << " for FD#" << fd_ << ".\n" + << logofs_flush; + } + #endif + + // + // Check if remote side used fast encoding. + // + + if (control -> RemoteDeltaCompression == 0) + { + int result = handleFastWriteEvent(decodeBuffer, outputOpcode, + outputMessage, outputLength); + if (result < 0) + { + return -1; + } + else if (result > 0) + { + continue; + } + } + + // + // Make space for message in the outgoing buffer + // and write opcode and sequence number. + // + + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + + *outputMessage = outputOpcode; + + PutUINT(lastSequence_, outputMessage + 2, bigEndian_); + + #ifdef DEBUG + *logofs << "handleWrite: Going to handle event or error OPCODE#" + << (unsigned int) outputOpcode << " for FD#" << fd_ + << " sequence " << lastSequence_ << " (real was " + << serverSequence_ << ").\n" << logofs_flush; + #endif + + switch (outputOpcode) + { + case X_Error: + { + unsigned char code; + decodeBuffer.decodeCachedValue(code, 8, + serverCache_ -> errorCodeCache); + outputMessage[1] = code; + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleWrite: Handled error ERR_CODE#" + << (unsigned int) code << " for FD#" << fd_; + #endif + + if ((code != 11) && (code != 8) && + (code != 15) && (code != 1)) + { + decodeBuffer.decodeValue(value, 32, 16); + PutULONG(value, outputMessage + 4, bigEndian_); + + #if defined(TEST) || defined(OPCODES) + *logofs << " RES_ID#" << value; + #endif + } + + if (code >= 18) + { + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> errorMinorCache); + PutUINT(value, outputMessage + 8, bigEndian_); + + #if defined(TEST) || defined(OPCODES) + *logofs << " MIN_OP#" << value; + #endif + } + + decodeBuffer.decodeCachedValue(cValue, 8, + serverCache_ -> errorMajorCache); + outputMessage[10] = cValue; + + #if defined(TEST) || defined(OPCODES) + *logofs << " MAJ_OP#" << (unsigned int) cValue; + #endif + + if (code >= 18) + { + unsigned char *nextDest = outputMessage + 11; + for (unsigned int i = 11; i < 32; i++) + { + decodeBuffer.decodeValue(value, 8); + *nextDest++ = (unsigned char) cValue; + } + } + + #if defined(TEST) || defined(OPCODES) + *logofs << " sequence " << lastSequence_ << " (real was " + << serverSequence_ << ") . Size is " + << (unsigned int) outputLength << ".\n" + << logofs_flush; + #endif + } + break; + case ButtonPress: + case ButtonRelease: + case KeyPress: + case KeyRelease: + case MotionNotify: + case EnterNotify: + case LeaveNotify: + { + if (outputOpcode == MotionNotify) + { + decodeBuffer.decodeBoolValue(value); + } + else if (outputOpcode == EnterNotify || outputOpcode == LeaveNotify) + { + decodeBuffer.decodeValue(value, 3); + } + else if (outputOpcode == KeyRelease) + { + decodeBuffer.decodeBoolValue(value); + if (value) + { + value = serverCache_ -> keyPressLastKey; + } + else + { + decodeBuffer.decodeValue(value, 8); + } + } + else if (outputOpcode == ButtonPress || outputOpcode == ButtonRelease) + { + decodeBuffer.decodeCachedValue(cValue, 8, + serverCache_ -> buttonCache); + value = (unsigned int) cValue; + } + else + { + decodeBuffer.decodeValue(value, 8); + } + + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeCachedValue(value, 32, + serverCache_ -> motionNotifyTimestampCache, 9); + serverCache_ -> lastTimestamp += value; + PutULONG(serverCache_ -> lastTimestamp, outputMessage + 4, + bigEndian_); + unsigned char *nextDest = outputMessage + 8; + int skipRest = 0; + if (outputOpcode == KeyRelease) + { + decodeBuffer.decodeBoolValue(value); + if (value) + { + for (unsigned int i = 0; i < 23; i++) + { + *nextDest++ = serverCache_ -> keyPressCache[i]; + } + skipRest = 1; + } + } + + if (!skipRest) + { + for (unsigned int i = 0; i < 3; i++) + { + decodeBuffer.decodeCachedValue(value, 29, + *serverCache_ -> motionNotifyWindowCache[i], 6); + PutULONG(value, nextDest, bigEndian_); + nextDest += 4; + } + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyRootXCache, 6); + serverCache_ -> motionNotifyLastRootX += value; + PutUINT(serverCache_ -> motionNotifyLastRootX, outputMessage + 20, + bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyRootYCache, 6); + serverCache_ -> motionNotifyLastRootY += value; + PutUINT(serverCache_ -> motionNotifyLastRootY, outputMessage + 22, + bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyEventXCache, 6); + PutUINT(serverCache_ -> motionNotifyLastRootX + value, + outputMessage + 24, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyEventYCache, 6); + PutUINT(serverCache_ -> motionNotifyLastRootY + value, + outputMessage + 26, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> motionNotifyStateCache); + PutUINT(value, outputMessage + 28, bigEndian_); + if (outputOpcode == EnterNotify || outputOpcode == LeaveNotify) + { + decodeBuffer.decodeValue(value, 2); + } + else + { + decodeBuffer.decodeBoolValue(value); + } + outputMessage[30] = (unsigned char) value; + if (outputOpcode == EnterNotify || outputOpcode == LeaveNotify) + { + decodeBuffer.decodeValue(value, 2); + outputMessage[31] = (unsigned char) value; + } + else if (outputOpcode == KeyPress) + { + serverCache_ -> keyPressLastKey = outputMessage[1]; + for (unsigned int i = 8; i < 31; i++) + { + serverCache_ -> keyPressCache[i - 8] = outputMessage[i]; + } + } + } + } + break; + case ColormapNotify: + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> colormapNotifyWindowCache, 8); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> colormapNotifyColormapCache, 8); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeBoolValue(value); + outputMessage[12] = (unsigned char) value; + decodeBuffer.decodeBoolValue(value); + outputMessage[13] = (unsigned char) value; + } + break; + case ConfigureNotify: + { + unsigned char *nextDest = outputMessage + 4; + for (unsigned int i = 0; i < 3; i++) + { + decodeBuffer.decodeCachedValue(value, 29, + *serverCache_ -> configureNotifyWindowCache[i], 9); + PutULONG(value, nextDest, bigEndian_); + nextDest += 4; + } + for (unsigned int j = 0; j < 5; j++) + { + decodeBuffer.decodeCachedValue(value, 16, + *serverCache_ -> configureNotifyGeomCache[j], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + decodeBuffer.decodeBoolValue(value); + *nextDest = value; + } + break; + case CreateNotify: + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> createNotifyWindowCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeValue(value, 29, 5); + serverCache_ -> createNotifyLastWindow += value; + serverCache_ -> createNotifyLastWindow &= 0x1fffffff; + PutULONG(serverCache_ -> createNotifyLastWindow, outputMessage + 8, + bigEndian_); + unsigned char* nextDest = outputMessage + 12; + for (unsigned int i = 0; i < 5; i++) + { + decodeBuffer.decodeValue(value, 16, 9); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + decodeBuffer.decodeBoolValue(value); + *nextDest = (unsigned char) value; + } + break; + case Expose: + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> exposeWindowCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned char *nextDest = outputMessage + 8; + for (unsigned int i = 0; i < 5; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *serverCache_ -> exposeGeomCache[i], 6); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + } + break; + case FocusIn: + case FocusOut: + { + decodeBuffer.decodeValue(value, 3); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> focusInWindowCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeValue(value, 2); + outputMessage[8] = (unsigned char) value; + } + break; + case KeymapNotify: + { + decodeBuffer.decodeBoolValue(value); + if (value) + memcpy(outputMessage + 1, ServerCache::lastKeymap.getData(), 31); + else + { + unsigned char *nextDest = outputMessage + 1; + for (unsigned int i = 1; i < 32; i++) + { + decodeBuffer.decodeValue(value, 8); + *nextDest++ = (unsigned char) value; + } + ServerCache::lastKeymap.set(31, outputMessage + 1); + } + } + break; + case MapNotify: + case UnmapNotify: + case DestroyNotify: + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> mapNotifyEventCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> mapNotifyWindowCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + if (outputOpcode == MapNotify || outputOpcode == UnmapNotify) + { + decodeBuffer.decodeBoolValue(value); + outputMessage[12] = (unsigned char) value; + } + } + break; + case NoExpose: + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> noExposeDrawableCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + serverCache_ -> noExposeMinorCache); + PutUINT(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(cValue, 8, + serverCache_ -> noExposeMajorCache); + outputMessage[10] = cValue; + } + break; + case PropertyNotify: + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> propertyNotifyWindowCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> propertyNotifyAtomCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeValue(value, 32, 9); + serverCache_ -> lastTimestamp += value; + PutULONG(serverCache_ -> lastTimestamp, outputMessage + 12, + bigEndian_); + decodeBuffer.decodeBoolValue(value); + outputMessage[16] = (unsigned char) value; + } + break; + case ReparentNotify: + { + unsigned char* nextDest = outputMessage + 4; + for (unsigned int i = 0; i < 3; i++) + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> reparentNotifyWindowCache, 9); + PutULONG(value, nextDest, bigEndian_); + nextDest += 4; + } + decodeBuffer.decodeValue(value, 16, 6); + PutUINT(value, nextDest, bigEndian_); + decodeBuffer.decodeValue(value, 16, 6); + PutUINT(value, nextDest + 2, bigEndian_); + decodeBuffer.decodeBoolValue(value); + outputMessage[20] = (unsigned char)value; + } + break; + case SelectionClear: + { + decodeBuffer.decodeValue(value, 32, 9); + serverCache_ -> lastTimestamp += value; + PutULONG(serverCache_ -> lastTimestamp, outputMessage + 4, + bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> selectionClearWindowCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> selectionClearAtomCache, 9); + PutULONG(value, outputMessage + 12, bigEndian_); + } + break; + case SelectionRequest: + { + decodeBuffer.decodeValue(value, 32, 9); + serverCache_ -> lastTimestamp += value; + PutULONG(serverCache_ -> lastTimestamp, outputMessage + 4, + bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> selectionClearWindowCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> selectionClearWindowCache, 9); + PutULONG(value, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> selectionClearAtomCache, 9); + PutULONG(value, outputMessage + 16, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> selectionClearAtomCache, 9); + PutULONG(value, outputMessage + 20, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> selectionClearAtomCache, 9); + PutULONG(value, outputMessage + 24, bigEndian_); + } + break; + case VisibilityNotify: + { + decodeBuffer.decodeCachedValue(value, 29, + serverCache_ -> visibilityNotifyWindowCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeValue(value, 2); + outputMessage[8] = (unsigned char) value; + } + break; + default: + { + #ifdef TEST + *logofs << "handleWrite: Using generic event compression " + << "for OPCODE#" << (unsigned int) outputOpcode + << ".\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(*(outputMessage + 1), 8, + serverCache_ -> genericEventCharCache); + + for (unsigned int i = 0; i < 14; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *serverCache_ -> genericEventIntCache[i]); + + PutUINT(value, outputMessage + i * 2 + 4, bigEndian_); + } + } + } // End of switch (outputOpcode)... + + #if defined(TEST) || defined(OPCODES) + if (outputOpcode != X_Error) + { + *logofs << "handleWrite: Handled event OPCODE#" + << (unsigned int) outputOpcode << " for FD#" + << fd_ << " sequence " << lastSequence_ << " (real was " + << serverSequence_ << "). Size is " << outputLength + << ".\n" << logofs_flush; + } + #endif + + // + // Check if we need to suppress the error. + // + + if (outputOpcode == X_Error && + handleTaintSyncError(*(outputMessage + 10)) > 0) + { + #if defined(TEST) || defined(OPCODES) + *logofs << "handleWrite: WARNING! Suppressed error OPCODE#" + << (unsigned int) outputOpcode << " for FD#" + << fd_ << " sequence " << lastSequence_ << ".\n" + << logofs_flush; + #endif + + writeBuffer_.removeMessage(32); + } + + } // End of if (outputOpcode == 1)... else ... + + // + // Check if we produced enough data. We need to + // decode all provided messages. Just update the + // finish flag in case of failure. + // + + handleFlush(flush_if_needed); + + } // End of while (decodeBuffer.decodeOpcodeValue(outputOpcode, 8, ... + + } // End of the decoding block. + + // + // Write any remaining data to the X connection. + // + + if (handleFlush(flush_if_any) < 0) + { + return -1; + } + + return 1; +} + +// +// End of handleWrite(). +// + +// +// Other members. +// + +int ClientChannel::handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, + T_store_action action, int position, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + #if defined(TEST) || defined(SPLIT) + + // Since ProtoStep8 (#issue 108) + *logofs << "handleSplit: PANIC! SPLIT! Split should " + << "not be enabled for message " << "OPCODE#" + << (unsigned int) store -> opcode() << ".\n" + << logofs_flush; + + HandleCleanup(); + + #endif + + // + // Refuse the split if it is not introduced + // by a start split. + // + + // Since ProtoStep7 (#issue 108) + if (splitState_.resource == nothing || enableSplit_ == 0) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Nothing to do for message " + << "OPCODE#" << (unsigned int) store -> opcode() + << " of size " << size << " position " << position + << " with action [" << DumpAction(action) << "] at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeBoolValue(0); + + return 0; + } + + // + // It's not advisable to allocate the store at + // the time we receive the start-split because + // we may process all the splits received and + // deallocate the store even before we receive + // the end split. Another message for the same + // split sequence may then come and we would + // have a null split store. + // + + handleSplitStoreAlloc(&splitResources_, splitState_.resource); + + // + // Check if the split was actually requested by + // the agent and if the request was saved in the + // message store. The split can also be refused + // if the message is smaller than the threshold + // or if the split store is already full. + // + + if (mustSplitMessage(splitState_.resource) == 0) + { + if (action == IS_HIT || canSplitMessage(splitState_.mode, size) == 0) + { + #if defined(TEST) || defined(SPLIT) + + if (splitState_.mode == split_none) + { + #ifdef PANIC + *logofs << "handleSplit: PANIC! SPLIT! Split state has " + << "mode 'none'.\n" << logofs_flush; + #endif + + HandleCleanup(); + } + + if (action != IS_HIT && (int) size >= + control -> SplitDataThreshold) + { + #ifdef WARNING + *logofs << "handleSplit: WARNING! SPLIT! Split stores have " + << clientStore_ -> getSplitTotalSize() << " messages " + << "and " << clientStore_ -> getSplitTotalStorageSize() + << " allocated bytes.\n" << logofs_flush; + #endif + } + + #endif + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Message OPCODE#" + << (unsigned int) store -> opcode() << " of size " << size + << " [not split] with resource " << splitState_.resource + << " mode " << splitState_.mode << " position " << position + << " and action [" << DumpAction(action) << "] at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeBoolValue(0); + + return 0; + } + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Message OPCODE#" + << (unsigned int) store -> opcode() << " of size " << size + << " [split] with resource " << splitState_.resource + << " mode " << splitState_.mode << " position " << position + << " and action [" << DumpAction(action) << "] at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeBoolValue(1); + + T_checksum checksum = NULL; + + if (action == IS_ADDED) + { + checksum = store -> getChecksum(position); + } + else if (action == is_discarded) + { + // + // Generate the checksum on the fly. + // + + checksum = store -> getChecksum(buffer, size, bigEndian_); + } + + // + // The method must abort the connection + // if it can't allocate the split. + // + + Split *splitMessage = clientStore_ -> getSplitStore(splitState_.resource) -> + add(store, splitState_.resource, splitState_.mode, + position, action, checksum, buffer, size); + + // + // Send the checksum. By using the checksum, + // the remote end will try to locate the + // message and load it from disk. + // + + if (action == IS_HIT) + { + splitMessage -> setState(split_loaded); + } + else if (handleSplitChecksum(encodeBuffer, checksum) == 0) + { + // + // If the checksum is not sent, for example + // because loading of messages from disk is + // disabled, then mark the split as missed. + // + + #ifdef WARNING + *logofs << "handleSplit: WARNING! Checksum not sent. " + << "Marking the split as [missed].\n" + << logofs_flush; + #endif + + splitMessage -> setState(split_missed); + } + + if (action == is_discarded) + { + delete [] checksum; + } + + // + // Check if we are ready to send a new split + // for this store. + // + + handleSplitPending(splitState_.resource); + + #if defined(TEST) || defined(SPLIT) + + *logofs << "handleSplit: SPLIT! There are " << clientStore_ -> + getSplitTotalSize() << " messages and " << clientStore_ -> + getSplitTotalStorageSize() << " bytes to send in " + << "the split stores.\n" << logofs_flush; + + clientStore_ -> dumpSplitStore(splitState_.resource); + + #endif + + return 1; +} + +int ClientChannel::handleSplit(EncodeBuffer &encodeBuffer) +{ + // + // Determine the maximum amount of bytes + // we can write in this iteration. + // + + int total = control -> SplitDataPacketLimit; + + int bytes = total; + int splits = 0; + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Handling splits " + << "for FD#" << fd_ << " with " << clientStore_ -> + getSplitTotalSize() << " elements and " << total + << " bytes to write at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + if (proxy -> handleAsyncSwitch(fd_) < 0) + { + return -1; + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Looping to find " + << "if there is any split to send.\n" + << logofs_flush; + #endif + + SplitStore *splitStore; + + Split *splitMessage; + + // + // Divide the available bandwidth among all the active + // split stores by implementing a simple round-robin + // mechanism. This can be extended by using an external + // function returning the number of bytes to be written + // based on the state of the split (splits which didn't + // receive yet a confirmation event could be delayed), + // the current bitrate, and by letting the agent asso- + // ciate a priority to the resource in the start split + // operation. + // + + splitState_.pending = 0; + + splitResources_.rotate(); + + // + // Copy the list since elements can be removed + // in the middle of the loop. + // + + T_list splitList = splitResources_.copyList(); + + for (T_list::iterator j = splitList.begin(); + j != splitList.end(); j++) + { + int resource = *j; + + #ifdef DEBUG + *logofs << "handleSplit: SPLIT! Looping with current " + << "resource " << resource << ".\n" + << logofs_flush; + #endif + + splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore != NULL) + { + // + // Don't send more than the the packet size + // bytes but ensure that we abort any split + // found in the disk cache. + // + + for (;;) + { + #if defined(TEST) || defined(SPLIT) + + clientStore_ -> dumpSplitStore(resource); + + #endif + + splitMessage = splitStore -> getFirstSplit(); + + if (splitMessage == NULL) + { + // + // We have created the store after a start + // split but no message was added yet. + // + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: WARNING! SPLIT! The split store " + << "is still empty.\n" << logofs_flush; + #endif + + break; + } + + // + // Splits already aborted can't be in the + // split store. + // + + #if defined(TEST) || defined(SPLIT) + + if (splitMessage -> getState() == split_aborted) + { + *logofs << "handleSplit: PANIC! SPLIT! Found an " + << "aborted split in store [" << resource + << "].\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + // + // Check if there are more messages in the + // store that can be aborted or if we have + // exceeded the number of bytes we can send + // for this iteration. + // + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Checking closure " + << "of the inner loop with " << bytes + << " bytes to write and split state [" + << DumpState(splitMessage -> getState()) + << "].\n" << logofs_flush; + #endif + + if ((splitMessage -> getMode() == split_sync && + splitMessage -> getState() == split_added) || + (bytes <= 0 && splitMessage -> + getState() != split_loaded)) + { + break; + } + + // + // If the split was loaded at the remote + // side abort it immediately. + // + + if (splitMessage -> getState() == split_loaded) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Sending more data " + << "for store [" << resource << "] with " + << "a split to be aborted.\n" + << logofs_flush; + #endif + + if (handleSplitSend(encodeBuffer, resource, splits, bytes) < 0) + { + return -1; + } + } + else if (bytes > 0) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Sending more data " + << "for store [" << resource << "] with " + << bytes << " bytes to send.\n" + << logofs_flush; + #endif + + if (handleSplitSend(encodeBuffer, resource, splits, bytes) < 0) + { + return -1; + } + } + + // + // Check if the split store was deleted. + // + + splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore == NULL) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Exiting from the " + << "inner loop with split store [" << resource + << "] destroyed.\n" << logofs_flush; + #endif + + break; + } + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Completed handling splits " + << "for store [" << resource << "] with " << bytes + << " bytes still to send.\n" << logofs_flush; + #endif + + // + // Check if there is still a split to + // send for the store just processed. + // + + handleSplitPending(resource); + } + } + + #if defined(TEST) || defined(SPLIT) + + if (splits == 0) + { + #ifdef PANIC + *logofs << "handleSplit: PANIC! Function called but " + << "no split message was sent.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + + *logofs << "handleSplit: SPLIT! Sent " << splits + << " splits and " << total - bytes << " bytes for FD#" << fd_ + << " with " << clientStore_ -> getSplitTotalStorageSize() + << " bytes and [" << clientStore_ -> getSplitTotalSize() + << "] splits remaining.\n" << logofs_flush; + + *logofs << "handleSplit: SPLIT! The pending split flag is " + << splitState_.pending << " with " << clientStore_ -> + getSplitTotalSize() << " splits in the split stores.\n" + << logofs_flush; + + clientStore_ -> dumpSplitStores(); + + #endif + + return 1; +} + +int ClientChannel::handleSplitSend(EncodeBuffer &encodeBuffer, int resource, + int &splits, int &bytes) +{ + #if defined(TEST) || defined(SPLIT) + + SplitStore *splitStore = clientStore_ -> getSplitStore(resource); + + Split *splitMessage = splitStore -> getFirstSplit(); + + if (splitStore -> getResource() != resource || + splitMessage -> getResource() != resource) + { + #ifdef PANIC + *logofs << "handleSplitSend: PANIC! The resource doesn't " + << "match the split store.\n" << logofs_flush; + #endif + + HandleCleanup(); + } + + *logofs << "handleSplitSend: SPLIT! Sending message " + << "OPCODE#" << (unsigned) opcodeStore_ -> splitData + << " for resource " << splitMessage -> getResource() + << " with request " << splitMessage -> getRequest() + << " position " << splitMessage -> getPosition() + << " and " << bytes << " bytes to write.\n" + << logofs_flush; + #endif + + // + // Use a special opcode to signal the other + // side this is part of a split and not a + // new message. + // + + encodeBuffer.encodeOpcodeValue(opcodeStore_ -> splitData, + clientCache_ -> opcodeCache); + + encodeBuffer.encodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + int result = clientStore_ -> getSplitStore(resource) -> + send(encodeBuffer, bytes); + + if (result < 0) + { + #ifdef PANIC + *logofs << "handleSplit: PANIC! Error sending splits for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Error sending splits for FD#" + << fd_ << ".\n"; + + return -1; + } + + // + // Get the bits written and update the + // statistics for this special opcode. + // + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(SPLIT)|| defined(OPCODES) + *logofs << "handleSplitSend: SPLIT! Handled request OPCODE#" + << (unsigned int) opcodeStore_ -> splitData << " (" + << DumpOpcode(opcodeStore_ -> splitData) << ")" << " for FD#" + << fd_ << " sequence none. 0 bytes in, " << bits << " bits (" + << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; + #endif + + statistics -> addRequestBits(opcodeStore_ -> splitData, 0, bits); + + bytes -= bits >> 3; + + splits++; + + if (result == 1) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitSend: SPLIT! Split at the head " + << "of the list was completely transferred.\n" + << logofs_flush; + #endif + + // + // The split at the head of the list was + // completely transferred. + // + + handleRestart(sequence_deferred, resource); + } + #if defined(TEST) || defined(SPLIT) + else + { + *logofs << "handleSplitSend: SPLIT! More data to send " + << "for the split at the head of the list.\n" + << logofs_flush; + } + #endif + + return result; +} + +int ClientChannel::handleSplitChecksum(EncodeBuffer &encodeBuffer, T_checksum checksum) +{ + // + // Send the checksum only if the loading + // or the saving of the message to the + // persistent image cache is enabled. + // + + if ((control -> ImageCacheEnableLoad == 1 || + control -> ImageCacheEnableSave == 1) && + (enableLoad_ == 1 || enableSave_ == 1)) + { + encodeBuffer.encodeBoolValue(1); + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + encodeBuffer.encodeValue((unsigned int) checksum[i], 8); + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitChecksum: SPLIT! Sent checksum " + << "[" << DumpChecksum(checksum) << "].\n" + << logofs_flush; + #endif + + return 1; + } + else + { + encodeBuffer.encodeBoolValue(0); + + return 0; + } +} + +void ClientChannel::handleSplitPending() +{ + #if defined(TEST) || defined(SPLIT) + + int previous = splitState_.pending; + + #endif + + if (clientStore_ -> getSplitTotalSize() == 0) + { + splitState_.pending = 0; + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitPending: SPLIT! Set the pending " + << "split flag to " << splitState_.pending + << " with split stores empty.\n" + << logofs_flush; + #endif + } + else + { + // + // Loop through the stores to find if + // there is any split that has become + // ready. + // + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitPending: WARNING! SPLIT! Looping to " + << "find if there is any split pending.\n" + << logofs_flush; + #endif + + splitState_.pending = 0; + + T_list &splitList = splitResources_.getList(); + + for (T_list::iterator j = splitList.begin(); + j != splitList.end(); j++) + { + int resource = *j; + + SplitStore *splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore != NULL) + { + #if defined(TEST) || defined(SPLIT) + + clientStore_ -> dumpSplitStore(resource); + + #endif + + Split *splitMessage = splitStore -> getFirstSplit(); + + if (splitMessage != NULL && canSendSplit(splitMessage) == 1) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitPending: SPLIT! Found a pending " + << "split in store [" << resource << "].\n" + << logofs_flush; + #endif + + splitState_.pending = 1; + + #if defined(TEST) || defined(SPLIT) + + if (splitMessage -> getState() == split_loaded) + { + *logofs << "handleSplitPending: PANIC! SPLIT! Found a " + << "loaded split in store [" << resource + << "].\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + break; + } + } + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitPending: SPLIT! Set the pending " + << "split flag to " << splitState_.pending + << " with " << clientStore_ -> getSplitTotalSize() + << " splits in the split stores.\n" + << logofs_flush; + #endif + } + + #if defined(TEST) || defined(SPLIT) + + if (splitState_.pending != previous) + { + *logofs << "handleSplitPending: SPLIT! Pending state " + << "changed from " << previous << " to " + << splitState_.pending << ".\n" + << logofs_flush; + } + + #endif +} + +int ClientChannel::handleSplitEvent(EncodeBuffer &encodeBuffer, Split *splitMessage) +{ + SplitStore *splitStore; + + int resource = splitMessage -> getResource(); + + #if defined(TEST) || defined(INFO) + + splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore == NULL) + { + #ifdef PANIC + *logofs << "handleSplitEvent: PANIC! The split store can't " + << "be NULL handling abort splits.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + else if (splitMessage -> getState() != split_loaded) + { + *logofs << "handleSplitEvent: PANIC! Can't find the split " + << "to be aborted.\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + // + // Send any split that it is possible to + // abort until the store is either empty + // or the next split can't be aborted. + // + + if (proxy -> handleAsyncSwitch(fd_) < 0) + { + return -1; + } + + while ((splitStore = clientStore_ -> + getSplitStore(resource)) != NULL && + (splitMessage = splitStore -> getFirstSplit()) != NULL && + splitMessage -> getState() == split_loaded) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Aborting split with " + << "checksum [" << DumpChecksum(splitMessage -> + getChecksum()) << "] for resource " << resource + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + int any = 0; + + if (handleSplitSend(encodeBuffer, resource, any, any) < 0) + { + return -1; + } + } + + #if defined(TEST) || defined(SPLIT) + + if ((splitStore = clientStore_ -> + getSplitStore(resource)) == NULL) + { + *logofs << "handleSplitEvent: SPLIT! The split store [" + << resource << "] has been destroyed.\n" + << logofs_flush; + } + else if ((splitMessage = splitStore -> + getFirstSplit()) == NULL) + { + *logofs << "handleSplitEvent: SPLIT! The split store [" + << resource << "] is empty.\n" + << logofs_flush; + } + else if (splitMessage -> getState() != split_loaded) + { + *logofs << "handleSplitEvent: SPLIT! The split at the " + << "head of store [" << resource << "] doesn't " + << "need to be aborted.\n" << logofs_flush; + } + + #endif + + return 1; +} + +int ClientChannel::handleSplitEvent(DecodeBuffer &decodeBuffer) +{ + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Handling abort " + << "split messages for FD#" << fd_ << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + // Since ProtoStep7 (#issue 108) + + // + // Decode the information about the + // message to be updated. + // + + unsigned char resource; + + decodeBuffer.decodeCachedValue(resource, 8, + serverCache_ -> resourceCache); + + unsigned int loaded; + + decodeBuffer.decodeBoolValue(loaded); + + unsigned char request; + unsigned int size; + + if (loaded == 1) + { + decodeBuffer.decodeOpcodeValue(request, serverCache_ -> abortOpcodeCache); + + decodeBuffer.decodeValue(size, 32, 14); + } + else + { + request = 0; + size = 0; + } + + unsigned int value; + + md5_byte_t checksum[MD5_LENGTH]; + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + decodeBuffer.decodeValue(value, 8); + + checksum[i] = (unsigned char) value; + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Checking split " + << "with checksum [" << DumpChecksum(checksum) + << "] loaded " << loaded << " request " << (unsigned int) + request << " compressed size " << size << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + Split *splitMessage = handleSplitFind(checksum, resource); + + if (splitMessage != NULL) + { + if (loaded == 1) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Marked split with " + << "checksum [" << DumpChecksum(checksum) << "] " + << "as [loaded] at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + splitMessage -> setState(split_loaded); + + #if defined(TEST) || defined(SPLIT) + + if (splitMessage -> compressedSize() != (int) size) + { + *logofs << "handleSplitEvent: WARNING! SPLIT! Updating " + << "compressed data size from " << splitMessage -> + compressedSize() << " to " << size << ".\n" + << logofs_flush; + } + + #endif + + splitMessage -> compressedSize(size); + + // + // The splits to be aborted are checked by the split + // store at the time we are going to send a new chunk + // of split data. The splits must be strictly handled + // in the same order as they were added to the split + // store and the split we want to abort here may be + // not at the head of the list. + // + + if (splitMessage == clientStore_ -> + getSplitStore(resource) -> getFirstSplit()) + { + // + // We don't need to flush this packet immediately. + // The abort can be sent at any time to the remote + // proxy. What's important is that we restart the + // agent resource as soon as possible. + // + + #if defined(TEST) || defined(SPLIT) + + T_timestamp startTs = getTimestamp(); + + *logofs << "handleSplitEvent: SPLIT! Encoding abort " + << "split events for FD#" << fd_ << " with " + << "resource " << (unsigned) resource << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + if (proxy -> handleAsyncSplit(fd_, splitMessage) < 0) + { + return -1; + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Spent " + << diffTimestamp(startTs, getTimestamp()) << " Ms " + << "handling abort split events for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + // + // Check if we can clear the pending flag. + // + + handleSplitPending(); + } + #if defined(TEST) || defined(SPLIT) + else + { + *logofs << "handleSplitEvent: WARNING! SPLIT! Abort split " + << "event not sent because not at the head " + << "of the list.\n" << logofs_flush; + } + #endif + } + else + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Marked split with " + << "checksum [" << DumpChecksum(checksum) << "] " + << "as [missed] at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + splitMessage -> setState(split_missed); + + // + // Check if we can set the pending flag. + // + + handleSplitPending(resource); + } + } + else + { + // + // The split report came after the split was already + // sent or the split store deleted. If the message + // had been loaded from disk by the remote side, we + // need to update the compressed size in our message + // store or the checksum will not match at the time + // we will try to save the message store on disk. + // + + if (loaded == 1 && size != 0) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: WARNING! SPLIT! Can't find " + << "the split. Updating in the message store.\n" + << logofs_flush; + #endif + + MessageStore *store = clientStore_ -> getRequestStore(request); + + if (store != NULL) + { + store -> updateData(checksum, size); + } + #if defined(TEST) || defined(SPLIT) + else + { + #ifdef PANIC + *logofs << "handleSplitEvent: PANIC! The message store " + << "can't be null.\n" << logofs_flush; + #endif + + HandleCleanup(); + } + #endif + } + #if defined(TEST) || defined(SPLIT) + else + { + *logofs << "handleSplitEvent: WARNING! SPLIT! No need to " + << "update the store with loaded " << loaded + << " and compressed size " << size << ".\n" + << logofs_flush; + } + #endif + } + + return 1; +} + +Split *ClientChannel::handleSplitFind(T_checksum checksum, int resource) +{ + // + // It can be that we handled all the splits, + // restarted the resource and deleted the + // store before the event could even reach + // our side. + // + + SplitStore *splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore != NULL) + { + Split *splitMessage; + + T_splits *splitList = splitStore -> getSplits(); + + for (T_splits::iterator i = splitList -> begin(); + i != splitList -> end(); i++) + { + splitMessage = (*i); + + if (splitMessage -> getChecksum() != NULL) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitFind: SPLIT! Comparing with message [" + << DumpChecksum(splitMessage -> getChecksum()) + << "].\n" << logofs_flush; + #endif + + if (memcmp(checksum, splitMessage -> getChecksum(), MD5_LENGTH) == 0) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitFind: SPLIT! Located split for " + << "checksum [" << DumpChecksum(checksum) << "] " + << "in store [" << splitStore -> getResource() + << "].\n" << logofs_flush; + #endif + + return splitMessage; + } + } + } + } + #if defined(TEST) || defined(SPLIT) + else + { + *logofs << "handleSplitFind: WARNING! SPLIT! The split store " + << "was already deleted.\n" << logofs_flush; + } + #endif + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitFind: WARNING! SPLIT! Can't find the " + << "split for checksum [" << DumpChecksum(checksum) + << "].\n" << logofs_flush; + #endif + + return NULL; +} + +int ClientChannel::handleRestart(T_sequence_mode mode, int resource) +{ + // + // The agent must send a start-split message, followed by the + // X messages that may be optionally split by the proxy. Usu- + // ally, in the middle of a start-split/end-split sequence is + // a single PutImage() or PutPackedImage(), that, in turn, + // can generate multiple partial requests, like a SetUnpack- + // Colormap() and SetUnpackAlpha() followed by the image that + // must be transferred. Multiple requests may be also genera- + // ted because the maximum size of a X request has been exce- + // eded, so that Xlib has divided the single image in multi- + // ple sub-image requests. The agent doesn't need to take care + // of that, except tracking the result of the split operation. + // + // By monitoring the notify events sent by the proxy, the + // agent will have to implement its own strategy to deal with + // its resources (for example its clients). For example: + // + // - It will issue a new image request and suspend a client + // if the image was not entirely sent in the main X oputput + // stream. + // + // - It will choose to commit or discard the messages after + // they are recomposed at the remote side. The set of mes- + // sages that will have to be committed will include all + // messages that were part of the split (the colormap, the + // alpha channel). + // + // - It will restart its own client, in the case it had been + // suspended. + // + // A more useful strategy would be to replace the original im- + // age with a tiny 'placeholder' if a split took place, and + // synchronize the content of the drawable at later time. This + // is generally referred as 'lazy encoding'. + // + // The agent will be able to identify the original split ope- + // ration (the one marked with the start-spit) by the small + // integer number (0-255) referred to as the 'resource' field. + // + // Before the proxy will be able to report the status of the + // split, the agent will have to close the sequence by issueing + // an end-split. The proxy will then report the result of the + // operation, so that the agent will have the option of suspend- + // ing the client or marking the drawable as dirty and take + // care of synchronizing it at later time. + // + // One of the following cases may be encountered: + // + // notify_no_split: All messages were sent in the main out- + // put stream, so that no split actually + // took place. + // + // notify_start_split: One or more messages were split, so, + // at discrection of the agent, the client + // may be suspended until the transferral + // is completed. + // + // notify_commit_split: One of the requests that made up the + // split was recomposed. The agent should + // either commit the given request or tell + // the proxy to discard it. + // + // notify_end_split: The split was duly completed. The agent + // can restart the client. + // + // notify_empty_split: No more split operation are pending. + // The agent can use this information to + // implement specific strategies requiring + // that all messages have been recomposed + // at the remote end, like updating the + // drawables that were not synchronized + // because of the lazy encoding. + // + // By checking the split and commit store we can determine if we + // need to send a new notification event to the agent. There can + // be four different cases: + // + // - If the split store is not null and not empty, we are still + // in the middle of a split. + // + // - If the commit store is not empty, we completely recomposed + // a full message and can send a new commit notify. + // + // - If the split store has become empty, we recomposed all the + // messages added for the given resource, and so will be able + // to restart the resource. + // + // - If no more messages are in the split stores, we can notify + // an empty split event to the agent. + // + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleRestart: SPLIT! Handling [" + << (mode == sequence_immediate ? "immediate" : "deferred") + << "] restart events for resource " << resource << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + SplitStore *splitStore = clientStore_ -> getSplitStore(resource); + + if (mode == sequence_immediate) + { + // + // We have received an end-split request. If the store + // was not deleted already, we mark the last split added + // as the one ending the row for this resource. If the + // commit() function returns 0 it means that the split + // store is either empty or that we did not add any split + // for this resource. This is because when connected to + // an old proxy version we only have a single store for + // all the resources. + // + // It can happen that all the split messages that were + // originally appended to the list were completely sent + // before our client had the chance of ending the split + // sequence. In this case the split store will be empty + // or already deleted and so we will be able to restart + // the resource. + // + + #if defined(TEST) || defined(SPLIT) + + if (splitStore == NULL) + { + *logofs << "handleRestart: WARNING! SPLIT! Split store [" + << resource << "] was already deleted.\n" + << logofs_flush; + } + else + { + clientStore_ -> dumpSplitStore(resource); + } + + #endif + + if (splitStore == NULL || splitStore -> getSize() == 0) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleRestart: SPLIT! Immediate agent split event " + << "TYPE#" << (unsigned) opcodeStore_ -> noSplitNotify + << " [no split] with resource " << resource + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + if (handleNotify(notify_no_split, sequence_immediate, + resource, nothing, nothing) < 0) + { + return -1; + } + } + else + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleRestart: SPLIT! Immediate agent split event " + << "TYPE#" << (unsigned) opcodeStore_ -> startSplitNotify + << " [start split] with resource " << resource + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + if (handleNotify(notify_start_split, sequence_immediate, + resource, nothing, nothing) < 0) + { + return -1; + } + } + } + else + { + // + // We have completely transferred a message + // that was put in the split store. + // + // The id of the resource can be different + // than the index of the store if we are + // connected to an old proxy. + // + + #if defined(TEST) || defined(SPLIT) + + if (splitStore == NULL) + { + #ifdef PANIC + *logofs << "handleRestart: PANIC! The split store can't " + << "be NULL handling deferred restart events.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + else + { + clientStore_ -> dumpSplitStore(resource); + } + + #endif + + CommitStore *commitStore = clientStore_ -> getCommitStore(); + + #if defined(TEST) || defined(SPLIT) + + clientStore_ -> dumpCommitStore(); + + #endif + + // + // Check if there is any commit to notify. + // + + Split *split; + + T_splits *commitList = commitStore -> getSplits(); + + for (T_splits::iterator i = commitList -> begin(); + i != commitList -> end(); i++) + { + split = *i; + + if (split -> getState() != split_notified) + { + #if defined(TEST) || defined(SPLIT) + + if (split -> getResource() != resource) + { + #ifdef PANIC + *logofs << "handleSplitSend: PANIC! The resource doesn't " + << "match the split store.\n" << logofs_flush; + #endif + + HandleCleanup(); + } + + #endif + + int request = split -> getRequest(); + int position = split -> getPosition(); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleRestart: SPLIT! Deferred agent split event " + << "TYPE#" << (unsigned) opcodeStore_ -> commitSplitNotify + << " [commit split] with resource " << resource << " request " + << request << " position " << position << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + if (handleNotify(notify_commit_split, sequence_deferred, + resource, request, position) < 0) + { + return -1; + } + + // + // Don't send the notification again. + // + + split -> setState(split_notified); + } + #if defined(TEST) || defined(SPLIT) + else + { + *logofs << "handleRestart: SPLIT! Split for request " + << split -> getRequest() << " and position " + << split -> getPosition() << " was already " + << "notified.\n" << logofs_flush; + } + #endif + } + + // + // Don't send the end split if we are still + // in the middle of a start-split/end-split + // sequence. We'll send a no-split at the + // time the end-split is received. + // + + if (splitStore -> getSize() == 0 && + splitStore -> getResource() != splitState_.resource) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleRestart: SPLIT! Deferred agent split event " + << "TYPE#" << (unsigned) opcodeStore_ -> endSplitNotify + << " [end split] with resource " << resource << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + if (handleNotify(notify_end_split, sequence_deferred, + resource, nothing, nothing) < 0) + { + return -1; + } + } + #if defined(TEST) || defined(SPLIT) + else if (splitStore -> getSize() == 0 && + splitStore -> getResource() == splitState_.resource) + { + *logofs << "handleRestart: SPLIT! WARNING! The split store " + << "for resource " << resource << " was emptied in the " + << "split sequence at " << strMsTimestamp() << ".\n" + << logofs_flush; + } + #endif + } + + // + // Remove the split store if it's empty. + // + + if (splitStore != NULL && splitStore -> getSize() == 0 && + splitStore -> getResource() != splitState_.resource) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleRestart: SPLIT! Removing the split store [" + << resource << "] at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + handleSplitStoreRemove(&splitResources_, resource); + + if (clientStore_ -> getSplitTotalSize() == 0) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleRestart: SPLIT! Deferred agent split event " + << "TYPE#" << (unsigned) opcodeStore_ -> emptySplitNotify + << " [empty split] for FD#" << fd_ << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + if (handleNotify(notify_empty_split, sequence_deferred, + nothing, nothing, nothing) < 0) + { + return -1; + } + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleRestart: SPLIT! There are " << clientStore_ -> + getSplitTotalSize() << " messages and " << clientStore_ -> + getSplitTotalStorageSize() << " bytes to send in " + << "the split stores.\n" << logofs_flush; + + if ((clientStore_ -> getSplitTotalSize() != 0 && + clientStore_ -> getSplitTotalStorageSize() == 0) || + (clientStore_ -> getSplitTotalSize() == 0 && + clientStore_ -> getSplitTotalStorageSize() != 0)) + { + #ifdef PANIC + *logofs << "handleRestart: PANIC! Inconsistency detected " + << "while handling the split stores.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + + #endif + } + + return 1; +} + +int ClientChannel::handleTaintLameRequest(unsigned char &opcode, const unsigned char *&buffer, + unsigned int &size) +{ + // + // Test the efficiency of the encoding + // without these RENDER requests. + // + + if (opcode == opcodeStore_ -> renderExtension && + (*(buffer + 1) == X_RenderCompositeGlyphs8 || + *(buffer + 1) == X_RenderCompositeGlyphs16 || + *(buffer + 1) == X_RenderCompositeGlyphs32 || + *(buffer + 1) == X_RenderAddGlyphs || + *(buffer + 1) == X_RenderTrapezoids)) + { + #ifdef TEST + *logofs << "handleTaintLameRequest: Tainting request " + << "OPCODE#" << (unsigned int) opcode << " MINOR#" + << (unsigned int) *(buffer + 1) << " for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + opcode = X_NoOperation; + + return 1; + } + + return 0; +} + +int ClientChannel::handleTaintSyncRequest(unsigned char &opcode, const unsigned char *&buffer, + unsigned int &size) +{ + // + // Should short-circuit other common replies + // whose values could be queried only once. + // Examples are X_InterAtom, X_ListExtension + // and X_QueryExtension. + // + + if (taintCounter_ >= control -> TaintThreshold) + { + #ifdef DEBUG + *logofs << "handleTaintSyncRequest: Reset taint counter after " + << taintCounter_ << " replies managed.\n" + << logofs_flush; + #endif + + taintCounter_ = 0; + + return 0; + } + + // + // Check if we are rolling the counter. + // The client sequence number has not + // been incremented yet in the loop. + // + + unsigned int sequence = (clientSequence_ + 1) & 0xffff; + + #ifdef DEBUG + *logofs << "handleTaintSyncRequest: Opcode is " << (unsigned) opcode + << " expected client sequence is " << sequence + << ".\n" << logofs_flush; + #endif + + if (sequence == 0xffff) + { + return 0; + } + + unsigned short t1; + unsigned char t2; + + // + // Check if there is a previous reply + // pending. + // + + if (sequenceQueue_.peek(t1, t2) != 0) + { + #ifdef DEBUG + *logofs << "handleTaintSyncRequest: Skipping taint of reply due to " + << "pending request OPCODE#" << t1 << " with sequence " + << (unsigned int) t2 << ".\n" << logofs_flush; + #endif + + return 0; + } + + #ifdef DEBUG + *logofs << "handleTaintSyncRequest: Suppressing get input focus " + << "request for FD#" << fd_ << " with sequence " + << sequence << ".\n" << logofs_flush; + #endif + + unsigned char *reply = writeBuffer_.addMessage(32); + + *(reply + 0) = X_Reply; + + PutUINT(sequence, reply + 2, bigEndian_); + + PutULONG(0, reply + 4, bigEndian_); + + // + // Set revert-to to none. + // + + *(reply + 1) = 0; + + // + // Set focus to none. + // + + PutULONG(0, reply + 8, bigEndian_); + + // + // Save the sequence number, not incremented + // yet, we used to auto-generate this reply. + // + + lastSequence_ = clientSequence_ + 1; + + #ifdef TEST + *logofs << "handleTaintSyncRequest: Registered " << lastSequence_ + << " as last auto-generated sequence number.\n" + << logofs_flush; + #endif + + // + // Taint the request to a X_NoOperation. + // + + opcode = X_NoOperation; + + // + // We may assume that the client has finished + // drawing and flush immediately, even if this + // seems to perceively affect the performance. + // + // priority_++; + // + + if (handleFlush(flush_if_any) < 0) + { + return -1; + } + + taintCounter_++; + + return 1; +} + +int ClientChannel::handleTaintSyncError(unsigned char opcode) +{ + if (control -> TaintReplies > 0) + { + // + // By enabling short-circuiting of replies + // some window managers can get confused + // by some otherwise innocuous X errors. + // + + if (opcode == X_GrabKey || opcode == X_ReparentWindow || + opcode == X_ConfigureWindow) + { + #if defined(TEST) || defined(OPCODES) + *logofs << "handleTaintSyncError: WARNING! Suppressed error " + << "on OPCODE#" << (unsigned int) opcode << " for FD#" + << fd_ << " sequence " << lastSequence_ << " (real was " + << serverSequence_ << ").\n" << logofs_flush; + #endif + + return 1; + } + } + + return 0; +} + +int ClientChannel::handleNotify(T_notification_type type, T_sequence_mode mode, + int resource, int request, int position) +{ + if (finish_ == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleNotify: Discarding notification on " + << "channel for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + // + // Add a new message to the write buffer. + // + + unsigned char *event = writeBuffer_.addMessage(32); + + // + // Event is ClientMessage, atom and + // window are 0, format is 32. + // + + *(event + 0) = ClientMessage; + + PutULONG(0, event + 4, bigEndian_); + PutULONG(0, event + 8, bigEndian_); + + *(event + 1) = 32; + + // + // If the event follows immediately the request (that is the + // sequence mode is 'immediate') then the sequence number is + // the one of the last request, else it should be the last + // sequence number encoded by peer proxy but, as we are ins- + // erting events in the stream, we must ensure that the se- + // quence we send is not less than the last sequence we have + // auto-generated. + // + + if (mode == sequence_immediate) + { + // + // Save the sequence number we used + // to auto-generate this event. + // + + lastSequence_ = clientSequence_; + + #if defined(TEST) || defined(INFO) + *logofs << "handleNotify: Registered " << lastSequence_ + << " as last auto-generated sequence number.\n" + << logofs_flush; + #endif + } + else + { + if (serverSequence_ > lastSequence_) + { + #ifdef DEBUG + *logofs << "handleNotify: Updating last event's sequence " + << lastSequence_ << " to X server's sequence number " + << serverSequence_ << " for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + lastSequence_ = serverSequence_; + } + #ifdef DEBUG + else if (serverSequence_ < lastSequence_) + { + // + // Use our last auto-generated sequence. + // + + *logofs << "handleNotify: Tainting sequence number " + << serverSequence_ << " to last event's sequence " + << lastSequence_ << " for FD#" << fd_ << ".\n" + << logofs_flush; + } + #endif + } + + PutUINT(lastSequence_, event + 2, bigEndian_); + + // + // Be sure we set to void the fields that + // are not significant for the specific + // notification message. + // + + PutULONG(nothing, event + 16, bigEndian_); + PutULONG(nothing, event + 20, bigEndian_); + PutULONG(nothing, event + 24, bigEndian_); + + switch (type) + { + case notify_no_split: + { + PutULONG(opcodeStore_ -> noSplitNotify, + event + 12, bigEndian_); + + PutULONG(resource, event + 16, bigEndian_); + + break; + } + case notify_start_split: + { + PutULONG(opcodeStore_ -> startSplitNotify, + event + 12, bigEndian_); + + PutULONG(resource, event + 16, bigEndian_); + + break; + } + case notify_commit_split: + { + PutULONG(opcodeStore_ -> commitSplitNotify, + event + 12, bigEndian_); + + PutULONG(resource, event + 16, bigEndian_); + + PutULONG(request, event + 20, bigEndian_); + + PutULONG(position, event + 24, bigEndian_); + + break; + } + case notify_end_split: + { + PutULONG(opcodeStore_ -> endSplitNotify, + event + 12, bigEndian_); + + PutULONG(resource, event + 16, bigEndian_); + + break; + } + case notify_empty_split: + { + PutULONG(opcodeStore_ -> emptySplitNotify, + event + 12, bigEndian_); + break; + } + default: + { + #ifdef PANIC + *logofs << "handleNotify: PANIC! Unrecognized notify " + << "TYPE#" << type << ".\n" + << logofs_flush; + #endif + + return -1; + } + } + + #if defined(TEST) || defined(INFO) || defined (SPLIT) + + *logofs << "handleNotify: Sending " + << (mode == sequence_immediate ? "immediate " : "deferred ") + << "agent notify event TYPE#" << GetULONG(event + 12, bigEndian_) + << logofs_flush; + + if (resource != nothing) + { + *logofs << " with resource " << GetULONG(event + 16, bigEndian_) + << logofs_flush; + + if (request != nothing && position != nothing) + { + *logofs << " request " << GetULONG(event + 20, bigEndian_) + << " position " << GetULONG(event + 24, bigEndian_) + << logofs_flush; + } + } + + *logofs << ".\n" << logofs_flush; + + #endif + + // + // Send the notification now. + // + + if (handleFlush(flush_if_any) < 0) + { + return -1; + } + + return 1; +} + +int ClientChannel::handleCommitSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + // + // Get the data of the request to be + // committed. + // + + unsigned char request = *(buffer + 5); + + MessageStore *store = clientStore_ -> getRequestStore(request); + + if (store == NULL) + { + #ifdef PANIC + *logofs << "handleCommitSplitRequest: PANIC! Can't commit split for " + << "request OPCODE#" << (unsigned int) request + << ". No message store found.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't commit split for request " + << "OPCODE#" << (unsigned int) request + << ". No message store found.\n"; + + return -1; + } + + // + // The position in cache of the message + // to commit. Encode it as difference in + // respect to the last encoded value. + // + + unsigned int position = GetULONG(buffer + 8, bigEndian_); + + unsigned char resource = *(buffer + 1); + unsigned int commit = *(buffer + 4); + + #if defined(TEST) || defined(SPLIT) + + if (commit == 1) + { + *logofs << "handleCommitSplitRequest: SPLIT! Committing request " + << "OPCODE#" << (unsigned) request << " at position " + << position << " for FD#" << fd_ << " with resource " + << (unsigned) resource << ".\n" << logofs_flush; + } + else + { + *logofs << "handleCommitSplitRequest: SPLIT! Discarding request " + << "OPCODE#" << (unsigned) request << " at position " + << position << " for FD#" << fd_ << " with resource " + << (unsigned) resource << ".\n" << logofs_flush; + } + + #endif + + encodeBuffer.encodeOpcodeValue(request, clientCache_ -> opcodeCache); + + int diffCommit = position - splitState_.commit; + + splitState_.commit = position; + + encodeBuffer.encodeValue(diffCommit, 32, 5); + + // + // Send the resource id and the commit + // flag. + // + + encodeBuffer.encodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + encodeBuffer.encodeBoolValue(commit); + + // + // Remove the split from the split queue. + // + + Split *split = handleSplitCommitRemove(request, resource, splitState_.commit); + + if (split == NULL) + { + return -1; + } + + clientStore_ -> getCommitStore() -> update(split); + + // + // Free the split. + // + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleCommitSplitRequest: SPLIT! Freeing up the " + << "committed split.\n" << logofs_flush; + #endif + + delete split; + + return 1; +} + +int ClientChannel::handleAbortSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + unsigned char resource = *(buffer + 1); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Handling abort split " + << "request for FD#"<< fd_ << " and resource " + << (unsigned int) resource << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + SplitStore *splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore == NULL) + { + #ifdef WARNING + *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The split " + << "store [" << (unsigned int) resource << "] " + << "is already empty.\n" << logofs_flush; + #endif + + return 0; + } + + // + // Loop through the messages in the split + // store and discard from the memory cache + // the messages that are still incomplete. + // Then remove the message from the split + // store. + // + + #if defined(TEST) || defined(SPLIT) + + clientStore_ -> dumpSplitStore(resource); + + #endif + + int splits = 0; + + Split *splitMessage; + + for (;;) + { + splitMessage = splitStore -> getFirstSplit(); + + if (splitMessage == NULL) + { + // + // Check if we had created the store + // but no message was added yet. + // + + #ifdef WARNING + + if (splits == 0) + { + *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The " + << "split store [" << (unsigned int) resource + << "] is unexpectedly empty.\n" + << logofs_flush; + } + + #endif + + break; + } + + // + // Splits already aborted can't be in the + // split store. + // + + #if defined(TEST) || defined(SPLIT) + + if (splitMessage -> getState() == split_aborted) + { + *logofs << "handleAbortSplitRequest: PANIC! SPLIT! Found an " + << "aborted split in store [" << (unsigned int) resource + << "].\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + if (splitMessage -> getAction() == IS_HIT) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Removing the " + << "split from the memory cache.\n" + << logofs_flush; + #endif + + splitMessage -> getStore() -> remove(splitMessage -> getPosition(), + use_checksum, discard_data); + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Removing the " + << "split from the split store.\n" + << logofs_flush; + #endif + + splitMessage = splitStore -> pop(); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Freeing up the " + << "aborted split.\n" << logofs_flush; + #endif + + delete splitMessage; + + splits++; + } + + // + // If the start-split/end-split sequence + // was closed, send the notification now, + // else wait for the end-split. + // + + if (resource != splitState_.resource) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Sending the " + << "deferred [end split] event.\n" + << logofs_flush; + #endif + + handleRestart(sequence_deferred, resource); + } + #if defined(TEST) || defined(SPLIT) + else + { + *logofs << "handleAbortSplitRequest: WARNING! SPLIT! Still " + << "waiting for the closure of the split " + << "sequence.\n" << logofs_flush; + } + #endif + + // + // Check if there is any other store + // having splits to send. + // + + handleSplitPending(); + + return (splits > 0); +} + +int ClientChannel::handleFinishSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + unsigned char resource = *(buffer + 1); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleFinishSplitRequest: SPLIT! Handling finish split " + << "request for FD#"<< fd_ << " and resource " + << (unsigned int) resource << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + // + // We need to get the protocol statistics + // for the finish message we are handling + // here because sending a new split will + // reset the bits counter. + // + + int bits = encodeBuffer.diffBits(); + + statistics -> addRequestBits(opcode, size << 3, bits); + + SplitStore *splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore == NULL) + { + #ifdef WARNING + *logofs << "handleFinishSplitRequest: WARNING! SPLIT! The split " + << "store [" << (unsigned int) resource << "] " + << "is already empty.\n" << logofs_flush; + #endif + + return 0; + } + + // + // Send all the split queued for the given + // resource until the split store becomes + // empty. + // + + #if defined(TEST) || defined(SPLIT) + + clientStore_ -> dumpSplitStore(resource); + + #endif + + Split *splitMessage; + + int total = MESSAGE_DATA_LIMIT; + + int bytes = total; + int splits = 0; + + for (;;) + { + splitMessage = splitStore -> getFirstSplit(); + + if (splitMessage == NULL) + { + // + // We have presumably created the store + // after a start split but no message + // was added yet. + // + + #ifdef WARNING + *logofs << "handleFinishSplitRequest: WARNING! SPLIT! The " + << "split store [" << (unsigned int) resource + << "] is unexpectedly empty.\n" + << logofs_flush; + #endif + + break; + } + + // + // Splits already aborted can't be in the + // split store. + // + + #if defined(TEST) || defined(SPLIT) + + if (splitMessage -> getState() == split_aborted) + { + *logofs << "handleFinishSplitRequest: PANIC! SPLIT! Found an " + << "aborted split in store [" << (unsigned int) resource + << "].\n" << logofs_flush; + + HandleCleanup(); + } + + *logofs << "handleFinishSplitRequest: SPLIT! Sending more " + << "data for store [" << (unsigned int) resource + << "].\n" << logofs_flush; + #endif + + if (handleSplitSend(encodeBuffer, resource, splits, bytes) < 0) + { + return -1; + } + + // + // Check if the split store was deleted. + // + + if (clientStore_ -> getSplitStore(resource) == NULL) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleFinishSplitRequest: SPLIT! Exiting " + << "from the finish loop with split store [" + << (unsigned int) resource << "] destroyed.\n" + << logofs_flush; + #endif + + break; + } + } + + // + // Check if there is any other store + // having splits to send. + // + + handleSplitPending(); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleFinishSplitRequest: SPLIT! Sent " << splits + << " splits and " << total - bytes << " bytes for FD#" << fd_ + << " with " << clientStore_ -> getSplitTotalStorageSize() + << " bytes and [" << clientStore_ -> getSplitTotalSize() + << "] splits remaining.\n" << logofs_flush; + #endif + + return (splits > 0); +} + +int ClientChannel::handleConfiguration() +{ + #ifdef TEST + *logofs << "ClientChannel: Setting new buffer parameters.\n" + << logofs_flush; + #endif + + readBuffer_.setSize(control -> ClientInitialReadSize, + control -> ClientMaximumBufferSize); + + writeBuffer_.setSize(control -> TransportXBufferSize, + control -> TransportXBufferThreshold, + control -> TransportMaximumBufferSize); + + transport_ -> setSize(control -> TransportXBufferSize, + control -> TransportXBufferThreshold, + control -> TransportMaximumBufferSize); + + return 1; +} + +int ClientChannel::handleFinish() +{ + #ifdef TEST + *logofs << "ClientChannel: Finishing channel for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + congestion_ = 0; + priority_ = 0; + + finish_ = 1; + + taintCounter_ = 0; + + splitState_.resource = nothing; + splitState_.pending = 0; + splitState_.commit = 0; + splitState_.mode = split_none; + + transport_ -> finish(); + + return 1; +} + +// +// If differential compression is disabled then use the +// most simple encoding but handle the image requests +// and the X_ListExtensions and X_QueryExtension messa- +// ges (needed to detect the opcode of the shape or the +// other extensions) in the usual way. +// + +int ClientChannel::handleFastReadRequest(EncodeBuffer &encodeBuffer, const unsigned char &opcode, + const unsigned char *&buffer, const unsigned int &size) +{ + // + // All the NX requests are handled in the + // main message loop. The X_PutImage can + // be handled here only if the split was + // not requested (since ProtoStep7 #issue 108). + // + + if ((opcode >= X_NXFirstOpcode && opcode <= X_NXLastOpcode) || + (opcode == X_PutImage && splitState_.resource != nothing) || + opcode == X_ListExtensions || + opcode == X_QueryExtension) + { + return 0; + } + + #ifdef DEBUG + *logofs << "handleFastReadRequest: Encoding raw request OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ + << " with size " << size << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeMemory(buffer, size); + + // + // Put request on the fast track + // if it needs a reply. + // + + switch (opcode) + { + case X_GetAtomName: + case X_GetGeometry: + case X_GetInputFocus: + case X_GetModifierMapping: + case X_GetKeyboardMapping: + case X_GetProperty: + case X_GetSelectionOwner: + case X_GrabPointer: + case X_GrabKeyboard: + case X_ListExtensions: + case X_ListFonts: + case X_LookupColor: + case X_AllocNamedColor: + case X_QueryPointer: + case X_GetWindowAttributes: + case X_QueryTree: + case X_QueryBestSize: + case X_QueryColors: + case X_QueryFont: + case X_TranslateCoords: + case X_GetImage: + case X_GetPointerMapping: + case X_GetKeyboardControl: + case X_InternAtom: + case X_AllocColor: + { + sequenceQueue_.push(clientSequence_, opcode); + + priority_++; + + break; + } + default: + { + break; + } + } + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + + *logofs << "handleFastReadRequest: Handled raw request OPCODE#" + << (unsigned int) opcode << " (" << DumpOpcode(opcode) << ")" + << " for FD#" << fd_ << " sequence " << clientSequence_ + << ". " << size << " bytes in, " << bits << " bits (" + << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; + + #endif + + statistics -> addRequestBits(opcode, size << 3, bits); + + if (opcode == opcodeStore_ -> renderExtension) + { + statistics -> addRenderRequestBits(*(buffer + 1), size << 3, bits); + } + + return 1; +} + +int ClientChannel::handleFastWriteReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + if ((opcode >= X_NXFirstOpcode && + opcode <= X_NXLastOpcode) || + opcode == X_ListExtensions || + opcode == X_QueryExtension) + { + return 0; + } + + #ifdef DEBUG + *logofs << "handleFastWriteReply: Decoding raw reply OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + buffer = writeBuffer_.addMessage(8); + + #ifndef __sun + + unsigned int *next = (unsigned int *) decodeBuffer.decodeMemory(8); + + *((unsigned int *) buffer) = *next++; + *((unsigned int *) (buffer + 4)) = *next; + + #else /* #ifndef __sun */ + + memcpy(buffer, decodeBuffer.decodeMemory(8), 8); + + #endif /* #ifndef __sun */ + + size = 32 + (GetULONG(buffer + 4, bigEndian_) << 2); + + writeBuffer_.registerPointer(&buffer); + + if (writeBuffer_.getAvailable() < size - 8 || + (int) size >= control -> TransportFlushBufferSize) + { + #ifdef DEBUG + *logofs << "handleFastWriteReply: Using scratch buffer for OPCODE#" + << (unsigned int) opcode << " with size " << size << " and " + << writeBuffer_.getLength() << " bytes in buffer.\n" + << logofs_flush; + #endif + + writeBuffer_.removeMessage(8); + + buffer = writeBuffer_.addScratchMessage(((unsigned char *) + decodeBuffer.decodeMemory(size - 8)) - 8, size); + } + else + { + writeBuffer_.addMessage(size - 8); + + #ifndef __sun + + if (size == 32) + { + next = (unsigned int *) decodeBuffer.decodeMemory(size - 8); + + for (int i = 8; i < 32; i += sizeof(unsigned int)) + { + *((unsigned int *) (buffer + i)) = *next++; + } + } + else + { + memcpy(buffer + 8, decodeBuffer.decodeMemory(size - 8), size - 8); + } + + #else /* #ifndef __sun */ + + memcpy(buffer + 8, decodeBuffer.decodeMemory(size - 8), size - 8); + + #endif /* #ifndef __sun */ + } + + writeBuffer_.unregisterPointer(); + + // + // We don't need to write our local sequence + // number. Replies are always sent with the + // original X server's sequence number. + // + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleFastWriteReply: Handled raw reply OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ << " with sequence " + << serverSequence_ << ". Output size is " << size << ".\n" + << logofs_flush; + #endif + + #ifdef DEBUG + *logofs << "handleFastWriteReply: Length of sequence queue is " + << sequenceQueue_.length() << ".\n" << logofs_flush; + #endif + + statistics -> addRepliedRequest(opcode); + + handleFlush(flush_if_needed); + + return 1; +} + +int ClientChannel::handleFastWriteEvent(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + #ifdef DEBUG + *logofs << "handleFastWriteEvent: Decoding raw " + << (opcode == X_Error ? "error" : "event") << " OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + size = 32; + + buffer = writeBuffer_.addMessage(size); + + #ifndef __sun + + unsigned int *next = (unsigned int *) decodeBuffer.decodeMemory(size); + + for (int i = 0; i < 32; i += sizeof(unsigned int)) + { + *((unsigned int *) (buffer + i)) = *next++; + } + + #else /* #ifndef __sun */ + + memcpy(buffer, decodeBuffer.decodeMemory(size), size); + + #endif /* #ifndef __sun */ + + // + // Use our local sequence number. + // + + PutUINT(lastSequence_, buffer + 2, bigEndian_); + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleFastWriteEvent: Handled raw " + << (opcode == X_Error ? "error" : "event") << " OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ << " with sequence " + << lastSequence_ << ". Output size is " << size << ".\n" + << logofs_flush; + #endif + + // + // Check if we need to suppress the error. + // + + if (opcode == X_Error && handleTaintSyncError(*(buffer + 10)) > 0) + { + #if defined(TEST) || defined(OPCODES) + *logofs << "handleFastWriteEvent: WARNING! Suppressed error OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ + << " with sequence " << lastSequence_ << ".\n" + << logofs_flush; + #endif + + writeBuffer_.removeMessage(32); + } + + handleFlush(flush_if_needed); + + return 1; +} + +int ClientChannel::handleShmemRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + // + // Will push sequence and set + // priority according to stage. + // + + unsigned int stage = *(buffer + 1); + + #ifdef TEST + *logofs << "handleShmemRequest: Encoding shmem request " + << "OPCODE#" << (unsigned int) opcode << " for FD#" + << fd_ << " with size " << size << " at stage " + << stage << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeValue(stage, 2); + + if (stage == 0) + { + unsigned int enableClient = 0; + unsigned int enableServer = 0; + + if (control -> ShmemClient == 1) + { + enableClient = *(buffer + 4); + } + + if (control -> ShmemServer == 1) + { + enableServer = *(buffer + 5); + } + + encodeBuffer.encodeBoolValue(enableClient); + encodeBuffer.encodeBoolValue(enableServer); + + unsigned int clientSegment = GetULONG(buffer + 8, bigEndian_); + unsigned int serverSegment = GetULONG(buffer + 12, bigEndian_); + + encodeBuffer.encodeValue(clientSegment, 29, 9); + encodeBuffer.encodeValue(serverSegment, 29, 9); + + #ifdef TEST + *logofs << "handleShmemRequest: Enable client is " + << enableClient << " enable server is " << enableServer + << " client segment is " << (void *) clientSegment + << " server segment is " << (void *) serverSegment + << ".\n" << logofs_flush; + #endif + + #ifdef TEST + *logofs << "handleShmemRequest: Size of the shared memory " + << "segment will be " << control -> ShmemServerSize + << ".\n" << logofs_flush; + #endif + } + + if (stage != 1) + { + sequenceQueue_.push(clientSequence_, opcodeStore_ -> + getShmemParameters); + + priority_++; + } + + return 1; +} + +int ClientChannel::handleShmemReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + #ifdef TEST + *logofs << "handleShmemReply: Received shmem parameters " + << "reply OPCODE#" << (unsigned int) opcode + << ".\n" << logofs_flush; + #endif + + size = 32; + buffer = writeBuffer_.addMessage(size); + + unsigned int stage; + + decodeBuffer.decodeValue(stage, 2); + + *(buffer + 1) = stage; + + if (stage == 2) + { + unsigned int clientEnabled; + unsigned int serverEnabled; + + decodeBuffer.decodeBoolValue(clientEnabled); + decodeBuffer.decodeBoolValue(serverEnabled); + + // + // Client support is not implemented + // and not useful. It is here only + // for compatibility. + // + + clientEnabled = 0; + + *(buffer + 8) = clientEnabled; + *(buffer + 9) = serverEnabled; + + PutULONG(0, buffer + 12, bigEndian_); + + if (serverEnabled == 1) + { + #ifdef TEST + *logofs << "handleShmemReply: Enabled shared memory " + << "support in X server with segment size " + << control -> ShmemServerSize << ".\n" + << logofs_flush; + #endif + + PutULONG(control -> ShmemServerSize, buffer + 16, bigEndian_); + } + else + { + PutULONG(0, buffer + 16, bigEndian_); + } + } + else + { + *(buffer + 8) = 0; + *(buffer + 9) = 0; + + PutULONG(0, buffer + 12, bigEndian_); + PutULONG(0, buffer + 16, bigEndian_); + } + + return 1; +} + +int ClientChannel::handleFontRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + #ifdef TEST + *logofs << "handleFontRequest: Encoding font request " + << "OPCODE#" << (unsigned int) opcode << " for FD#" + << fd_ << " with size " << size << ".\n" + << logofs_flush; + #endif + + sequenceQueue_.push(clientSequence_, opcodeStore_ -> + getFontParameters); + + return 1; +} + +int ClientChannel::handleFontReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + #ifdef TEST + *logofs << "handleFontReply: Received font operation " + << "reply OPCODE#" << (unsigned int) opcode + << ".\n" << logofs_flush; + #endif + + unsigned int length; + + decodeBuffer.decodeValue(length, 8); + + size = 32 + RoundUp4(length + 1); + buffer = writeBuffer_.addMessage(size); + + unsigned char *next = buffer + 32; + + *next++ = length; + + decodeBuffer.decodeTextData(next, length); + + #ifdef TEST + + *logofs << "handleFontReply: Received tunneled font server " + << "path '"; + + for (unsigned int i = 0; i < length; i++) + { + *logofs << *(buffer + 32 + 1 + i); + } + + *logofs << "' for FD#" << fd_ << ".\n" << logofs_flush; + + #endif + + if (fontPort_ == -1) + { + // + // The local side is not going to forward + // the font server connections. + // + + #ifdef TEST + *logofs << "handleFontReply: WARNING! Returning an empty " + << "font server path.\n" << logofs_flush; + #endif + + writeBuffer_.removeMessage(size); + + size = 36; + buffer = writeBuffer_.addMessage(size); + + // + // Set the length of the returned + // path to 0. + // + + *(buffer + 32) = 0; + } + #ifdef TEST + else + { + *logofs << "handleFontReply: Returning the received " + << "font server path.\n" << logofs_flush; + } + #endif + + return 1; +} + +int ClientChannel::handleCacheRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + #ifdef TEST + *logofs << "handleCacheRequest: Handling cache request " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + enableCache_ = *(buffer + 4); + enableSplit_ = *(buffer + 5); + enableSave_ = *(buffer + 6); + enableLoad_ = *(buffer + 7); + + #ifdef TEST + *logofs << "handleCacheRequest: Set cache parameters to " + << " cache " << enableCache_ << " split " << enableSplit_ + << " save " << enableSave_ << " load " << enableLoad_ + << ".\n" << logofs_flush; + #endif + + // + // Encode all the parameters as a + // single unsigned int so we can + // use an int cache. + // + + unsigned int mask = enableSave_ << 8 | enableLoad_; + + encodeBuffer.encodeCachedValue(mask, 32, clientCache_ -> + setCacheParametersCache); + return 0; +} + +int ClientChannel::handleStartSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + #if defined(TEST) || defined(SPLIT) + *logofs << "handleStartSplitRequest: SPLIT! Handling start split " + << "request for FD#"<< fd_ << ".\n" << logofs_flush; + #endif + + if (splitState_.resource != nothing) + { + #ifdef PANIC + *logofs << "handleStartSplitRequest: PANIC! SPLIT! Split requested " + << "for resource id " << (unsigned int) *(buffer + 1) + << " while handling resource " << splitState_.resource + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Split requested for " + << "resource id " << (unsigned int) *(buffer + 1) + << " while handling resource " << splitState_.resource + << ".\n"; + + return -1; + } + else if (fd_ != firstClient_) + { + // + // It can be that an auxiliary channel is the + // first to connect, then comes the agent that + // is actually using the NX opcodes. + // + + #ifdef WARNING + *logofs << "handleStartSplitRequest: WARNING SPLIT! Split requested " + << "on FD#" << fd_ << " while expecting FD#" << firstClient_ + << ".\n" << logofs_flush; + #endif + + firstClient_ = fd_; + } + + // + // Set the agent's resource for which we are + // going to split the request. + // + + splitState_.resource = *(buffer + 1); + + #if defined(TEST) || defined(SPLIT) + + *logofs << "handleStartSplitRequest: SPLIT! Registered id " + << splitState_.resource << " as resource " + << "waiting for a split.\n" << logofs_flush; + + if (clientStore_ -> getSplitStore(splitState_.resource) != NULL) + { + *logofs << "handleStartSplitRequest: WARNING! SPLIT! A split " + << "store for resource id " << splitState_.resource + << " already exists.\n" << logofs_flush; + + clientStore_ -> dumpSplitStore(splitState_.resource); + } + + #endif + + // + // Send the selected resource to the remote. + // + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeCachedValue(splitState_.resource, 8, + clientCache_ -> resourceCache); + + splitState_.mode = (T_split_mode) *(buffer + 4); + + if (splitState_.mode != NXSplitModeAsync && + splitState_.mode != NXSplitModeSync) + { + splitState_.mode = (T_split_mode) control -> SplitMode; + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleStartSplitRequest: SPLIT! Set split " + << "mode to '" << splitState_.mode << "' with " + << "provided value '" << (unsigned) *(buffer + 4) + << "'.\n" << logofs_flush; + #endif + } + + #if defined(TEST) || defined(SPLIT) + + if (splitState_.mode == NXSplitModeAsync) + { + *logofs << "handleStartSplitRequest: SPLIT! Selected split " + << "mode is [split_async].\n" << logofs_flush; + } + else if (splitState_.mode == NXSplitModeSync) + { + *logofs << "handleStartSplitRequest: SPLIT! Selected split " + << "mode is [split_sync].\n" << logofs_flush; + } + + clientStore_ -> dumpSplitStores(); + + #endif + + return 1; +} + +int ClientChannel::handleEndSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + #if defined(TEST) || defined(SPLIT) + *logofs << "handleEndSplitRequest: SPLIT! Handling end split " + << "request for FD#"<< fd_ << ".\n" << logofs_flush; + #endif + + // + // Verify that the agent resource matches. + // + + if (splitState_.resource == nothing) + { + #ifdef PANIC + *logofs << "handleEndSplitRequest: PANIC! SPLIT! Received an end of " + << "split for resource id " << (unsigned int) *(buffer + 1) + << " without a previous start.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Received an end of split " + << "for resource id " << (unsigned int) *(buffer + 1) + << " without a previous start.\n"; + + return -1; + } + else if (splitState_.resource != *(buffer + 1)) + { + #ifdef PANIC + *logofs << "handleEndSplitRequest: PANIC! SPLIT! Invalid resource id " + << (unsigned int) *(buffer + 1) << " received while " + << "waiting for resource id " << splitState_.resource + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid resource id " + << (unsigned int) *(buffer + 1) << " received while " + << "waiting for resource id " << splitState_.resource + << ".\n"; + + return -1; + } + + // + // Send the selected resource to the remote. + // + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeCachedValue(splitState_.resource, 8, + clientCache_ -> resourceCache); + + // + // Send the split notification events + // to the agent. + // + + handleRestart(sequence_immediate, splitState_.resource); + + // + // Check if we still have splits to send. + // + + handleSplitPending(); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleEndSplitRequest: SPLIT! Reset id " + << splitState_.resource << " as resource " + << "selected for splits.\n" << logofs_flush; + #endif + + splitState_.resource = nothing; + splitState_.mode = split_none; + + #if defined(TEST) || defined(SPLIT) + + clientStore_ -> dumpSplitStores(); + + #endif + + return 1; +} + +void ClientChannel::handleDecodeCharInfo(DecodeBuffer &decodeBuffer, unsigned char *nextDest) +{ + unsigned int value; + + decodeBuffer.decodeCachedValue(value, 32, + *serverCache_ -> queryFontCharInfoCache[0], 6); + + PutUINT(value & 0xffff, nextDest, bigEndian_); + PutUINT(value >> 16, nextDest + 10, bigEndian_); + + nextDest += 2; + + for (unsigned int i = 1; i < 5; i++) + { + unsigned int value; + + decodeBuffer.decodeCachedValue(value, 16, + *serverCache_ -> queryFontCharInfoCache[i], 6); + + PutUINT(value, nextDest, bigEndian_); + + nextDest += 2; + } +} + +int ClientChannel::setBigEndian(int flag) +{ + bigEndian_ = flag; + + return 1; +} + +int ClientChannel::setReferences() +{ + #ifdef TEST + *logofs << "ClientChannel: Initializing the static " + << "members for the client channels.\n" + << logofs_flush; + #endif + + #ifdef REFERENCES + + references_ = 0; + + #endif + + return 1; +} diff --git a/nxcomp/src/ClientChannel.h b/nxcomp/src/ClientChannel.h new file mode 100644 index 000000000..ae92648d5 --- /dev/null +++ b/nxcomp/src/ClientChannel.h @@ -0,0 +1,434 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ClientChannel_H +#define ClientChannel_H + +#include "List.h" +#include "Channel.h" + +#include "SequenceQueue.h" + +#include "ClientReadBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// If defined, the client channel will +// have the chance of suppressing more +// opcodes for test purposes. +// + +#undef LAME + +// +// Define this to log a line when a +// channel is created or destroyed. +// + +#undef REFERENCES + +// +// This class implements the X client +// side compression of the protocol. +// + +class ClientChannel : public Channel +{ + public: + + ClientChannel(Transport *transport, StaticCompressor *compressor); + + virtual ~ClientChannel(); + + virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, + unsigned int length); + + virtual int handleWrite(const unsigned char *message, unsigned int length); + + virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, + T_store_action action, int position, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, + T_store_action action, int position, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) + { + return 0; + } + + virtual int handleSplit(EncodeBuffer &encodeBuffer); + + virtual int handleSplit(DecodeBuffer &decodeBuffer) + { + return 0; + } + + virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split); + + virtual int handleSplitEvent(DecodeBuffer &decodeBuffer); + + virtual int handleMotion(EncodeBuffer &encodeBuffer) + { + return 0; + } + + virtual int handleCompletion(EncodeBuffer &encodeBuffer) + { + return 0; + } + + virtual int handleConfiguration(); + + virtual int handleFinish(); + + virtual int handleAsyncEvents() + { + return 0; + } + + virtual int needSplit() const + { + #if defined(TEST) || defined(SPLIT) + *logofs << "needSplit: SPLIT! Returning pending split " + << "flag " << splitState_.pending << " with " + << clientStore_ -> getSplitTotalSize() + << " splits in the split stores.\n" + << logofs_flush; + #endif + + return splitState_.pending; + } + + virtual int needMotion() const + { + return 0; + } + + virtual T_channel_type getType() const + { + return channel_x11; + } + + int setBigEndian(int flag); + + // + // Initialize the static members. + // + + static int setReferences(); + + private: + + int handleFastReadRequest(EncodeBuffer &encodeBuffer, const unsigned char &opcode, + const unsigned char *&buffer, const unsigned int &size); + + int handleFastWriteReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + int handleFastWriteEvent(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + // + // Intercept the request before the opcode + // is encoded. + // + + int handleTaintRequest(unsigned char &opcode, const unsigned char *&buffer, + unsigned int &size) + { + if (control -> TaintReplies > 0 && + opcode == X_GetInputFocus) + { + return handleTaintSyncRequest(opcode, buffer, size); + } + + #ifdef LAME + + return handleTaintLameRequest(opcode, buffer, size); + + #endif + + return 0; + } + + int handleTaintLameRequest(unsigned char &opcode, const unsigned char *&buffer, + unsigned int &size); + + int handleTaintSyncRequest(unsigned char &opcode, const unsigned char *&buffer, + unsigned int &size); + + int handleTaintSyncError(unsigned char opcode); + + // + // How to handle sequence counter + // in notification event. + // + + enum T_sequence_mode + { + sequence_immediate, + sequence_deferred + }; + + // + // Send split notifications to the + // agent. + // + + int handleRestart(T_sequence_mode mode, int resource); + + int handleNotify(T_notification_type type, T_sequence_mode mode, + int resource, int request, int position); + + // + // Other utility functions used in + // handling of the image streaming. + // + + int mustSplitMessage(int resource) + { + return (clientStore_ -> getSplitStore(resource) -> + getSize() != 0); + } + + int canSplitMessage(T_split_mode mode, unsigned int size) + { + return ((int) size >= control -> SplitDataThreshold && + (clientStore_ -> getSplitTotalStorageSize() < control -> + SplitTotalStorageSize && clientStore_ -> + getSplitTotalSize() < control -> SplitTotalSize)); + } + + int canSendSplit(Split *split) + { + return (split -> getMode() != split_sync || + split -> getState() == split_missed || + split -> getState() == split_loaded); + } + + int handleSplitSend(EncodeBuffer &encodeBuffer, int resource, + int &total, int &bytes); + + Split *handleSplitFind(T_checksum checksum, int resource); + + int handleSplitChecksum(EncodeBuffer &encodeBuffer, T_checksum checksum); + + void handleSplitPending(int resource) + { + if (splitState_.pending == 0) + { + if (clientStore_ -> getSplitStore(resource) != NULL && + clientStore_ -> getSplitStore(resource) -> + getFirstSplit() != NULL) + { + splitState_.pending = canSendSplit(clientStore_ -> + getSplitStore(resource) -> getFirstSplit()); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitPending: SPLIT! Set the pending " + << "split flag to " << splitState_.pending + << " with " << clientStore_ -> getSplitTotalSize() + << " splits in the split stores.\n" + << logofs_flush; + #endif + } + } + } + + // + // Scan all the split stores to find + // if there is any split to send. + // + + void handleSplitPending(); + + // + // Handle the MIT-SHM initialization + // messages exchanged with the remote + // proxy. + // + + int handleShmemRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + int handleShmemReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + // + // Query the port used to tunnel + // the font server connections. + // + + int handleFontRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + int handleFontReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + // + // Let the agent set the cache + // policy for image requests. + // + + int handleCacheRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + // + // Encode the start and end split + // requests. + // + + int handleStartSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + int handleEndSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + // + // Empty a split store and send the + // restart event. + // + + int handleAbortSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + // + // Force the proxy to finalize all + // the pending split operations and + // restart a resource. + // + + int handleFinishSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + // + // Tell the remote peer to send the + // split requests to the X server. + // + + int handleCommitSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + // + // Other utilities. + // + + void handleDecodeCharInfo(DecodeBuffer &, unsigned char *); + + // + // Own read buffer. It is able to identify + // full messages read from the X descriptor. + // + + ClientReadBuffer readBuffer_; + + // + // Sequence number of last request coming + // from the X client or the X server. + // + + unsigned int clientSequence_; + unsigned int serverSequence_; + + // + // Last sequence number known by client. It can + // be the real sequence generated by server or + // the one of the last auto-generated event. + // + + unsigned int lastSequence_; + + // + // Used to identify replies based on sequence + // number of original request. + // + + SequenceQueue sequenceQueue_; + + // + // This is used to test the synchronous flush + // in the proxy. + // + + int lastRequest_; + + // + // Current resource id selected as target and + // other information related to the image split. + // The pending and abort flags are set when we + // want the proxy to give us a chance to send + // more split data. We also save the position + // of the last commit operation performed by + // channel so we can differentially encode the + // position of next message to commit. + // + + typedef struct + { + int resource; + int pending; + int commit; + T_split_mode mode; + + } T_split_state; + + T_split_state splitState_; + + // + // List of agent resources. + // + + List splitResources_; + + // + // How many sync requests we + // have tainted so far. + // + + int taintCounter_; + + private: + + // + // Keep track of object + // creation and deletion. + // + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +#endif /* ClientChannel_H */ diff --git a/nxcomp/src/ClientProxy.cpp b/nxcomp/src/ClientProxy.cpp new file mode 100644 index 000000000..3574d3bf3 --- /dev/null +++ b/nxcomp/src/ClientProxy.cpp @@ -0,0 +1,553 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Socket.h" +#include "Agent.h" + +#include "ClientProxy.h" + +#include "ClientChannel.h" +#include "GenericChannel.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Log the operations related to sending +// and receiving the control tokens. +// + +#undef TOKEN + +ClientProxy::ClientProxy(int proxyFd) : Proxy(proxyFd) +{ + fontServerPort_ = NULL; + + #ifdef DEBUG + *logofs << "ClientProxy: Created new object at " << this + << ".\n" << logofs_flush; + #endif +} + +ClientProxy::~ClientProxy() +{ + delete [] fontServerPort_; + + #ifdef DEBUG + *logofs << "ClientProxy: Deleted object at " << this + << ".\n" << logofs_flush; + #endif +} + +void ClientProxy::handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, + sockaddr * xServerAddr, unsigned int xServerAddrLength) +{ + #ifdef DEBUG + *logofs << "ClientProxy: No display configuration to set.\n" + << logofs_flush; + #endif +} + +void ClientProxy::handlePortConfiguration(ChannelEndPoint &cupsServerPort, + ChannelEndPoint &smbServerPort, + ChannelEndPoint &mediaServerPort, + ChannelEndPoint &httpServerPort, + const char *fontServerPort) +{ + delete [] fontServerPort_; + + fontServerPort_ = new char[strlen(fontServerPort) + 1]; + + strcpy(fontServerPort_, fontServerPort); + + #ifdef DEBUG + *logofs << "ClientProxy: Set port configuration to font '" + << fontServerPort_ << "'.\n" + << logofs_flush; + #endif +} + +int ClientProxy::handleNewConnection(T_channel_type type, int clientFd) +{ + switch (type) + { + case channel_x11: + { + return handleNewXConnection(clientFd); + } + case channel_cups: + { + return handleNewGenericConnection(clientFd, channel_cups, "CUPS"); + } + case channel_smb: + { + return handleNewGenericConnection(clientFd, channel_smb, "SMB"); + } + case channel_media: + { + return handleNewGenericConnection(clientFd, channel_media, "media"); + } + case channel_http: + { + return handleNewGenericConnection(clientFd, channel_http, "HTTP"); + } + case channel_slave: + { + return handleNewSlaveConnection(clientFd); + } + default: + { + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Unsupported channel with type '" + << getTypeName(type) << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unsupported channel with type '" + << getTypeName(type) << "'.\n"; + + return -1; + } + } +} + +int ClientProxy::handleNewConnectionFromProxy(T_channel_type type, int channelId) +{ + switch (type) + { + case channel_font: + { + int port = atoi(fontServerPort_); + + if (port > 0) + { + // + // Connect on the TCP port number. + // + + return handleNewGenericConnectionFromProxyTCP(channelId, channel_font, "localhost", + port, "font"); + } + else + { + // + // Connect to the Unix path. + // + + return handleNewGenericConnectionFromProxyUnix(channelId, channel_font, + fontServerPort_, "font"); + } + } + case channel_slave: + { + return handleNewSlaveConnectionFromProxy(channelId); + } + default: + { + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Unsupported channel with type '" + << getTypeName(type) << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unsupported channel with type '" + << getTypeName(type) << "'.\n"; + + return -1; + } + } +} + +int ClientProxy::handleNewAgentConnection(Agent *agent) +{ + int clientFd = agent -> getLocalFd(); + + int channelId = allocateChannelMap(clientFd); + + if (channelId == -1) + { + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Maximum number of available " + << "channels exceeded.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Maximum number of available " + << "channels exceeded.\n"; + + return -1; + } + + transports_[channelId] = agent -> getTransport(); + + agent_ = channelId; + + return handleNewXConnection(clientFd); +} + +int ClientProxy::handleNewXConnection(int clientFd) +{ + int channelId = getChannel(clientFd); + + // + // Check if the channel has been + // already mapped. + // + + if (channelId == -1) + { + channelId = allocateChannelMap(clientFd); + + if (channelId == -1) + { + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Maximum number of available " + << "channels exceeded.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Maximum number of available " + << "channels exceeded.\n"; + + return -1; + } + } + + #ifdef TEST + *logofs << "ClientProxy: X client descriptor FD#" << clientFd + << " mapped to channel ID#" << channelId << ".\n" + << logofs_flush; + #endif + + // + // Turn queuing off for path proxy-to-X-client. + // + + if (control -> OptionClientNoDelay == 1) + { + SetNoDelay(clientFd, control -> OptionClientNoDelay); + } + + // + // If requested, set the size of the TCP send + // and receive buffers. + // + + if (control -> OptionClientSendBuffer != -1) + { + SetSendBuffer(clientFd, control -> OptionClientSendBuffer); + } + + if (control -> OptionClientReceiveBuffer != -1) + { + SetReceiveBuffer(clientFd, control -> OptionClientReceiveBuffer); + } + + if (allocateTransport(clientFd, channelId) < 0) + { + return -1; + } + + // + // Starting from protocol level 3 client and server + // caches are created in proxy and shared between all + // channels. If remote proxy has older protocol level + // pointers are NULL and channels must create their + // own instances. + // + + channels_[channelId] = new ClientChannel(transports_[channelId], compressor_); + + if (channels_[channelId] == NULL) + { + deallocateTransport(channelId); + + return -1; + } + + increaseChannels(channelId); + + // + // Propagate channel stores and caches to the new + // channel. + // + + channels_[channelId] -> setOpcodes(opcodeStore_); + + channels_[channelId] -> setStores(clientStore_, serverStore_); + + channels_[channelId] -> setCaches(clientCache_, serverCache_); + + int port = atoi(fontServerPort_); + + if (port > 0 || *fontServerPort_ != '\0') + { + channels_[channelId] -> setPorts(1); + } + + if (handleControl(code_new_x_connection, channelId) < 0) + { + return -1; + } + + // + // Let channel configure itself according + // to control parameters. + // + + channels_[channelId] -> handleConfiguration(); + + return 1; +} + +int ClientProxy::handleNewXConnectionFromProxy(int channelId) +{ + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Can't create a new X channel " + << "with ID#" << channelId << " at this side.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't create a new X channel " + << "with ID#" << channelId << " at this side.\n"; + + return -1; +} + +int ClientProxy::handleLoad(T_load_type type) +{ + int channelCount = getChannels(channel_x11); + + if ((channelCount == 0 && type == load_if_first) || + (channelCount > 0 && type == load_if_any)) + { + #ifdef TEST + *logofs << "ClientProxy: Going to load content of client store.\n" + << logofs_flush; + #endif + + int result = handleLoadStores(); + + if (result == 1) + { + if (handleControl(code_load_request) < 0) + { + return -1; + } + + priority_ = 1; + } + else if (result < 0) + { + #ifdef WARNING + *logofs << "ClientProxy: WARNING! Failed to load content " + << "of persistent cache.\n" << logofs_flush; + #endif + + // + // Don't abort the proxy connection in the case + // of a corrupted cache. By not sending the load + // message to the remote peer, both sides will + // start encoding messages using empty stores. + // This behaviour is compatible with old proxy + // versions. + // + + if (channelCount == 0 && type == load_if_first) + { + if (handleResetStores() < 0) + { + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Failed to reset message stores.\n" + << logofs_flush; + #endif + + return -1; + } + } + else + { + return -1; + } + } + } + else + { + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Can't load the stores with " + << channelCount << " remaining channels.\n" + << logofs_flush; + #endif + + return -1; + } + + return 1; +} + +int ClientProxy::handleSave() +{ + // + // If no more X channels are remaining + // then save content of message stores. + // + + int channelCount = getChannels(channel_x11); + + if (channelCount == 0) + { + int result = handleSaveStores(); + + if (result == 1) + { + if (handleControl(code_save_request) < 0) + { + return -1; + } + + priority_ = 1; + + return 1; + } + else if (result < 0) + { + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Failed to save stores " + << "to persistent cache.\n" << logofs_flush; + #endif + + return -1; + } + } + else + { + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Can't save the stores with " + << channelCount << " remaining channels.\n" + << logofs_flush; + #endif + + return -1; + } + + return 1; +} + +int ClientProxy::handleAsyncEvents() +{ + if (canRead() == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: WARNING! Reading while writing " + << "with data available on the proxy link.\n" + << logofs_flush; + #endif + + if (handleRead() < 0) + { + return -1; + } + + return 1; + } + + return 0; +} + +int ClientProxy::handleLoadFromProxy() +{ + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Invalid load control message " + << "received in proxy.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid load control message " + << "received in proxy.\n"; + + return -1; +} + +int ClientProxy::handleSaveFromProxy() +{ + #ifdef PANIC + *logofs << "ClientProxy: PANIC! Invalid save control message " + << "received in proxy.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid save control message " + << "received in proxy.\n"; + + return -1; +} + +int ClientProxy::handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient) const +{ + if (clientStore_ -> saveRequestStores(cachefs, md5StateStream, md5StateClient, + use_checksum, discard_data) < 0) + { + return -1; + } + else if (serverStore_ -> saveReplyStores(cachefs, md5StateStream, md5StateClient, + discard_checksum, use_data) < 0) + { + return -1; + } + else if (serverStore_ -> saveEventStores(cachefs, md5StateStream, md5StateClient, + discard_checksum, use_data) < 0) + { + return -1; + } + + return 1; +} + +int ClientProxy::handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const +{ + if (clientStore_ -> loadRequestStores(cachefs, md5StateStream, + use_checksum, discard_data) < 0) + { + return -1; + } + else if (serverStore_ -> loadReplyStores(cachefs, md5StateStream, + discard_checksum, use_data) < 0) + { + return -1; + } + else if (serverStore_ -> loadEventStores(cachefs, md5StateStream, + discard_checksum, use_data) < 0) + { + return -1; + } + + return 1; +} + diff --git a/nxcomp/src/ClientProxy.h b/nxcomp/src/ClientProxy.h new file mode 100644 index 000000000..b89785b1a --- /dev/null +++ b/nxcomp/src/ClientProxy.h @@ -0,0 +1,113 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ClientProxy_H +#define ClientProxy_H + +#include "Proxy.h" + +// +// Set the verbosity level. +// + +#undef TEST +#undef DEBUG + +class ClientProxy : public Proxy +{ + public: + + ClientProxy(int proxyFD); + + virtual ~ClientProxy(); + + virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, + sockaddr *xServerAddr, unsigned int xServerAddrLength); + + virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort, + ChannelEndPoint &smbServerPort, + ChannelEndPoint &mediaServerPort, + ChannelEndPoint &httpServerPort, + const char *fontServerPort); + + protected: + + // + // Create a new channel. + // + + virtual int handleNewConnection(T_channel_type type, int clientFd); + + virtual int handleNewConnectionFromProxy(T_channel_type type, int channelId); + + virtual int handleNewAgentConnection(Agent *agent); + + virtual int handleNewXConnection(int clientFd); + + virtual int handleNewXConnectionFromProxy(int channelId); + + // + // Implement persistence according + // to our proxy mode. + // + + virtual int handleLoad(T_load_type type); + virtual int handleSave(); + + virtual int handleAsyncEvents(); + + virtual int handleLoadFromProxy(); + virtual int handleSaveFromProxy(); + + virtual int handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient) const; + + virtual int handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const; + + // + // Utility function used to realize + // a new connection. + // + + protected: + + virtual int checkLocalChannelMap(int channelId) + { + // Since ProtoStep7 (#issue 108) + return ((channelId & control -> ChannelMask) != 0); + } + + // + // Ports where to forward extended services' + // TCP connections. + // + + private: + + char *fontServerPort_; +}; + + +#endif /* ClientProxy_H */ diff --git a/nxcomp/src/ClientReadBuffer.cpp b/nxcomp/src/ClientReadBuffer.cpp new file mode 100644 index 000000000..c8f4f69a4 --- /dev/null +++ b/nxcomp/src/ClientReadBuffer.cpp @@ -0,0 +1,178 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ClientReadBuffer.h" + +#include "ClientChannel.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +unsigned int ClientReadBuffer::suggestedLength(unsigned int pendingLength) +{ + // + // Even if the pending data is not + // enough to make a complete message, + // resize the buffer to accommodate + // it all. + // + + unsigned int readLength = pendingLength; + + if (pendingLength < remaining_) + { + readLength = remaining_; + } + + return readLength; +} + +int ClientReadBuffer::locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength) +{ + unsigned int size = end - start; + + #ifdef TEST + *logofs << "ClientReadBuffer: Locating message for FD#" + << transport_ -> fd() << " with " << size + << " bytes.\n" << logofs_flush; + #endif + + if (firstMessage_) + { + if (size < 12) + { + remaining_ = 12 - size; + + #ifdef TEST + *logofs << "ClientReadBuffer: No message was located " + << "with remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + if (*start == 0x42) + { + bigEndian_ = 1; + } + else + { + bigEndian_ = 0; + } + + channel_ -> setBigEndian(bigEndian_); + + dataLength = 12 + RoundUp4(GetUINT(start + 6, bigEndian_)) + + RoundUp4(GetUINT(start + 8, bigEndian_)); + + // + // Send the data immediately if this is unlikely + // to be a X connection attempt. + // + + if (dataLength > 4096) + { + #ifdef WARNING + *logofs << "ClientReadBuffer: WARNING! Flushing suspicious X " + << "connection with first request of " << dataLength + << " bytes.\n" << logofs_flush; + #endif + + dataLength = size; + } + } + else + { + if (size < 4) + { + remaining_ = 4 - size; + + #ifdef TEST + *logofs << "ClientReadBuffer: No message was located " + << "with remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + dataLength = (GetUINT(start + 2, bigEndian_) << 2); + + if (dataLength < 4) + { + #ifdef TEST + *logofs << "ClientReadBuffer: WARNING! Assuming length 4 " + << "for suspicious message of length " << dataLength + << ".\n" << logofs_flush; + #endif + + dataLength = 4; + } + } + + #ifdef TEST + *logofs << "ClientReadBuffer: Length of the next message is " + << dataLength << ".\n" << logofs_flush; + #endif + + if (size < dataLength) + { + remaining_ = dataLength - size; + + #ifdef TEST + *logofs << "ClientReadBuffer: No message was located " + << "with remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + firstMessage_ = 0; + + controlLength = 0; + trailerLength = 0; + + remaining_ = 0; + + #ifdef TEST + *logofs << "ClientReadBuffer: Located message with " + << "remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 1; +} diff --git a/nxcomp/src/ClientReadBuffer.h b/nxcomp/src/ClientReadBuffer.h new file mode 100644 index 000000000..c557417fa --- /dev/null +++ b/nxcomp/src/ClientReadBuffer.h @@ -0,0 +1,65 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ClientReadBuffer_H +#define ClientReadBuffer_H + +#include "Control.h" +#include "ReadBuffer.h" + +class ClientChannel; + +class ClientReadBuffer : public ReadBuffer +{ + public: + + ClientReadBuffer(Transport *transport, ClientChannel *channel) + + : ReadBuffer(transport), firstMessage_(1), channel_(channel) + { + } + + virtual ~ClientReadBuffer() + { + } + + protected: + + virtual unsigned int suggestedLength(unsigned int pendingLength); + + virtual int locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength); + + int bigEndian_; + + int firstMessage_; + + ClientChannel *channel_; +}; + +#endif /* ClientReadBuffer_H */ diff --git a/nxcomp/src/ClientStore.cpp b/nxcomp/src/ClientStore.cpp new file mode 100644 index 000000000..0c12eefd8 --- /dev/null +++ b/nxcomp/src/ClientStore.cpp @@ -0,0 +1,226 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ClientStore.h" + +// +// Cached request classes. +// + +#include "ChangeProperty.h" +#include "SendEvent.h" +#include "CreateGC.h" +#include "ChangeGC.h" +#include "CreatePixmap.h" +#include "SetClipRectangles.h" +#include "CopyArea.h" +#include "PolyLine.h" +#include "PolySegment.h" +#include "PolyFillRectangle.h" +#include "PutImage.h" +#include "TranslateCoords.h" +#include "GetImage.h" +#include "ClearArea.h" +#include "ConfigureWindow.h" +#include "ShapeExtension.h" +#include "RenderExtension.h" +#include "PolyText8.h" +#include "PolyText16.h" +#include "ImageText8.h" +#include "ImageText16.h" +#include "PolyPoint.h" +#include "PolyFillArc.h" +#include "PolyArc.h" +#include "FillPoly.h" +#include "InternAtom.h" +#include "GetProperty.h" +#include "SetUnpackGeometry.h" +#include "SetUnpackColormap.h" +#include "SetUnpackAlpha.h" +#include "PutPackedImage.h" +#include "GenericRequest.h" + +// +// Set the verbosity level. +// + +#define WARNING +#define PANIC +#undef TEST + +ClientStore::ClientStore(StaticCompressor *compressor) + + : compressor_(compressor) +{ + if (logofs == NULL) + { + logofs = &cout; + } + + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + requests_[i] = NULL; + } + + requests_[X_ChangeProperty] = new ChangePropertyStore(); + requests_[X_SendEvent] = new SendEventStore(); + requests_[X_CreateGC] = new CreateGCStore(); + requests_[X_SetClipRectangles] = new SetClipRectanglesStore(); + requests_[X_CopyArea] = new CopyAreaStore(); + requests_[X_PolyLine] = new PolyLineStore(); + requests_[X_PolySegment] = new PolySegmentStore(); + requests_[X_PolyFillRectangle] = new PolyFillRectangleStore(); + requests_[X_PutImage] = new PutImageStore(compressor); + requests_[X_TranslateCoords] = new TranslateCoordsStore(); + requests_[X_GetImage] = new GetImageStore(); + requests_[X_ClearArea] = new ClearAreaStore(); + requests_[X_ConfigureWindow] = new ConfigureWindowStore(); + requests_[X_PolyText8] = new PolyText8Store(); + requests_[X_PolyText16] = new PolyText16Store(); + requests_[X_ImageText8] = new ImageText8Store(); + requests_[X_ImageText16] = new ImageText16Store(); + requests_[X_PolyPoint] = new PolyPointStore(); + requests_[X_PolyFillArc] = new PolyFillArcStore(); + requests_[X_PolyArc] = new PolyArcStore(); + requests_[X_FillPoly] = new FillPolyStore(); + requests_[X_InternAtom] = new InternAtomStore(); + requests_[X_GetProperty] = new GetPropertyStore(); + + requests_[X_NXInternalShapeExtension] = new ShapeExtensionStore(compressor); + requests_[X_NXInternalGenericRequest] = new GenericRequestStore(compressor); + requests_[X_NXInternalRenderExtension] = new RenderExtensionStore(compressor); + requests_[X_NXSetUnpackGeometry] = new SetUnpackGeometryStore(compressor); + requests_[X_NXPutPackedImage] = new PutPackedImageStore(compressor); + + // Since ProtoStep7 (#issue 108) + requests_[X_ChangeGC] = new ChangeGCStore(); + requests_[X_CreatePixmap] = new CreatePixmapStore(); + requests_[X_NXSetUnpackColormap] = new SetUnpackColormapStore(compressor); + requests_[X_NXSetUnpackAlpha] = new SetUnpackAlphaStore(compressor); + + for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++) + { + splits_[i] = NULL; + } + + commits_ = new CommitStore(compressor); +} + +ClientStore::~ClientStore() +{ + if (logofs == NULL) + { + logofs = &cout; + } + + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + delete requests_[i]; + } + + for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++) + { + delete splits_[i]; + } + + delete commits_; +} + +int ClientStore::saveRequestStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient, T_checksum_action checksumAction, + T_data_action dataAction) const +{ + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + if (requests_[i] != NULL && + requests_[i] -> saveStore(cachefs, md5StateStream, md5StateClient, + checksumAction, dataAction, + storeBigEndian()) < 0) + { + #ifdef WARNING + *logofs << "ClientStore: WARNING! Error saving request store " + << "for OPCODE#" << (unsigned int) i << ".\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Error saving request store " + << "for opcode '" << (unsigned int) i << "'.\n"; + + return -1; + } + } + + return 1; +} + +int ClientStore::loadRequestStores(istream *cachefs, md5_state_t *md5StateStream, + T_checksum_action checksumAction, T_data_action dataAction) const +{ + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + if (requests_[i] != NULL && + requests_[i] -> loadStore(cachefs, md5StateStream, + checksumAction, dataAction, + storeBigEndian()) < 0) + { + #ifdef WARNING + *logofs << "ClientStore: WARNING! Error loading request store " + << "for OPCODE#" << (unsigned int) i << ".\n" + << logofs_flush; + #endif + + return -1; + } + } + + return 1; +} + +void ClientStore::dumpSplitStores() const +{ + for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++) + { + if (splits_[i] != NULL) + { + splits_[i] -> dump(); + } + } + + if ((getSplitTotalSize() != 0 && getSplitTotalStorageSize() == 0) || + (getSplitTotalSize() == 0 && getSplitTotalStorageSize() != 0)) + { + #ifdef PANIC + *logofs << "ClientStore: PANIC! Inconsistency detected " + << "while handling the split stores.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } +} diff --git a/nxcomp/src/ClientStore.h b/nxcomp/src/ClientStore.h new file mode 100644 index 000000000..009d87d9f --- /dev/null +++ b/nxcomp/src/ClientStore.h @@ -0,0 +1,143 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ClientStore_H +#define ClientStore_H + +#include "Message.h" +#include "Split.h" + +#include "ChannelStore.h" + +class StaticCompressor; + +class ClientStore : public ChannelStore +{ + public: + + ClientStore(StaticCompressor *compressor); + + virtual ~ClientStore(); + + // + // Get the store based on the index. + // + + MessageStore *getRequestStore(unsigned char opcode) const + { + return requests_[opcode]; + } + + SplitStore *getSplitStore(int resource) const + { + return splits_[resource]; + } + + int getSplitTotalSize() const + { + return SplitStore::getTotalSize(); + } + + int getSplitTotalStorageSize() const + { + return SplitStore::getTotalStorageSize(); + } + + CommitStore *getCommitStore() const + { + return commits_; + } + + int getCommitSize() const + { + return commits_ -> getSize(); + } + + void dumpSplitStore(int resource) const + { + splits_[resource] -> dump(); + } + + void dumpCommitStore() const + { + commits_ -> dump(); + } + + void dumpSplitStores() const; + + SplitStore *createSplitStore(int resource) + { + splits_[resource] = new SplitStore(compressor_, commits_, resource); + + return splits_[resource]; + } + + void destroySplitStore(int resource) + { + delete splits_[resource]; + + splits_[resource] = NULL; + } + + // + // Actually save the message store + // to disk according to proxy mode. + // + + int saveRequestStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient, T_checksum_action checksumAction, + T_data_action dataAction) const; + + int loadRequestStores(istream *cachefs, md5_state_t *md5StateStream, + T_checksum_action checksumAction, T_data_action dataAction) const; + + private: + + // + // A client store contains requests. + // + + MessageStore *requests_[CHANNEL_STORE_OPCODE_LIMIT]; + + // + // Client messages being split. + // + + SplitStore *splits_[CHANNEL_STORE_RESOURCE_LIMIT]; + + // + // Messages having been recomposed. + // + + CommitStore *commits_; + + // + // Passed forward to the other stores. + // + + StaticCompressor *compressor_; +}; + +#endif /* ClientStore_H */ diff --git a/nxcomp/src/Colormap.cpp b/nxcomp/src/Colormap.cpp new file mode 100644 index 000000000..afe99ecae --- /dev/null +++ b/nxcomp/src/Colormap.cpp @@ -0,0 +1,106 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Unpack.h" +#include "Colormap.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +int UnpackColormap(unsigned char method, unsigned char *src_data, int src_size, + unsigned char *dst_data, int dst_size) +{ + if (*src_data == 0) + { + if (dst_size != src_size - 1) + { + #ifdef TEST + *logofs << "UnpackColormap: PANIC! Invalid destination size " + << dst_size << " with source " << src_size + << ".\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef TEST + *logofs << "UnpackColormap: Expanding " << src_size - 1 + << " bytes of plain colormap data.\n" << logofs_flush; + #endif + + memcpy(dst_data, src_data + 1, src_size - 1); + + return 1; + } + + unsigned int check_size = dst_size; + + int result = ZDecompress(&unpackStream, dst_data, &check_size, + src_data + 1, src_size - 1); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "UnpackColormap: PANIC! Failure decompressing colormap data. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decompressing colormap data. " + << "Error is '" << zError(result) << "'.\n"; + + return -1; + } + else if (check_size != (unsigned int) dst_size) + { + #ifdef PANIC + *logofs << "UnpackColormap: PANIC! Size mismatch in colormap data. " + << "Resulting size is " << check_size << " with " + << "expected size " << dst_size << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Size mismatch in colormap data. " + << "Resulting size is " << check_size << " with " + << "expected size " << dst_size << ".\n"; + + return -1; + } + + #ifdef TEST + *logofs << "UnpackColormap: Decompressed " << src_size - 1 + << " bytes to " << dst_size << " bytes of colormap data.\n" + << logofs_flush; + #endif + + return 1; +} diff --git a/nxcomp/src/Colormap.h b/nxcomp/src/Colormap.h new file mode 100644 index 000000000..a96d003fa --- /dev/null +++ b/nxcomp/src/Colormap.h @@ -0,0 +1,32 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Colormap_H +#define Colormap_H + +int UnpackColormap(unsigned char method, unsigned char *src_data, int src_size, + unsigned char *dst_data, int dst_size); + +#endif /* Colormap_H */ diff --git a/nxcomp/src/ConfigureWindow.cpp b/nxcomp/src/ConfigureWindow.cpp new file mode 100644 index 000000000..32d3153b9 --- /dev/null +++ b/nxcomp/src/ConfigureWindow.cpp @@ -0,0 +1,142 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ConfigureWindow.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int ConfigureWindowStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message; + + // + // Here is the fingerprint. + // + + configureWindow -> window = GetULONG(buffer + 4, bigEndian); + + configureWindow -> value_mask = GetUINT(buffer + 8, bigEndian); + + // + // To increase effectiveness of the caching algorithm + // we remove the unused bytes carried in the data part. + // + + if ((int) size > dataOffset) + { + #ifdef DEBUG + *logofs << name() << ": Removing unused bytes from the data payload.\n" << logofs_flush; + #endif + + configureWindow -> value_mask &= (1 << 7) - 1; + + unsigned int mask = 0x1; + unsigned char *source = (unsigned char *) buffer + CONFIGUREWINDOW_DATA_OFFSET; + unsigned long value = 0; + + for (unsigned int i = 0; i < 7; i++) + { + if (configureWindow -> value_mask & mask) + { + value = GetULONG(source, bigEndian); + + value &= (1 << CONFIGUREWINDOW_FIELD_WIDTH[i]) - 1; + + PutULONG(value, source, bigEndian); + + source += 4; + } + mask <<= 1; + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ConfigureWindowStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(configureWindow -> window, buffer + 4, bigEndian); + + PutUINT(configureWindow -> value_mask, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void ConfigureWindowStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message; + + *logofs << "ConfigureWindow: window " << configureWindow -> window + << ", value_mask " << configureWindow -> value_mask + << ", size " << configureWindow -> size_ << ".\n"; + + #endif +} + +void ConfigureWindowStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 4, 4); + md5_append(md5_state_, buffer + 8, 2); +} diff --git a/nxcomp/src/ConfigureWindow.h b/nxcomp/src/ConfigureWindow.h new file mode 100644 index 000000000..e02c2aae1 --- /dev/null +++ b/nxcomp/src/ConfigureWindow.h @@ -0,0 +1,178 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ConfigureWindow_H +#define ConfigureWindow_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define CONFIGUREWINDOW_ENABLE_CACHE 1 +#define CONFIGUREWINDOW_ENABLE_DATA 0 +#define CONFIGUREWINDOW_ENABLE_SPLIT 0 +#define CONFIGUREWINDOW_ENABLE_COMPRESS 0 + +#define CONFIGUREWINDOW_DATA_LIMIT 32 +#define CONFIGUREWINDOW_DATA_OFFSET 12 + +#define CONFIGUREWINDOW_CACHE_SLOTS 3000 +#define CONFIGUREWINDOW_CACHE_THRESHOLD 5 +#define CONFIGUREWINDOW_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class ConfigureWindowMessage : public Message +{ + friend class ConfigureWindowStore; + + public: + + ConfigureWindowMessage() + { + } + + ~ConfigureWindowMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int window; + unsigned short value_mask; +}; + +class ConfigureWindowStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + ConfigureWindowStore() : MessageStore() + { + enableCache = CONFIGUREWINDOW_ENABLE_CACHE; + enableData = CONFIGUREWINDOW_ENABLE_DATA; + enableSplit = CONFIGUREWINDOW_ENABLE_SPLIT; + enableCompress = CONFIGUREWINDOW_ENABLE_COMPRESS; + + dataLimit = CONFIGUREWINDOW_DATA_LIMIT; + dataOffset = CONFIGUREWINDOW_DATA_OFFSET; + + cacheSlots = CONFIGUREWINDOW_CACHE_SLOTS; + cacheThreshold = CONFIGUREWINDOW_CACHE_THRESHOLD; + cacheLowerThreshold = CONFIGUREWINDOW_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~ConfigureWindowStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "ConfigureWindow"; + } + + virtual unsigned char opcode() const + { + return X_ConfigureWindow; + } + + virtual unsigned int storage() const + { + return sizeof(ConfigureWindowMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new ConfigureWindowMessage(); + } + + virtual Message *create(const Message &message) const + { + return new ConfigureWindowMessage((const ConfigureWindowMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (ConfigureWindowMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* ConfigureWindow_H */ diff --git a/nxcomp/src/Control.cpp b/nxcomp/src/Control.cpp new file mode 100644 index 000000000..75fd56e3f --- /dev/null +++ b/nxcomp/src/Control.cpp @@ -0,0 +1,822 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "NX.h" +#include "NXpack.h" + +#include "Control.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Flush immediately on prioritized messages. +// + +#define FLUSH_PRIORITY 0 + +// +// Maximum number of bytes sent for each token. +// + +#define TOKEN_SIZE 1536 + +// +// Maximum number of tokens that can be spent +// by the client proxy before having to block +// waiting for a token reply. +// + +#define TOKEN_LIMIT 24 + +// +// By default assume the proxy is running as a +// standalone program. +// + +#define LINK_ENCRYPTED 0 + +// +// Maximum number of pids the proxy will record +// and kill at shutdown. +// + +#define KILL_LIMIT 16 + +// +// Allocate on the NX client side channels whose +// ids are a multiple of 8 (starting from 0). All +// the other ids can be used to allocate channels +// at the NX server side (X client side). +// + +#define CHANNEL_MASK 0x07 + +// +// Kill session if control parameters cannot be +// negotiated before this timeout. +// + +#define INIT_TIMEOUT 60000 + +// +// Enter the congestion state if the remote does +// not reply to a ping within the given amount +// of time. +// + +#define PING_TIMEOUT 5000 + +// +// Only send one motion event any N milliseconds. +// + +#define MOTION_TIMEOUT 0 + + +// +// Force an update of the congestion counter if +// the proxy is idle for this time. +// + +#define IDLE_TIMEOUT 50 + +// +// Close X connection if can't write before this +// timeout. +// + +#define CHANNEL_TIMEOUT 10000 + +// +// Warn user (or close proxy connection) if don't +// receive any data before this timeout. +// + +#define PROXY_TIMEOUT 120000 + +// +// How many milliseconds to wait for the shared +// memory completion event to become available. +// + +#define SHMEM_TIMEOUT 200 +// +// Before closing down the proxy, wait for the +// given amount of miliseconds to let all the +// running applications to close down their +// connections. +// +// A null timeout will cause the proxy to wait +// indefinitely, until the watchdog process is +// killed. This is usually the way the proxy is +// started by the NX server. If on the other +// hand a timeout is given and there no channel +// is remaining, the proxy will be closed down +// using a small timeout, presently of 500 ms. +// + +#define CLEANUP_TIMEOUT 3000 + +// +// Wait this amount of milliseconds after any +// iteration of the house-keeping process. +// + +#define KEEPER_TIMEOUT 60000 + +// +// In case of timeout, select can return control +// to program earlier or later of this amount of +// ms. Consider this when calculating if timeout +// is elapsed. +// + +#define LATENCY_TIMEOUT 1 + +// +// Control memory allocation in transport +// and other classes. +// + +#define TRANSPORT_X_BUFFER_SIZE 131072 +#define TRANSPORT_PROXY_BUFFER_SIZE 65536 +#define TRANSPORT_GENERIC_BUFFER_SIZE 16384 + +#define TRANSPORT_X_BUFFER_THRESHOLD 262144 +#define TRANSPORT_PROXY_BUFFER_THRESHOLD 131072 +#define TRANSPORT_GENERIC_BUFFER_THRESHOLD 32768 + +// +// Never allow buffers to exceed this limit. +// + +#define TRANSPORT_MAXIMUM_BUFFER_SIZE 393216 + +// +// Immediately flush the accumulated data to +// the X server if the write buffer exceeds +// this size. +// + +#define TRANSPORT_FLUSH_BUFFER_SIZE 16384 + +// +// Defaults used for socket options. +// + +#define OPTION_PROXY_KEEP_ALIVE 0 +#define OPTION_PROXY_LOW_DELAY 1 +#define OPTION_PROXY_CLIENT_NO_DELAY 1 +#define OPTION_PROXY_SERVER_NO_DELAY 1 +#define OPTION_CLIENT_NO_DELAY 1 +#define OPTION_SERVER_NO_DELAY 1 + +#define OPTION_PROXY_RECEIVE_BUFFER -1 +#define OPTION_CLIENT_RECEIVE_BUFFER -1 +#define OPTION_SERVER_RECEIVE_BUFFER -1 + +#define OPTION_PROXY_SEND_BUFFER -1 +#define OPTION_CLIENT_SEND_BUFFER -1 +#define OPTION_SERVER_SEND_BUFFER -1 + +#define OPTION_PROXY_RETRY_CONNECT 30 +#define OPTION_PROXY_RETRY_ACCEPT 3 +#define OPTION_SERVER_RETRY_CONNECT 3 + +// +// Defaults used for cache persistence. +// + +#define PERSISTENT_CACHE_THRESHOLD 102400 + +#define PERSISTENT_CACHE_ENABLE_LOAD 1 +#define PERSISTENT_CACHE_ENABLE_SAVE 1 + +#define PERSISTENT_CACHE_CHECK_ON_SHUTDOWN 0 + +#define PERSISTENT_CACHE_LOAD_PACKED 1 +#define PERSISTENT_CACHE_LOAD_RENDER 1 + +#define PERSISTENT_CACHE_DISK_LIMIT 33554432 + +// +// Defaults used for image cache. +// + +#define IMAGE_CACHE_ENABLE_LOAD 0 +#define IMAGE_CACHE_ENABLE_SAVE 0 + +#define IMAGE_CACHE_DISK_LIMIT 33554432 + +// +// Suggested defaults for read length parameters +// used by read buffer classes. +// + +#define CLIENT_INITIAL_READ_SIZE 8192 +#define CLIENT_MAXIMUM_BUFFER_SIZE 262144 + +#define SERVER_INITIAL_READ_SIZE 8192 +#define SERVER_MAXIMUM_BUFFER_SIZE 65536 + +#define PROXY_INITIAL_READ_SIZE 65536 +#define PROXY_MAXIMUM_BUFFER_SIZE 262144 + 1024 + +#define GENERIC_INITIAL_READ_SIZE 8192 +#define GENERIC_MAXIMUM_BUFFER_SIZE 8192 + +// +// Calculate bitrate in given time frames. +// Values are in milliseconds. +// + +#define SHORT_BITRATE_TIME_FRAME 5000 +#define LONG_BITRATE_TIME_FRAME 30000 + +// +// Bandwidth control. A value of 0 means no +// limit. Values are stored internally in +// bytes per second. +// + +#define CLIENT_BITRATE_LIMIT 0 +#define SERVER_BITRATE_LIMIT 0 + +// +// Default values for cache control. We limit +// the maximum size of a request to 262144 but +// we need to consider the replies, whose size +// may be up to 4MB. +// + +#define MINIMUM_MESSAGE_SIZE 4 +#define MAXIMUM_MESSAGE_SIZE 4194304 +#define MAXIMUM_REQUEST_SIZE 262144 + +#define CLIENT_TOTAL_STORAGE_SIZE 8388608 +#define SERVER_TOTAL_STORAGE_SIZE 8388608 + +#define STORE_TIME_LIMIT 3600 + +#define STORE_HITS_LOAD_BONUS 10 +#define STORE_HITS_ADD_BONUS 20 +#define STORE_HITS_LIMIT 100 + +#define STORE_HITS_TOUCH 1 +#define STORE_HITS_UNTOUCH 2 + +// +// Default parameters for message splitting. +// + +#define SPLIT_MODE 1 +#define SPLIT_TIMEOUT 50 +#define SPLIT_TOTAL_SIZE 128 +#define SPLIT_TOTAL_STORAGE_SIZE 1048576 +#define SPLIT_DATA_THRESHOLD 65536 +#define SPLIT_DATA_PACKET_LIMIT 24576 + +// +// Agent related parameters. +// + +#define PACK_METHOD 63 +#define PACK_QUALITY 9 +#define HIDE_RENDER 0 +#define TAINT_REPLIES 1 +#define TAINT_THRESHOLD 8 + +// +// In current version only X server support is +// implemented. Note that use of shared memory +// is negotiated according to options provided +// by the user. +// + +#define SHMEM_CLIENT 0 +#define SHMEM_SERVER 1 + +// +// Default size of shared memory segments used +// in MIT-SHM support. +// + +#define SHMEM_CLIENT_SIZE 0 +#define SHMEM_SERVER_SIZE 2097152 + +// +// What do we do at the end of session? If this +// flag is set, we launch a new client letting +// the user run a new NX session. +// + +#define ENABLE_RESTART_ON_SHUTDOWN 0 + +// +// Do we produce a core dump on fatal errors? +// + +#define ENABLE_CORE_DUMP_ON_ABORT 0 + +// +// Reopen the log file if it exceeds this size. +// + +#define FILE_SIZE_LIMIT 60000000 + +// +// Check periodically if we need to truncate the +// log file. By default check every minute. +// + +#define FILE_SIZE_CHECK_TIMEOUT 60000 + +// +// Protocol version compatibility values +// + +const int Control::NX_MIN_PROTO_STEP = 10; +const int Control::NX_MAX_PROTO_STEP = 10; +const char* const Control::NXPROXY_COMPATIBILITY_VERSION = "3.5.0"; + +// +// Set defaults for control. They should be what +// you get in case of 'local' connection. +// + +Control::Control() +{ + ProxyMode = proxy_undefined; + ProxyStage = stage_undefined; + SessionMode = session_undefined; + FlushPolicy = policy_undefined; + LinkMode = link_undefined; + + LinkEncrypted = LINK_ENCRYPTED; + FlushPriority = FLUSH_PRIORITY; + + TokenSize = TOKEN_SIZE; + TokenLimit = TOKEN_LIMIT; + + ChannelMask = CHANNEL_MASK; + + InitTimeout = INIT_TIMEOUT; + PingTimeout = PING_TIMEOUT; + MotionTimeout = MOTION_TIMEOUT; + IdleTimeout = IDLE_TIMEOUT; + + ChannelTimeout = CHANNEL_TIMEOUT; + ProxyTimeout = PROXY_TIMEOUT; + ShmemTimeout = SHMEM_TIMEOUT; + + CleanupTimeout = CLEANUP_TIMEOUT; + KeeperTimeout = KEEPER_TIMEOUT; + LatencyTimeout = LATENCY_TIMEOUT; + + FileSizeLimit = FILE_SIZE_LIMIT; + FileSizeCheckTimeout = FILE_SIZE_CHECK_TIMEOUT; + + EnableRestartOnShutdown = ENABLE_RESTART_ON_SHUTDOWN; + + KillDaemonOnShutdownLimit = KILL_LIMIT; + + KillDaemonOnShutdown = new int[KillDaemonOnShutdownLimit]; + + for (int i = 0; i < KILL_LIMIT; i++) + { + KillDaemonOnShutdown[i] = -1; + } + + KillDaemonOnShutdownNumber = 0; + + EnableCoreDumpOnAbort = ENABLE_CORE_DUMP_ON_ABORT; + + // + // Collect statistics by default. + // + + EnableStatistics = 1; + + // + // Memory restrictions if any. + // + + LocalMemoryLevel = -1; + + // + // Compression must be negotiated between proxies. + // + + LocalDeltaCompression = -1; + RemoteDeltaCompression = -1; + + LocalDataCompression = -1; + LocalStreamCompression = -1; + + RemoteDataCompression = -1; + RemoteStreamCompression = -1; + + LocalDataCompressionLevel = -1; + LocalDataCompressionThreshold = -1; + LocalStreamCompressionLevel = -1; + + RemoteDataCompressionLevel = -1; + RemoteStreamCompressionLevel = -1; + + // + // Transport buffers' allocation parameters. + // + + TransportXBufferSize = TRANSPORT_X_BUFFER_SIZE; + TransportProxyBufferSize = TRANSPORT_PROXY_BUFFER_SIZE; + TransportGenericBufferSize = TRANSPORT_GENERIC_BUFFER_SIZE; + + TransportXBufferThreshold = TRANSPORT_X_BUFFER_THRESHOLD; + TransportProxyBufferThreshold = TRANSPORT_PROXY_BUFFER_THRESHOLD; + TransportGenericBufferThreshold = TRANSPORT_GENERIC_BUFFER_THRESHOLD; + + TransportMaximumBufferSize = TRANSPORT_MAXIMUM_BUFFER_SIZE; + + // + // Flush the write buffer if it exceeds + // this size. + // + + TransportFlushBufferSize = TRANSPORT_FLUSH_BUFFER_SIZE; + + // + // Socket options. + // + + OptionProxyKeepAlive = OPTION_PROXY_KEEP_ALIVE; + OptionProxyLowDelay = OPTION_PROXY_LOW_DELAY; + OptionProxyClientNoDelay = OPTION_PROXY_CLIENT_NO_DELAY; + OptionProxyServerNoDelay = OPTION_PROXY_SERVER_NO_DELAY; + OptionClientNoDelay = OPTION_CLIENT_NO_DELAY; + OptionServerNoDelay = OPTION_SERVER_NO_DELAY; + + OptionProxyReceiveBuffer = OPTION_PROXY_RECEIVE_BUFFER; + OptionClientReceiveBuffer = OPTION_CLIENT_RECEIVE_BUFFER; + OptionServerReceiveBuffer = OPTION_SERVER_RECEIVE_BUFFER; + + OptionProxySendBuffer = OPTION_PROXY_SEND_BUFFER; + OptionClientSendBuffer = OPTION_CLIENT_SEND_BUFFER; + OptionServerSendBuffer = OPTION_SERVER_SEND_BUFFER; + + OptionProxyRetryAccept = OPTION_PROXY_RETRY_ACCEPT; + OptionProxyRetryConnect = OPTION_PROXY_RETRY_CONNECT; + OptionServerRetryConnect = OPTION_SERVER_RETRY_CONNECT; + + // + // Base NX directories. + // + + HomePath = NULL; + RootPath = NULL; + SystemPath = NULL; + TempPath = NULL; + ClientPath = NULL; + + // + // Set defaults for handling persistent cache. + // + + PersistentCachePath = NULL; + PersistentCacheName = NULL; + + PersistentCacheThreshold = PERSISTENT_CACHE_THRESHOLD; + + PersistentCacheEnableLoad = PERSISTENT_CACHE_ENABLE_LOAD; + PersistentCacheEnableSave = PERSISTENT_CACHE_ENABLE_SAVE; + + PersistentCacheCheckOnShutdown = PERSISTENT_CACHE_CHECK_ON_SHUTDOWN; + + PersistentCacheLoadPacked = PERSISTENT_CACHE_LOAD_PACKED; + PersistentCacheLoadRender = PERSISTENT_CACHE_LOAD_RENDER; + + PersistentCacheDiskLimit = PERSISTENT_CACHE_DISK_LIMIT; + + // + // Set defaults for image cache. + // + + ImageCachePath = NULL; + + ImageCacheEnableLoad = IMAGE_CACHE_ENABLE_LOAD; + ImageCacheEnableSave = IMAGE_CACHE_ENABLE_SAVE; + + ImageCacheDiskLimit = IMAGE_CACHE_DISK_LIMIT; + + // + // Set defaults for the read buffers. + // + + ClientInitialReadSize = CLIENT_INITIAL_READ_SIZE; + ClientMaximumBufferSize = CLIENT_MAXIMUM_BUFFER_SIZE; + + ServerInitialReadSize = SERVER_INITIAL_READ_SIZE; + ServerMaximumBufferSize = SERVER_MAXIMUM_BUFFER_SIZE; + + ProxyInitialReadSize = PROXY_INITIAL_READ_SIZE; + ProxyMaximumBufferSize = PROXY_MAXIMUM_BUFFER_SIZE; + + GenericInitialReadSize = GENERIC_INITIAL_READ_SIZE; + GenericMaximumBufferSize = GENERIC_MAXIMUM_BUFFER_SIZE; + + ShortBitrateTimeFrame = SHORT_BITRATE_TIME_FRAME; + LongBitrateTimeFrame = LONG_BITRATE_TIME_FRAME; + + // + // Bandwidth control. + // + + LocalBitrateLimit = -1; + + ClientBitrateLimit = CLIENT_BITRATE_LIMIT; + ServerBitrateLimit = SERVER_BITRATE_LIMIT; + + // + // Default parameters for message handling. + // + + ClientTotalStorageSize = CLIENT_TOTAL_STORAGE_SIZE; + ServerTotalStorageSize = SERVER_TOTAL_STORAGE_SIZE; + + LocalTotalStorageSize = -1; + RemoteTotalStorageSize = -1; + + StoreTimeLimit = STORE_TIME_LIMIT; + + StoreHitsLoadBonus = STORE_HITS_LOAD_BONUS; + StoreHitsAddBonus = STORE_HITS_ADD_BONUS; + StoreHitsLimit = STORE_HITS_LIMIT; + + StoreHitsTouch = STORE_HITS_TOUCH; + StoreHitsUntouch = STORE_HITS_UNTOUCH; + + MinimumMessageSize = MINIMUM_MESSAGE_SIZE; + MaximumMessageSize = MAXIMUM_MESSAGE_SIZE; + MaximumRequestSize = MAXIMUM_REQUEST_SIZE; + + SplitMode = SPLIT_MODE; + SplitTimeout = SPLIT_TIMEOUT; + SplitTotalSize = SPLIT_TOTAL_SIZE; + SplitTotalStorageSize = SPLIT_TOTAL_STORAGE_SIZE; + SplitDataThreshold = SPLIT_DATA_THRESHOLD; + SplitDataPacketLimit = SPLIT_DATA_PACKET_LIMIT; + + PackMethod = PACK_METHOD; + PackQuality = PACK_QUALITY; + HideRender = HIDE_RENDER; + TaintReplies = TAINT_REPLIES; + TaintThreshold = TAINT_THRESHOLD; + + ShmemClient = SHMEM_CLIENT; + ShmemServer = SHMEM_SERVER; + + ShmemClientSize = SHMEM_CLIENT_SIZE; + ShmemServerSize = SHMEM_SERVER_SIZE; + + // + // Get local version number from compile time + // settings. Version of remote proxy will be + // checked at connection time. + // + + RemoteVersionMajor = -1; + RemoteVersionMinor = -1; + RemoteVersionPatch = -1; + RemoteVersionMaintenancePatch = -1; + + CompatVersionMajor = -1; + CompatVersionMinor = -1; + CompatVersionPatch = -1; + CompatVersionMaintenancePatch = -1; + + LocalVersionMajor = NXMajorVersion(); + LocalVersionMinor = NXMinorVersion(); + LocalVersionPatch = NXPatchVersion(); + LocalVersionMaintenancePatch = NXMaintenancePatchVersion(); + + #ifdef TEST + *logofs << "Control: Major version is " << LocalVersionMajor + << " minor is " << LocalVersionMinor << " patch is " + << LocalVersionPatch << " Maintenance version is " + << LocalVersionMaintenancePatch << ".\n" << logofs_flush; + #endif + + // + // Initialize local implemented methods later + // and negotiate remote methods at connection + // time. + // + + LocalUnpackMethods = NULL; + RemoteUnpackMethods = NULL; + + // + // Set to 1 those methods which are implemented. + // + + setLocalUnpackMethods(); + + // + // Set the protocol version at the + // time the session is negotiated. + // + + protoStep_ = 0; +} + +Control::~Control() +{ + if (KillDaemonOnShutdown != NULL) + { + delete [] KillDaemonOnShutdown; + } + + if (HomePath != NULL) + { + delete [] HomePath; + } + + if (RootPath != NULL) + { + delete [] RootPath; + } + + if (SystemPath != NULL) + { + delete [] SystemPath; + } + + if (TempPath != NULL) + { + delete [] TempPath; + } + + if (ClientPath != NULL) + { + delete [] ClientPath; + } + + if (PersistentCachePath != NULL) + { + delete [] PersistentCachePath; + } + + if (PersistentCacheName != NULL) + { + delete [] PersistentCacheName; + } + + if (LocalUnpackMethods != NULL) + { + delete [] LocalUnpackMethods; + } + + if (RemoteUnpackMethods != NULL) + { + delete [] RemoteUnpackMethods; + } + + if (ImageCachePath != NULL) + { + delete [] ImageCachePath; + } +} + +// +// Set the protocol step based on the +// remote version. +// + +void Control::setProtoStep(int step) +{ + if (isValidProtoStep(step)) + { + protoStep_ = step; + } + else + { + #ifdef PANIC + *logofs << "Control: PANIC! Invalid protocol step " + << "with value " << step << ".\n" + << logofs_flush; + #endif + + HandleCleanup(); + } +} + +int Control::getProtoStep() +{ + if (isValidProtoStep(protoStep_)) + { + return protoStep_; + } + else + { + #ifdef PANIC + *logofs << "Control: PANIC! Can't identify the " + << "protocol step.\n" << logofs_flush; + #endif + + HandleCleanup(); + } +} + +// +// Set here the pack/unpack methods that are +// implemented by this NX proxy. +// + +void Control::setLocalUnpackMethods() +{ + LocalUnpackMethods = new unsigned char[PACK_METHOD_LIMIT]; + RemoteUnpackMethods = new unsigned char[PACK_METHOD_LIMIT]; + + for (int i = 0; i < PACK_METHOD_LIMIT; i++) + { + LocalUnpackMethods[i] = 0; + RemoteUnpackMethods[i] = 0; + } + + LocalUnpackMethods[NO_PACK] = 1; + + LocalUnpackMethods[PACK_MASKED_8_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_64_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_256_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_512_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_4K_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_32K_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_64K_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_256K_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_2M_COLORS] = 1; + LocalUnpackMethods[PACK_MASKED_16M_COLORS] = 1; + + LocalUnpackMethods[PACK_RAW_8_BITS] = 1; + LocalUnpackMethods[PACK_RAW_16_BITS] = 1; + LocalUnpackMethods[PACK_RAW_24_BITS] = 1; + + LocalUnpackMethods[PACK_COLORMAP_256_COLORS] = 1; + + LocalUnpackMethods[PACK_JPEG_8_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_64_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_256_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_512_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_4K_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_32K_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_64K_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_256K_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_2M_COLORS] = 1; + LocalUnpackMethods[PACK_JPEG_16M_COLORS] = 1; + + LocalUnpackMethods[PACK_PNG_8_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_64_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_256_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_512_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_4K_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_32K_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_64K_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_256K_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_2M_COLORS] = 1; + LocalUnpackMethods[PACK_PNG_16M_COLORS] = 1; + + LocalUnpackMethods[PACK_RGB_16M_COLORS] = 1; + LocalUnpackMethods[PACK_RLE_16M_COLORS] = 1; + + LocalUnpackMethods[PACK_ALPHA] = 1; + LocalUnpackMethods[PACK_COLORMAP] = 1; + + LocalUnpackMethods[PACK_BITMAP_16M_COLORS] = 1; +} diff --git a/nxcomp/src/Control.h b/nxcomp/src/Control.h new file mode 100644 index 000000000..764fca2c1 --- /dev/null +++ b/nxcomp/src/Control.h @@ -0,0 +1,764 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Control_H +#define Control_H + +#include "NXpack.h" + +#include "Misc.h" +#include "Types.h" +#include "Timestamp.h" +#include "Statistics.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// This is the mode proxy is running. +// + +typedef enum +{ + proxy_undefined = -1, + proxy_client, + proxy_server, + proxy_last_tag +} +T_proxy_mode; + +// +// Handle advances in the connection +// procedure. +// + +typedef enum +{ + stage_undefined, + stage_initializing, + stage_connecting, + stage_connected, + stage_waiting_forwarder_version, + stage_waiting_forwarder_options, + stage_sending_forwarder_options, + stage_waiting_proxy_version, + stage_waiting_proxy_options, + stage_sending_proxy_options, + stage_waiting_proxy_caches, + stage_sending_proxy_caches, + stage_operational, + stage_terminating, + stage_terminated +} +T_proxy_stage; + +// +// Hint about whether or not the proxy is +// connected to a NX agen. +// + +typedef enum +{ + session_undefined = -1, + session_agent, + session_shadow, + session_proxy, + session_last_tag +} +T_session_mode; + +// +// Set how data will be written to the peer +// socket. +// + +typedef enum +{ + policy_undefined = -1, + policy_immediate, + policy_deferred +} +T_flush_policy; + +// +// Link mode, after negotiation, will be set to +// any of the values defined in the NXproto.h. +// + +#define link_undefined -1; + +// +// This class collects functioning parameters, +// to be configurable at run-time. They are for +// the most part regarding timeouts, transport +// and message stores handling. +// + +class Control +{ + public: + + // + // Does proxy run in client mode or server mode? + // As soon as we'll have gone through parsing of + // the command line options the current mode will + // be propagated to the control class. + // + + T_proxy_mode ProxyMode; + + // + // Goes from initializing to operational. + // + + T_proxy_stage ProxyStage; + + // + // Hint about type of session currently running. + // + + T_session_mode SessionMode; + + // + // Either immediate or defferred flushes. + // + + T_flush_policy FlushPolicy; + + // + // If set, the channels will try to flush the + // encoded data whenever there is a prioritized + // message. Depending on the flush policy, this + // may determine an immediate flush or an event + // being generated telling to the agent that it + // should flush the proxy link. + // + + int FlushPriority; + + // + // Id corresponding to link speed negotiated + // between proxies. + // + + int LinkMode; + + // + // Set if the proxy is connected to a program + // providing the encryption of the point to + // point communication. + // + + int LinkEncrypted; + + // + // Maximum number of bytes sent for each token. + // + + int TokenSize; + + // + // Maximum number of tokens that can be spent + // by the client proxy before having to block + // waiting for a reply. + // + + int TokenLimit; + + // + // Bitmask used to determine the distribution + // of channel ids between the client and server + // proxies. + // + + int ChannelMask; + + // + // Kill session if control parameters cannot + // be negotiated before this timeout. + // + + int InitTimeout; + + // + // Enter the congestion state if the remote does + // not reply to the ping within the given amount + // of time. + // + + int PingTimeout; + + // + // Enqueue motion notify events in server channel. + // + + int MotionTimeout; + + // + // Force an update of the congestion counter if + // the proxy is idle for this time. + // + + int IdleTimeout; + + // + // Close the connection if can't write before + // this timeout. + // + + int ChannelTimeout; + + // + // Close connection if can't write before + // this timeout. + // + + int ProxyTimeout; + + // + // How many milliseconds to wait for the shared + // memory completion event to become available. + // + + int ShmemTimeout; + + // + // Wait for applications to complete at the time + // proxy is shut down. + // + + int CleanupTimeout; + + // + // Wait this amount of milliseconds before any + // iteration of the house-keeping process. + // + + int KeeperTimeout; + + // + // Adjust timeout calculations. + // + + int LatencyTimeout; + + // + // Maximum allowed size of log files. + // + + int FileSizeLimit; + int FileSizeCheckTimeout; + + // + // What do we do at the end of session? If + // this flag is set we launch a new client + // letting the user run a new NX session. + // + + int EnableRestartOnShutdown; + + // + // The client can request the proxy to kill + // a number of processes before exiting. + // + + int *KillDaemonOnShutdown; + int KillDaemonOnShutdownNumber; + int KillDaemonOnShutdownLimit; + + // + // Do we generate a core dump and exit in + // case of program errors? + // + + int EnableCoreDumpOnAbort; + + // + // Is statistic output enabled? + // + + int EnableStatistics; + + // + // Version number of local and remote proxy. + // + + /* + * LocalVersionMaintenancePatch, RemoteVersionMaintenancePatch + * CompatVersionMaintenancePatch + * + * currently not used, for future compatibility checks + */ + int LocalVersionMajor; + int LocalVersionMinor; + int LocalVersionPatch; + int LocalVersionMaintenancePatch; + + int RemoteVersionMajor; + int RemoteVersionMinor; + int RemoteVersionPatch; + int RemoteVersionMaintenancePatch; + + int CompatVersionMajor; + int CompatVersionMinor; + int CompatVersionPatch; + int CompatVersionMaintenancePatch; + + // + // Compatibility version for the proxy + // + + static const char* const NXPROXY_COMPATIBILITY_VERSION; + + // + // Which unpack methods are implemented in proxy? + // + + unsigned char *LocalUnpackMethods; + unsigned char *RemoteUnpackMethods; + + // + // Memory restriction imposed by user. + // + + int LocalMemoryLevel; + + // + // Use or not differential compression + // and caching of X protocol messages. + // + + int LocalDeltaCompression; + int RemoteDeltaCompression; + + // + // Compression of images and replies. + // + + int LocalDataCompression; + int LocalDataCompressionLevel; + + int RemoteDataCompression; + int RemoteDataCompressionLevel; + + // + // Minimum packet size to be compressed. + // + + int LocalDataCompressionThreshold; + + // + // Compress or not data flowing through the proxy + // link. Level should be one of the ZLIB level as + // Z_DEFAULT_COMPRESSION or Z_BEST_COMPRESSION. + // + + int LocalStreamCompression; + int LocalStreamCompressionLevel; + + int RemoteStreamCompression; + int RemoteStreamCompressionLevel; + + // + // Size of read operations in read buffer classes. + // + + int ClientInitialReadSize; + int ClientMaximumBufferSize; + + int ServerInitialReadSize; + int ServerMaximumBufferSize; + + int ProxyInitialReadSize; + int ProxyMaximumBufferSize; + + int GenericInitialReadSize; + int GenericMaximumBufferSize; + + // + // Set initial size and resize policy of + // transport buffers. If maximum size is + // exceeded, print a warning. + // + + int TransportXBufferSize; + int TransportProxyBufferSize; + int TransportGenericBufferSize; + + int TransportXBufferThreshold; + int TransportProxyBufferThreshold; + int TransportGenericBufferThreshold; + + int TransportMaximumBufferSize; + + // + // Flush the data produced for the channel + // connection if it exceeds this size. + // + + int TransportFlushBufferSize; + + // + // Socket options. + // + + int OptionProxyKeepAlive; + int OptionProxyLowDelay; + int OptionProxyClientNoDelay; + int OptionProxyServerNoDelay; + int OptionClientNoDelay; + int OptionServerNoDelay; + + int OptionProxyReceiveBuffer; + int OptionClientReceiveBuffer; + int OptionServerReceiveBuffer; + + int OptionProxySendBuffer; + int OptionClientSendBuffer; + int OptionServerSendBuffer; + + int OptionProxyRetryAccept; + int OptionProxyRetryConnect; + int OptionServerRetryConnect; + + // + // Calculate current bitrate on proxy link + // using these observation periods. Value + // is in milliseconds. + // + + int ShortBitrateTimeFrame; + int LongBitrateTimeFrame; + + // + // Limit the bandwidth usage of the proxy + // link. + // + + int LocalBitrateLimit; + + int ClientBitrateLimit; + int ServerBitrateLimit; + + // + // This is the limit imposed by user on + // total cache size. + // + + int ClientTotalStorageSize; + int ServerTotalStorageSize; + + int LocalTotalStorageSize; + int RemoteTotalStorageSize; + + // + // Discard messages in store older than + // this amount of seconds. + // + + int StoreTimeLimit; + + // + // Any new message in store starts with + // this amount of hits. + // + + int StoreHitsAddBonus; + + // + // Unless it is loaded from persistent + // cache. + // + + int StoreHitsLoadBonus; + + // + // Stop increasing hits at this threshold. + // + + int StoreHitsLimit; + + // + // Give a special weight to messages put or + // taken from cache during startup time. + // + + int StoreHitsStartup; + + // + // Weight of touch and untoch operations. + // + + int StoreHitsTouch; + int StoreHitsUntouch; + + // + // Directives on size of messages to cache. + // + + int MinimumMessageSize; + int MaximumMessageSize; + + // + // Maximum size of a single X request. + // + + int MaximumRequestSize; + + // + // Currently selected streaming mode. + // + + int SplitMode; + + // + // Send new split data any given amount of + // milliseconds. + // + + int SplitTimeout; + + // + // Maximum number of distinct messages and + // maximum size in bytes of the temporary + // storage. + // + + int SplitTotalSize; + int SplitTotalStorageSize; + + // + // Don't split messages smaller that this + // threshold and send no more than the + // given amount of bytes in a single data + // shot when streaming the split messages. + // + + int SplitDataThreshold; + int SplitDataPacketLimit; + + // + // Agent related parameters. These values apply + // to the agent which, at startup, must query + // the user's settings. + // + + int PackMethod; + int PackQuality; + int HideRender; + int TaintReplies; + int TaintThreshold; + + // + // Do we allow shared memory image support in + // client and or server? + // + + int ShmemClient; + int ShmemServer; + + // + // Default size of shared memory segments used + // in MIT-SHM support. + // + + int ShmemClientSize; + int ShmemServerSize; + + // + // The user's home directory. + // + + char *HomePath; + + // + // The ".nx" directory, usually in + // the user's home. + // + + char *RootPath; + + // + // Usually the /usr/NX" directory. + // + + char *SystemPath; + + // + // Usually the "/tmp" directory. + // + + char *TempPath; + + // + // The complete path to the client. + // + + char *ClientPath; + + // + // String containing path of cache + // file selected for load or save. + // + + char *PersistentCachePath; + + // + // Name of selected cache file. + // + + char *PersistentCacheName; + + // + // Minimum size of cache in memory + // to proceed to its storage on disk. + // + + int PersistentCacheThreshold; + + // + // Is persistent cache enabled? + // + + int PersistentCacheEnableLoad; + int PersistentCacheEnableSave; + + // + // This is used just for test because + // it requires that client and server + // reside on the same machine. + // + + int PersistentCacheCheckOnShutdown; + + // + // Load packed image and render extension + // message stores. This currently depends + // on the type of session. + // + + int PersistentCacheLoadPacked; + int PersistentCacheLoadRender; + + // + // Maximum disk consumption of message + // caches on disk. + // + + int PersistentCacheDiskLimit; + + // + // String containing the base path + // of image cache files. + // + + char *ImageCachePath; + + // + // Is image cache enabled? + // + + int ImageCacheEnableLoad; + int ImageCacheEnableSave; + + // + // Maximum disk consumption of image + // caches on disk. + // + + int ImageCacheDiskLimit; + + // + // Only constructor, destructor + // and a few utility functions. + // + + Control(); + + ~Control(); + + // + // Should not leverage control to find channel + // stores' size limits. As most of values in + // control, this info must be moved elsewhere. + // + + int getUpperStorageSize() const + { + return (ClientTotalStorageSize > + ServerTotalStorageSize ? + ClientTotalStorageSize : + ServerTotalStorageSize); + } + + int getLowerStorageSize() const + { + return (ClientTotalStorageSize < + ServerTotalStorageSize ? + ClientTotalStorageSize : + ServerTotalStorageSize); + } + + void setProtoStep(int step); + + int getProtoStep(); + + private: + + // + // Look in Control.cpp. + // + + void setLocalUnpackMethods(); + + // + // Manage the encoding according + // to the protocol version. + // + + int protoStep_; + + // + // Min and max values allowed for protocol step + // depending on protocol version compatibility + // + + static const int NX_MIN_PROTO_STEP; + static const int NX_MAX_PROTO_STEP; + + // + // Check the validity of protocol step + // + + bool isValidProtoStep(int step) + { + return ((step >= NX_MIN_PROTO_STEP) && (step <= NX_MAX_PROTO_STEP)); + } + +}; + +#endif /* Control_H */ diff --git a/nxcomp/src/CopyArea.cpp b/nxcomp/src/CopyArea.cpp new file mode 100644 index 000000000..c2a19c2df --- /dev/null +++ b/nxcomp/src/CopyArea.cpp @@ -0,0 +1,199 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "CopyArea.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +int CopyAreaStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + CopyAreaMessage *copyArea = (CopyAreaMessage *) message; + + // + // Here is the fingerprint. + // + + copyArea -> src_drawable = GetULONG(buffer + 4, bigEndian); + copyArea -> dst_drawable = GetULONG(buffer + 8, bigEndian); + copyArea -> gcontext = GetULONG(buffer + 12, bigEndian); + + copyArea -> src_x = GetUINT(buffer + 16, bigEndian); + copyArea -> src_y = GetUINT(buffer + 18, bigEndian); + copyArea -> dst_x = GetUINT(buffer + 20, bigEndian); + copyArea -> dst_y = GetUINT(buffer + 22, bigEndian); + + copyArea -> width = GetUINT(buffer + 24, bigEndian); + copyArea -> height = GetUINT(buffer + 26, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int CopyAreaStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + CopyAreaMessage *copyArea = (CopyAreaMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(copyArea -> src_drawable, buffer + 4, bigEndian); + PutULONG(copyArea -> dst_drawable, buffer + 8, bigEndian); + PutULONG(copyArea -> gcontext, buffer + 12, bigEndian); + + PutUINT(copyArea -> src_x, buffer + 16, bigEndian); + PutUINT(copyArea -> src_y, buffer + 18, bigEndian); + PutUINT(copyArea -> dst_x, buffer + 20, bigEndian); + PutUINT(copyArea -> dst_y, buffer + 22, bigEndian); + + PutUINT(copyArea -> width, buffer + 24, bigEndian); + PutUINT(copyArea -> height, buffer + 26, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void CopyAreaStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + CopyAreaMessage *copyArea = (CopyAreaMessage *) message; + + *logofs << name() << ": Identity src_drawable " << copyArea -> src_drawable + << ", dst_drawable " << copyArea -> dst_drawable << ", gcontext " << copyArea -> gcontext + << ", src_x " << copyArea -> src_x << ", src_y " << copyArea -> src_y + << ", dst_x " << copyArea -> dst_x << ", dst_y " << copyArea -> dst_y + << ", width " << copyArea -> width << ", height " << copyArea -> height + << ", size " << copyArea -> size_ << ".\n"; + + #endif +} + +void CopyAreaStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 16, 12); +} + +void CopyAreaStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + CopyAreaMessage *copyArea = (CopyAreaMessage *) message; + CopyAreaMessage *cachedCopyArea = (CopyAreaMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << copyArea -> src_drawable + << " as " << "src_drawable" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(copyArea -> src_drawable, clientCache -> drawableCache); + + cachedCopyArea -> src_drawable = copyArea -> src_drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << copyArea -> dst_drawable + << " as " << "dst_drawable" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(copyArea -> dst_drawable, clientCache -> drawableCache); + + cachedCopyArea -> dst_drawable = copyArea -> dst_drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << copyArea -> gcontext + << " as " << "gcontext" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(copyArea -> gcontext, clientCache -> gcCache); + + cachedCopyArea -> gcontext = copyArea -> gcontext; +} + +void CopyAreaStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + CopyAreaMessage *copyArea = (CopyAreaMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + copyArea -> src_drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << copyArea -> src_drawable + << " as " << "src_drawable" << " field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + copyArea -> dst_drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << copyArea -> dst_drawable + << " as " << "dst_drawable" << " field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + copyArea -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << copyArea -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/CopyArea.h b/nxcomp/src/CopyArea.h new file mode 100644 index 000000000..6b2617875 --- /dev/null +++ b/nxcomp/src/CopyArea.h @@ -0,0 +1,192 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef CopyArea_H +#define CopyArea_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define COPYAREA_ENABLE_CACHE 1 +#define COPYAREA_ENABLE_DATA 0 +#define COPYAREA_ENABLE_SPLIT 0 +#define COPYAREA_ENABLE_COMPRESS 0 + +#define COPYAREA_DATA_LIMIT 0 +#define COPYAREA_DATA_OFFSET 28 + +#define COPYAREA_CACHE_SLOTS 3000 +#define COPYAREA_CACHE_THRESHOLD 5 +#define COPYAREA_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class CopyAreaMessage : public Message +{ + friend class CopyAreaStore; + + public: + + CopyAreaMessage() + { + } + + ~CopyAreaMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int src_drawable; + unsigned int dst_drawable; + unsigned int gcontext; + unsigned short src_x; + unsigned short src_y; + unsigned short dst_x; + unsigned short dst_y; + unsigned short width; + unsigned short height; +}; + +class CopyAreaStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + CopyAreaStore() : MessageStore() + { + enableCache = COPYAREA_ENABLE_CACHE; + enableData = COPYAREA_ENABLE_DATA; + enableSplit = COPYAREA_ENABLE_SPLIT; + enableCompress = COPYAREA_ENABLE_COMPRESS; + + dataLimit = COPYAREA_DATA_LIMIT; + dataOffset = COPYAREA_DATA_OFFSET; + + cacheSlots = COPYAREA_CACHE_SLOTS; + cacheThreshold = COPYAREA_CACHE_THRESHOLD; + cacheLowerThreshold = COPYAREA_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~CopyAreaStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "CopyArea"; + } + + virtual unsigned char opcode() const + { + return X_CopyArea; + } + + virtual unsigned int storage() const + { + return sizeof(CopyAreaMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new CopyAreaMessage(); + } + + virtual Message *create(const Message &message) const + { + return new CopyAreaMessage((const CopyAreaMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (CopyAreaMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* CopyArea_H */ diff --git a/nxcomp/src/CreateGC.cpp b/nxcomp/src/CreateGC.cpp new file mode 100644 index 000000000..34978de13 --- /dev/null +++ b/nxcomp/src/CreateGC.cpp @@ -0,0 +1,194 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "CreateGC.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int CreateGCStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + CreateGCMessage *createGC = (CreateGCMessage *) message; + + // + // Here is the fingerprint. + // + + createGC -> gcontext = GetULONG(buffer + 4, bigEndian); + createGC -> drawable = GetULONG(buffer + 8, bigEndian); + createGC -> value_mask = GetULONG(buffer + 12, bigEndian); + + // + // Clear the unused bytes carried in the + // payload to increase the effectiveness + // of the caching algorithm. + // + + if ((int) size > dataOffset) + { + #ifdef DEBUG + *logofs << name() << ": Removing unused bytes from the " + << "data payload.\n" << logofs_flush; + #endif + + createGC -> value_mask &= (1 << 23) - 1; + + unsigned int mask = 0x1; + unsigned char *source = (unsigned char *) buffer + CREATEGC_DATA_OFFSET; + unsigned long value = 0; + + for (unsigned int i = 0; i < 23; i++) + { + if (createGC -> value_mask & mask) + { + value = GetULONG(source, bigEndian); + + value &= (0xffffffff >> (32 - CREATEGC_FIELD_WIDTH[i])); + + PutULONG(value, source, bigEndian); + + source += 4; + } + + mask <<= 1; + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int CreateGCStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + CreateGCMessage *createGC = (CreateGCMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(createGC -> gcontext, buffer + 4, bigEndian); + PutULONG(createGC -> drawable, buffer + 8, bigEndian); + PutULONG(createGC -> value_mask, buffer + 12, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void CreateGCStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + CreateGCMessage *createGC = (CreateGCMessage *) message; + + *logofs << name() << ": Identity gcontext " << createGC -> gcontext << ", drawable " + << createGC -> drawable << ", value_mask " << createGC -> value_mask + << ", size " << createGC -> size_ << ".\n" << logofs_flush; + #endif +} + +void CreateGCStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // This didn't include the drawable + // in previous versions. + // + + md5_append(md5_state_, buffer + 8, 8); +} + +void CreateGCStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + CreateGCMessage *createGC = (CreateGCMessage *) message; + CreateGCMessage *cachedCreateGC = (CreateGCMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + // Since ProtoStep7 (#issue 108) + #ifdef TEST + *logofs << name() << ": Encoding value " << createGC -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeNewXidValue(createGC -> gcontext, clientCache -> lastId, + clientCache -> lastIdCache, clientCache -> gcCache, + clientCache -> freeGCCache); + + cachedCreateGC -> gcontext = createGC -> gcontext; +} + +void CreateGCStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + CreateGCMessage *createGC = (CreateGCMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeNewXidValue(value, clientCache -> lastId, + clientCache -> lastIdCache, clientCache -> gcCache, + clientCache -> freeGCCache); + + createGC -> gcontext = value; + + #ifdef TEST + *logofs << name() << ": Decoded value " << createGC -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/CreateGC.h b/nxcomp/src/CreateGC.h new file mode 100644 index 000000000..03e27d685 --- /dev/null +++ b/nxcomp/src/CreateGC.h @@ -0,0 +1,186 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef CreateGC_H +#define CreateGC_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define CREATEGC_ENABLE_CACHE 1 +#define CREATEGC_ENABLE_DATA 0 +#define CREATEGC_ENABLE_SPLIT 0 +#define CREATEGC_ENABLE_COMPRESS 0 + +#define CREATEGC_DATA_LIMIT 144 +#define CREATEGC_DATA_OFFSET 16 + +#define CREATEGC_CACHE_SLOTS 2000 +#define CREATEGC_CACHE_THRESHOLD 2 +#define CREATEGC_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class CreateGCMessage : public Message +{ + friend class CreateGCStore; + + public: + + CreateGCMessage() + { + } + + ~CreateGCMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int gcontext; + unsigned int drawable; + unsigned int value_mask; +}; + +class CreateGCStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + CreateGCStore() : MessageStore() + { + enableCache = CREATEGC_ENABLE_CACHE; + enableData = CREATEGC_ENABLE_DATA; + enableSplit = CREATEGC_ENABLE_SPLIT; + enableCompress = CREATEGC_ENABLE_COMPRESS; + + dataLimit = CREATEGC_DATA_LIMIT; + dataOffset = CREATEGC_DATA_OFFSET; + + cacheSlots = CREATEGC_CACHE_SLOTS; + cacheThreshold = CREATEGC_CACHE_THRESHOLD; + cacheLowerThreshold = CREATEGC_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~CreateGCStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "CreateGC"; + } + + virtual unsigned char opcode() const + { + return X_CreateGC; + } + + virtual unsigned int storage() const + { + return sizeof(CreateGCMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new CreateGCMessage(); + } + + virtual Message *create(const Message &message) const + { + return new CreateGCMessage((const CreateGCMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (CreateGCMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* CreateGC_H */ diff --git a/nxcomp/src/CreatePixmap.cpp b/nxcomp/src/CreatePixmap.cpp new file mode 100644 index 000000000..a60134cd5 --- /dev/null +++ b/nxcomp/src/CreatePixmap.cpp @@ -0,0 +1,280 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "CreatePixmap.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Constructors and destructors. +// + +CreatePixmapStore::CreatePixmapStore() + + : MessageStore() +{ + enableCache = CREATEPIXMAP_ENABLE_CACHE; + enableData = CREATEPIXMAP_ENABLE_DATA; + enableSplit = CREATEPIXMAP_ENABLE_SPLIT; + enableCompress = CREATEPIXMAP_ENABLE_COMPRESS; + + dataLimit = CREATEPIXMAP_DATA_LIMIT; + dataOffset = CREATEPIXMAP_DATA_OFFSET; + + cacheSlots = CREATEPIXMAP_CACHE_SLOTS; + cacheThreshold = CREATEPIXMAP_CACHE_THRESHOLD; + cacheLowerThreshold = CREATEPIXMAP_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +CreatePixmapStore::~CreatePixmapStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int CreatePixmapStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(*(buffer + 1), 8, + clientCache -> depthCache); + + encodeBuffer.encodeNewXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> drawableCache, + clientCache -> freeDrawableCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> windowCache); + + encodeBuffer.encodeCachedValue(GetUINT(buffer + 12, bigEndian), 16, + clientCache -> createPixmapXCache, 8); + + encodeBuffer.encodeCachedValue(GetUINT(buffer + 14, bigEndian), 16, + clientCache -> createPixmapYCache, 8); + + #ifdef TEST + *logofs << name() << ": Encoded message. Size is " + << size << ".\n" << logofs_flush; + #endif + + return 1; +} + +int CreatePixmapStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned char cValue; + unsigned int value; + + size = 16; + + buffer = writeBuffer -> addMessage(size); + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + + *(buffer + 1) = cValue; + + decodeBuffer.decodeNewXidValue(value, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> drawableCache, + clientCache -> freeDrawableCache); + + PutULONG(value, buffer + 4, bigEndian); + + decodeBuffer.decodeXidValue(value, + clientCache -> windowCache); + + PutULONG(value, buffer + 8, bigEndian); + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> createPixmapXCache, 8); + + PutUINT(value, buffer + 12, bigEndian); + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> createPixmapYCache, 8); + + PutUINT(value, buffer + 14, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Size is " + << size << ".\n" << logofs_flush; + #endif + + return 1; +} + +int CreatePixmapStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + CreatePixmapMessage *createPixmap = (CreatePixmapMessage *) message; + + createPixmap -> depth = *(buffer + 1); + + createPixmap -> id = GetULONG(buffer + 4, bigEndian); + createPixmap -> drawable = GetULONG(buffer + 8, bigEndian); + + createPixmap -> width = GetUINT(buffer + 12, bigEndian); + createPixmap -> height = GetUINT(buffer + 14, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Size is " + << createPixmap -> size_ << " identity is " + << createPixmap -> i_size_ << ".\n" + << logofs_flush; + #endif + + return 1; +} + +int CreatePixmapStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + CreatePixmapMessage *createPixmap = (CreatePixmapMessage *) message; + + *(buffer + 1) = createPixmap -> depth; + + PutULONG(createPixmap -> id, buffer + 4, bigEndian); + PutULONG(createPixmap -> drawable, buffer + 8, bigEndian); + + PutUINT(createPixmap -> width, buffer + 12, bigEndian); + PutUINT(createPixmap -> height, buffer + 14, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Size is " + << createPixmap -> size_ << " identity is " + << createPixmap -> i_size_ << ".\n" + << logofs_flush; + #endif + + return 1; +} + +void CreatePixmapStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + #ifdef WARNING + *logofs << name() << ": WARNING! Dump of identity not implemented.\n" + << logofs_flush; + #endif + + #endif +} + +void CreatePixmapStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 8, 8); +} + +void CreatePixmapStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + CreatePixmapMessage *createPixmap = (CreatePixmapMessage *) message; + CreatePixmapMessage *cachedCreatePixmap = (CreatePixmapMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeNewXidValue(createPixmap -> id, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> drawableCache, + clientCache -> freeDrawableCache); + + cachedCreatePixmap -> id = createPixmap -> id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Size is " + << createPixmap -> size_ << " identity is " + << createPixmap -> i_size_ << ".\n" + << logofs_flush; + #endif +} + +void CreatePixmapStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + CreatePixmapMessage *createPixmap = (CreatePixmapMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeNewXidValue(createPixmap -> id, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> drawableCache, + clientCache -> freeDrawableCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Size is " + << createPixmap -> size_ << " identity is " + << createPixmap -> i_size_ << ".\n" + << logofs_flush; + #endif +} diff --git a/nxcomp/src/CreatePixmap.h b/nxcomp/src/CreatePixmap.h new file mode 100644 index 000000000..0a3212dd9 --- /dev/null +++ b/nxcomp/src/CreatePixmap.h @@ -0,0 +1,162 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef CreatePixmap_H +#define CreatePixmap_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define CREATEPIXMAP_ENABLE_CACHE 1 +#define CREATEPIXMAP_ENABLE_DATA 0 +#define CREATEPIXMAP_ENABLE_SPLIT 0 +#define CREATEPIXMAP_ENABLE_COMPRESS 0 + +#define CREATEPIXMAP_DATA_LIMIT 16 +#define CREATEPIXMAP_DATA_OFFSET 16 + +#define CREATEPIXMAP_CACHE_SLOTS 1000 +#define CREATEPIXMAP_CACHE_THRESHOLD 2 +#define CREATEPIXMAP_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class CreatePixmapMessage : public Message +{ + friend class CreatePixmapStore; + + public: + + CreatePixmapMessage() + { + } + + ~CreatePixmapMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char depth; + + unsigned int id; + unsigned int drawable; + + unsigned short width; + unsigned short height; +}; + +class CreatePixmapStore : public MessageStore +{ + public: + + CreatePixmapStore(); + + virtual ~CreatePixmapStore(); + + virtual const char *name() const + { + return "CreatePixmap"; + } + + virtual unsigned char opcode() const + { + return X_CreatePixmap; + } + + virtual unsigned int storage() const + { + return sizeof(CreatePixmapMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new CreatePixmapMessage(); + } + + virtual Message *create(const Message &message) const + { + return new CreatePixmapMessage((const CreatePixmapMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (CreatePixmapMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* CreatePixmap_H */ diff --git a/nxcomp/src/DecodeBuffer.cpp b/nxcomp/src/DecodeBuffer.cpp new file mode 100644 index 000000000..4c1530d9b --- /dev/null +++ b/nxcomp/src/DecodeBuffer.cpp @@ -0,0 +1,639 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Control.h" + +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +DecodeBuffer::DecodeBuffer(const unsigned char *data, unsigned int length) + + : buffer_(data), end_(buffer_ + length), nextSrc_(buffer_), srcMask_(0x80) +{ + // Since ProtoStep7 (#issue 108) + end_ = buffer_ + length - DECODE_BUFFER_POSTFIX_SIZE; +} + +int DecodeBuffer::decodeValue(unsigned int &value, unsigned int numBits, + unsigned int blockSize, int endOkay) +{ + #ifdef DUMP + *logofs << "DecodeBuffer: Decoding " << numBits + << " bits value with block " << blockSize + << " and " << (nextSrc_ - buffer_) + << " bytes in buffer.\n" << logofs_flush; + #endif + + unsigned int result = 0; + unsigned int destMask = 0x1; + unsigned int bitsRead = 0; + + if (blockSize == 0) + blockSize = numBits; + + unsigned char nextSrcChar = *nextSrc_; + unsigned int numBlocks = 1; + + do + { + if (numBlocks == 4) + { + blockSize = numBits; + } + + unsigned int bitsToRead = (blockSize > numBits - bitsRead ? + numBits - bitsRead : blockSize); + unsigned int count = 0; + unsigned char lastBit; + + do + { + if (nextSrc_ >= end_) + { + if (!endOkay) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [A] " + << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) + << " end_ = " << (end_ - buffer_) << ".\n" + << logofs_flush; + #endif + + // + // Label "context" is just used to identify + // the routine which detected the problem in + // present source file. + // + + cerr << "Error" << ": Failure decoding data in context [A].\n"; + + HandleAbort(); + } + + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [B] " + << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) + << " end_ = " << (end_ - buffer_) << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [B].\n"; + + HandleAbort(); + } + + lastBit = (nextSrcChar & srcMask_); + + if (lastBit) + result |= destMask; + + srcMask_ >>= 1; + + if (srcMask_ == 0) + { + srcMask_ = 0x80; + nextSrc_++; + nextSrcChar = *nextSrc_; + } + + destMask <<= 1; + } + while (bitsToRead > ++count); + + bitsRead += bitsToRead; + + if (bitsRead < numBits) + { + if (nextSrc_ >= end_) + { + if (!endOkay) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [C] " + << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) + << " end_ = " << (end_ - buffer_) << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [C].\n"; + + HandleAbort(); + } + + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [D] " + << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) + << " end_ = " << (end_ - buffer_) << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [D].\n"; + + HandleAbort(); + } + + unsigned char moreData = (nextSrcChar & srcMask_); + + srcMask_ >>= 1; + + if (srcMask_ == 0) + { + srcMask_ = 0x80; + nextSrc_++; + nextSrcChar = *nextSrc_; + } + + if (!moreData) + { + if (lastBit) + { + do + { + result |= destMask; + destMask <<= 1; + } + while (numBits > ++bitsRead); + } + else + bitsRead = numBits; + } + } + + blockSize >>= 1; + + if (blockSize < 2) + blockSize = 2; + + numBlocks++; + } + while (numBits > bitsRead); + + value = result; + + return 1; +} + +int DecodeBuffer::decodeCachedValue(unsigned int &value, unsigned int numBits, + IntCache &cache, unsigned int blockSize, + int endOkay) +{ + #ifdef DUMP + *logofs << "DecodeBuffer: Decoding " << numBits + << " bits cached value with block " << blockSize + << " and " << (nextSrc_ - buffer_) + << " bytes in buffer.\n" << logofs_flush; + #endif + + if (nextSrc_ >= end_) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [E] " + << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) + << " end_ = " << (end_ - buffer_) << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [E].\n"; + + HandleAbort(); + } + + unsigned int index = 0; + unsigned char nextSrcChar = *nextSrc_; + + while (!(nextSrcChar & srcMask_)) + { + index++; + srcMask_ >>= 1; + if (srcMask_ == 0) + { + srcMask_ = 0x80; + nextSrc_++; + if (nextSrc_ >= end_) + { + if (!endOkay) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [F] " + << "in decodeCachedValue() nextSrc_ = " + << (nextSrc_ - buffer_) << " end_ = " + << (end_ - buffer_) << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [F].\n"; + + HandleAbort(); + } + + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [G] " + << "in decodeValue() nextSrc_ = " << (nextSrc_ - buffer_) + << " end_ = " << (end_ - buffer_) << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [G].\n"; + + HandleAbort(); + } + + nextSrcChar = *nextSrc_; + } + } + + srcMask_ >>= 1; + + if (srcMask_ == 0) + { + srcMask_ = 0x80; + nextSrc_++; + } + + if (index == 2) + { + // Since ProtoStep8 (#issue 108) + blockSize = cache.getBlockSize(blockSize); + + if (decodeValue(value, numBits, blockSize, endOkay)) + { + cache.insert(value, IntMask[numBits]); + + return 1; + } + + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [H] " + << "in decodeCacheValue() with no value found.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [H].\n"; + + HandleAbort(); + } + else + { + if (index > 2) + { + index--; + } + + if (index > cache.getSize()) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [I] " + << "in decodeCachedValue() index = " << index + << " cache size = " << cache.getSize() << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [I].\n"; + + HandleAbort(); + } + + value = cache.get(index); + + return 1; + } +} + +int DecodeBuffer::decodeCachedValue(unsigned char &value, unsigned int numBits, + CharCache &cache, unsigned int blockSize, + int endOkay) +{ + #ifdef DUMP + *logofs << "DecodeBuffer: Decoding " << numBits + << " bits char cached value with block " << blockSize + << " and " << nextSrc_ - buffer_ << " bytes read out of " + << end_ - buffer_ << ".\n" << logofs_flush; + #endif + + if (nextSrc_ >= end_) + { + #ifdef TEST + *logofs << "DecodeBuffer: End of buffer reached in context [J] with " + << nextSrc_ - buffer_ << " bytes read out of " + << end_ - buffer_ << ".\n" << logofs_flush; + #endif + + return 0; + } + + unsigned int index = 0; + unsigned char nextSrcChar = *nextSrc_; + + while (!(nextSrcChar & srcMask_)) + { + index++; + srcMask_ >>= 1; + + if (srcMask_ == 0) + { + srcMask_ = 0x80; + nextSrc_++; + + if (nextSrc_ >= end_) + { + if (!endOkay) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [K] " + << "in decodeCachedValue() nextSrc_ " + << (nextSrc_ - buffer_) << " end_ " << (end_ - buffer_) + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [K].\n"; + + HandleAbort(); + } + + #ifdef TEST + *logofs << "DecodeBuffer: End of buffer reached in context [L] with " + << nextSrc_ - buffer_ << " bytes read out of " + << end_ - buffer_ << ".\n" << logofs_flush; + #endif + + return 0; + } + + nextSrcChar = *nextSrc_; + } + } + + srcMask_ >>= 1; + + if (srcMask_ == 0) + { + srcMask_ = 0x80; + nextSrc_++; + } + + if (index == 2) + { + unsigned int temp; + + if (decodeValue(temp, numBits, blockSize, endOkay)) + { + value = (unsigned char) temp; + + cache.insert(value); + } + else + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [M] " + << "in decodeValue() with index = 2.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [M].\n"; + + HandleAbort(); + } + } + else + { + if (index > 2) + { + index--; + } + + if (index > cache.getSize()) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [N] " + << "in decodeCachedValue() " << "index = " << index + << " cache size = " << cache.getSize() << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [N].\n"; + + HandleAbort(); + } + + value = cache.get(index); + } + + return 1; +} + +// +// Simply returns a pointer to the correct spot in +// the internal buffer. If the caller needs this +// data to last beyond the lifetime of the internal +// buffer, it must copy the data in its own memory. +// + +const unsigned char *DecodeBuffer::decodeMemory(unsigned int numBytes) +{ + #ifdef DUMP + *logofs << "DecodeBuffer: Decoding " << numBytes + << " bytes of memory with " << (nextSrc_ - buffer_) + << " bytes in buffer.\n" << logofs_flush; + #endif + + const unsigned char *result; + + // + // Force ourselves to a byte boundary. + // Is up to application to ensure data + // is word alligned when needed. + // + + if (srcMask_ != 0x80) + { + srcMask_ = 0x80; + nextSrc_++; + } + + result = nextSrc_; + + if (numBytes > DECODE_BUFFER_OVERFLOW_SIZE) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Can't decode a buffer of " + << numBytes << " bytes with limit set to " + << DECODE_BUFFER_OVERFLOW_SIZE << ".\n" + << logofs_flush; + + *logofs << "DecodeBuffer: PANIC! Assuming failure decoding " + << "data in context [O].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Should never decode buffer of size " + << "greater than " << DECODE_BUFFER_OVERFLOW_SIZE + << " bytes.\n"; + + cerr << "Error" << ": Assuming failure decoding data in " + << "context [O].\n"; + + HandleAbort(); + } + else if (end_ - nextSrc_ < (int) numBytes) + { + #ifdef PANIC + *logofs << "DecodeBuffer: PANIC! Assertion failed. Error [P] " + << "in decodeMemory() " << "with length " << numBytes + << " and " << (end_ - nextSrc_) + << " bytes remaining.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failure decoding data in context [P].\n"; + + HandleAbort(); + } + + nextSrc_ += numBytes; + + return result; +} + +void DecodeBuffer::decodeActionValue(unsigned char &value, unsigned short &position, + ActionCache &cache) +{ + unsigned int t; + + decodeCachedValue(t, 15, *(cache.base_[cache.slot_])); + + cache.last_ += t; + cache.last_ &= 0x7fff; + + value = cache.last_ >> 13; + + position = cache.last_ & 0x1fff; + + #ifdef DEBUG + *logofs << "DecodeBuffer: Decoded value " + << (unsigned) value << " and position " + << position << " with base " << cache.slot_ + << ".\n" << logofs_flush; + #endif + + #ifdef DEBUG + *logofs << "DecodeBuffer: Action block prediction is " + << (*(cache.base_[cache.slot_])).getBlockSize(15) + << ".\n" << logofs_flush; + #endif + + cache.slot_ = (cache.last_ & 0xff); +} + +void DecodeBuffer::decodeNewXidValue(unsigned int &value, unsigned int &lastId, + IntCache &lastIdCache, IntCache &cache, + FreeCache &freeCache) +{ + decodeCachedValue(value, 29, lastIdCache); + + lastId += (value + 1); + lastId &= 0x1fffffff; + + value = lastId; + + cache.push(value, 0x1fffffff); + + freeCache.push(value, 0x1fffffff); +} + +void DecodeBuffer::decodeNewXidValue(unsigned int &value, unsigned int &lastId, + IntCache &lastIdCache, XidCache &cache, + FreeCache &freeCache) +{ + decodeCachedValue(value, 29, lastIdCache); + + #ifdef DEBUG + *logofs << "DecodeBuffer: Decoded new Xid difference " + << value << ".\n" << logofs_flush; + #endif + + lastId += (value + 1); + lastId &= 0x1fffffff; + + value = lastId; + + unsigned int t = (value - cache.last_); + + cache.last_ = value; + + #ifdef DEBUG + *logofs << "DecodeBuffer: Decoded new Xid " << value + << " with base " << cache.slot_ << ".\n" + << logofs_flush; + #endif + + cache.slot_ = (value & 0xff); + + cache.base_[cache.slot_] -> push(t, 0x1fffffff); + + freeCache.push(value, 0x1fffffff); +} + +void DecodeBuffer::decodeXidValue(unsigned int &value, XidCache &cache) +{ + unsigned int t; + + decodeCachedValue(t, 29, *(cache.base_[cache.slot_])); + + cache.last_ += t; + cache.last_ &= 0x1fffffff; + + value = cache.last_; + + #ifdef DEBUG + *logofs << "DecodeBuffer: Decoded Xid " << value + << " with base " << cache.slot_ << ".\n" + << logofs_flush; + #endif + + cache.slot_ = (value & 0xff); + + #ifdef DEBUG + *logofs << "DecodeBuffer: Xid block prediction is " + << (*(cache.base_[cache.slot_])).getBlockSize(29) + << ".\n" << logofs_flush; + #endif +} + +void DecodeBuffer::decodeFreeXidValue(unsigned int &value, FreeCache &cache) +{ + decodeCachedValue(value, 29, cache); +} + diff --git a/nxcomp/src/DecodeBuffer.h b/nxcomp/src/DecodeBuffer.h new file mode 100644 index 000000000..f5f84c54f --- /dev/null +++ b/nxcomp/src/DecodeBuffer.h @@ -0,0 +1,138 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef DecodeBuffer_H +#define DecodeBuffer_H + +#include + +#include "IntCache.h" +#include "CharCache.h" +#include "XidCache.h" +#include "FreeCache.h" +#include "OpcodeCache.h" +#include "ActionCache.h" + +#define DECODE_BUFFER_OVERFLOW_SIZE 4194304 + +#define DECODE_BUFFER_POSTFIX_SIZE 1 + +class DecodeBuffer +{ + public: + + DecodeBuffer(const unsigned char *data, unsigned int length); + + ~DecodeBuffer() + { + } + + int decodeValue(unsigned int &value, unsigned int numBits, + unsigned int blockSize = 0, int endOkay = 0); + + int decodeCachedValue(unsigned int &value, unsigned int numBits, + IntCache &cache, unsigned int blockSize = 0, + int endOkay = 0); + + int decodeCachedValue(unsigned char &value, unsigned int numBits, + CharCache &cache, unsigned int blockSize = 0, + int endOkay = 0); + + void decodeDiffCachedValue(unsigned int &value, unsigned int &previous, + unsigned int numBits, IntCache &cache, + unsigned int blockSize = 0) + { + decodeCachedValue(value, numBits, cache, blockSize); + + previous += (value + 1); + previous &= (0xffffffff >> (32 - numBits)); + + value = previous; + } + + void decodeBoolValue(unsigned int &value) + { + decodeValue(value, 1); + } + + int decodeOpcodeValue(unsigned char &value, OpcodeCache &cache, int endOkay = 0) + { + int result = decodeCachedValue(value, 8, cache.base_[cache.slot_], 8, endOkay); + + if (result == 1) + { + cache.slot_ = value; + } + + return result; + } + + void decodeActionValue(unsigned char &value, unsigned short &position, + ActionCache &cache); + + void decodeNewXidValue(unsigned int &value, unsigned int &lastId, + IntCache &lastIdCache, IntCache &cache, + FreeCache &freeCache); + + void decodeNewXidValue(unsigned int &value, unsigned int &lastId, + IntCache &lastIdCache, XidCache &cache, + FreeCache &freeCache); + + void decodeXidValue(unsigned int &value, XidCache &cache); + + void decodeFreeXidValue(unsigned int &value, FreeCache &cache); + + void decodeTextData(unsigned char *buffer, unsigned int numBytes) + { + decodeMemory(buffer, numBytes); + } + + void decodeIntData(unsigned char *buffer, unsigned int numBytes) + { + decodeMemory(buffer, numBytes); + } + + void decodeLongData(unsigned char *buffer, unsigned int numBytes) + { + decodeMemory(buffer, numBytes); + } + + const unsigned char *decodeMemory(unsigned int numBytes); + + void decodeMemory(unsigned char *buffer, unsigned int numBytes) + { + memcpy(buffer, decodeMemory(numBytes), numBytes); + } + + private: + + const unsigned char *buffer_; + const unsigned char *end_; + const unsigned char *nextSrc_; + + unsigned char srcMask_; +}; + +#endif /* DecodeBuffer_H */ diff --git a/nxcomp/src/EncodeBuffer.cpp b/nxcomp/src/EncodeBuffer.cpp new file mode 100644 index 000000000..e112113a8 --- /dev/null +++ b/nxcomp/src/EncodeBuffer.cpp @@ -0,0 +1,623 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Control.h" + +#include "EncodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +#define ADVANCE_DEST \ +\ +if (destShift_ == 0) \ +{ \ + destShift_ = 7; nextDest_++; *nextDest_ = 0; \ +} \ +else \ +{ \ + destShift_--; \ +} + +EncodeBuffer::EncodeBuffer() +{ + size_ = ENCODE_BUFFER_DEFAULT_SIZE; + + buffer_ = new unsigned char[size_ + ENCODE_BUFFER_PREFIX_SIZE + + ENCODE_BUFFER_POSTFIX_SIZE] + ENCODE_BUFFER_PREFIX_SIZE; + end_ = buffer_ + size_; + + nextDest_ = buffer_; + *nextDest_ = 0; + destShift_ = 7; + + lastBits_ = 0; + + initialSize_ = ENCODE_BUFFER_DEFAULT_SIZE; + thresholdSize_ = ENCODE_BUFFER_DEFAULT_SIZE << 1; + maximumSize_ = ENCODE_BUFFER_DEFAULT_SIZE << 4; +} + +EncodeBuffer::~EncodeBuffer() +{ + delete [] (buffer_ - ENCODE_BUFFER_PREFIX_SIZE); +} + +void EncodeBuffer::setSize(unsigned int initialSize, unsigned int thresholdSize, + unsigned int maximumSize) +{ + initialSize_ = initialSize; + thresholdSize_ = thresholdSize; + maximumSize_ = maximumSize; + + #ifdef TEST + *logofs << "EncodeBuffer: Set buffer sizes to " + << initialSize_ << "/" << thresholdSize_ + << "/" << maximumSize_ << ".\n" + << logofs_flush; + #endif +} + +void EncodeBuffer::fullReset() +{ + if (size_ > initialSize_) + { + delete [] (buffer_ - ENCODE_BUFFER_PREFIX_SIZE); + + size_ = initialSize_; + + buffer_ = new unsigned char[size_ + ENCODE_BUFFER_PREFIX_SIZE + + ENCODE_BUFFER_POSTFIX_SIZE] + ENCODE_BUFFER_PREFIX_SIZE; + } + + end_ = buffer_ + size_; + + nextDest_ = buffer_; + *nextDest_ = 0; + destShift_ = 7; + + lastBits_ = 0; +} + +void EncodeBuffer::encodeValue(unsigned int value, unsigned int numBits, + unsigned int blockSize) +{ + #ifdef DUMP + *logofs << "EncodeBuffer: Encoding " << numBits + << " bits value with block " << blockSize + << " and " << (nextDest_ - buffer_) + << " bytes in buffer.\n" << logofs_flush; + #endif + + value &= IntMask[numBits]; + + unsigned int srcMask = 0x1; + unsigned int bitsWritten = 0; + + if (blockSize == 0) + blockSize = numBits; + + if (end_ - nextDest_ < 8) + { + growBuffer(); + } + + unsigned int numBlocks = 1; + + do + { + if (numBlocks == 4) + blockSize = numBits; + + unsigned int bitsToWrite = (blockSize > numBits - bitsWritten ? + numBits - bitsWritten : blockSize); + unsigned int count = 0; + unsigned int lastBit; + + do + { + lastBit = (value & srcMask); + if (lastBit) + *nextDest_ |= (1 << destShift_); + ADVANCE_DEST; + srcMask <<= 1; + } + while (bitsToWrite > ++count); + + bitsWritten += bitsToWrite; + + if (bitsWritten < numBits) + { + unsigned int tmpMask = srcMask; + unsigned int i = bitsWritten; + + if (lastBit) + { + do + { + unsigned int nextBit = (value & tmpMask); + + if (!nextBit) + break; + + tmpMask <<= 1; + } + while (numBits > ++i); + } + else + { + do + { + unsigned int nextBit = (value & tmpMask); + + if (nextBit) + break; + + tmpMask <<= 1; + } + while (numBits > ++i); + } + + if (i < numBits) + *nextDest_ |= (1 << destShift_); + else + bitsWritten = numBits; + + ADVANCE_DEST; + } + blockSize >>= 1; + + if (blockSize < 2) + blockSize = 2; + + numBlocks++; + } + while (numBits > bitsWritten); +} + +void EncodeBuffer::encodeCachedValue(unsigned int value, unsigned int numBits, + IntCache &cache, unsigned int blockSize) +{ + #ifdef DUMP + *logofs << "EncodeBuffer: Encoding " << numBits + << " bits cached value with block " << blockSize + << " and " << (nextDest_ - buffer_) + << " bytes in buffer.\n" << logofs_flush; + #endif + + value &= IntMask[numBits]; + + if (end_ - nextDest_ < 8) + { + growBuffer(); + } + + blockSize = cache.getBlockSize(blockSize); + + unsigned int index; + unsigned int sameDiff; + + #ifdef DUMP + + diffBits(); + + #endif + + if (cache.lookup(value, index, IntMask[numBits], sameDiff)) + { + if (index > 1) + index++; + + while (destShift_ < index) + { + index -= destShift_; + index--; + destShift_ = 7; + nextDest_++; + *nextDest_ = 0; + } + + destShift_ -= index; + *nextDest_ |= (1 << destShift_); + ADVANCE_DEST; + + #ifdef DUMP + *logofs << "EncodeBuffer: Encoded cached int using " + << diffBits() << " bits out of " << numBits + << ".\n" << logofs_flush; + #endif + } + else + { + ADVANCE_DEST; + ADVANCE_DEST; + *nextDest_ |= (1 << destShift_); + ADVANCE_DEST; + + // + // The attempt is very seldom successful. + // Avoid to encode the additional bool. + // + + // Since ProtoStep8 (#issue 108) + #ifdef DUMP + *logofs << "EncodeBuffer: Encoded missed int using " + << diffBits() << " bits out of " << numBits + << ".\n" << logofs_flush; + #endif + + encodeValue(value, numBits, blockSize); + } +} + +void EncodeBuffer::encodeCachedValue(unsigned char value, unsigned int numBits, + CharCache &cache, unsigned int blockSize) +{ + #ifdef DUMP + *logofs << "EncodeBuffer: Encoding " << numBits + << " bits char cached value with block " << blockSize + << " and " << (nextDest_ - buffer_) + << " bytes in buffer.\n" << logofs_flush; + #endif + + value &= IntMask[numBits]; + + if (end_ - nextDest_ < 8) + { + growBuffer(); + } + + unsigned int index; + + #ifdef DUMP + + diffBits(); + + #endif + + if (cache.lookup(value, index)) + { + if (index > 1) + index++; + + while (destShift_ < index) + { + index -= destShift_; + index--; + destShift_ = 7; + nextDest_++; + *nextDest_ = 0; + } + + destShift_ -= index; + *nextDest_ |= (1 << destShift_); + ADVANCE_DEST; + + #ifdef DUMP + *logofs << "EncodeBuffer: Encoded cached char using " + << diffBits() << " bits out of " << numBits + << ".\n" << logofs_flush; + #endif + } + else + { + ADVANCE_DEST; + ADVANCE_DEST; + *nextDest_ |= (1 << destShift_); + ADVANCE_DEST; + + encodeValue(value, numBits, blockSize); + + #ifdef DUMP + *logofs << "EncodeBuffer: Encoded missed char using " + << diffBits() << " bits out of " << numBits + << ".\n" << logofs_flush; + #endif + } +} + +void EncodeBuffer::encodeMemory(const unsigned char *buffer, unsigned int numBytes) +{ + #ifdef DUMP + *logofs << "EncodeBuffer: Encoding " << numBytes + << " bytes of memory with " << (nextDest_ - buffer_) + << " bytes in buffer.\n" << logofs_flush; + #endif + + if (numBytes > ENCODE_BUFFER_OVERFLOW_SIZE) + { + #ifdef PANIC + *logofs << "EncodeBuffer: PANIC! Should never encode buffer " + << "of size greater than " << ENCODE_BUFFER_OVERFLOW_SIZE + << " bytes.\n" << logofs_flush; + + *logofs << "EncodeBuffer: PANIC! Assuming failure encoding data " + << "in context [A].\n" << logofs_flush; + #endif + + // + // Label "context" is just used to identify + // the routine which detected the problem in + // present source file. + // + + cerr << "Error" << ": Should never encode buffer of size " + << "greater than " << ENCODE_BUFFER_OVERFLOW_SIZE + << " bytes.\n"; + + cerr << "Error" << ": Assuming failure encoding data " + << "in context [A].\n" ; + + HandleAbort(); + } + + alignBuffer(); + + if (end_ - nextDest_ < (int) numBytes) + { + growBuffer(numBytes); + } + + memcpy(nextDest_, buffer, numBytes); + + nextDest_ += numBytes; + + if (nextDest_ == end_) + { + growBuffer(); + } + else if (nextDest_ > end_) + { + #ifdef PANIC + *logofs << "EncodeBuffer: PANIC! Assertion failed. Error [B] " + << "in encodeMemory() nextDest_ " << (nextDest_ - buffer) + << " end_ " << (end_ - buffer) << ".\n" + << logofs_flush; + #endif + + // + // Label "context" is just used to identify + // the routine which detected the problem in + // present source file. + // + + cerr << "Error" << ": Failure encoding raw data " + << "in context [B].\n" ; + + HandleAbort(); + } + + *nextDest_ = 0; +} + +unsigned int EncodeBuffer::getLength() const +{ + unsigned int length = nextDest_ - buffer_; + + if (destShift_ != 7) + { + length++; + } + + // Since ProtoStep7 (#issue 108) + if (length > 0) + { + return length + ENCODE_BUFFER_POSTFIX_SIZE; + } + + return length; +} + +unsigned int EncodeBuffer::diffBits() +{ + unsigned int bits = ((nextDest_ - buffer_) << 3); + + bits += (7 - destShift_); + + unsigned int diff = bits - lastBits_; + + lastBits_ = bits; + + return diff; +} + +void EncodeBuffer::growBuffer(unsigned int numBytes) +{ + if (numBytes == 0) + { + numBytes = initialSize_; + } + + unsigned int bytesInBuffer = nextDest_ - buffer_; + + unsigned int newSize = thresholdSize_; + + while (newSize < bytesInBuffer + numBytes) + { + newSize <<= 1; + + if (newSize > maximumSize_) + { + newSize = bytesInBuffer + numBytes + initialSize_; + } + } + + unsigned char *newBuffer; + + newBuffer = new unsigned char[newSize + ENCODE_BUFFER_PREFIX_SIZE + + ENCODE_BUFFER_POSTFIX_SIZE] + ENCODE_BUFFER_PREFIX_SIZE; + + if (newBuffer == NULL) + { + #ifdef PANIC + *logofs << "EncodeBuffer: PANIC! Error in context [C] " + << "growing buffer to accommodate " << numBytes + << " bytes .\n" << logofs_flush; + #endif + + cerr << "Error" << ": Error in context [C] " + << "growing encode buffer to accommodate " + << numBytes << " bytes.\n"; + + HandleAbort(); + } + + #ifdef TEST + if (newSize >= maximumSize_) + { + *logofs << "EncodeBuffer: WARNING! Buffer grown to reach " + << "size of " << newSize << " bytes.\n" + << logofs_flush; + } + #endif + + // + // Prefix should not contain any valid data. + // It is proxy that will fill it with control + // messages and data length at the time a new + // frame is written to socket. + // + + memcpy(newBuffer, buffer_, bytesInBuffer + 1); + + newBuffer[bytesInBuffer + 1] = 0; + + delete [] (buffer_ - ENCODE_BUFFER_PREFIX_SIZE); + + buffer_ = newBuffer; + size_ = newSize; + end_ = buffer_ + size_; + + nextDest_ = buffer_ + bytesInBuffer; +} + +void EncodeBuffer::alignBuffer() +{ + if (destShift_ != 7) + { + destShift_ = 7; + nextDest_++; + + if (nextDest_ >= end_) + { + growBuffer(); + } + + *nextDest_ = 0; + } +} + +void EncodeBuffer::encodeActionValue(unsigned char value, unsigned short position, + ActionCache &cache) +{ + unsigned int v = (value << 13) | position; + + unsigned int t = (v - cache.last_); + + encodeCachedValue(t, 15, *(cache.base_[cache.slot_])); + + cache.last_ = v; + + #ifdef DEBUG + *logofs << "EncodeBuffer: Encoded value " + << (unsigned) value << " and position " + << position << " with base " << cache.slot_ + << ".\n" << logofs_flush; + #endif + + cache.slot_ = (cache.last_ & 0xff); +} + +void EncodeBuffer::encodeNewXidValue(unsigned int value, unsigned int &lastId, + IntCache &lastIdCache, IntCache &cache, + FreeCache &freeCache) +{ + encodeCachedValue((value - 1) - lastId, 29, lastIdCache); + + lastId = value; + + cache.push(value, 0x1fffffff); + + freeCache.push(value, 0x1fffffff); +} + +void EncodeBuffer::encodeNewXidValue(unsigned int value, unsigned int &lastId, + IntCache &lastIdCache, XidCache &cache, + FreeCache &freeCache) +{ + encodeCachedValue((value - 1) - lastId, 29, lastIdCache); + + lastId = value; + + unsigned int t = (value - cache.last_); + + cache.last_ = value; + + #ifdef DEBUG + *logofs << "EncodeBuffer: Encoded new Xid " << value + << " with base " << cache.slot_ << ".\n" + << logofs_flush; + #endif + + cache.slot_ = (value & 0xff); + + cache.base_[cache.slot_] -> push(t, 0x1fffffff); + + freeCache.push(value, IntMask[29]); +} + +void EncodeBuffer::encodeXidValue(unsigned int value, XidCache &cache) +{ + unsigned int t = (value - cache.last_); + + encodeCachedValue(t, 29, *(cache.base_[cache.slot_])); + + cache.last_ = value; + + #ifdef DEBUG + *logofs << "EncodeBuffer: Encoded Xid " << value + << " with base " << cache.slot_ << ".\n" + << logofs_flush; + #endif + + cache.slot_ = (value & 0xff); +} + +void EncodeBuffer::encodeFreeXidValue(unsigned int value, FreeCache &cache) +{ + encodeCachedValue(value, 29, cache); +} diff --git a/nxcomp/src/EncodeBuffer.h b/nxcomp/src/EncodeBuffer.h new file mode 100644 index 000000000..67f6ff093 --- /dev/null +++ b/nxcomp/src/EncodeBuffer.h @@ -0,0 +1,183 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef EncodeBuffer_H +#define EncodeBuffer_H + +#include "IntCache.h" +#include "CharCache.h" +#include "XidCache.h" +#include "FreeCache.h" +#include "OpcodeCache.h" +#include "ActionCache.h" + +#define ENCODE_BUFFER_DEFAULT_SIZE 16384 + +// +// This should match the maximum size of +// a single message added to write buffer +// (see WriteBuffer.h). +// + +#define ENCODE_BUFFER_OVERFLOW_SIZE 4194304 + +// +// Adjust for the control messages and the +// frame length added by the proxy. +// + +#define ENCODE_BUFFER_PREFIX_SIZE 64 + +// +// The encode routines may write one byte +// past the nominal end of the encode buffer. +// This additional byte is included in the +// payload. This is actually a harmless bug. +// + +#define ENCODE_BUFFER_POSTFIX_SIZE 1 + +class EncodeBuffer +{ + public: + + EncodeBuffer(); + + ~EncodeBuffer(); + + void setSize(unsigned int initialSize, unsigned int thresholdSize, + unsigned int maximumSize); + + void encodeValue(unsigned int value, unsigned int numBits, + unsigned int blockSize = 0); + + void encodeCachedValue(unsigned int value, unsigned int numBits, + IntCache &cache, unsigned int blockSize = 0); + + void encodeCachedValue(unsigned char value, unsigned int numBits, + CharCache &cache, unsigned int blockSize = 0); + + void encodeDiffCachedValue(const unsigned int value, unsigned int &previous, + unsigned int numBits, IntCache &cache, + unsigned int blockSize = 0) + { + encodeCachedValue((value - 1) - previous, numBits, cache, blockSize); + + previous = value; + } + + void encodeBoolValue(unsigned int value) + { + encodeValue(value, 1); + } + + void encodeOpcodeValue(unsigned char value, OpcodeCache &cache) + { + encodeCachedValue(value, 8, cache.base_[cache.slot_], 8); + + cache.slot_ = value; + } + + void encodeActionValue(unsigned char value, ActionCache &cache) + { + unsigned short position = 0; + + encodeActionValue(value, position, cache); + } + + void encodeActionValue(unsigned char value, unsigned short position, + ActionCache &cache); + + void encodeNewXidValue(unsigned int value, unsigned int &lastId, + IntCache &lastIdCache, IntCache &cache, + FreeCache &freeCache); + + void encodeNewXidValue(unsigned int value, unsigned int &lastId, + IntCache &lastIdCache, XidCache &cache, + FreeCache &freeCache); + + void encodeXidValue(unsigned int value, XidCache &cache); + + void encodeFreeXidValue(unsigned int value, FreeCache &cache); + + void encodeTextData(const unsigned char *buffer, unsigned int numBytes) + { + encodeMemory(buffer, numBytes); + } + + void encodeIntData(const unsigned char *buffer, unsigned int numBytes) + { + encodeMemory(buffer, numBytes); + } + + void encodeLongData(const unsigned char *buffer, unsigned int numBytes) + { + encodeMemory(buffer, numBytes); + } + + void encodeMemory(const unsigned char *buffer, unsigned int numBytes); + + unsigned char *getData() + { + return buffer_; + } + + unsigned int getLength() const; + + unsigned int getBits() const + { + return ((nextDest_ - buffer_) << 3) + (7 - destShift_); + } + + unsigned int diffBits(); + + void fullReset(); + + private: + + void growBuffer(unsigned int numBytes = 0); + + void alignBuffer(); + + unsigned int size_; + unsigned char *buffer_; + + // + // This points to the first byte + // just beyond end of the buffer. + // + + const unsigned char *end_; + + unsigned char *nextDest_; + unsigned int destShift_; + unsigned int lastBits_; + + unsigned int initialSize_; + unsigned int thresholdSize_; + unsigned int maximumSize_; +}; + +#endif /* EncodeBuffer_H */ diff --git a/nxcomp/src/FillPoly.cpp b/nxcomp/src/FillPoly.cpp new file mode 100644 index 000000000..b5928d5cf --- /dev/null +++ b/nxcomp/src/FillPoly.cpp @@ -0,0 +1,239 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "FillPoly.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int FillPolyStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + FillPolyMessage *fillPoly = (FillPolyMessage *) message; + + // + // Here is the fingerprint. + // + + fillPoly -> drawable = GetULONG(buffer + 4, bigEndian); + fillPoly -> gcontext = GetULONG(buffer + 8, bigEndian); + + fillPoly -> shape = *(buffer + 12); + fillPoly -> mode = *(buffer + 13); + + // Since ProtoStep8 (#issue 108) + if (size >= (unsigned int) dataOffset) + { + fillPoly -> x_origin = GetUINT(buffer + 16, bigEndian); + fillPoly -> y_origin = GetUINT(buffer + 18, bigEndian); + } + else + { + fillPoly -> x_origin = 0; + fillPoly -> y_origin = 0; + } + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int FillPolyStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + FillPolyMessage *fillPoly = (FillPolyMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(fillPoly -> drawable, buffer + 4, bigEndian); + PutULONG(fillPoly -> gcontext, buffer + 8, bigEndian); + + *(buffer + 12) = fillPoly -> shape; + *(buffer + 13) = fillPoly -> mode; + + // Since ProtoStep8 (#issue 108) + if (size >= (unsigned int) dataOffset) + { + PutUINT(fillPoly -> x_origin, buffer + 16, bigEndian); + PutUINT(fillPoly -> y_origin, buffer + 18, bigEndian); + } + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void FillPolyStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + FillPolyMessage *fillPoly = (FillPolyMessage *) message; + + *logofs << name() << ": Identity drawable " << fillPoly -> drawable + << ", gcontext " << fillPoly -> gcontext << ", shape " + << fillPoly -> shape << ", mode " << fillPoly -> mode + << fillPoly -> size_ << ", x_origin " << fillPoly -> x_origin + << ", y_origin " << fillPoly -> y_origin << ".\n" + << logofs_flush; + #endif +} + +void FillPolyStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Fields shape, mode. + // + + md5_append(md5_state_, buffer + 12, 2); +} + +void FillPolyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + FillPolyMessage *fillPoly = (FillPolyMessage *) message; + FillPolyMessage *cachedFillPoly = (FillPolyMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << fillPoly -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(fillPoly -> drawable, clientCache -> drawableCache); + + cachedFillPoly -> drawable = fillPoly -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << fillPoly -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(fillPoly -> gcontext, clientCache -> gcCache); + + cachedFillPoly -> gcontext = fillPoly -> gcontext; + + // Since ProtoStep8 (#issue 108) + if (fillPoly -> size_ >= dataOffset) + { + #ifdef TEST + *logofs << name() << ": Encoding value " << fillPoly -> x_origin + << " as x_origin field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(fillPoly -> x_origin, 16, + *clientCache -> fillPolyXAbsCache[0], 8); + + cachedFillPoly -> x_origin = fillPoly -> x_origin; + + #ifdef TEST + *logofs << name() << ": Encoding value " << fillPoly -> y_origin + << " as y_origin field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(fillPoly -> y_origin, 16, + *clientCache -> fillPolyYAbsCache[0], 8); + + cachedFillPoly -> y_origin = fillPoly -> y_origin; + } +} + +void FillPolyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + FillPolyMessage *fillPoly = (FillPolyMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(fillPoly -> drawable, clientCache -> drawableCache); + + #ifdef TEST + *logofs << name() << ": Decoded value " << fillPoly -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(fillPoly -> gcontext, clientCache -> gcCache); + + #ifdef TEST + *logofs << name() << ": Decoded value " << fillPoly -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + // Since ProtoStep8 (#issue 108) + if (fillPoly -> size_ >= dataOffset) + { + unsigned int value; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache -> fillPolyXAbsCache[0], 8); + + fillPoly -> x_origin = value; + + #ifdef TEST + *logofs << name() << ": Decoded value " << fillPoly -> x_origin + << " as x_origin field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache -> fillPolyYAbsCache[0], 8); + + fillPoly -> y_origin = value; + + #ifdef TEST + *logofs << name() << ": Decoded value " << fillPoly -> y_origin + << " as y_origin field.\n" << logofs_flush; + #endif + } +} + + diff --git a/nxcomp/src/FillPoly.h b/nxcomp/src/FillPoly.h new file mode 100644 index 000000000..4ceb96c09 --- /dev/null +++ b/nxcomp/src/FillPoly.h @@ -0,0 +1,200 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef FillPoly_H +#define FillPoly_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define FILLPOLY_ENABLE_CACHE 1 +#define FILLPOLY_ENABLE_DATA 0 +#define FILLPOLY_ENABLE_SPLIT 0 +#define FILLPOLY_ENABLE_COMPRESS 0 + +#define FILLPOLY_DATA_LIMIT 512 + +#define FILLPOLY_CACHE_SLOTS 2000 +#define FILLPOLY_CACHE_THRESHOLD 3 +#define FILLPOLY_CACHE_LOWER_THRESHOLD 1 + +#define FILLPOLY_DATA_OFFSET_IF_PROTO_STEP_8 20 + +// +// The message class. +// + +class FillPolyMessage : public Message +{ + friend class FillPolyStore; + + public: + + FillPolyMessage() + { + } + + ~FillPolyMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char shape; + unsigned char mode; + unsigned int drawable; + unsigned int gcontext; + + unsigned short x_origin; + unsigned short y_origin; +}; + +class FillPolyStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + FillPolyStore() : MessageStore() + { + enableCache = FILLPOLY_ENABLE_CACHE; + enableData = FILLPOLY_ENABLE_DATA; + enableSplit = FILLPOLY_ENABLE_SPLIT; + enableCompress = FILLPOLY_ENABLE_COMPRESS; + + dataLimit = FILLPOLY_DATA_LIMIT; + + // Since ProtoStep8 (#issue 108) + dataOffset = FILLPOLY_DATA_OFFSET_IF_PROTO_STEP_8; + + cacheSlots = FILLPOLY_CACHE_SLOTS; + cacheThreshold = FILLPOLY_CACHE_THRESHOLD; + cacheLowerThreshold = FILLPOLY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~FillPolyStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "FillPoly"; + } + + virtual unsigned char opcode() const + { + return X_FillPoly; + } + + virtual unsigned int storage() const + { + return sizeof(FillPolyMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new FillPolyMessage(); + } + + virtual Message *create(const Message &message) const + { + return new FillPolyMessage((const FillPolyMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (FillPolyMessage *) message; + } + + virtual int identitySize(const unsigned char *buffer, unsigned int size) + { + // Since ProtoStep8 (#issue 108) + return (size >= FILLPOLY_DATA_OFFSET_IF_PROTO_STEP_8 ? + FILLPOLY_DATA_OFFSET_IF_PROTO_STEP_8 : size); + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* FillPoly_H */ diff --git a/nxcomp/src/Fork.cpp b/nxcomp/src/Fork.cpp new file mode 100644 index 000000000..657c36134 --- /dev/null +++ b/nxcomp/src/Fork.cpp @@ -0,0 +1,110 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "Fork.h" +#include "Misc.h" +#include "Timestamp.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Only on Cygwin, retry n times waiting a +// given amount of milliseconds after each +// attempt. +// + +#define RETRY_LIMIT 30 +#define RETRY_TIMEOUT 1000 + +int Fork() +{ + #ifdef __CYGWIN32__ + + int limit = RETRY_LIMIT; + int timeout = RETRY_TIMEOUT; + + #else + + int limit = 1; + int timeout = 0; + + #endif + + int pid = 0; + + for (int i = 0; i < limit; i++) + { + #ifdef TEST + *logofs << "Fork: Trying at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + // + // It could optionally try again only if the + // error code is 11, 'Resource temporarily + // unavailable'. + // + + if ((pid = fork()) >= 0) + { + break; + } + else if (i < limit - 1) + { + #ifdef WARNING + *logofs << "Fork: WARNING! Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'. Retrying...\n" << logofs_flush; + #endif + + usleep(timeout * 1000); + } + } + + #ifdef TEST + + if (pid <= 0) + { + *logofs << "Fork: Returning at " << strMsTimestamp() + << ".\n" << logofs_flush; + } + + #endif + + return pid; +} diff --git a/nxcomp/src/Fork.h b/nxcomp/src/Fork.h new file mode 100644 index 000000000..94238ed90 --- /dev/null +++ b/nxcomp/src/Fork.h @@ -0,0 +1,31 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +// +// Try again if the fork() fails, as it can happen +// often on Cygwin. +// + +extern int Fork(); diff --git a/nxcomp/src/FreeCache.h b/nxcomp/src/FreeCache.h new file mode 100644 index 000000000..bf5c801e5 --- /dev/null +++ b/nxcomp/src/FreeCache.h @@ -0,0 +1,42 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef FreeCache_H +#define FreeCache_H + +#include "IntCache.h" + +class FreeCache : public IntCache +{ + public: + + FreeCache(unsigned int size) + + : IntCache(size) + { + } +}; + +#endif /* FreeCache_H */ diff --git a/nxcomp/src/GenericChannel.cpp b/nxcomp/src/GenericChannel.cpp new file mode 100644 index 000000000..877412cee --- /dev/null +++ b/nxcomp/src/GenericChannel.cpp @@ -0,0 +1,495 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "GenericChannel.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "StaticCompressor.h" + +#include "Statistics.h" +#include "Proxy.h" + +extern Proxy *proxy; + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Log the important tracepoints related +// to writing packets to the peer proxy. +// + +#undef FLUSH + +// +// Define this to log when a channel +// is created or destroyed. +// + +#undef REFERENCES + +// +// Here are the static members. +// + +#ifdef REFERENCES + +int GenericChannel::references_ = 0; + +#endif + +GenericChannel::GenericChannel(Transport *transport, StaticCompressor *compressor) + + : Channel(transport, compressor), readBuffer_(transport_, this) +{ + #ifdef REFERENCES + *logofs << "GenericChannel: Created new object at " + << this << " for FD#" << fd_ << " out of " + << ++references_ << " allocated channels.\n" + << logofs_flush; + #endif +} + +GenericChannel::~GenericChannel() +{ + #ifdef REFERENCES + *logofs << "GenericChannel: Deleted object at " + << this << " for FD#" << fd_ << " out of " + << --references_ << " allocated channels.\n" + << logofs_flush; + #endif +} + +// +// Beginning of handleRead(). +// + +int GenericChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, + unsigned int length) +{ + #ifdef TEST + *logofs << "handleRead: Called for FD#" << fd_ + << " with " << encodeBuffer.getLength() + << " bytes already encoded.\n" + << logofs_flush; + #endif + + // + // Pointer to located message and + // its size in bytes. + // + + const unsigned char *inputMessage; + unsigned int inputLength; + + // + // Tag message as generic data in compression + // routine. Opcode is not actually transferred + // over the network. + // + + unsigned char inputOpcode = X_NXInternalGenericData; + + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: Trying to read from FD#" + << fd_ << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + int result = readBuffer_.readMessage(); + + #ifdef DEBUG + *logofs << "handleRead: Read result on FD#" << fd_ + << " is " << result << ".\n" + << logofs_flush; + #endif + + if (result < 0) + { + // + // Let the proxy close the channel. + // + + return -1; + } + else if (result == 0) + { + #if defined(TEST) || defined(INFO) + + *logofs << "handleRead: PANIC! No data read from FD#" + << fd_ << " while encoding messages.\n" + << logofs_flush; + + HandleCleanup(); + + #endif + + return 0; + } + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "handleRead: Encoding messages for FD#" << fd_ + << " with " << readBuffer_.getLength() << " bytes " + << "in the buffer.\n" << logofs_flush; + #endif + + // + // Divide the available data in multiple + // messages and encode them one by one. + // + + if (proxy -> handleAsyncSwitch(fd_) < 0) + { + return -1; + } + + while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) + { + encodeBuffer.encodeValue(inputLength, 32, 14); + + if (isCompressed() == 1) + { + unsigned int compressedDataSize = 0; + unsigned char *compressedData = NULL; + + if (handleCompress(encodeBuffer, inputOpcode, 0, + inputMessage, inputLength, compressedData, + compressedDataSize) < 0) + { + return -1; + } + } + else + { + encodeBuffer.encodeMemory(inputMessage, inputLength); + } + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleRead: Handled generic data for FD#" << fd_ + << ". " << inputLength << " bytes in, " << bits << " bits (" + << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; + #endif + + addProtocolBits(inputLength << 3, bits); + + if (isPrioritized() == 1) + { + priority_++; + } + + } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) ... + + // + // All data has been read from the read buffer. + // We still need to mark the end of the encode + // buffer just before sending the frame. This + // allows us to accommodate multiple reads in + // a single frame. + // + + if (priority_ > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: WARNING! Requesting flush " + << "because of " << priority_ << " prioritized " + << "messages for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + if (proxy -> handleAsyncPriority() < 0) + { + return -1; + } + + // + // Reset the priority flag. + // + + priority_ = 0; + } + + // + // Flush if we produced enough data. + // + + if (proxy -> canAsyncFlush() == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: WARNING! Requesting flush " + << "because of enough data or timeout on the " + << "proxy link.\n" << logofs_flush; + #endif + + if (proxy -> handleAsyncFlush() < 0) + { + return -1; + } + } + + #if defined(TEST) || defined(INFO) + + if (transport_ -> pending() != 0 || + readBuffer_.checkMessage() != 0) + { + *logofs << "handleRead: PANIC! Buffer for X descriptor FD#" + << fd_ << " has " << transport_ -> pending() + << " bytes to read.\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + // + // Reset the read buffer. + // + + readBuffer_.fullReset(); + + return 1; +} + +// +// End of handleRead(). +// + +// +// Beginning of handleWrite(). +// + +int GenericChannel::handleWrite(const unsigned char *message, unsigned int length) +{ + #ifdef TEST + *logofs << "handleWrite: Called for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + // + // Create the buffer from which to + // decode messages. + // + + DecodeBuffer decodeBuffer(message, length); + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "handleWrite: Decoding messages for FD#" << fd_ + << " with " << length << " bytes in the buffer.\n" + << logofs_flush; + #endif + + unsigned char *outputMessage; + unsigned int outputLength; + + // + // Tag message as generic data + // in decompression. + // + + unsigned char outputOpcode = X_NXInternalGenericData; + + for (;;) + { + decodeBuffer.decodeValue(outputLength, 32, 14); + + if (outputLength == 0) + { + break; + } + + if (isCompressed() == 1) + { + if (writeBuffer_.getAvailable() < outputLength || + (int) outputLength >= control -> TransportFlushBufferSize) + { + #ifdef DEBUG + *logofs << "handleWrite: Using scratch buffer for " + << "generic data with size " << outputLength << " and " + << writeBuffer_.getLength() << " bytes in buffer.\n" + << logofs_flush; + #endif + + outputMessage = writeBuffer_.addScratchMessage(outputLength); + } + else + { + outputMessage = writeBuffer_.addMessage(outputLength); + } + + const unsigned char *compressedData = NULL; + unsigned int compressedDataSize = 0; + + int decompressed = handleDecompress(decodeBuffer, outputOpcode, 0, + outputMessage, outputLength, compressedData, + compressedDataSize); + if (decompressed < 0) + { + return -1; + } + } + else + { + #ifdef DEBUG + *logofs << "handleWrite: Using scratch buffer for " + << "generic data with size " << outputLength << " and " + << writeBuffer_.getLength() << " bytes in buffer.\n" + << logofs_flush; + #endif + + writeBuffer_.addScratchMessage((unsigned char *) + decodeBuffer.decodeMemory(outputLength), outputLength); + } + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleWrite: Handled generic data for FD#" << fd_ + << ". " << outputLength << " bytes out.\n" + << logofs_flush; + #endif + + handleFlush(flush_if_needed); + } + + // + // Write any remaining data to socket. + // + + if (handleFlush(flush_if_any) < 0) + { + return -1; + } + + return 1; +} + +// +// End of handleWrite(). +// + +// +// Other members. +// + +int GenericChannel::handleCompletion(EncodeBuffer &encodeBuffer) +{ + // + // Add the bits telling to the remote + // that all data in the frame has been + // encoded. + // + + if (encodeBuffer.getLength() > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleCompletion: Writing completion bits with " + << encodeBuffer.getLength() << " bytes encoded " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeValue(0, 32, 14); + + return 1; + } + #if defined(TEST) || defined(INFO) + else + { + *logofs << "handleCompletion: PANIC! No completion to write " + << "for FD#" << fd_ << ".\n" << logofs_flush; + + HandleCleanup(); + } + #endif + + return 0; +} + +int GenericChannel::handleConfiguration() +{ + #ifdef TEST + *logofs << "GenericChannel: Setting new buffer parameters.\n" + << logofs_flush; + #endif + + readBuffer_.setSize(control -> GenericInitialReadSize, + control -> GenericMaximumBufferSize); + + writeBuffer_.setSize(control -> TransportGenericBufferSize, + control -> TransportGenericBufferThreshold, + control -> TransportMaximumBufferSize); + + transport_ -> setSize(control -> TransportGenericBufferSize, + control -> TransportGenericBufferThreshold, + control -> TransportMaximumBufferSize); + + return 1; +} + +int GenericChannel::handleFinish() +{ + #ifdef TEST + *logofs << "GenericChannel: Finishing channel for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + congestion_ = 0; + priority_ = 0; + + finish_ = 1; + + transport_ -> fullReset(); + + return 1; +} + +int GenericChannel::setReferences() +{ + #ifdef TEST + *logofs << "GenericChannel: Initializing the static " + << "members for the generic channels.\n" + << logofs_flush; + #endif + + #ifdef REFERENCES + + references_ = 0; + + #endif + + return 1; +} diff --git a/nxcomp/src/GenericChannel.h b/nxcomp/src/GenericChannel.h new file mode 100644 index 000000000..3df18f444 --- /dev/null +++ b/nxcomp/src/GenericChannel.h @@ -0,0 +1,440 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef GenericChannel_H +#define GenericChannel_H + +#include "Channel.h" + +#include "Statistics.h" + +#include "GenericReadBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#undef TEST +#undef DEBUG + +// +// Define this to log a line when a channel +// is created or destroyed. +// + +#undef REFERENCES + +// +// This class implements the client +// side compression of X protocol. +// + +class GenericChannel : public Channel +{ + public: + + GenericChannel(Transport *transport, StaticCompressor *compressor); + + virtual ~GenericChannel(); + + virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, + unsigned int length); + + virtual int handleWrite(const unsigned char *message, unsigned int length); + + + virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, + T_store_action action, int position, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) + { + return 0; + } + + virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, + T_store_action action, int position, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) + { + return 0; + } + + + virtual int handleSplit(EncodeBuffer &encodeBuffer) + { + return 0; + } + + virtual int handleSplit(DecodeBuffer &decodeBuffer) + { + return 0; + } + + virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split) + { + return 0; + } + + virtual int handleSplitEvent(DecodeBuffer &decodeBuffer) + { + return 0; + } + + virtual int handleMotion(EncodeBuffer &encodeBuffer) + { + return 0; + } + + virtual int handleCompletion(EncodeBuffer &encodeBuffer); + + virtual int handleConfiguration(); + + virtual int handleFinish(); + + virtual int handleAsyncEvents() + { + return 0; + } + + virtual int needSplit() const + { + return 0; + } + + virtual int needMotion() const + { + return 0; + } + + virtual T_channel_type getType() const = 0; + + // + // Initialize the static members. + // + + static int setReferences(); + + protected: + + // + // Generic channels are considered to be + // in congestion state as soon as the + // socket is blocked for write. + // + + virtual int isCongested() + { + return (transport_ -> blocked() == 1); + } + + virtual int isReliable() + { + return 0; + } + + // + // Model generic channels' encoding and + // decoding policy. + // + + virtual int isCompressed() = 0; + + // + // Return true if the channel contains + // time sensitive data. + // + + virtual int isPrioritized() = 0; + + // + // Record the protocol bits for the + // specific service. + // + + virtual void addProtocolBits(unsigned int bitsIn, unsigned int bitsOut) = 0; + + // + // Channel's own read buffer. + // + + GenericReadBuffer readBuffer_; + + private: + + // + // Keep track of object's creation + // and deletion. + // + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +class CupsChannel : public GenericChannel +{ + public: + + CupsChannel(Transport *transport, StaticCompressor *compressor) + + : GenericChannel(transport, compressor) + { + } + + virtual ~CupsChannel() + { + } + + protected: + + virtual T_channel_type getType() const + { + return channel_cups; + } + + virtual int isCompressed() + { + // Since ProtoStep8 (#issue 108) + return 0; + } + + virtual int isPrioritized() + { + return 0; + } + + virtual void addProtocolBits(unsigned int bitsIn, + unsigned int bitsOut) + { + statistics -> addCupsBits(bitsIn, bitsOut); + } +}; + +class SmbChannel : public GenericChannel +{ + public: + + SmbChannel(Transport *transport, StaticCompressor *compressor) + + : GenericChannel(transport, compressor) + { + } + + virtual ~SmbChannel() + { + } + + protected: + + virtual T_channel_type getType() const + { + return channel_smb; + } + + virtual int isCompressed() + { + // Since ProtoStep8 (#issue 108) + return 0; + } + + virtual int isPrioritized() + { + return 0; + } + + virtual void addProtocolBits(unsigned int bitsIn, + unsigned int bitsOut) + { + statistics -> addSmbBits(bitsIn, bitsOut); + } +}; + +class MediaChannel : public GenericChannel +{ + public: + + MediaChannel(Transport *transport, StaticCompressor *compressor) + + : GenericChannel(transport, compressor) + { + } + + virtual ~MediaChannel() + { + } + + protected: + + virtual T_channel_type getType() const + { + return channel_media; + } + + // + // Don't try to compress the media data. + // + + virtual int isCompressed() + { + return 0; + } + + // + // Reduce the latency of media channels + // by setting them as prioritized, even + // if this will take away bandwidth from + // the X channels. + // + + virtual int isPrioritized() + { + return 1; + } + + virtual void addProtocolBits(unsigned int bitsIn, + unsigned int bitsOut) + { + statistics -> addMediaBits(bitsIn, bitsOut); + } +}; + +class HttpChannel : public GenericChannel +{ + public: + + HttpChannel(Transport *transport, StaticCompressor *compressor) + + : GenericChannel(transport, compressor) + { + } + + virtual ~HttpChannel() + { + } + + protected: + + virtual T_channel_type getType() const + { + return channel_http; + } + + virtual int isCompressed() + { + // Since ProtoStep8 (#issue 108) + return 0; + } + + virtual int isPrioritized() + { + return 0; + } + + virtual void addProtocolBits(unsigned int bitsIn, + unsigned int bitsOut) + { + statistics -> addHttpBits(bitsIn, bitsOut); + } +}; + +class FontChannel : public GenericChannel +{ + public: + + FontChannel(Transport *transport, StaticCompressor *compressor) + + : GenericChannel(transport, compressor) + { + } + + virtual ~FontChannel() + { + } + + protected: + + virtual T_channel_type getType() const + { + return channel_font; + } + + virtual int isCompressed() + { + // Since ProtoStep8 (#issue 108) + return 0; + } + + virtual int isPrioritized() + { + return 1; + } + + virtual void addProtocolBits(unsigned int bitsIn, + unsigned int bitsOut) + { + statistics -> addFontBits(bitsIn, bitsOut); + } +}; + +class SlaveChannel : public GenericChannel +{ + public: + + SlaveChannel(Transport *transport, StaticCompressor *compressor) + + : GenericChannel(transport, compressor) + { + } + + virtual ~SlaveChannel() + { + } + + protected: + + virtual T_channel_type getType() const + { + return channel_slave; + } + + virtual int isCompressed() + { + return 0; + } + + virtual int isPrioritized() + { + return 0; + } + + virtual void addProtocolBits(unsigned int bitsIn, + unsigned int bitsOut) + { + statistics -> addSlaveBits(bitsIn, bitsOut); + } +}; + +#endif /* GenericChannel_H */ diff --git a/nxcomp/src/GenericReadBuffer.cpp b/nxcomp/src/GenericReadBuffer.cpp new file mode 100644 index 000000000..78217157e --- /dev/null +++ b/nxcomp/src/GenericReadBuffer.cpp @@ -0,0 +1,82 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "GenericReadBuffer.h" + +#include "GenericChannel.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +unsigned int GenericReadBuffer::suggestedLength(unsigned int pendingLength) +{ + // + // Always read the initial read size. + // + + return 0; +} + +int GenericReadBuffer::locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength) +{ + // + // We don't care about the endianess + // in generic channels. + // + + unsigned int size = end - start; + + #ifdef TEST + *logofs << "GenericReadBuffer: Locating message for FD#" + << transport_ -> fd() << " with " << size + << " bytes.\n" << logofs_flush; + #endif + + if (size == 0) + { + remaining_ = 1; + + return 0; + } + + dataLength = size; + + controlLength = 0; + trailerLength = 0; + + remaining_ = 0; + + return 1; +} diff --git a/nxcomp/src/GenericReadBuffer.h b/nxcomp/src/GenericReadBuffer.h new file mode 100644 index 000000000..5ea4d939d --- /dev/null +++ b/nxcomp/src/GenericReadBuffer.h @@ -0,0 +1,61 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef GenericReadBuffer_H +#define GenericReadBuffer_H + +#include "ReadBuffer.h" +#include "Control.h" + +class GenericChannel; + +class GenericReadBuffer : public ReadBuffer +{ + public: + + GenericReadBuffer(Transport *transport, GenericChannel *channel) + + : ReadBuffer(transport), channel_(channel) + { + } + + virtual ~GenericReadBuffer() + { + } + + protected: + + virtual unsigned int suggestedLength(unsigned int pendingLength); + + virtual int locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength); + + GenericChannel *channel_; +}; + +#endif /* GenericReadBuffer_H */ diff --git a/nxcomp/src/GenericReply.cpp b/nxcomp/src/GenericReply.cpp new file mode 100644 index 000000000..b56e579e8 --- /dev/null +++ b/nxcomp/src/GenericReply.cpp @@ -0,0 +1,302 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "GenericReply.h" + +#include "ServerCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +GenericReplyStore::GenericReplyStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = GENERICREPLY_ENABLE_CACHE; + enableData = GENERICREPLY_ENABLE_DATA; + enableSplit = GENERICREPLY_ENABLE_SPLIT; + + // Since ProtoStep7 (#issue 108) + enableCompress = GENERICREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = GENERICREPLY_DATA_LIMIT; + dataOffset = GENERICREPLY_DATA_OFFSET; + + cacheSlots = GENERICREPLY_CACHE_SLOTS; + cacheThreshold = GENERICREPLY_CACHE_THRESHOLD; + cacheLowerThreshold = GENERICREPLY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +GenericReplyStore::~GenericReplyStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int GenericReplyStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ServerCache *serverCache = (ServerCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" + << logofs_flush; + #endif + + encodeBuffer.encodeValue(GetULONG(buffer + 4, bigEndian), 32, 15); + + encodeBuffer.encodeCachedValue(*(buffer + 1), 8, + serverCache -> genericReplyCharCache); + + for (unsigned int i = 0; i < 6; i++) + { + encodeBuffer.encodeCachedValue(GetULONG(buffer + i * 4 + 8, bigEndian), 32, + *serverCache -> genericReplyIntCache[i]); + } + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" + << logofs_flush; + #endif + + return 1; +} + +int GenericReplyStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ServerCache *serverCache = (ServerCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" + << logofs_flush; + #endif + + decodeBuffer.decodeValue(size, 32, 15); + + size = 32 + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + decodeBuffer.decodeCachedValue(*(buffer + 1), 8, + serverCache -> genericReplyCharCache); + + unsigned int value; + + for (unsigned int i = 0; i < 6; i++) + { + decodeBuffer.decodeCachedValue(value, 32, + *serverCache -> genericReplyIntCache[i]); + + PutULONG(value, buffer + i * 4 + 8, bigEndian); + } + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" + << logofs_flush; + #endif + + return 1; +} + +int GenericReplyStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GenericReplyMessage *genericReply = (GenericReplyMessage *) message; + + genericReply -> byte_data = *(buffer + 1); + + for (int i = 0; i < 12; i++) + { + genericReply -> short_data[i] = GetUINT(buffer + i * 2 + 8, bigEndian); + } + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int GenericReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GenericReplyMessage *genericReply = (GenericReplyMessage *) message; + + *(buffer + 1) = genericReply -> byte_data; + + for (int i = 0; i < 12; i++) + { + PutUINT(genericReply -> short_data[i], buffer + i * 2 + 8, bigEndian); + } + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void GenericReplyStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + GenericReplyMessage *genericReply = (GenericReplyMessage *) message; + + *logofs << name() << ": Identity byte_data " + << (unsigned) genericReply -> byte_data; + + for (int i = 0; i < 12; i++) + { + *logofs << ", short_data[" << i << "]" + << (unsigned) genericReply -> short_data[i]; + } + + *logofs << ", size " << genericReply -> size_ << ".\n"; + + #endif +} + +void GenericReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} + +void GenericReplyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + // + // Encode the variant part. + // + + GenericReplyMessage *genericReply = (GenericReplyMessage *) message; + GenericReplyMessage *cachedGenericReply = (GenericReplyMessage *) cachedMessage; + + ServerCache *serverCache = (ServerCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " + << (unsigned int) genericReply -> byte_data + << " as byte_data field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(genericReply -> byte_data, 8, + serverCache -> genericReplyCharCache); + + cachedGenericReply -> byte_data = genericReply -> byte_data; + + for (unsigned int i = 0; i < 12; i++) + { + #ifdef TEST + *logofs << name() << ": Encoding value " << genericReply -> short_data[i] + << " as short_data[" << i << "] field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(genericReply -> short_data[i], 16, + *serverCache -> genericReplyIntCache[i]); + + cachedGenericReply -> short_data[i] = genericReply -> short_data[i]; + } +} + +void GenericReplyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + // + // Decode the variant part. + // + + GenericReplyMessage *genericReply = (GenericReplyMessage *) message; + + ServerCache *serverCache = (ServerCache *) channelCache; + + decodeBuffer.decodeCachedValue(genericReply -> byte_data, 8, + serverCache -> genericReplyCharCache); + + #ifdef TEST + *logofs << name() << ": Decoded value " + << (unsigned int) genericReply -> byte_data + << " as byte_data field.\n" << logofs_flush; + #endif + + unsigned int value; + + for (unsigned int i = 0; i < 12; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *serverCache -> genericReplyIntCache[i]); + + genericReply -> short_data[i] = (unsigned short) value; + + #ifdef TEST + *logofs << name() << ": Decoded value " << genericReply -> short_data[i] + << " as short_data[" << i << "] field.\n" << logofs_flush; + #endif + } +} diff --git a/nxcomp/src/GenericReply.h b/nxcomp/src/GenericReply.h new file mode 100644 index 000000000..e899b8467 --- /dev/null +++ b/nxcomp/src/GenericReply.h @@ -0,0 +1,161 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef GenericReply_H +#define GenericReply_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define GENERICREPLY_ENABLE_CACHE 1 +#define GENERICREPLY_ENABLE_DATA 1 +#define GENERICREPLY_ENABLE_SPLIT 0 + +#define GENERICREPLY_DATA_LIMIT 1048576 - 32 +#define GENERICREPLY_DATA_OFFSET 32 + +#define GENERICREPLY_CACHE_SLOTS 400 +#define GENERICREPLY_CACHE_THRESHOLD 5 +#define GENERICREPLY_CACHE_LOWER_THRESHOLD 1 + +#define GENERICREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +// +// The message class. +// + +class GenericReplyMessage : public Message +{ + friend class GenericReplyStore; + + public: + + GenericReplyMessage() + { + } + + ~GenericReplyMessage() + { + } + + // + // Put here the fields which constitute the + // 'identity' part of the message. Starting + // from protocol level 3 we use short data + // to increase cache efficiency. + // + + private: + + unsigned char byte_data; + unsigned int int_data[6]; + unsigned short short_data[12]; +}; + +class GenericReplyStore : public MessageStore +{ + public: + + GenericReplyStore(StaticCompressor *compressor); + + virtual ~GenericReplyStore(); + + virtual const char *name() const + { + return "GenericReply"; + } + + virtual unsigned char opcode() const + { + return X_NXInternalGenericReply; + } + + virtual unsigned int storage() const + { + return sizeof(GenericReplyMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new GenericReplyMessage(); + } + + virtual Message *create(const Message &message) const + { + return new GenericReplyMessage((const GenericReplyMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (GenericReplyMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* GenericReply_H */ diff --git a/nxcomp/src/GenericRequest.cpp b/nxcomp/src/GenericRequest.cpp new file mode 100644 index 000000000..c569d6a24 --- /dev/null +++ b/nxcomp/src/GenericRequest.cpp @@ -0,0 +1,334 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "GenericRequest.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +GenericRequestStore::GenericRequestStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = GENERICREQUEST_ENABLE_CACHE; + enableData = GENERICREQUEST_ENABLE_DATA; + enableSplit = GENERICREQUEST_ENABLE_SPLIT; + + // Since ProtoStep7 (#issue 108) + enableCompress = GENERICREQUEST_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = GENERICREQUEST_DATA_LIMIT; + dataOffset = GENERICREQUEST_DATA_OFFSET; + + cacheSlots = GENERICREQUEST_CACHE_SLOTS; + cacheThreshold = GENERICREQUEST_CACHE_THRESHOLD; + cacheLowerThreshold = GENERICREQUEST_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +GenericRequestStore::~GenericRequestStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int GenericRequestStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; + #endif + + encodeBuffer.encodeValue(size >> 2, 16, 10); + + encodeBuffer.encodeCachedValue(*(buffer + 1), 8, + clientCache -> genericRequestOpcodeCache); + + for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) + { + #ifdef DEBUG + *logofs << name() << ": Encoding data[" << i << "] " + << "at position " << i * 2 + 4 << " with value " + << GetUINT(buffer + (i * 2) + 4, bigEndian) + << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(GetUINT(buffer + (i * 2) + 4, bigEndian), 16, + *clientCache -> genericRequestDataCache[i]); + } + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int GenericRequestStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; + #endif + + decodeBuffer.decodeValue(size, 16, 10); + + size <<= 2; + + buffer = writeBuffer -> addMessage(size); + + decodeBuffer.decodeCachedValue(*(buffer + 1), 8, + clientCache -> genericRequestOpcodeCache); + + unsigned int value; + + for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache -> genericRequestDataCache[i]); + + #ifdef DEBUG + *logofs << name() << ": Decoding data[" << i << "] " + << "at position " << i * 2 + 4 << " with value " + << value << ".\n" << logofs_flush; + #endif + + PutUINT(value, buffer + 4 + (i * 2), bigEndian); + } + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int GenericRequestStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; + + genericRequest -> opcode = *(buffer + 1); + + for (unsigned int i = 0; i < 8; i++) + { + if ((i * 2 + 4) < size) + { + genericRequest -> data[i] = GetUINT(buffer + i * 2 + 4, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed data[" << i << "] " + << "with value " << genericRequest -> data[i] + << ".\n" << logofs_flush; + #endif + } + else + { + genericRequest -> data[i] = 0; + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int GenericRequestStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; + + *(buffer + 1) = genericRequest -> opcode; + + for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) + { + #ifdef DEBUG + *logofs << name() << ": Unparsed data[" << i << "] " + << "with value " << genericRequest -> data[i] + << ".\n" << logofs_flush; + #endif + + PutUINT(genericRequest -> data[i], buffer + i * 2 + 4, bigEndian); + } + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void GenericRequestStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; + + *logofs << name() << ": Identity opcode " << (unsigned) genericRequest -> opcode; + + for (int i = 0; i < 8; i++) + { + *logofs << ", data[" << i << "] " << genericRequest -> data[i]; + } + + *logofs << ", size " << genericRequest -> size_ << ".\n" << logofs_flush; + + #endif +} + +void GenericRequestStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // As data offset can be beyond the real end of + // the message, we need to include the message's + // size or we will match any message whose size + // is less or equal to the data offset. + // + + md5_append(md5_state_, buffer + 2, 2); +} + +void GenericRequestStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + // + // Encode the variant part. + // + + GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; + GenericRequestMessage *cachedGenericRequest = (GenericRequestMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Updating value " + << (unsigned) genericRequest -> opcode + << " as opcode field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue((unsigned int) genericRequest -> opcode, 8, + clientCache -> genericRequestOpcodeCache); + + cachedGenericRequest -> opcode = genericRequest -> opcode; + + for (int i = 0; i < 8 && (i * 2 + 4) < genericRequest -> size_; i++) + { + #ifdef TEST + *logofs << name() << ": Updating data[" << i << "] " + << "with value " << genericRequest -> data[i] + << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue((unsigned int) genericRequest -> data[i], 16, + *clientCache -> genericRequestDataCache[i]); + + cachedGenericRequest -> data[i] = genericRequest -> data[i]; + } +} + +void GenericRequestStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + GenericRequestMessage *genericRequest = (GenericRequestMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(genericRequest -> opcode, 8, + clientCache -> genericRequestOpcodeCache); + + #ifdef TEST + *logofs << name() << ": Updated value " + << (unsigned) genericRequest -> opcode + << " as opcode field.\n" << logofs_flush; + #endif + + unsigned int value; + + for (int i = 0; i < 8 && (i * 2 + 4) < genericRequest -> size_; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache -> genericRequestDataCache[i]); + + genericRequest -> data[i] = (unsigned short) value; + + #ifdef TEST + *logofs << name() << ": Updated data[" << i << "] " + << "with value " << genericRequest -> data[i] + << ".\n" << logofs_flush; + #endif + } +} diff --git a/nxcomp/src/GenericRequest.h b/nxcomp/src/GenericRequest.h new file mode 100644 index 000000000..13ffea718 --- /dev/null +++ b/nxcomp/src/GenericRequest.h @@ -0,0 +1,160 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef GenericRequest_H +#define GenericRequest_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define GENERICREQUEST_ENABLE_CACHE 1 +#define GENERICREQUEST_ENABLE_DATA 1 +#define GENERICREQUEST_ENABLE_SPLIT 0 + +#define GENERICREQUEST_DATA_LIMIT 262144 - 20 +#define GENERICREQUEST_DATA_OFFSET 20 + +#define GENERICREQUEST_CACHE_SLOTS 400 +#define GENERICREQUEST_CACHE_THRESHOLD 5 +#define GENERICREQUEST_CACHE_LOWER_THRESHOLD 1 + +#define GENERICREQUEST_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +// +// The message class. +// + +class GenericRequestMessage : public Message +{ + friend class GenericRequestStore; + + public: + + GenericRequestMessage() + { + } + + ~GenericRequestMessage() + { + } + + // + // Note that we consider for this message a data offset + // of 4 (or 20 starting from protocol 3). Bytes from 9 + // to 20, if present, are taken as part of identity and + // encoded through an array of int caches. + // + + private: + + unsigned char opcode; + unsigned short data[8]; +}; + +class GenericRequestStore : public MessageStore +{ + public: + + GenericRequestStore(StaticCompressor *compressor); + + virtual ~GenericRequestStore(); + + virtual const char *name() const + { + return "GenericRequest"; + } + + virtual unsigned char opcode() const + { + return X_NXInternalGenericRequest; + } + + virtual unsigned int storage() const + { + return sizeof(GenericRequestMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new GenericRequestMessage(); + } + + virtual Message *create(const Message &message) const + { + return new GenericRequestMessage((const GenericRequestMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (GenericRequestMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* GenericRequest_H */ diff --git a/nxcomp/src/GetImage.cpp b/nxcomp/src/GetImage.cpp new file mode 100644 index 000000000..20b6a07d1 --- /dev/null +++ b/nxcomp/src/GetImage.cpp @@ -0,0 +1,177 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "GetImage.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int GetImageStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GetImageMessage *getImage = (GetImageMessage *) message; + + // + // Here is the fingerprint. + // + + getImage -> format = *(buffer + 1); + + #ifdef TEST + if (getImage -> format != 1 && getImage -> format != 2) + { + *logofs << name() << ": WARNING! Dirty value " << getImage -> format + << " for field format.\n" << logofs_flush; + } + #endif + + getImage -> drawable = GetULONG(buffer + 4, bigEndian); + + getImage -> x = GetUINT(buffer + 8, bigEndian); + getImage -> y = GetUINT(buffer + 10, bigEndian); + getImage -> width = GetUINT(buffer + 12, bigEndian); + getImage -> height = GetUINT(buffer + 14, bigEndian); + + getImage -> plane_mask = GetULONG(buffer + 16, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int GetImageStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GetImageMessage *getImage = (GetImageMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = getImage -> format; + + PutULONG(getImage -> drawable, buffer + 4, bigEndian); + + PutUINT(getImage -> x, buffer + 8, bigEndian); + PutUINT(getImage -> y, buffer + 10, bigEndian); + PutUINT(getImage -> width, buffer + 12, bigEndian); + PutUINT(getImage -> height, buffer + 14, bigEndian); + + PutULONG(getImage -> plane_mask, buffer + 16, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void GetImageStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + GetImageMessage *getImage = (GetImageMessage *) message; + + *logofs << name() << ": Identity format " << (unsigned) getImage -> format + << ", drawable " << getImage -> drawable << ", x " << getImage -> x + << ", y " << getImage -> y << ", width " << getImage -> width + << ", height " << getImage -> height << ", plane_mask " + << getImage -> plane_mask << ", size " << getImage -> size_ + << ".\n" << logofs_flush; + + #endif +} + +void GetImageStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 8, 2); + md5_append(md5_state_, buffer + 10, 2); + md5_append(md5_state_, buffer + 12, 2); + md5_append(md5_state_, buffer + 14, 2); + md5_append(md5_state_, buffer + 16, 4); +} + +void GetImageStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + GetImageMessage *getImage = (GetImageMessage *) message; + GetImageMessage *cachedGetImage = (GetImageMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << getImage -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(getImage -> drawable, clientCache -> drawableCache); + + cachedGetImage -> drawable = getImage -> drawable; +} + +void GetImageStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + GetImageMessage *getImage = (GetImageMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + getImage -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << getImage -> drawable + << " as drawable field.\n" << logofs_flush; + #endif +} + diff --git a/nxcomp/src/GetImage.h b/nxcomp/src/GetImage.h new file mode 100644 index 000000000..1c3558d14 --- /dev/null +++ b/nxcomp/src/GetImage.h @@ -0,0 +1,190 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef GetImage_H +#define GetImage_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define GETIMAGE_ENABLE_CACHE 1 +#define GETIMAGE_ENABLE_DATA 0 +#define GETIMAGE_ENABLE_SPLIT 0 +#define GETIMAGE_ENABLE_COMPRESS 0 + +#define GETIMAGE_DATA_LIMIT 0 +#define GETIMAGE_DATA_OFFSET 20 + +#define GETIMAGE_CACHE_SLOTS 200 +#define GETIMAGE_CACHE_THRESHOLD 1 +#define GETIMAGE_CACHE_LOWER_THRESHOLD 0 + +// +// The message class. +// + +class GetImageMessage : public Message +{ + friend class GetImageStore; + + public: + + GetImageMessage() + { + } + + ~GetImageMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char format; + unsigned int drawable; + unsigned short int x; + unsigned short int y; + unsigned short int width; + unsigned short int height; + unsigned int plane_mask; +}; + +class GetImageStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + GetImageStore() : MessageStore() + { + enableCache = GETIMAGE_ENABLE_CACHE; + enableData = GETIMAGE_ENABLE_DATA; + enableSplit = GETIMAGE_ENABLE_SPLIT; + enableCompress = GETIMAGE_ENABLE_COMPRESS; + + dataLimit = GETIMAGE_DATA_LIMIT; + dataOffset = GETIMAGE_DATA_OFFSET; + + cacheSlots = GETIMAGE_CACHE_SLOTS; + cacheThreshold = GETIMAGE_CACHE_THRESHOLD; + cacheLowerThreshold = GETIMAGE_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~GetImageStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "GetImage"; + } + + virtual unsigned char opcode() const + { + return X_GetImage; + } + + virtual unsigned int storage() const + { + return sizeof(GetImageMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new GetImageMessage(); + } + + virtual Message *create(const Message &message) const + { + return new GetImageMessage((const GetImageMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (GetImageMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* GetImage_H */ diff --git a/nxcomp/src/GetImageReply.cpp b/nxcomp/src/GetImageReply.cpp new file mode 100644 index 000000000..5100804ab --- /dev/null +++ b/nxcomp/src/GetImageReply.cpp @@ -0,0 +1,194 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "GetImageReply.h" + +#include "ServerCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +GetImageReplyStore::GetImageReplyStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = GETIMAGEREPLY_ENABLE_CACHE; + enableData = GETIMAGEREPLY_ENABLE_DATA; + enableSplit = GETIMAGEREPLY_ENABLE_SPLIT; + + // Since ProtoStep7 (#issue 108) + enableCompress = GETIMAGEREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = GETIMAGEREPLY_DATA_LIMIT; + dataOffset = GETIMAGEREPLY_DATA_OFFSET; + + cacheSlots = GETIMAGEREPLY_CACHE_SLOTS; + cacheThreshold = GETIMAGEREPLY_CACHE_THRESHOLD; + cacheLowerThreshold = GETIMAGEREPLY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +GetImageReplyStore::~GetImageReplyStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int GetImageReplyStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; + + // + // Here is the fingerprint. + // + + getImageReply -> depth = *(buffer + 1); + + getImageReply -> visual = GetULONG(buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int GetImageReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = getImageReply -> depth; + + PutULONG(getImageReply -> visual, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void GetImageReplyStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; + + *logofs << name() << ": Identity depth " << (unsigned) getImageReply -> depth + << ", visual " << getImageReply -> visual << ", size " + << getImageReply -> size_ << ".\n"; + + #endif +} + +void GetImageReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Field depth. + // + + md5_append(md5_state_, buffer + 1, 1); +} + +void GetImageReplyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + // + // Encode the variant part. + // + + GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; + + ServerCache *serverCache = (ServerCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << getImageReply -> visual + << " as visual field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(getImageReply -> visual, 29, + serverCache -> visualCache); +} + +void GetImageReplyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + // + // Decode the variant part. + // + + GetImageReplyMessage *getImageReply = (GetImageReplyMessage *) message; + + ServerCache *serverCache = (ServerCache *) channelCache; + + decodeBuffer.decodeCachedValue(getImageReply -> visual, 29, + serverCache -> visualCache); +} diff --git a/nxcomp/src/GetImageReply.h b/nxcomp/src/GetImageReply.h new file mode 100644 index 000000000..d4f7c4267 --- /dev/null +++ b/nxcomp/src/GetImageReply.h @@ -0,0 +1,150 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef GetImageReply_H +#define GetImageReply_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define GETIMAGEREPLY_ENABLE_CACHE 1 +#define GETIMAGEREPLY_ENABLE_DATA 1 +#define GETIMAGEREPLY_ENABLE_SPLIT 0 + +#define GETIMAGEREPLY_DATA_LIMIT 1048576 - 32 +#define GETIMAGEREPLY_DATA_OFFSET 32 + +#define GETIMAGEREPLY_CACHE_SLOTS 1000 +#define GETIMAGEREPLY_CACHE_THRESHOLD 20 +#define GETIMAGEREPLY_CACHE_LOWER_THRESHOLD 2 + +#define GETIMAGEREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +// +// The message class. +// + +class GetImageReplyMessage : public Message +{ + friend class GetImageReplyStore; + + public: + + GetImageReplyMessage() + { + } + + ~GetImageReplyMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char depth; + unsigned int visual; +}; + +class GetImageReplyStore : public MessageStore +{ + public: + + GetImageReplyStore(StaticCompressor *compressor); + + virtual ~GetImageReplyStore(); + + virtual const char *name() const + { + return "GetImageReply"; + } + + virtual unsigned char opcode() const + { + return X_GetImage; + } + + virtual unsigned int storage() const + { + return sizeof(GetImageReplyMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new GetImageReplyMessage(); + } + + virtual Message *create(const Message &message) const + { + return new GetImageReplyMessage((const GetImageReplyMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (GetImageReplyMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* GetImageReply_H */ diff --git a/nxcomp/src/GetProperty.cpp b/nxcomp/src/GetProperty.cpp new file mode 100644 index 000000000..1c5e77ccc --- /dev/null +++ b/nxcomp/src/GetProperty.cpp @@ -0,0 +1,119 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "GetProperty.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int GetPropertyStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GetPropertyMessage *getProperty = (GetPropertyMessage *) message; + + // + // Here is the fingerprint. + // + + getProperty -> property_delete = *(buffer + 1); + + getProperty -> window = GetULONG(buffer + 4, bigEndian); + getProperty -> property = GetULONG(buffer + 8, bigEndian); + getProperty -> type = GetULONG(buffer + 12, bigEndian); + getProperty -> long_offset = GetULONG(buffer + 16, bigEndian); + getProperty -> long_length = GetULONG(buffer + 20, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int GetPropertyStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + + GetPropertyMessage *getProperty = (GetPropertyMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = getProperty -> property_delete; + + PutULONG(getProperty -> window, buffer + 4, bigEndian); + PutULONG(getProperty -> property, buffer + 8, bigEndian); + PutULONG(getProperty -> type, buffer + 12, bigEndian); + PutULONG(getProperty -> long_offset, buffer + 16, bigEndian); + PutULONG(getProperty -> long_length, buffer + 20, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void GetPropertyStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + GetPropertyMessage *getProperty = (GetPropertyMessage *) message; + + *logofs << name() << ": Identity property_delete " << (unsigned int) getProperty -> property_delete + << ", window " << getProperty -> window << ", property " << getProperty -> property + << ", type " << getProperty -> type << ", long-offset " << getProperty -> long_offset + << ", long-length " << getProperty -> long_length << ".\n" << logofs_flush; + + #endif +} + +void GetPropertyStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 4, 20); +} diff --git a/nxcomp/src/GetProperty.h b/nxcomp/src/GetProperty.h new file mode 100644 index 000000000..46727280b --- /dev/null +++ b/nxcomp/src/GetProperty.h @@ -0,0 +1,183 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef GetProperty_H +#define GetProperty_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define GETPROPERTY_ENABLE_CACHE 1 +#define GETPROPERTY_ENABLE_DATA 0 +#define GETPROPERTY_ENABLE_SPLIT 0 +#define GETPROPERTY_ENABLE_COMPRESS 0 + +#define GETPROPERTY_DATA_LIMIT 0 +#define GETPROPERTY_DATA_OFFSET 24 + +#define GETPROPERTY_CACHE_SLOTS 2000 +#define GETPROPERTY_CACHE_THRESHOLD 2 +#define GETPROPERTY_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class GetPropertyMessage : public Message +{ + friend class GetPropertyStore; + + public: + + GetPropertyMessage() + { + } + + ~GetPropertyMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char property_delete; + unsigned long window; + unsigned long property; + unsigned long type; + unsigned long long_offset; + unsigned long long_length; +}; + +class GetPropertyStore : public MessageStore +{ + + // + // Constructors and destructors. + // + + public: + + GetPropertyStore() : MessageStore() + { + enableCache = GETPROPERTY_ENABLE_CACHE; + enableData = GETPROPERTY_ENABLE_DATA; + enableSplit = GETPROPERTY_ENABLE_SPLIT; + enableCompress = GETPROPERTY_ENABLE_COMPRESS; + + dataLimit = GETPROPERTY_DATA_LIMIT; + dataOffset = GETPROPERTY_DATA_OFFSET; + + cacheSlots = GETPROPERTY_CACHE_SLOTS; + cacheThreshold = GETPROPERTY_CACHE_THRESHOLD; + cacheLowerThreshold = GETPROPERTY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~GetPropertyStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "GetProperty"; + } + + virtual unsigned char opcode() const + { + return X_GetProperty; + } + + virtual unsigned int storage() const + { + return sizeof(GetPropertyMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new GetPropertyMessage(); + } + + virtual Message *create(const Message &message) const + { + return new GetPropertyMessage((const GetPropertyMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (GetPropertyMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* GetProperty_H */ diff --git a/nxcomp/src/GetPropertyReply.cpp b/nxcomp/src/GetPropertyReply.cpp new file mode 100644 index 000000000..bf6879c5f --- /dev/null +++ b/nxcomp/src/GetPropertyReply.cpp @@ -0,0 +1,304 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "GetPropertyReply.h" + +#include "ServerCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +GetPropertyReplyStore::GetPropertyReplyStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = GETPROPERTYREPLY_ENABLE_CACHE; + enableData = GETPROPERTYREPLY_ENABLE_DATA; + enableSplit = GETPROPERTYREPLY_ENABLE_SPLIT; + + // Since ProtoStep7 (#issue 108) + enableCompress = GETPROPERTYREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = GETPROPERTYREPLY_DATA_LIMIT; + dataOffset = GETPROPERTYREPLY_DATA_OFFSET; + + cacheSlots = GETPROPERTYREPLY_CACHE_SLOTS; + cacheThreshold = GETPROPERTYREPLY_CACHE_THRESHOLD; + cacheLowerThreshold = GETPROPERTYREPLY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +GetPropertyReplyStore::~GetPropertyReplyStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int GetPropertyReplyStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ServerCache *serverCache = (ServerCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" + << logofs_flush; + #endif + + unsigned char format = (unsigned int) *(buffer + 1); + + encodeBuffer.encodeCachedValue(format, 8, + serverCache -> getPropertyFormatCache); + + unsigned int numBytes = GetULONG(buffer + 16, bigEndian); + + encodeBuffer.encodeValue(numBytes, 32, 9); + + if (format == 16) + { + numBytes <<= 1; + } + else if (format == 32) + { + numBytes <<= 2; + } + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 8, bigEndian), 29, + serverCache -> getPropertyTypeCache, 9); + + encodeBuffer.encodeValue(GetULONG(buffer + 12, bigEndian), 32, 9); + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" + << logofs_flush; + #endif + + return 1; +} + +int GetPropertyReplyStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ServerCache *serverCache = (ServerCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" + << logofs_flush; + #endif + + unsigned char format; + + decodeBuffer.decodeCachedValue(format, 8, + serverCache -> getPropertyFormatCache); + + unsigned int length; + + decodeBuffer.decodeValue(length, 32, 9); + + unsigned int numBytes = length; + + if (format == 16) + { + numBytes <<= 1; + } + else if (format == 32) + { + numBytes <<= 2; + } + + size = 32 + RoundUp4(numBytes); + + buffer = writeBuffer -> addMessage(size); + + *(buffer + 1) = format; + + PutULONG(length, buffer + 16, bigEndian); + + unsigned int value; + + decodeBuffer.decodeCachedValue(value, 29, + serverCache -> getPropertyTypeCache, 9); + + PutULONG(value, buffer + 8, bigEndian); + + decodeBuffer.decodeValue(value, 32, 9); + + PutULONG(value, buffer + 12, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" + << logofs_flush; + #endif + + return 1; +} + +int GetPropertyReplyStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GetPropertyReplyMessage *getPropertyReply = (GetPropertyReplyMessage *) message; + + getPropertyReply -> format = *(buffer + 1); + + getPropertyReply -> type = GetULONG(buffer + 8, bigEndian); + getPropertyReply -> after = GetULONG(buffer + 12, bigEndian); + getPropertyReply -> items = GetULONG(buffer + 16, bigEndian); + + // + // Cleanup the padding bytes. + // + + unsigned int uiLengthInBytes; + unsigned int uiFormat; + + if ((int) size > GETPROPERTYREPLY_DATA_OFFSET) + { + uiLengthInBytes = getPropertyReply -> items; + + uiFormat = *(buffer + 1); + + #ifdef DEBUG + *logofs << name() << ": length " << uiLengthInBytes + << ", format " << uiFormat << ", size " + << size << ".\n" << logofs_flush; + #endif + + if (uiFormat == 16) + { + uiLengthInBytes <<= 1; + } + else if (uiFormat == 32) + { + uiLengthInBytes <<= 2; + } + + unsigned char *end = ((unsigned char *) buffer) + size; + unsigned char *pad = ((unsigned char *) buffer) + GETPROPERTYREPLY_DATA_OFFSET + uiLengthInBytes; + + CleanData((unsigned char *) pad, end - pad); + } + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int GetPropertyReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + GetPropertyReplyMessage *getPropertyReply = (GetPropertyReplyMessage *) message; + + *(buffer + 1) = getPropertyReply -> format; + + PutULONG(getPropertyReply -> type, buffer + 8, bigEndian); + PutULONG(getPropertyReply -> after, buffer + 12, bigEndian); + PutULONG(getPropertyReply -> items, buffer + 16, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void GetPropertyReplyStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + GetPropertyReplyMessage *getPropertyReply = (GetPropertyReplyMessage *) message; + + *logofs << name() << ": Identity format " + << (unsigned) getPropertyReply -> format << ", type " + << getPropertyReply -> type << ", after " << getPropertyReply -> after + << ", items " << getPropertyReply -> items << ", size " + << getPropertyReply -> size_ << ".\n"; + + #endif +} + +void GetPropertyReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Fields format, type, after, items. + // + + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 8, 12); +} + +void GetPropertyReplyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ +} + +void GetPropertyReplyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ +} diff --git a/nxcomp/src/GetPropertyReply.h b/nxcomp/src/GetPropertyReply.h new file mode 100644 index 000000000..01634b408 --- /dev/null +++ b/nxcomp/src/GetPropertyReply.h @@ -0,0 +1,160 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef GetPropertyReply_H +#define GetPropertyReply_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define GETPROPERTYREPLY_ENABLE_CACHE 1 +#define GETPROPERTYREPLY_ENABLE_DATA 1 +#define GETPROPERTYREPLY_ENABLE_SPLIT 0 + +#define GETPROPERTYREPLY_DATA_LIMIT 1048576 - 32 +#define GETPROPERTYREPLY_DATA_OFFSET 32 + +#define GETPROPERTYREPLY_CACHE_SLOTS 400 +#define GETPROPERTYREPLY_CACHE_THRESHOLD 5 +#define GETPROPERTYREPLY_CACHE_LOWER_THRESHOLD 1 + +#define GETPROPERTYREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +// +// The message class. +// + +class GetPropertyReplyMessage : public Message +{ + friend class GetPropertyReplyStore; + + public: + + GetPropertyReplyMessage() + { + } + + ~GetPropertyReplyMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char format; + unsigned int type; + unsigned int after; + unsigned int items; +}; + +class GetPropertyReplyStore : public MessageStore +{ + public: + + GetPropertyReplyStore(StaticCompressor *compressor); + + virtual ~GetPropertyReplyStore(); + + virtual const char *name() const + { + return "GetPropertyReply"; + } + + virtual unsigned char opcode() const + { + return X_GetProperty; + } + + virtual unsigned int storage() const + { + return sizeof(GetPropertyReplyMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new GetPropertyReplyMessage(); + } + + virtual Message *create(const Message &message) const + { + return new GetPropertyReplyMessage((const GetPropertyReplyMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (GetPropertyReplyMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* GetPropertyReply_H */ diff --git a/nxcomp/src/ImageText16.cpp b/nxcomp/src/ImageText16.cpp new file mode 100644 index 000000000..af057635f --- /dev/null +++ b/nxcomp/src/ImageText16.cpp @@ -0,0 +1,231 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ImageText16.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int ImageText16Store::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ImageText16Message *imageText16 = (ImageText16Message *) message; + + // + // Here is the fingerprint. + // + + imageText16 -> len = *(buffer + 1); + + imageText16 -> drawable = GetULONG(buffer + 4, bigEndian); + imageText16 -> gcontext = GetULONG(buffer + 8, bigEndian); + + imageText16 -> x = GetUINT(buffer + 12, bigEndian); + imageText16 -> y = GetUINT(buffer + 14, bigEndian); + + if ((int) size > dataOffset) + { + int pad = (size - dataOffset) - (imageText16 -> len * 2); + + if (pad > 0) + { + CleanData((unsigned char *) buffer + size - pad, pad); + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ImageText16Store::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ImageText16Message *imageText16 = (ImageText16Message *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = imageText16 -> len; + + PutULONG(imageText16 -> drawable, buffer + 4, bigEndian); + PutULONG(imageText16 -> gcontext, buffer + 8, bigEndian); + + PutUINT(imageText16 -> x, buffer + 12, bigEndian); + PutUINT(imageText16 -> y, buffer + 14, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void ImageText16Store::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + ImageText16Message *imageText16 = (ImageText16Message *) message; + + *logofs << name() << ": Identity len " << (unsigned int) imageText16 -> len + << " drawable " << imageText16 -> drawable << ", gcontext " + << imageText16 -> gcontext << ", x " << imageText16 -> x << ", y " + << imageText16 -> y << ", size " << imageText16 -> size_ << ".\n"; + + #endif +} + +void ImageText16Store::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); +} + +void ImageText16Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + ImageText16Message *imageText16 = (ImageText16Message *) message; + ImageText16Message *cachedImageText16 = (ImageText16Message *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << imageText16 -> drawable + << " as " << "drawable" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(imageText16 -> drawable, clientCache -> drawableCache); + + cachedImageText16 -> drawable = imageText16 -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << imageText16 -> gcontext + << " as " << "gcontext" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(imageText16 -> gcontext, clientCache -> gcCache); + + cachedImageText16 -> gcontext = imageText16 -> gcontext; + + #ifdef TEST + *logofs << name() << ": Encoding value " << imageText16 -> x + << " as " << "x" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_x = imageText16 -> x - cachedImageText16 -> x; + + encodeBuffer.encodeCachedValue(diff_x, 16, + clientCache -> imageTextCacheX); + + cachedImageText16 -> x = imageText16 -> x; + + #ifdef TEST + *logofs << name() << ": Encoding value " << imageText16 -> y + << " as " << "y" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_y = imageText16 -> y - cachedImageText16 -> y; + + encodeBuffer.encodeCachedValue(diff_y, 16, + clientCache -> imageTextCacheY); + + cachedImageText16 -> y = imageText16 -> y; +} + +void ImageText16Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + ImageText16Message *imageText16 = (ImageText16Message *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + imageText16 -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << imageText16 -> drawable + << " as " << "drawable" << " field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + imageText16 -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << imageText16 -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> imageTextCacheX); + + imageText16 -> x += value; + imageText16 -> x &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << imageText16 -> x + << " as x field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> imageTextCacheY); + + imageText16 -> y += value; + imageText16 -> y &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << imageText16 -> y + << " as y field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/ImageText16.h b/nxcomp/src/ImageText16.h new file mode 100644 index 000000000..98462ab35 --- /dev/null +++ b/nxcomp/src/ImageText16.h @@ -0,0 +1,190 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ImageText16_H +#define ImageText16_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define IMAGETEXT16_ENABLE_CACHE 1 +#define IMAGETEXT16_ENABLE_DATA 0 +#define IMAGETEXT16_ENABLE_SPLIT 0 +#define IMAGETEXT16_ENABLE_COMPRESS 0 + +#define IMAGETEXT16_DATA_LIMIT 512 +#define IMAGETEXT16_DATA_OFFSET 16 + +#define IMAGETEXT16_CACHE_SLOTS 3000 +#define IMAGETEXT16_CACHE_THRESHOLD 5 +#define IMAGETEXT16_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class ImageText16Message : public Message +{ + friend class ImageText16Store; + + public: + + ImageText16Message() + { + } + + ~ImageText16Message() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char len; + + unsigned int drawable; + unsigned int gcontext; + + unsigned short x; + unsigned short y; +}; + +class ImageText16Store : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + ImageText16Store() : MessageStore() + { + enableCache = IMAGETEXT16_ENABLE_CACHE; + enableData = IMAGETEXT16_ENABLE_DATA; + enableSplit = IMAGETEXT16_ENABLE_SPLIT; + enableCompress = IMAGETEXT16_ENABLE_COMPRESS; + + dataLimit = IMAGETEXT16_DATA_LIMIT; + dataOffset = IMAGETEXT16_DATA_OFFSET; + + cacheSlots = IMAGETEXT16_CACHE_SLOTS; + cacheThreshold = IMAGETEXT16_CACHE_THRESHOLD; + cacheLowerThreshold = IMAGETEXT16_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~ImageText16Store() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "ImageText16"; + } + + virtual unsigned char opcode() const + { + return X_ImageText16; + } + + virtual unsigned int storage() const + { + return sizeof(ImageText16Message); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new ImageText16Message(); + } + + virtual Message *create(const Message &message) const + { + return new ImageText16Message((const ImageText16Message &) message); + } + + virtual void destroy(Message *message) const + { + delete (ImageText16Message *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* ImageText16_H */ diff --git a/nxcomp/src/ImageText8.cpp b/nxcomp/src/ImageText8.cpp new file mode 100644 index 000000000..61fcef825 --- /dev/null +++ b/nxcomp/src/ImageText8.cpp @@ -0,0 +1,231 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ImageText8.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int ImageText8Store::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ImageText8Message *imageText8 = (ImageText8Message *) message; + + // + // Here is the fingerprint. + // + + imageText8 -> len = *(buffer + 1); + + imageText8 -> drawable = GetULONG(buffer + 4, bigEndian); + imageText8 -> gcontext = GetULONG(buffer + 8, bigEndian); + + imageText8 -> x = GetUINT(buffer + 12, bigEndian); + imageText8 -> y = GetUINT(buffer + 14, bigEndian); + + if ((int) size > dataOffset) + { + int pad = (size - dataOffset) - imageText8 -> len; + + if (pad > 0) + { + CleanData((unsigned char *) buffer + size - pad, pad); + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ImageText8Store::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ImageText8Message *imageText8 = (ImageText8Message *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = imageText8 -> len; + + PutULONG(imageText8 -> drawable, buffer + 4, bigEndian); + PutULONG(imageText8 -> gcontext, buffer + 8, bigEndian); + + PutUINT(imageText8 -> x, buffer + 12, bigEndian); + PutUINT(imageText8 -> y, buffer + 14, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void ImageText8Store::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + ImageText8Message *imageText8 = (ImageText8Message *) message; + + *logofs << name() << ": Identity len " << (unsigned int) imageText8 -> len + << " drawable " << imageText8 -> drawable << ", gcontext " + << imageText8 -> gcontext << ", x " << imageText8 -> x << ", y " + << imageText8 -> y << ", size " << imageText8 -> size_ << ".\n"; + + #endif +} + +void ImageText8Store::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); +} + +void ImageText8Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + ImageText8Message *imageText8 = (ImageText8Message *) message; + ImageText8Message *cachedImageText8 = (ImageText8Message *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << imageText8 -> drawable + << " as " << "drawable" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(imageText8 -> drawable, clientCache -> drawableCache); + + cachedImageText8 -> drawable = imageText8 -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << imageText8 -> gcontext + << " as " << "gcontext" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(imageText8 -> gcontext, clientCache -> gcCache); + + cachedImageText8 -> gcontext = imageText8 -> gcontext; + + #ifdef TEST + *logofs << name() << ": Encoding value " << imageText8 -> x + << " as " << "x" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_x = imageText8 -> x - cachedImageText8 -> x; + + encodeBuffer.encodeCachedValue(diff_x, 16, + clientCache -> imageTextCacheX); + + cachedImageText8 -> x = imageText8 -> x; + + #ifdef TEST + *logofs << name() << ": Encoding value " << imageText8 -> y + << " as " << "y" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_y = imageText8 -> y - cachedImageText8 -> y; + + encodeBuffer.encodeCachedValue(diff_y, 16, + clientCache -> imageTextCacheY); + + cachedImageText8 -> y = imageText8 -> y; +} + +void ImageText8Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + ImageText8Message *imageText8 = (ImageText8Message *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + imageText8 -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << imageText8 -> drawable + << " as " << "drawable" << " field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + imageText8 -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << imageText8 -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> imageTextCacheX); + + imageText8 -> x += value; + imageText8 -> x &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << imageText8 -> x + << " as x field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> imageTextCacheY); + + imageText8 -> y += value; + imageText8 -> y &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << imageText8 -> y + << " as y field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/ImageText8.h b/nxcomp/src/ImageText8.h new file mode 100644 index 000000000..aa9ccb5d9 --- /dev/null +++ b/nxcomp/src/ImageText8.h @@ -0,0 +1,190 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ImageText8_H +#define ImageText8_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define IMAGETEXT8_ENABLE_CACHE 1 +#define IMAGETEXT8_ENABLE_DATA 0 +#define IMAGETEXT8_ENABLE_SPLIT 0 +#define IMAGETEXT8_ENABLE_COMPRESS 0 + +#define IMAGETEXT8_DATA_LIMIT 256 +#define IMAGETEXT8_DATA_OFFSET 16 + +#define IMAGETEXT8_CACHE_SLOTS 3000 +#define IMAGETEXT8_CACHE_THRESHOLD 5 +#define IMAGETEXT8_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class ImageText8Message : public Message +{ + friend class ImageText8Store; + + public: + + ImageText8Message() + { + } + + ~ImageText8Message() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char len; + + unsigned int drawable; + unsigned int gcontext; + + unsigned short x; + unsigned short y; +}; + +class ImageText8Store : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + ImageText8Store() : MessageStore() + { + enableCache = IMAGETEXT8_ENABLE_CACHE; + enableData = IMAGETEXT8_ENABLE_DATA; + enableSplit = IMAGETEXT8_ENABLE_SPLIT; + enableCompress = IMAGETEXT8_ENABLE_COMPRESS; + + dataLimit = IMAGETEXT8_DATA_LIMIT; + dataOffset = IMAGETEXT8_DATA_OFFSET; + + cacheSlots = IMAGETEXT8_CACHE_SLOTS; + cacheThreshold = IMAGETEXT8_CACHE_THRESHOLD; + cacheLowerThreshold = IMAGETEXT8_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~ImageText8Store() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "ImageText8"; + } + + virtual unsigned char opcode() const + { + return X_ImageText8; + } + + virtual unsigned int storage() const + { + return sizeof(ImageText8Message); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new ImageText8Message(); + } + + virtual Message *create(const Message &message) const + { + return new ImageText8Message((const ImageText8Message &) message); + } + + virtual void destroy(Message *message) const + { + delete (ImageText8Message *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* ImageText8_H */ diff --git a/nxcomp/src/IntCache.cpp b/nxcomp/src/IntCache.cpp new file mode 100644 index 000000000..c72b81200 --- /dev/null +++ b/nxcomp/src/IntCache.cpp @@ -0,0 +1,230 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "Misc.h" +#include "IntCache.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +IntCache::IntCache(unsigned int size) + + : size_(size), length_(0), buffer_(new unsigned int[size]), + lastDiff_(0), lastValueInserted_(0), predictedBlockSize_(0) +{ +} + +int IntCache::lookup(unsigned int &value, unsigned int &index, + unsigned int mask, unsigned int &sameDiff) +{ + for (unsigned int i = 0; i < length_; i++) + { + if (value == buffer_[i]) + { + index = i; + if (i) + { + unsigned int target = (i >> 1); + do + { + buffer_[i] = buffer_[i - 1]; + i--; + } + while (i > target); + buffer_[target] = value; + } + return 1; + } + } + unsigned int insertionPoint; + if (2 >= length_) + insertionPoint = length_; + else + insertionPoint = 2; + unsigned int start; + if (length_ >= size_) + start = size_ - 1; + else + { + start = length_; + length_++; + } + for (unsigned int k = start; k > insertionPoint; k--) + buffer_[k] = buffer_[k - 1]; + buffer_[insertionPoint] = value; + unsigned int diff = value - lastValueInserted_; + + lastValueInserted_ = (value & mask); + value = (diff & mask); + sameDiff = (value == lastDiff_); + if (!sameDiff) + { + lastDiff_ = value; + + unsigned int lastChangeIndex = 0; + unsigned int lastBitIsOne = (lastDiff_ & 0x1); + unsigned int j = 1; + for (unsigned int nextMask = 0x2; nextMask & mask; nextMask <<= 1) + { + unsigned int nextBitIsOne = (lastDiff_ & nextMask); + if (nextBitIsOne) + { + if (!lastBitIsOne) + { + lastChangeIndex = j; + lastBitIsOne = nextBitIsOne; + } + } + else + { + if (lastBitIsOne) + { + lastChangeIndex = j; + lastBitIsOne = nextBitIsOne; + } + } + j++; + } + predictedBlockSize_ = lastChangeIndex + 1; + if (predictedBlockSize_ < 2) + predictedBlockSize_ = 2; + } + return 0; +} + +void IntCache::insert(unsigned int &value, unsigned int mask) +{ + unsigned int insertionPoint; + if (2 >= length_) + insertionPoint = length_; + else + insertionPoint = 2; + unsigned int start; + if (length_ >= size_) + start = size_ - 1; + else + { + start = length_; + length_++; + } + for (unsigned int k = start; k > insertionPoint; k--) + buffer_[k] = buffer_[k - 1]; + if (lastDiff_ != value) + { + lastDiff_ = value; + unsigned int lastChangeIndex = 0; + unsigned int lastBitIsOne = (lastDiff_ & 0x1); + unsigned int j = 1; + for (unsigned int nextMask = 0x2; nextMask & mask; nextMask <<= 1) + { + unsigned int nextBitIsOne = (lastDiff_ & nextMask); + if (nextBitIsOne) + { + if (!lastBitIsOne) + { + lastChangeIndex = j; + lastBitIsOne = nextBitIsOne; + } + } + else + { + if (lastBitIsOne) + { + lastChangeIndex = j; + lastBitIsOne = nextBitIsOne; + } + } + j++; + } + predictedBlockSize_ = lastChangeIndex + 1; + if (predictedBlockSize_ < 2) + predictedBlockSize_ = 2; + } + lastValueInserted_ += value; + lastValueInserted_ &= mask; + buffer_[insertionPoint] = lastValueInserted_; + value = lastValueInserted_; +} + +void IntCache::push(unsigned int &value, unsigned int mask) +{ + // + // Using a memmove() appears to be slower. + // + // memmove((char *) &buffer_[1], (char *) &buffer_[0], + // sizeof(unsigned int) * (size_ - 1)); + // + // if (length_ < size_) + // { + // length_++; + // } + // + + unsigned int start; + + if (length_ >= size_) + { + start = size_ - 1; + } + else + { + start = length_; + + length_++; + } + + for (unsigned int k = start; k > 0; k--) + { + buffer_[k] = buffer_[k - 1]; + } + + value &= mask; + + buffer_[0] = value; +} + +void IntCache::dump() +{ + #ifdef DUMP + + *logofs << "IntCache: Dumping content of cache at " + << (void *) this << ":\n" << logofs_flush; + + for (unsigned int i = 0; i < length_; i++) + { + *logofs << "IntCache: [" << i << "][" << buffer_[i] << "]\n"; + } + + #endif +} diff --git a/nxcomp/src/IntCache.h b/nxcomp/src/IntCache.h new file mode 100644 index 000000000..69c522325 --- /dev/null +++ b/nxcomp/src/IntCache.h @@ -0,0 +1,119 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef IntCache_H +#define IntCache_H + +class IntCache +{ + public: + + IntCache(unsigned int size); + + ~IntCache() + { + delete [] buffer_; + } + + unsigned int getSize() const + { + return length_; + } + + int lookup(unsigned int &value, unsigned int &index, + unsigned int mask, unsigned int &sameDiff); + + // + // This can be inlined as it is only + // called by decodeCachedValue(). + // + + unsigned int get(unsigned int index) + { + unsigned int result = buffer_[index]; + + if (index != 0) + { + // + // Using a memmove() appears to be slower. + // + // unsigned int target = index >> 1; + // + // memmove((char *) &buffer_[target + 1], (char *) &buffer_[target], + // sizeof(unsigned int) * (index - target)); + // + // buffer_[target] = result; + // + + unsigned int i = index; + + unsigned int target = (i >> 1); + + do + { + buffer_[i] = buffer_[i - 1]; + + i--; + } + while (i > target); + + buffer_[target] = result; + } + + return result; + } + + void insert(unsigned int &value, unsigned int mask); + + void push(unsigned int &value, unsigned int mask); + + void dump(); + + unsigned int getLastDiff(unsigned int mask) const + { + return lastDiff_; + } + + unsigned int getBlockSize(unsigned int bits) const + { + if (bits > 0) + { + return (predictedBlockSize_ < bits ? predictedBlockSize_ : bits); + } + + return predictedBlockSize_; + } + + private: + + unsigned int size_; + unsigned int length_; + unsigned int *buffer_; + unsigned int lastDiff_; + unsigned int lastValueInserted_; + unsigned int predictedBlockSize_; +}; + +#endif /* IntCache_H */ diff --git a/nxcomp/src/InternAtom.cpp b/nxcomp/src/InternAtom.cpp new file mode 100644 index 000000000..9d0ab1b6d --- /dev/null +++ b/nxcomp/src/InternAtom.cpp @@ -0,0 +1,131 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "InternAtom.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int InternAtomStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + InternAtomMessage *internAtom = (InternAtomMessage *) message; + + // + // Here is the fingerprint. + // + + internAtom -> only_if_exists = *(buffer + 1); + internAtom -> name_length = GetUINT(buffer + 4, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + // + // Clean up padding bytes. + // + + if ((int) size > dataOffset) + { + unsigned char *end = ((unsigned char *) buffer) + size; + + for (unsigned char *pad = ((unsigned char *) buffer) + 8 + + internAtom -> name_length; pad < end; pad++) + { + *pad = 0; + } + } + + return 1; +} + +int InternAtomStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + InternAtomMessage *internAtom = (InternAtomMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = internAtom -> only_if_exists; + + PutUINT(internAtom -> name_length, buffer + 4, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void InternAtomStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + InternAtomMessage *internAtom = (InternAtomMessage *) message; + + *logofs << name() << ": Identity only_if_exists " + << (unsigned int) internAtom -> only_if_exists + << ", name_length " << internAtom -> name_length + << ", name '"; + + for (int i = 0; i < internAtom -> name_length; i++) + { + *logofs << internAtom -> data_[i]; + } + + *logofs << "'.\n" << logofs_flush; + + #endif +} + +void InternAtomStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 4, 2); +} diff --git a/nxcomp/src/InternAtom.h b/nxcomp/src/InternAtom.h new file mode 100644 index 000000000..6e69eca24 --- /dev/null +++ b/nxcomp/src/InternAtom.h @@ -0,0 +1,178 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef InternAtom_H +#define InternAtom_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define INTERNATOM_ENABLE_CACHE 1 +#define INTERNATOM_ENABLE_DATA 0 +#define INTERNATOM_ENABLE_SPLIT 0 +#define INTERNATOM_ENABLE_COMPRESS 0 + +#define INTERNATOM_DATA_LIMIT 80 +#define INTERNATOM_DATA_OFFSET 8 + +#define INTERNATOM_CACHE_SLOTS 2000 +#define INTERNATOM_CACHE_THRESHOLD 2 +#define INTERNATOM_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class InternAtomMessage : public Message +{ + friend class InternAtomStore; + + public: + + InternAtomMessage() + { + } + + ~InternAtomMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char only_if_exists; + unsigned short name_length; +}; + +class InternAtomStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + InternAtomStore() : MessageStore() + { + enableCache = INTERNATOM_ENABLE_CACHE; + enableData = INTERNATOM_ENABLE_DATA; + enableSplit = INTERNATOM_ENABLE_SPLIT; + enableCompress = INTERNATOM_ENABLE_COMPRESS; + + dataLimit = INTERNATOM_DATA_LIMIT; + dataOffset = INTERNATOM_DATA_OFFSET; + + cacheSlots = INTERNATOM_CACHE_SLOTS; + cacheThreshold = INTERNATOM_CACHE_THRESHOLD; + cacheLowerThreshold = INTERNATOM_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~InternAtomStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "InternAtom"; + } + + virtual unsigned char opcode() const + { + return X_InternAtom; + } + + virtual unsigned int storage() const + { + return sizeof(InternAtomMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new InternAtomMessage(); + } + + virtual Message *create(const Message &message) const + { + return new InternAtomMessage((const InternAtomMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (InternAtomMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* InternAtom_H */ diff --git a/nxcomp/src/Jpeg.cpp b/nxcomp/src/Jpeg.cpp new file mode 100644 index 000000000..64a537497 --- /dev/null +++ b/nxcomp/src/Jpeg.cpp @@ -0,0 +1,890 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef ANDROID +#include +#endif +#include +#include +#include + +#ifdef __cplusplus + +extern "C" +{ + #include + #include +} + +#else + +#include +#include + +#endif + +#include "Misc.h" +#include "Jpeg.h" +#include "Unpack.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#define RGB24_TO_PIXEL(bpp,r,g,b) \ + ((((CARD##bpp)(r) & 0xff) * srcRedMax + 127) / 255 \ + << srcRedShift | \ + (((CARD##bpp)(g) & 0xff) * srcGreenMax + 127) / 255 \ + << srcGreenShift | \ + (((CARD##bpp)(b) & 0xff) * srcBlueMax + 127) / 255 \ + << srcBlueShift) + +#define RGB24_TO_PIXEL32(r,g,b) \ + (((CARD32)(r) & 0xff) << srcRedShift | \ + ((CARD32)(g) & 0xff) << srcGreenShift | \ + ((CARD32)(b) & 0xff) << srcBlueShift) + +// +// Functions from Unpack.cpp +// + +extern int Unpack32To32(const T_colormask *colormask, const unsigned int *data, + unsigned int *out, unsigned int *end); + +extern int Unpack24To24(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +extern int Unpack16To16(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +// +// Local functions used for the jpeg decompression. +// + +static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData, int compressedLen); +static void JpegInitSource(j_decompress_ptr cinfo); +static void JpegTermSource(j_decompress_ptr cinfo); +static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes); + +static boolean JpegFillInputBuffer(j_decompress_ptr cinfo); + +static int DecompressJpeg16(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder); + +static int DecompressJpeg24(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder); + +static int DecompressJpeg32(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder); + +void UnpackJpegErrorHandler(j_common_ptr cinfo); + +// +// Colormap stuff. +// + +CARD16 srcRedMax, srcGreenMax, srcBlueMax; +CARD8 srcRedShift, srcGreenShift, srcBlueShift; + +// +// Error handler. +// + +static bool jpegError; + +jmp_buf UnpackJpegContext; + +void UnpackJpegErrorHandler(j_common_ptr cinfo) +{ + #ifdef PANIC + *logofs << "UnpackJpegErrorHandler: PANIC! Detected error in JPEG decompression.\n" + << logofs_flush; + + *logofs << "UnpackJpegErrorHandler: PANIC! Trying to revert to the previous context.\n" + << logofs_flush; + #endif + + jpegError = 1; + + longjmp(UnpackJpegContext, 1); +} + +// +// Attributes used for the jpeg decompression. +// + +static struct jpeg_source_mgr jpegSrcManager; +static JOCTET *jpegBufferPtr; +static size_t jpegBufferLen; + +static char *tmpBuf; +static int tmpBufSize = 0; + +int UnpackJpeg(T_geometry *geometry, unsigned char method, unsigned char *srcData, + int srcSize, int dstBpp, int dstWidth, int dstHeight, + unsigned char *dstData, int dstSize) +{ + int byteOrder = geometry -> image_byte_order; + + // + // Check if data is coming from a failed unsplit. + // + + if (srcSize < 2 || (srcData[0] == SPLIT_PATTERN && + srcData[1] == SPLIT_PATTERN)) + { + #ifdef WARNING + *logofs << "UnpackJpeg: WARNING! Skipping unpack of dummy data.\n" + << logofs_flush; + #endif + + return -1; + } + + #ifdef DEBUG + *logofs << "UnpackJpeg: Decompression. Source size " + << srcSize << " bits per plane " << dstBpp + << ".\n" << logofs_flush; + #endif + + srcRedShift = ffs(geometry -> red_mask) - 1; + srcGreenShift = ffs(geometry -> green_mask) - 1; + srcBlueShift = ffs(geometry -> blue_mask) - 1; + + #ifdef DEBUG + *logofs << "UnpackJpeg: Red shift " << (int) srcRedShift + << " green shift " << (int) srcGreenShift << " blue shift " + << (int) srcBlueShift << ".\n" << logofs_flush; + #endif + + srcRedMax = geometry -> red_mask >> srcRedShift; + srcGreenMax = geometry -> green_mask >> srcGreenShift; + srcBlueMax = geometry -> blue_mask >> srcBlueShift; + + #ifdef DEBUG + *logofs << "UnpackJpeg: Red mask " << (void *) geometry -> red_mask + << " green mask " << (void *) geometry -> green_mask + << " blue mask " << (void *) geometry -> blue_mask + << ".\n" << logofs_flush; + #endif + + #ifdef DEBUG + *logofs << "UnpackJpeg: Red max " << srcRedMax << " green max " + << srcGreenMax << " blue max " << srcBlueMax + << ".\n" << logofs_flush; + #endif + + // + // Make enough space in the temporary + // buffer to have one complete row of + // the image with 3 bytes for a pixel. + // + + tmpBufSize = dstWidth * 3; + tmpBuf = new char[tmpBufSize]; + + if (tmpBuf == NULL) + { + #ifdef PANIC + *logofs << "UnpackJpeg: PANIC! Cannot allocate " + << dstWidth * 3 << " bytes for Jpeg " + << "decompressed data.\n" << logofs_flush; + #endif + + delete [] tmpBuf; + + return -1; + } + + int result = 1; + + switch(dstBpp) + { + case 8: + { + // + // Simply move the data from srcData to dstData + // taking into consideration the correct padding. + // + + int row; + + unsigned char * dstBuff = dstData; + unsigned char * srcBuff = srcData; + + for (row = 0; row < dstHeight; row++) + { + memcpy(dstBuff, srcBuff, dstWidth); + + dstBuff += RoundUp4(dstWidth); + srcBuff += dstWidth; + } + + break; + } + case 16: + { + result = DecompressJpeg16(srcData, srcSize, dstWidth, + dstHeight, dstData, byteOrder); + break; + } + case 24: + { + result = DecompressJpeg24(srcData, srcSize, dstWidth, + dstHeight, dstData, byteOrder); + break; + } + case 32: + { + result = DecompressJpeg32(srcData, srcSize, dstWidth, + dstHeight, dstData, byteOrder); + break; + } + default: + { + #ifdef PANIC + *logofs << "UnpackJpeg: PANIC! Failed to decode Jpeg image. " + << " Unsupported Bpp value " << dstBpp + << " for the Jpeg compression" + << ".\n" << logofs_flush; + #endif + + delete [] tmpBuf; + + result = -1; + } + } + + #ifdef DEBUG + *logofs << "UnpackJpeg: Decompression finished with result " + << result << ".\n" << logofs_flush; + #endif + + if (result == -1) + { + delete [] tmpBuf; + + #ifdef PANIC + *logofs << "UnpackJpeg: PANIC! Failed to decode Jpeg image using " + << dstBpp << " Bpp destination.\n" << logofs_flush; + #endif + + return result; + } + + // + // Apply the correction for the brightness. + // + + int maskMethod; + + switch(method) + { + case PACK_JPEG_8_COLORS: + { + maskMethod = MASK_8_COLORS; + + break; + } + case PACK_JPEG_64_COLORS: + { + maskMethod = MASK_64_COLORS; + + break; + } + case PACK_JPEG_256_COLORS: + { + maskMethod = MASK_256_COLORS; + + break; + } + case PACK_JPEG_512_COLORS: + { + maskMethod = MASK_512_COLORS; + + break; + } + case PACK_JPEG_4K_COLORS: + { + maskMethod = MASK_4K_COLORS; + + break; + } + case PACK_JPEG_32K_COLORS: + { + maskMethod = MASK_32K_COLORS; + + break; + } + case PACK_JPEG_64K_COLORS: + { + maskMethod = MASK_64K_COLORS; + + break; + } + case PACK_JPEG_256K_COLORS: + { + maskMethod = MASK_256K_COLORS; + + break; + } + case PACK_JPEG_2M_COLORS: + { + maskMethod = MASK_2M_COLORS; + + break; + } + case PACK_JPEG_16M_COLORS: + { + maskMethod = MASK_16M_COLORS; + + break; + } + default: + { + delete [] tmpBuf; + + return -1; + } + } + + const T_colormask *colorMask = MethodColorMask(maskMethod); + + unsigned char *dstBuff = dstData; + + switch (dstBpp) + { + case 16: + { + Unpack16To16(colorMask, dstBuff, dstBuff, dstBuff + dstSize); + + break; + } + case 24: + { + break; + } + case 32: + { + Unpack32To32(colorMask, (unsigned int *) dstBuff, (unsigned int *) dstBuff, + (unsigned int *) (dstBuff + dstSize)); + break; + } + default: + { + delete [] tmpBuf; + + return -1; + } + } + + delete [] tmpBuf; + + return 1; +} + +// +// Functions that actually do the Jpeg decompression. +// + +int DecompressJpeg16(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + unsigned char *data; + JSAMPROW rowPointer[1]; + + unsigned int dx = 0; + unsigned int dy = 0; + + #ifdef DEBUG + *logofs << "DecompressJpeg16: Decompressing with length " + << compressedLen << " width " << w << " height " + << h << ".\n" << logofs_flush; + #endif + + jpegError = 0; + + cinfo.err = jpeg_std_error(&jerr); + + jerr.error_exit = UnpackJpegErrorHandler; + + if (setjmp(UnpackJpegContext) == 1) + { + #ifdef TEST + *logofs << "DecompressJpeg16: Out of the long jump with error '" + << jpegError << "'.\n" << logofs_flush; + #endif + + goto AbortDecompressJpeg16; + } + + jpeg_create_decompress(&cinfo); + + if (jpegError) goto AbortDecompressJpeg16; + + JpegSetSrcManager(&cinfo, compressedData, compressedLen); + + jpeg_read_header(&cinfo, TRUE); + + if (jpegError) goto AbortDecompressJpeg16; + + cinfo.out_color_space = JCS_RGB; + + jpeg_start_decompress(&cinfo); + + if (jpegError) goto AbortDecompressJpeg16; + + if (cinfo.output_width != w || + cinfo.output_height != h || + cinfo.output_components != 3) + { + #ifdef PANIC + *logofs << "DecompressJpeg16: PANIC! Wrong JPEG data received.\n" + << logofs_flush; + #endif + + jpeg_destroy_decompress(&cinfo); + + return -1; + } + + // + // PixelPtr points to dstBuf which is + // already padded correctly for the final + // image to put + // + + data = dstBuf; + + rowPointer[0] = (JSAMPROW) tmpBuf; + + unsigned long pixel; + + while (cinfo.output_scanline < cinfo.output_height) + { + jpeg_read_scanlines(&cinfo, rowPointer, 1); + + if (jpegError) goto AbortDecompressJpeg16; + + for (dx = 0; dx < w; dx++) + { + pixel = RGB24_TO_PIXEL(16, tmpBuf[dx * 3], tmpBuf[dx * 3 + 1], + tmpBuf[dx * 3 + 2]); + + // + // Follow the server byte order when arranging data. + // + + if (byteOrder == LSBFirst) + { + data[0] = (unsigned char) (pixel & 0xff); + data[1] = (unsigned char) ((pixel >> 8) & 0xff); + } + else + { + data[1] = (unsigned char) (pixel & 0xff); + data[0] = (unsigned char) ((pixel >> 8) & 0xff); + } + + data += 2; + } + + // + // Move data at the beginning of the + // next line. + // + + data = data + (RoundUp4(w * 2) - w * 2); + + dy++; + } + + AbortDecompressJpeg16: + + if (jpegError == 0) + { + jpeg_finish_decompress(&cinfo); + } + + jpeg_destroy_decompress(&cinfo); + + if (jpegError == 1) + { + #ifdef PANIC + *logofs << "DecompressJpeg16: Failed to decompress JPEG image.\n" + << logofs_flush; + #endif + + return -1; + } + + #ifdef TEST + *logofs << "DecompressJpeg16: Decompression finished with " + << dy << " lines handled.\n" << logofs_flush; + #endif + + return 1; +} + +int DecompressJpeg24(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + CARD8 *pixelPtr = NULL; + JSAMPROW rowPointer[1]; + + unsigned int dx = 0; + unsigned int dy = 0; + + #ifdef TEST + *logofs << "DecompressJpeg24: Decompressing with length " + << compressedLen << " width " << w << " height " + << h << ".\n" << logofs_flush; + #endif + + jpegError = 0; + + cinfo.err = jpeg_std_error(&jerr); + + jerr.error_exit = UnpackJpegErrorHandler; + + if (setjmp(UnpackJpegContext) == 1) + { + #ifdef TEST + *logofs << "DecompressJpeg24: Out of the long jump with error '" + << jpegError << "'.\n" << logofs_flush; + #endif + + goto AbortDecompressJpeg24; + } + + jpeg_create_decompress(&cinfo); + + if (jpegError) goto AbortDecompressJpeg24; + + JpegSetSrcManager(&cinfo, compressedData, compressedLen); + + jpeg_read_header(&cinfo, TRUE); + + if (jpegError) goto AbortDecompressJpeg24; + + cinfo.out_color_space = JCS_RGB; + + jpeg_start_decompress(&cinfo); + + if (jpegError) goto AbortDecompressJpeg24; + + if (cinfo.output_width != w || + cinfo.output_height != h || + cinfo.output_components != 3) + { + #ifdef PANIC + *logofs << "DecompressJpeg24: PANIC! Wrong JPEG data received.\n" + << logofs_flush; + #endif + + jpeg_destroy_decompress(&cinfo); + + return -1; + } + + // + // PixelPtr points to dstBuf which is + // already padded correctly for the final + // image to put. + // + + pixelPtr = (CARD8 *) dstBuf; + + rowPointer[0] = (JSAMPROW) tmpBuf; + + while (cinfo.output_scanline < cinfo.output_height) + { + jpeg_read_scanlines(&cinfo, rowPointer, 1); + + if (jpegError) goto AbortDecompressJpeg24; + + for (dx = 0; dx < w; dx++) + { + // + // Follow the server byte order when arranging data. + // + + if (byteOrder == LSBFirst) + { + pixelPtr[0] = tmpBuf[dx * 3]; + pixelPtr[1] = tmpBuf[dx * 3 + 1]; + pixelPtr[2] = tmpBuf[dx * 3 + 2]; + } + else + { + pixelPtr[2] = tmpBuf[dx * 3]; + pixelPtr[1] = tmpBuf[dx * 3 + 1]; + pixelPtr[0] = tmpBuf[dx * 3 + 2]; + } + + pixelPtr += 3; + } + + // + // Go to the next line. + // + + pixelPtr = (CARD8 *) (((char *) pixelPtr) + (RoundUp4(w * 3) - w * 3)); + + dy++; + } + + AbortDecompressJpeg24: + + if (jpegError == 0) + { + jpeg_finish_decompress(&cinfo); + } + + jpeg_destroy_decompress(&cinfo); + + if (jpegError == 1) + { + #ifdef PANIC + *logofs << "DecompressJpeg24: Failed to decompress JPEG image.\n" + << logofs_flush; + #endif + + return -1; + } + + #ifdef TEST + *logofs << "DecompressJpeg24: Decompression finished with " + << dy << " lines handled.\n" << logofs_flush; + #endif + + return 1; +} + +int DecompressJpeg32(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + unsigned char *data; + JSAMPROW rowPointer[1]; + + unsigned int dx = 0; + unsigned int dy = 0; + + #ifdef TEST + *logofs << "DecompressJpeg32: Decompressing with length " + << compressedLen << " width " << w << " height " + << h << ".\n" << logofs_flush; + #endif + + jpegError = 0; + + cinfo.err = jpeg_std_error(&jerr); + + jerr.error_exit = UnpackJpegErrorHandler; + + if (setjmp(UnpackJpegContext) == 1) + { + #ifdef TEST + *logofs << "DecompressJpeg32: Out of the long jump with error '" + << jpegError << "'.\n" << logofs_flush; + #endif + + goto AbortDecompressJpeg32; + } + + jpeg_create_decompress(&cinfo); + + if (jpegError) goto AbortDecompressJpeg32; + + JpegSetSrcManager(&cinfo, compressedData, compressedLen); + + jpeg_read_header(&cinfo, TRUE); + + if (jpegError) goto AbortDecompressJpeg32; + + cinfo.out_color_space = JCS_RGB; + + jpeg_start_decompress(&cinfo); + + if (jpegError) goto AbortDecompressJpeg32; + + if (cinfo.output_width != w || + cinfo.output_height != h || + cinfo.output_components != 3) + { + #ifdef PANIC + *logofs << "DecompressJpeg32 : PANIC! Wrong JPEG data received.\n" + << logofs_flush; + #endif + + jpeg_destroy_decompress(&cinfo); + + return -1; + } + + // + // PixelPtr points to dstBuf which is + // already padded correctly for the final + // image to put + // + + data = dstBuf; + + rowPointer[0] = (JSAMPROW) tmpBuf; + + unsigned long pixel; + + int i; + + while (cinfo.output_scanline < cinfo.output_height) + { + jpeg_read_scanlines(&cinfo, rowPointer, 1); + + if (jpegError) goto AbortDecompressJpeg32; + + for (dx = 0; dx < w; dx++) + { + pixel = RGB24_TO_PIXEL(32, tmpBuf[dx * 3], tmpBuf[dx * 3 + 1], + tmpBuf[dx * 3 + 2]); + + // + // Follow the server byte order when arranging data. + // + + if (byteOrder == LSBFirst) + { + for (i = 0; i < 4; i++) + { + data[i] = (unsigned char)(pixel & 0xff); + pixel >>= 8; + } + } + else + { + for (i = 3; i >= 0; i--) + { + data[i] = (unsigned char) (pixel & 0xff); + pixel >>= 8; + } + } + + data += 4; + } + + dy++; + } + + AbortDecompressJpeg32: + + if (jpegError == 0) + { + jpeg_finish_decompress(&cinfo); + } + + jpeg_destroy_decompress(&cinfo); + + if (jpegError == 1) + { + #ifdef PANIC + *logofs << "DecompressJpeg32: Failed to decompress JPEG image.\n" + << logofs_flush; + #endif + + return -1; + } + + #ifdef TEST + *logofs << "DecompressJpeg32: Decompression finished with " + << dy << " lines handled.\n" << logofs_flush; + #endif + + return 1; +} + +static void JpegInitSource(j_decompress_ptr cinfo) +{ + jpegError = 0; +} + +static boolean JpegFillInputBuffer(j_decompress_ptr cinfo) +{ + jpegError = 1; + + jpegSrcManager.bytes_in_buffer = jpegBufferLen; + jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr; + + return TRUE; +} + +static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes) +{ + if (num_bytes < 0 || (unsigned long) num_bytes > jpegSrcManager.bytes_in_buffer) + { + jpegError = 1; + + jpegSrcManager.bytes_in_buffer = jpegBufferLen; + jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr; + } + else + { + jpegSrcManager.next_input_byte += (size_t) num_bytes; + jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes; + } +} + +static void JpegTermSource(j_decompress_ptr cinfo) +{ +} + +static void JpegSetSrcManager(j_decompress_ptr cinfo, + CARD8 *compressedData, + int compressedLen) +{ + jpegBufferPtr = (JOCTET *) compressedData; + jpegBufferLen = (size_t) compressedLen; + + jpegSrcManager.init_source = JpegInitSource; + jpegSrcManager.fill_input_buffer = JpegFillInputBuffer; + jpegSrcManager.skip_input_data = JpegSkipInputData; + jpegSrcManager.resync_to_restart = jpeg_resync_to_restart; + jpegSrcManager.term_source = JpegTermSource; + jpegSrcManager.next_input_byte = jpegBufferPtr; + jpegSrcManager.bytes_in_buffer = jpegBufferLen; + + cinfo->src = &jpegSrcManager; +} diff --git a/nxcomp/src/Jpeg.h b/nxcomp/src/Jpeg.h new file mode 100644 index 000000000..58a5bffef --- /dev/null +++ b/nxcomp/src/Jpeg.h @@ -0,0 +1,36 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Jpeg_H +#define Jpeg_H + +#include "Misc.h" +#include "Unpack.h" + +int UnpackJpeg(T_geometry *geometry, unsigned char method, unsigned char *srcData, + int srcSize, int dstBpp, int dstWidth, int dstHeight, + unsigned char *dstData, int dstSize); + +#endif /* Jpeg_H */ diff --git a/nxcomp/src/Keeper.cpp b/nxcomp/src/Keeper.cpp new file mode 100644 index 000000000..4babbe8a6 --- /dev/null +++ b/nxcomp/src/Keeper.cpp @@ -0,0 +1,612 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "Keeper.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Remove the directory if it's empty +// since more than 30 * 24 h. +// + +#define EMPTY_DIR_TIME 2592000 + +// +// Sleep once any ONCE entries. +// + +#define ONCE 2 + +// +// Define this to trace messages while +// they are allocated and deallocated. +// + +#undef REFERENCES + +// +// This is used for reference count. +// + +#ifdef REFERENCES + +int File::references_ = 0; + +#endif + +bool T_older::operator () (File *a, File *b) const +{ + return a -> compare(b); +} + +File::File() +{ + name_ = NULL; + + size_ = 0; + time_ = 0; + + #ifdef REFERENCES + + references_++; + + *logofs << "Keeper: Created new File at " + << this << " out of " << references_ + << " allocated references.\n" + << logofs_flush; + + #endif +} + +// +// TODO: This class can leak industrial amounts of memory. +// I'm 100% sure that the desctructor is called and that +// also the string pointed in the File structure is dele- +// ted. Everything is logged, but still the memory is not +// freed. This is less a problem on Windows, where the me- +// mory occupation remains almost constant. Obviously the +// problem lies in the STL allocators of the GNU libstc++. +// + +File::~File() +{ + #ifdef TEST + *logofs << "Keeper: Deleting name for File at " + << this << ".\n" << logofs_flush; + #endif + + delete [] name_; + + #ifdef REFERENCES + + *logofs << "Keeper: Deleted File at " + << this << " out of " << references_ + << " allocated references.\n" + << logofs_flush; + + references_--; + + #endif +} + +bool File::compare(File *b) const +{ + if (this -> time_ == b -> time_) + { + return (this -> size_ < b -> size_); + } + + return (this -> time_ < b -> time_); +} + +Keeper::Keeper(int caches, int images, const char *root, + int sleep, int parent) +{ + caches_ = caches; + images_ = images; + sleep_ = sleep; + parent_ = parent; + + root_ = new char[strlen(root) + 1]; + + strcpy(root_, root); + + total_ = 0; + signal_ = 0; + + files_ = new T_files; +} + +Keeper::~Keeper() +{ + empty(); + + delete files_; + + delete [] root_; +} + +int Keeper::cleanupCaches() +{ + #ifdef TEST + *logofs << "Keeper: Looking for cache directories in '" + << root_ << "'.\n" << logofs_flush; + #endif + + DIR *rootDir = opendir(root_); + + if (rootDir != NULL) + { + dirent *dirEntry; + + struct stat fileStat; + + int baseSize = strlen(root_); + + int s = 0; + + while (((dirEntry = readdir(rootDir)) != NULL)) + { + if (s++ % ONCE == 0) usleep(sleep_ * 1000); + + if (signal_ != 0) break; + + if (strcmp(dirEntry -> d_name, "cache") == 0 || + strncmp(dirEntry -> d_name, "cache-", 6) == 0) + { + char *dirName = new char[baseSize + strlen(dirEntry -> d_name) + 2]; + + if (dirName == NULL) + { + #ifdef WARNING + *logofs << "Keeper: WARNING! Can't check directory entry '" + << dirEntry -> d_name << "'.\n" << logofs_flush; + #endif + + delete [] dirName; + + continue; + } + + strcpy(dirName, root_); + strcpy(dirName + baseSize, "/"); + strcpy(dirName + baseSize + 1, dirEntry -> d_name); + + #ifdef TEST + *logofs << "Keeper: Checking directory '" << dirName + << "'.\n" << logofs_flush; + #endif + + if (stat(dirName, &fileStat) == 0 && + S_ISDIR(fileStat.st_mode) != 0) + { + // + // Add to repository all the "C-" and + // "S-" files in the given directory. + // + + collect(dirName); + } + + delete [] dirName; + } + } + + closedir(rootDir); + } + else + { + #ifdef WARNING + *logofs << "Keeper: WARNING! Can't open NX root directory '" + << root_ << "'. Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Can't open NX root directory '" + << root_ << "'. Error is " << EGET() << " '" + << ESTR() << "'.\n"; + } + + // + // Remove older files. + // + + cleanup(caches_); + + // + // Empty the repository. + // + + empty(); + + return 1; +} + +int Keeper::cleanupImages() +{ + #ifdef TEST + *logofs << "Keeper: Looking for image directory in '" + << root_ << "'.\n" << logofs_flush; + #endif + + char *imagesPath = new char[strlen(root_) + strlen("/images") + 1]; + + if (imagesPath == NULL) + { + return -1; + } + + strcpy(imagesPath, root_); + strcat(imagesPath, "/images"); + + // + // Check if the cache directory does exist. + // + + struct stat dirStat; + + if (stat(imagesPath, &dirStat) == -1) + { + #ifdef WARNING + *logofs << "Keeper: WARNING! Can't stat NX images cache directory '" + << imagesPath << ". Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Can't stat NX images cache directory '" + << imagesPath << ". Error is " << EGET() << " '" + << ESTR() << "'.\n"; + + delete [] imagesPath; + + return -1; + } + + // + // Check any of the 16 directories in the + // images root path. + // + + char *digitPath = new char[strlen(imagesPath) + 5]; + + strcpy(digitPath, imagesPath); + + for (char digit = 0; digit < 16; digit++) + { + // + // Give up if we received a signal or + // our parent is gone. + // + + if (signal_ != 0) + { + #ifdef TEST + *logofs << "Keeper: Signal detected. Aborting.\n" + << logofs_flush; + #endif + + goto KeeperCleanupImagesAbort; + } + else if (parent_ != getppid() || parent_ == 1) + { + #ifdef WARNING + *logofs << "Keeper: WARNING! Parent process appears " + << "to be dead. Returning.\n" + << logofs_flush; + #endif + + goto KeeperCleanupImagesAbort; + + return 0; + } + + sprintf(digitPath + strlen(imagesPath), "/I-%01X", digit); + + // + // Add to the repository all the files + // in the given directory. + // + + collect(digitPath); + } + + delete [] imagesPath; + delete [] digitPath; + + // + // Remove the oldest files. + // + + cleanup(images_); + + // + // Empty the repository. + // + + empty(); + + return 1; + +KeeperCleanupImagesAbort: + + delete [] imagesPath; + delete [] digitPath; + + empty(); + + return 0; +} + +int Keeper::collect(const char *path) +{ + #ifdef TEST + *logofs << "Keeper: Looking for files in directory '" + << path << "'.\n" << logofs_flush; + #endif + + DIR *cacheDir = opendir(path); + + if (cacheDir != NULL) + { + File *file; + + dirent *dirEntry; + + struct stat fileStat; + + int baseSize = strlen(path); + int fileSize = baseSize + 3 + MD5_LENGTH * 2 + 1; + + int n = 0; + int s = 0; + + while (((dirEntry = readdir(cacheDir)) != NULL)) + { + if (s++ % ONCE == 0) usleep(sleep_ * 1000); + + if (signal_ != 0) break; + + if (strcmp(dirEntry -> d_name, ".") == 0 || + strcmp(dirEntry -> d_name, "..") == 0) + { + continue; + } + + n++; + + if (strlen(dirEntry -> d_name) == (MD5_LENGTH * 2 + 2) && + (strncmp(dirEntry -> d_name, "I-", 2) == 0 || + strncmp(dirEntry -> d_name, "S-", 2) == 0 || + strncmp(dirEntry -> d_name, "C-", 2) == 0)) + { + file = new File(); + + char *fileName = new char[fileSize]; + + if (file == NULL || fileName == NULL) + { + #ifdef WARNING + *logofs << "Keeper: WARNING! Can't add file '" + << dirEntry -> d_name << "' to repository.\n" + << logofs_flush; + #endif + + delete [] fileName; + + delete file; + + continue; + } + + strcpy(fileName, path); + strcpy(fileName + baseSize, "/"); + strcpy(fileName + baseSize + 1, dirEntry -> d_name); + + file -> name_ = fileName; + + #ifdef DEBUG + *logofs << "Keeper: Adding file '" << file -> name_ + << "'.\n" << logofs_flush; + #endif + + if (stat(file -> name_, &fileStat) == -1) + { + #ifdef WARNING + *logofs << "Keeper: WARNING! Can't stat NX file '" + << file -> name_ << ". Error is " << EGET() + << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + delete file; + + continue; + } + + file -> size_ = fileStat.st_size; + file -> time_ = fileStat.st_mtime; + + files_ -> insert(T_files::value_type(file)); + + total_ += file -> size_; + } + } + + closedir(cacheDir); + + if (n == 0) + { + time_t now = time(NULL); + + if (now > 0 && stat(path, &fileStat) == 0) + { + #ifdef TEST + *logofs << "Keeper: Empty NX subdirectory '" << path + << "' unused since " << now - fileStat.st_mtime + << " S.\n" << logofs_flush; + #endif + + if (now - fileStat.st_mtime > EMPTY_DIR_TIME) + { + #ifdef TEST + *logofs << "Keeper: Removing empty NX subdirectory '" + << path << "'.\n" << logofs_flush; + #endif + + rmdir(path); + } + } + } + } + else + { + #ifdef WARNING + *logofs << "Keeper: WARNING! Can't open NX subdirectory '" + << path << ". Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Can't open NX subdirectory '" + << path << ". Error is " << EGET() << " '" << ESTR() + << "'.\n"; + } + + return 1; +} + +int Keeper::cleanup(int threshold) +{ + #ifdef TEST + *logofs << "Keeper: Deleting the oldest files with " + << files_ -> size() << " elements threshold " + << threshold << " and size " << total_ << ".\n" + << logofs_flush; + #endif + + // + // At least some versions of the standard + // library don't allow erasing an element + // while looping. This is not the most ef- + // ficient way to release the objects, but + // it's better than making a copy of the + // container. + // + + while (total_ > threshold && files_ -> size() > 0) + { + T_files::iterator i = files_ -> begin(); + + File *file = *i; + + #ifdef TEST + *logofs << "Keeper: Removing '" << file -> name_ + << "' with time " << file -> time_ << " and size " + << file -> size_ << ".\n" << logofs_flush; + #endif + + unlink(file -> name_); + + total_ -= file -> size_; + + #ifdef DEBUG + *logofs << "Keeper: Going to delete the file at " + << file << " while cleaning up.\n" + << logofs_flush; + #endif + + delete file; + + #ifdef DEBUG + *logofs << "Keeper: Going to erase the element " + << "while cleaning up.\n" + << logofs_flush; + #endif + + files_ -> erase(i); + } + + #ifdef TEST + *logofs << "Keeper: Bytes in repository are " + << total_ << ".\n" << logofs_flush; + #endif + + return 1; +} + +void Keeper::empty() +{ + #ifdef TEST + *logofs << "Keeper: Getting rid of files in repository.\n" + << logofs_flush; + #endif + + while (files_ -> size() > 0) + { + T_files::iterator i = files_ -> begin(); + + File *file = *i; + + #ifdef DEBUG + *logofs << "Keeper: Going to delete the file at " + << file << " while emptying.\n" + << logofs_flush; + #endif + + delete file; + + #ifdef DEBUG + *logofs << "Keeper: Going to erase the element " + << "while emptying.\n" + << logofs_flush; + #endif + + files_ -> erase(i); + } + + total_ = 0; + + #ifdef TEST + *logofs << "Keeper: Bytes in repository are " + << total_ << ".\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/Keeper.h b/nxcomp/src/Keeper.h new file mode 100644 index 000000000..b440beceb --- /dev/null +++ b/nxcomp/src/Keeper.h @@ -0,0 +1,199 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Keeper_H +#define Keeper_H + +#include "Misc.h" +#include "Types.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Define this to check how many file +// nodes are allocated and deallocated. +// + +#undef REFERENCES + +class Keeper; + +class File +{ + friend class Keeper; + + public: + + File(); + + ~File(); + + // + // Allow sort by time and size. If time + // is the same, keep the bigger element. + // + + bool compare(File *b) const; + + private: + + char *name_; + + int size_; + time_t time_; + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +class Keeper +{ + public: + + Keeper(int caches, int images, const char *root, + int sleep, int parent); + + ~Keeper(); + + // + // Call this just once. + // + + int cleanupCaches(); + + // + // Call this at any given interval. + // + + int cleanupImages(); + + // + // Call this if it's time to exit. + // + + void setSignal(int signal) + { + signal_ = signal; + } + + int getSignal() + { + return signal_; + } + + int getParent() + { + return parent_; + } + + private: + + // + // Get a list of files in directory. + // + + int collect(const char *path); + + // + // Sort the collected files according to + // last modification time and delete the + // older ones until disk size is below + // the threshold. + // + + int cleanup(int threshold); + + // + // Empty the files repository. + // + + void empty(); + + // + // Size in bytes of total allowed + // storage for persistent caches. + // + + int caches_; + + // + // Size in bytes of total allowed + // storage for images cache. + // + + int images_; + + // + // Path of the NX root directory. + // + + char *root_; + + // + // The little delay to be introduced + // before reading a new entry. + // + + int sleep_; + + // + // Total size of files in repository. + // + + int total_; + + // + // The parent process, so we can exit + // if it is gone. + // + + int parent_; + + // + // Set if we need to give up because + // of a signal. + // + + int signal_; + + // + // Repository where to collect files. + // + + T_files *files_; +}; + +#endif /* Keeper_H */ + diff --git a/nxcomp/src/List.cpp b/nxcomp/src/List.cpp new file mode 100644 index 000000000..b2db7151c --- /dev/null +++ b/nxcomp/src/List.cpp @@ -0,0 +1,112 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "List.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Define this to know how many instances +// are allocated and deallocated. +// + +#undef REFERENCES + +#ifdef REFERENCES + +int List::references_ = 0; + +#endif + +List::List() +{ + #ifdef REFERENCES + + references_++; + + *logofs << "List: Created new List at " + << this << " out of " << references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +List::~List() +{ + #ifdef REFERENCES + + references_--; + + *logofs << "List: Deleted List at " + << this << " out of " << references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +void List::remove(int value) +{ + for (T_list::iterator i = list_.begin(); i != list_.end(); i++) + { + if (*i == value) + { + list_.erase(i); + + return; + } + } + + #ifdef PANIC + *logofs << "List: PANIC! Should not try to remove " + << "an element not found in the list.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Should not try to remove " + << "an element not found in the list.\n"; + + HandleAbort(); +} + +void List::rotate() +{ + if (list_.size() > 1) + { + int value = *(list_.begin()); + + list_.pop_front(); + + list_.push_back(value); + } +} diff --git a/nxcomp/src/List.h b/nxcomp/src/List.h new file mode 100644 index 000000000..31c80f835 --- /dev/null +++ b/nxcomp/src/List.h @@ -0,0 +1,95 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef List_H +#define List_H + +#include "Misc.h" +#include "Types.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Define this to log when lists are +// allocated and deallocated. +// + +#undef REFERENCES + +class List +{ + public: + + List(); + + ~List(); + + int getSize() + { + return list_.size(); + } + + T_list &getList() + { + return list_; + } + + T_list copyList() + { + return list_; + } + + void add(int value) + { + list_.push_back(value); + } + + void remove(int value); + + void rotate(); + + private: + + // + // The list container. + // + + T_list list_; + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +#endif /* List_H */ diff --git a/nxcomp/src/ListFontsReply.cpp b/nxcomp/src/ListFontsReply.cpp new file mode 100644 index 000000000..16be522a1 --- /dev/null +++ b/nxcomp/src/ListFontsReply.cpp @@ -0,0 +1,213 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ListFontsReply.h" + +#include "ServerCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef DUMP +#undef TEST +#undef DEBUG + +ListFontsReplyStore::ListFontsReplyStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = LISTFONTSREPLY_ENABLE_CACHE; + enableData = LISTFONTSREPLY_ENABLE_DATA; + enableSplit = LISTFONTSREPLY_ENABLE_SPLIT; + + // Since ProtoStep7 (#issue 108) + enableCompress = LISTFONTSREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = LISTFONTSREPLY_DATA_LIMIT; + dataOffset = LISTFONTSREPLY_DATA_OFFSET; + + cacheSlots = LISTFONTSREPLY_CACHE_SLOTS; + cacheThreshold = LISTFONTSREPLY_CACHE_THRESHOLD; + cacheLowerThreshold = LISTFONTSREPLY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +ListFontsReplyStore::~ListFontsReplyStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int ListFontsReplyStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ListFontsReplyMessage *listFontsReply = (ListFontsReplyMessage *) message; + + // + // Here is the fingerprint. + // + + listFontsReply -> number_of_names = GetUINT(buffer + 8, bigEndian); + + // + // Clean up padding bytes. + // + + if ((int) size > dataOffset) + { + unsigned int current; + unsigned int length; + unsigned int nstringInNames; + + unsigned char *end = NULL; + unsigned char *pad = NULL; + + #ifdef DUMP + + *logofs << "\n" << logofs_flush; + + *logofs << "Number of STRING8 " << listFontsReply -> number_of_names << ".\n" << logofs_flush; + + *logofs << "Size " << size << ".\n" << logofs_flush; + + DumpHexData(buffer, size); + + *logofs << "\n" << logofs_flush; + + #endif + + length = LISTFONTSREPLY_DATA_OFFSET; + + for (nstringInNames = 0; + nstringInNames < listFontsReply -> number_of_names && + listFontsReply -> number_of_names > 0; + nstringInNames++) + { + // + // Start with offset LISTFONTSREPLY_DATA_OFFSET 32. + // + + current = buffer[length]; + + length += current + 1; + + #ifdef DUMP + *logofs << "\nString number : " << nstringInNames << " Current length : " + << current << "\n" << logofs_flush; + #endif + } + + #ifdef DUMP + *logofs << "\nFinal length " << length << "\n" << logofs_flush; + #endif + + end = ((unsigned char *) buffer) + size; + + for (pad = ((unsigned char *) buffer) + length; pad < end; pad++) + { + *pad = 0; + + #ifdef DUMP + *logofs << "\nPadding ." << "\n" << logofs_flush; + #endif + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ListFontsReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ListFontsReplyMessage *listFontsReply = (ListFontsReplyMessage *) message; + + // + // Fill all the message's fields. + // + + PutUINT(listFontsReply -> number_of_names, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void ListFontsReplyStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + ListFontsReplyMessage *listFontsReply = (ListFontsReplyMessage *) message; + + *logofs << name() << ": Identity number_of_names " + << listFontsReply -> number_of_names << ", size " + << listFontsReply -> size_ << ".\n"; + + #endif +} + +void ListFontsReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Field number_of_names. + // + + md5_append(md5_state_, buffer + 8, 2); +} diff --git a/nxcomp/src/ListFontsReply.h b/nxcomp/src/ListFontsReply.h new file mode 100644 index 000000000..c731878e0 --- /dev/null +++ b/nxcomp/src/ListFontsReply.h @@ -0,0 +1,146 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ListFontsReply_H +#define ListFontsReply_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define LISTFONTSREPLY_ENABLE_CACHE 1 +#define LISTFONTSREPLY_ENABLE_DATA 1 +#define LISTFONTSREPLY_ENABLE_SPLIT 0 + +#define LISTFONTSREPLY_DATA_LIMIT 1048576 - 32 +#define LISTFONTSREPLY_DATA_OFFSET 32 + +#define LISTFONTSREPLY_CACHE_SLOTS 200 +#define LISTFONTSREPLY_CACHE_THRESHOLD 20 +#define LISTFONTSREPLY_CACHE_LOWER_THRESHOLD 5 + +#define LISTFONTSREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +// +// The message class. +// + +class ListFontsReplyMessage : public Message +{ + friend class ListFontsReplyStore; + + public: + + ListFontsReplyMessage() + { + } + + ~ListFontsReplyMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned short int number_of_names; +}; + +class ListFontsReplyStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + ListFontsReplyStore(StaticCompressor *compressor); + + virtual ~ListFontsReplyStore(); + + virtual const char *name() const + { + return "ListFontsReply"; + } + + virtual unsigned char opcode() const + { + return X_ListFonts; + } + + virtual unsigned int storage() const + { + return sizeof(ListFontsReplyMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new ListFontsReplyMessage(); + } + + virtual Message *create(const Message &message) const + { + return new ListFontsReplyMessage((const ListFontsReplyMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (ListFontsReplyMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* ListFontsReply_H */ diff --git a/nxcomp/src/Loop.cpp b/nxcomp/src/Loop.cpp new file mode 100644 index 000000000..238e503b7 --- /dev/null +++ b/nxcomp/src/Loop.cpp @@ -0,0 +1,16693 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Misc.h" + +#ifdef __sun +#include +#endif + +// +// MacOSX 10.4 defines socklen_t. This is +// intended to ensure compatibility with +// older versions. +// + +#ifdef __APPLE__ +#include +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3 +typedef int socklen_t; +#endif +#endif + +#ifdef _AIX +#include +#include +#endif + +#ifndef __CYGWIN32__ +#include +#endif + +// +// NX include files. +// + +#include "NX.h" +#include "NXalert.h" + +#include "Misc.h" +#include "Control.h" +#include "Socket.h" +#include "Statistics.h" +#include "Auth.h" +#include "Keeper.h" +#include "Agent.h" + +#include "ClientProxy.h" +#include "ServerProxy.h" + +#include "Message.h" +#include "ChannelEndPoint.h" + +// +// System specific defines. +// + + +// +// HP-UX hides this define. +// + +#if defined(hpux) && !defined(RLIM_INFINITY) + +#define RLIM_INFINITY 0x7fffffff + +#endif + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Enable log output in signal handler. +// This is likely to hang the proxy at +// random, at least on Linux. +// + +#undef UNSAFE + +// +// Let all logs go to the standard error. +// This is useful to interleave the Xlib +// log output with the proxy output in a +// single file. +// + +#undef MIXED + +// +// Define this to check if the client and +// server caches match at shutdown. This +// is a test facility as it requires that +// both proxies are running on the same +// host. +// + +#undef MATCH + +// +// If defined, reduce the size of the log +// file and be sure it never exceeds the +// limit. +// + +#undef QUOTA + +// +// If defined, force very strict limits for +// the proxy tokens and force the proxy to +// enter often in congestion state. +// + +#undef STRICT + +// +// Print a line in the log if the time we +// spent inside the select or handling the +// messages exceeded a given time value. +// + +#undef TIME + +// +// This can be useful when testing the forwarding +// of the SSHD connection by nxssh to the agent. +// The debug output will go to a well known file +// that will be opened also by nxssh when BINDER +// is enabled there. +// + +#undef BINDER + +// +// Define this to override the limits on +// the core dump size. +// + +#define COREDUMPS + +// +// Upper limit of pre-allocated buffers +// for string parameters. +// + +#define DEFAULT_STRING_LENGTH 256 + +// +// Maximum length of remote options data +// passed by peer proxy at startup. +// + +#define DEFAULT_REMOTE_OPTIONS_LENGTH 512 + +// +// Maximum length of NX display string. +// + +#define DEFAULT_DISPLAY_OPTIONS_LENGTH 1024 + +// +// Maximum number of cache file names to +// send to the server side. +// + +#define DEFAULT_REMOTE_CACHE_ENTRIES 100 + +// +// Maximum length of remote options string +// that can be received from the peer proxy. +// + +#define MAXIMUM_REMOTE_OPTIONS_LENGTH 4096 + +// +// Macro is true if we determined our proxy +// mode. +// + +#define WE_SET_PROXY_MODE (control -> ProxyMode != proxy_undefined) + +// +// Macro is true if our side is the one that +// should connect to remote. +// + +#define WE_INITIATE_CONNECTION (connectSocket.enabled()) + +// +// Is true if we must provide our credentials +// to the remote peer. +// + +#define WE_PROVIDE_CREDENTIALS (control -> ProxyMode == proxy_server) + +// +// Is true if we listen for a local forwarder +// that will tunnel the traffic through a SSH +// or HTTP link. +// + +#define WE_LISTEN_FORWARDER (control -> ProxyMode == proxy_server && \ + listenSocket.enabled()) + +// +// You must define FLUSH in Misc.h if +// you want an immediate flush of the +// log output. +// + +ostream *logofs = NULL; + +// +// Other stream destriptors used for +// logging. +// + +ostream *statofs = NULL; +ostream *errofs = NULL; + +// +// Save standard error's rdbuf here +// and restore it when exiting. +// + +static streambuf *errsbuf = NULL; + +// +// Allow faults to be recovered by +// jumping back into the main loop. +// + +jmp_buf context; + +// +// Provide operational parameters. +// + +Control *control = NULL; + +// +// Collect and print statistics. +// + +Statistics *statistics = NULL; + +// +// Keep data for X11 authentication. +// + +Auth *auth = NULL; + +// +// This class makes the hard work. +// + +Proxy *proxy = NULL; + +// +// Used to handle memory-to-memory +// transport to the X agent. +// + +Agent *agent = NULL; + +// +// The image cache house-keeping class. +// + +Keeper *keeper = NULL; + +// +// Callback set by the child process +// to be notified about signals. +// + +int (*handler)(int) = NULL; + +// +// Signal handling functions. +// + +void DisableSignals(); +void EnableSignals(); +void InstallSignals(); + +static void RestoreSignals(); +static void HandleSignal(int signal); + +// +// Signal handling utilities. +// + +static void InstallSignal(int signal, int action); +static void RestoreSignal(int signal); + +static int HandleChildren(); + +int HandleChild(int child); +static int CheckChild(int pid, int status); +static int WaitChild(int child, const char *label, int force); + +int CheckParent(const char *name, const char *type, int parent); + +void RegisterChild(int child); + +static int CheckAbort(); + +// +// Timer handling utilities. +// + +void SetTimer(int timeout); +void ResetTimer(); + +static void HandleTimer(int signal); + +// +// Kill or check a running child. +// + +static int KillProcess(int pid, const char *label, int signal, int wait); +static int CheckProcess(int pid, const char *label); + +// +// Macros used to test the pid of a child. +// + +#define IsFailed(pid) ((pid) < 0) +#define IsRunning(pid) ((pid) > 1) +#define IsNotRunning(pid) ((pid) == 0) +#define IsRestarting(pid) ((pid) == 1) + +#define SetNotRunning(pid) ((pid) = 0) +#define SetRestarting(pid) ((pid) = 1) + +// +// Start or restart the house-keeper process. +// + +static int StartKeeper(); + +// +// Cleanup functions. +// + +void CleanupConnections(); +void CleanupListeners(); +void CleanupSockets(); +void CleanupGlobal(); + +static void CleanupChildren(); +static void CleanupLocal(); +static void CleanupKeeper(); +static void CleanupStreams(); + +// +// Loop forever until the connections +// to the peer proxy is dropped. +// + +static void WaitCleanup(); + +// +// Initialization functions. +// + +static int InitBeforeNegotiation(); +static int SetupProxyConnection(); +static int InitAfterNegotiation(); +static int SetupProxyInstance(); +static int SetupAuthInstance(); +static int SetupAgentInstance(); + +static int SetupTcpSocket(); +static int SetupUnixSocket(); +static int SetupServiceSockets(); +static int SetupDisplaySocket(int &xServerAddrFamily, sockaddr *&xServerAddr, + unsigned int &xServerAddrLength); + +// +// Setup a listening socket and accept +// a new connection. +// + +static int ListenConnection(ChannelEndPoint &endPoint, const char *label); +static int ListenConnectionTCP(const char *host, long port, const char *label); +static int ListenConnectionUnix(const char *path, const char *label); +static int ListenConnectionAny(sockaddr *addr, socklen_t addrlen, const char *label); +static int AcceptConnection(int fd, int domain, const char *label); + +// +// Other convenience functions. +// + +static int PrepareProxyConnectionTCP(char** hostName, long int* portNum, int* timeout, int* proxyFD, int* reason); +static int PrepareProxyConnectionUnix(char** path, int* timeout, int* proxyFD, int* reason); + +static int WaitForRemote(ChannelEndPoint &socketAddress); +static int ConnectToRemote(ChannelEndPoint &socketAddress); + +static int SendProxyOptions(int fd); +static int SendProxyCaches(int fd); +static int ReadProxyVersion(int fd); +static int ReadProxyOptions(int fd); +static int ReadProxyCaches(int fd); +static int ReadForwarderVersion(int fd); +static int ReadForwarderOptions(int fd); + +static int ReadRemoteData(int fd, char *buffer, int size, char stop); +static int WriteLocalData(int fd, const char *buffer, int size); + +static void PrintVersionInfo(); +static void PrintProcessInfo(); +static void PrintConnectionInfo(); +static void PrintUsageInfo(const char *option, const int error); +static void PrintOptionIgnored(const char *type, const char *name, const char *value); + +// +// This is not static to avoid a warning. +// + +void PrintCopyrightInfo(); + +static const char *GetOptions(const char *options); +static const char *GetArg(int &argi, int argc, const char **argv); +static int CheckArg(const char *type, const char *name, const char *value); +static int ParseArg(const char *type, const char *name, const char *value); +static int ValidateArg(const char *type, const char *name, const char *value); +static void SetAndValidateChannelEndPointArg(const char *type, const char *name, const char *value, + ChannelEndPoint &endPoint); +static int LowercaseArg(const char *type, const char *name, char *value); +static int CheckSignal(int signal); + +extern "C" +{ + int ParseCommandLineOptions(int argc, const char **argv); + int ParseEnvironmentOptions(const char *env, int force); + int ParseBindOptions(char **host, int *port); +} + +static int ParseFileOptions(const char *file); +static int ParseRemoteOptions(char *opts); +static int ParseForwarderOptions(char *opts); + +// +// These functions are used to parse literal +// values provided by the user and set the +// control parameters accordingly. +// + +static int ParseLinkOption(const char *opt); +static int ParseBitrateOption(const char *opt); +static int ParseCacheOption(const char *opt); +static int ParseShmemOption(const char *opt); +static int ParseImagesOption(const char *opt); +static int ParsePackOption(const char *opt); + +// +// Set host and port where NX proxy is supposed +// to be listening in case such parameters are +// given on the command line. +// + +static int ParseHostOption(const char *opt, char *host, long &port); + +// +// Translate a font server port specification +// to the corresponding Unix socket path. +// + +static int ParseFontPath(char *path); + +// +// Translate a pack method id in a literal. +// + +static int ParsePackMethod(const int method, const int quality); + +// +// Try to increase the size of the allowed +// core dumps. +// + +static int SetCore(); + +// +// Set the proxy mode to either client or +// server. +// + +static int SetMode(int mode); + +// +// Determine the path of the NX_* directories +// from the environment. +// + +static int SetDirectories(); + +// +// Set the defaults used for the log file and +// statistics. +// + +static int SetLogs(); + +// +// Check if local and remote protocol versions +// are compatible and, eventually, downgrade +// local version to the minimum level that is +// known to work. +// + +static int SetVersion(); + +// +// Setup the listening TCP ports used for the +// additional channels according to user's +// wishes. +// + +static int SetPorts(); + +// +// Set the maximum number of open descriptors. +// + +static int SetDescriptors(); + +// +// Set the path used for choosing the cache. +// It must be selected after determining the +// session type. +// + +static int SetCaches(); + +// +// Initialize, one after the other, all the +// configuration parameters. +// + +static int SetParameters(); + +// +// Set the specific configuration parameter. +// + +static int SetSession(); +static int SetStorage(); +static int SetShmem(); +static int SetPack(); +static int SetImages(); +static int SetLimits(); + +// +// Set up the control parameters based on +// the link speed negotiated between the +// proxies. +// + +static int SetLink(); + +static int SetLinkModem(); +static int SetLinkIsdn(); +static int SetLinkAdsl(); +static int SetLinkWan(); +static int SetLinkLan(); + +// +// Adjust the compression parameters. +// + +static int SetCompression(); + +static int SetCompressionModem(); +static int SetCompressionIsdn(); +static int SetCompressionAdsl(); +static int SetCompressionWan(); +static int SetCompressionLan(); + +// +// Determine the NX paths based on the +// user's parameters or the environment. +// + +char *GetClientPath(); + +static char *GetSystemPath(); +static char *GetHomePath(); +static char *GetTempPath(); +static char *GetRootPath(); +static char *GetCachePath(); +static char *GetImagesPath(); +static char *GetSessionPath(); +static char *GetLastCache(char *list, const char *path); + +static int OpenLogFile(char *name, ostream *&stream); +static int ReopenLogFile(char *name, ostream *&stream, int limit); + +// +// Perform operations on the managed +// descriptors in the main loop. +// + +static void handleCheckSessionInLoop(); +static void handleCheckBitrateInLoop(); + +#if defined(TEST) || defined(INFO) +static void handleCheckSelectInLoop(int &setFDs, fd_set &readSet, + fd_set &writeSet, T_timestamp selectTs); +static void handleCheckResultInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, + fd_set &writeSet, struct timeval &selectTs, + struct timeval &startTs); +static void handleCheckStateInLoop(int &setFDs); +#endif + +static void handleCheckSessionInConnect(); + +static inline void handleSetReadInLoop(fd_set &readSet, int &setFDs, struct timeval &selectTs); +static inline void handleSetWriteInLoop(fd_set &writeSet, int &setFDs, struct timeval &selectTs); +static inline void handleSetListenersInLoop(fd_set &writeSet, int &setFDs); +static inline void handleSetAgentInLoop(int &setFDs, fd_set &readSet, fd_set &writeSet, + struct timeval &selectTs); + +static void handleAlertInLoop(); +static void handleStatisticsInLoop(); + +static inline void handleAgentInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, + fd_set &writeSet, struct timeval &selectTs); +static inline void handleAgentLateInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, + fd_set &writeSet, struct timeval &selectTs); + +static inline void handleReadableInLoop(int &resultFDs, fd_set &readSet); +static inline void handleWritableInLoop(int &resultFDs, fd_set &writeSet); + +static inline void handleRotateInLoop(); +static inline void handleEventsInLoop(); +static inline void handleFlushInLoop(); + +// +// Manage the proxy link during the negotiation +// phase. +// + +static void handleNegotiationInLoop(int &setFDs, fd_set &readSet, + fd_set &writeSet, T_timestamp &selectTs); + +// +// Print the 'terminating' messages in the +// session log. +// + +static inline void handleTerminatingInLoop(); +static inline void handleTerminatedInLoop(); + +// +// Monitor the size of the log file. +// + +static void handleLogReopenInLoop(T_timestamp &logsTs, T_timestamp &nowTs); + +// +// Directory where the NX binaries and libraries reside. +// + +static char systemDir[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Directory used for temporary files. +// + +static char tempDir[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Actually the full path to the client. +// + +static char clientDir[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// User's home directory. +// + +static char homeDir[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Root of directory structure to be created by proxy. +// + +static char rootDir[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Root of statistics and log files to be created by proxy. +// + +static char sessionDir[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Log files for errors and statistics. Error log is +// the place where we print also debug informations. +// Both files are closed, deleted and reopened as +// their size exceed the limit set in control class. +// The session log is not reopened, as it is used by +// the NX client and server to track the advance of +// the session. +// + +static char errorsFileName[DEFAULT_STRING_LENGTH] = { 0 }; +static char statsFileName[DEFAULT_STRING_LENGTH] = { 0 }; +static char sessionFileName[DEFAULT_STRING_LENGTH] = { 0 }; +static char optionsFileName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// String literal representing selected link speed +// parameter. Value is translated in control values +// used by proxies to stay synchronized. +// + +static char linkSpeedName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// String literal representing selected +// cache size. +// + +static char cacheSizeName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// String literal representing selected +// shared memory segment size. +// + +static char shsegSizeName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// String literal of images cache size. +// + +static char imagesSizeName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// String literal for bandwidth limit. +// + +static char bitrateLimitName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// String literal for image packing method. +// + +static char packMethodName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Product name provided by the server or client. +// + +static char productName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Its corresponding value from NXpack.h. +// + +static int packMethod = -1; +static int packQuality = -1; + +// +// String literal for session type. Persistent caches +// are searched in directory whose name matches this +// parameter. +// + +static char sessionType[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Unique id assigned to session. It is used as +// name of directory where all files are placed. +// + +static char sessionId[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Set if we already parsed the options. +// + +static int parsedOptions = 0; +static int parsedCommand = 0; + +// +// Buffer data received from the remote proxy at +// session negotiation. +// + +static char remoteData[MAXIMUM_REMOTE_OPTIONS_LENGTH] = { 0 }; +static int remotePosition = 0; + +// +// Main loop file descriptors. +// + +static int tcpFD = -1; +static int unixFD = -1; +static int cupsFD = -1; +static int auxFD = -1; +static int smbFD = -1; +static int mediaFD = -1; +static int httpFD = -1; +static int fontFD = -1; +static int slaveFD = -1; +static int proxyFD = -1; + +// +// Used for internal communication +// with the X agent. +// + +static int agentFD[2] = { -1, -1 }; + +// +// Flags determining which protocols and +// ports are forwarded. +// + +int useUnixSocket = 1; + +static int useTcpSocket = 1; +static int useCupsSocket = 0; +static int useAuxSocket = 0; +static int useSmbSocket = 0; +static int useMediaSocket = 0; +static int useHttpSocket = 0; +static int useFontSocket = 0; +static int useSlaveSocket = 0; +static int useAgentSocket = 0; + +// +// Set if the launchd service is running +// and its socket must be used as X socket. +// + +static int useLaunchdSocket = 0; + +// +// Set by user if he/she wants to modify +// the default TCP_NODELAY option as set +// in control. +// + +static int useNoDelay = -1; + +// +// Set if user wants to override default +// flush timeout set according to link. +// + +static int usePolicy = -1; + +// +// Set if user wants to hide the RENDER +// extension or wants to short-circuit +// some simple replies at client side. +// + +static int useRender = -1; +static int useTaint = -1; + +// +// Set if the user wants to reduce the +// nominal size of the token messages +// exchanged between the proxies. +// + +static int useStrict = -1; + +// +// Set if the proxy is running as part +// of SSH on the client. +// + +static int useEncryption = -1; + +// +// Name of Unix socket created by the client proxy to +// accept client connections. File must be unlinked +// by cleanup function. +// + +static char unixSocketName[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Other parameters. +// + +static char acceptHost[DEFAULT_STRING_LENGTH] = { 0 }; +static char displayHost[DEFAULT_STRING_LENGTH] = { 0 }; +static char authCookie[DEFAULT_STRING_LENGTH] = { 0 }; + +static int loopbackBind = DEFAULT_LOOPBACK_BIND; +static int proxyPort = DEFAULT_NX_PROXY_PORT; +static int xPort = DEFAULT_NX_X_PORT; + +// +// Used to setup the connection the real +// X display socket. +// + +static int xServerAddrFamily = -1; +static sockaddr *xServerAddr = NULL; +static unsigned int xServerAddrLength = 0; + +// +// The representation of a Unix socket path or +// a bind address, denoting where the local proxy +// will await the peer connection. +// + +static ChannelEndPoint listenSocket; + +// +// The TCP host and port or Unix file socket where +// the remote proxy will be contacted. +// + +static ChannelEndPoint connectSocket; + +// +// Helper channels are disabled by default. +// + +static ChannelEndPoint cupsPort; +static ChannelEndPoint auxPort; +static ChannelEndPoint smbPort; +static ChannelEndPoint mediaPort; +static ChannelEndPoint httpPort; +static ChannelEndPoint slavePort; + +// +// Can be either a port number or a Unix +// socket. +// + +static char fontPort[DEFAULT_STRING_LENGTH] = { 0 }; + +// +// Host and port where the existing proxy +// is running. +// + +static char bindHost[DEFAULT_STRING_LENGTH] = { 0 }; +static int bindPort = -1; + +// +// Pointers to the callback functions and +// parameter set by the agent +// + +static void (*flushCallback)(void *, int) = NULL; +static void *flushParameter = NULL; + +static void (*statisticsCallback)(void *, int) = NULL; +static void *statisticsParameter = NULL; + +// +// State variables shared between the init +// function and the main loop. +// + +T_timestamp initTs; +T_timestamp startTs; +T_timestamp logsTs; +T_timestamp nowTs; + +int diffTs; + +// +// This is set to the main proxy process id. +// + +int lastProxy = 0; + +// +// Set to last dialog process launched by proxy. +// + +int lastDialog = 0; + +// +// Set to watchdog process launched by proxy. +// + +int lastWatchdog = 0; + +// +// Set if a cache house-keeper process is running. +// + +int lastKeeper = 0; + +// +// Let an inner routine register the pid of a slave +// process. +// + +static int lastChild = 0; + +// +// Exit code of the last child process exited. +// + +static int lastStatus = 0; + +// +// Set if shutdown was requested through a signal. +// + +static int lastKill = 0; + +// +// Set if the agent confirmed the destruction of +// the NX transport. +// + +static int lastDestroy = 0; + +// +// This is set to the code and local flag of the +// last requested alert. +// + +static struct +{ + int code; + int local; + +} lastAlert; + +// +// Manage the current signal masks. +// + +static struct +{ + sigset_t saved; + + int blocked; + int installed; + + int enabled[32]; + int forward[32]; + + struct sigaction action[32]; + +} lastMasks; + +// +// Manage the current timer. +// + +static struct +{ + struct sigaction action; + struct itimerval value; + struct timeval start; + struct timeval next; + +} lastTimer; + +// +// This is set to last signal received in handler. +// + +static int lastSignal = 0; + +// +// Set to the last time bytes readable were queried +// by the agent. +// + +static T_timestamp lastReadableTs = nullTimestamp(); + +// +// Here are interfaces declared in NX.h. +// + +int NXTransProxy(int fd, int mode, const char* options) +{ + // + // Let the log temporarily go to the standard + // error. Be also sure we have a jump context, + // in the case any subsequent operation will + // cause a cleanup. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + if (setjmp(context) == 1) + { + #ifdef TEST + *logofs << "NXTransProxy: Out of the long jump with pid '" + << lastProxy << "'.\n" << logofs_flush; + #endif + + return -1; + } + + // + // Check if have already performed a parsing of + // parameters, as in the case we are running as + // a stand-alone process. If needed create the + // parameters repository + // + + if (control == NULL) + { + control = new Control(); + } + + lastProxy = getpid(); + + #ifdef TEST + *logofs << "NXTransProxy: Main process started with pid '" + << lastProxy << "'.\n" << logofs_flush; + #endif + + SetMode(mode); + + if (mode == NX_MODE_CLIENT) + { + if (fd != NX_FD_ANY) + { + #ifdef TEST + + *logofs << "NXTransProxy: Agent descriptor for X client connections is FD#" + << fd << ".\n" << logofs_flush; + + *logofs << "NXTransProxy: Disabling listening on further X client connections.\n" + << logofs_flush; + + #endif + + useTcpSocket = 0; + useUnixSocket = 0; + useAgentSocket = 1; + + agentFD[1] = fd; + } + } + else if (mode == NX_MODE_SERVER) + { + if (fd != NX_FD_ANY) + { + #ifdef TEST + *logofs << "NXTransProxy: PANIC! Agent descriptor for X server connections " + << "not supported yet.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Agent descriptor for X server connections " + << "not supported yet.\n"; + + return -1; + } + } + + const char *env = GetOptions(options); + + if (ParseEnvironmentOptions(env, 0) < 0) + { + cerr << "Error" << ": Parsing of NX transport options failed.\n"; + + return -1; + } + + // + // Set the path of the NX directories. + // + + SetDirectories(); + + // + // Open the log files. + // + + SetLogs(); + + #ifdef TEST + *logofs << "NXTransProxy: Going to run the NX transport loop.\n" + << logofs_flush; + #endif + + WaitCleanup(); + + // + // This function should never return. + // + + exit(0); +} + +void NXTransExit(int code) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + static int recurse; + + if (++recurse > 1) + { + #ifdef TEST + *logofs << "NXTransExit: Aborting process with pid '" + << getpid() << "' due to recursion through " + << "exit.\n" << logofs_flush; + #endif + + abort(); + } + + #ifdef TEST + *logofs << "NXTransExit: Process with pid '" + << getpid() << "' called exit with code '" + << code << "'.\n" << logofs_flush; + #endif + + if (control != NULL) + { + // + // Be sure that there we can detect the + // termination of the watchdog. + // + + EnableSignals(); + + // + // Close the NX transport if it was not + // shut down already. + // + + NXTransDestroy(NX_FD_ANY); + } + + exit(code); +} + +int NXTransParseCommandLine(int argc, const char **argv) +{ + return ParseCommandLineOptions(argc, argv); +} + +int NXTransParseEnvironment(const char *env, int force) +{ + return ParseEnvironmentOptions(env, force); +} + +void NXTransCleanup() +{ + HandleCleanup(); +} + +void NXTransCleanupForReconnect() +{ + HandleCleanupForReconnect(); +} + +// +// Check the parameters for subsequent +// initialization of the NX transport. +// + +int NXTransCreate(int fd, int mode, const char* options) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + // + // Be sure we have a jump context, in the + // case a subsequent operation will cause + // a cleanup. + // + + if (setjmp(context) == 1) + { + return -1; + } + + // + // Create the parameters repository + // + + if (control != NULL) + { + #ifdef PANIC + *logofs << "NXTransCreate: PANIC! The NX transport seems " + << "to be already running.\n" << logofs_flush; + #endif + + cerr << "Error" << ": The NX transport seems " + << "to be already running.\n"; + + return -1; + } + + control = new Control(); + + if (control == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error creating the NX transport.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error creating the NX transport.\n"; + + return -1; + } + + lastProxy = getpid(); + + #ifdef TEST + *logofs << "NXTransCreate: Caller process running with pid '" + << lastProxy << "'.\n" << logofs_flush; + #endif + + // + // Set the local proxy mode an parse the + // display NX options. + // + + SetMode(mode); + + const char *env = GetOptions(options); + + if (ParseEnvironmentOptions(env, 0) < 0) + { + cerr << "Error" << ": Parsing of NX transport options failed.\n"; + + return -1; + } + + // + // Set the path of the NX directories. + // + + SetDirectories(); + + // + // Open the log files. + // + + SetLogs(); + + // + // Use the provided descriptor. + // + + proxyFD = fd; + + #ifdef TEST + *logofs << "NXTransCreate: Called with NX proxy descriptor '" + << proxyFD << "'.\n" << logofs_flush; + #endif + + #ifdef TEST + *logofs << "NXTransCreate: Creation of the NX transport completed.\n" + << logofs_flush; + #endif + + return 1; +} + +// +// Tell the proxy to use the descriptor as the internal +// connection to the X client side NX agent. This will +// have the side effect of disabling listening for add- +// itional X client connections. +// + +int NXTransAgent(int fd[2]) +{ + // + // Be sure we have a jump context, in the + // case a subsequent operation will cause + // a cleanup. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + if (setjmp(context) == 1) + { + return -1; + } + + if (control == NULL) + { + cerr << "Error" << ": Can't set the NX agent without a NX transport.\n"; + + return -1; + } + else if (control -> ProxyMode != proxy_client) + { + #ifdef PANIC + *logofs << "NXTransAgent: Invalid mode while setting the NX agent.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid mode while setting the NX agent.\n\n"; + + return -1; + } + + useTcpSocket = 0; + useUnixSocket = 0; + useAgentSocket = 1; + + agentFD[0] = fd[0]; + agentFD[1] = fd[1]; + + #ifdef TEST + + *logofs << "NXTransAgent: Internal descriptors for agent are FD#" + << agentFD[0] << " and FD#" << agentFD[1] << ".\n" + << logofs_flush; + + *logofs << "NXTransAgent: Disabling listening for further X client " + << "connections.\n" << logofs_flush; + + #endif + + agent = new Agent(agentFD); + + if (agent == NULL || agent -> isValid() != 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error creating the NX memory transport .\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error creating the NX memory transport.\n"; + + HandleCleanup(); + } + + #ifdef TEST + *logofs << "NXTransAgent: Enabling memory-to-memory transport.\n" + << logofs_flush; + #endif + + return 1; +} + +int NXTransClose(int fd) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + /* + * Only handle the proxy connection. The X + * transport will take care of closing its + * end of the socket pair. + */ + + if (control != NULL && ((agent != NULL && + (fd == agentFD[0] || fd == NX_FD_ANY)) || + (fd == proxyFD || fd == NX_FD_ANY))) + { + if (proxy != NULL) + { + #ifdef TEST + *logofs << "NXTransClose: Closing down all the X connections.\n" + << logofs_flush; + #endif + + CleanupConnections(); + } + } + #ifdef TEST + else + { + *logofs << "NXTransClose: The NX transport is not running.\n" + << logofs_flush; + } + #endif + + return 1; +} + +// +// Close down the transport and free the +// allocated NX resources. +// + +int NXTransDestroy(int fd) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + if (control != NULL && ((agent != NULL && + (fd == agentFD[0] || fd == NX_FD_ANY)) || + (fd == proxyFD || fd == NX_FD_ANY))) + { + // + // Shut down the X connections and + // wait the cleanup to complete. + // + + if (proxy != NULL) + { + #ifdef TEST + *logofs << "NXTransDestroy: Closing down all the X connections.\n" + << logofs_flush; + #endif + + CleanupConnections(); + } + + #ifdef TEST + *logofs << "NXTransDestroy: Waiting for the NX transport to terminate.\n" + << logofs_flush; + #endif + + lastDestroy = 1; + + WaitCleanup(); + } + #ifdef TEST + else + { + *logofs << "NXTransDestroy: The NX transport is not running.\n" + << logofs_flush; + } + #endif + + return 1; +} + +// +// Assume that the NX transport is valid +// as long as the control class has not +// been destroyed. +// + +int NXTransRunning(int fd) +{ + return (control != NULL); +} + +int NXTransContinue(struct timeval *selectTs) +{ + if (control != NULL) + { + // + // If no timeout is provided use + // the default. + // + + T_timestamp newTs; + + if (selectTs == NULL) + { + setTimestamp(newTs, control -> PingTimeout); + + selectTs = &newTs; + } + + // + // Use empty masks and only get the + // descriptors set by the proxy. + // + + fd_set readSet; + fd_set writeSet; + + int setFDs; + int errorFDs; + int resultFDs; + + setFDs = 0; + + FD_ZERO(&readSet); + FD_ZERO(&writeSet); + + // + // Run a new loop. If the transport + // is gone avoid sleeping until the + // timeout. + // + + if (NXTransPrepare(&setFDs, &readSet, &writeSet, selectTs) != 0) + { + NXTransSelect(&resultFDs, &errorFDs, &setFDs, &readSet, &writeSet, selectTs); + + NXTransExecute(&resultFDs, &errorFDs, &setFDs, &readSet, &writeSet, selectTs); + } + } + + return (control != NULL); +} + +int NXTransSignal(int signal, int action) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + if (control == NULL) + { + return 0; + } + + if (action == NX_SIGNAL_RAISE) + { + #ifdef TEST + *logofs << "NXTransSignal: Raising signal '" << DumpSignal(signal) + << "' in the proxy handler.\n" << logofs_flush; + #endif + + HandleSignal(signal); + + return 1; + } + else if (signal == NX_SIGNAL_ANY) + { + #ifdef TEST + *logofs << "NXTransSignal: Setting action of all signals to '" + << action << "'.\n" << logofs_flush; + #endif + + for (int i = 0; i < 32; i++) + { + if (CheckSignal(i) == 1) + { + NXTransSignal(i, action); + } + } + + return 1; + } + else if (CheckSignal(signal) == 1) + { + #ifdef TEST + *logofs << "NXTransSignal: Setting action of signal '" + << DumpSignal(signal) << "' to '" << action + << "'.\n" << logofs_flush; + #endif + + if (action == NX_SIGNAL_ENABLE || + action == NX_SIGNAL_FORWARD) + { + InstallSignal(signal, action); + + return 1; + } + else if (action == NX_SIGNAL_DISABLE) + { + RestoreSignal(signal); + + return 1; + } + } + + #ifdef WARNING + *logofs << "NXTransSignal: WARNING! Unable to perform action '" + << action << "' on signal '" << DumpSignal(signal) + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Unable to perform action '" << action + << "' on signal '" << DumpSignal(signal) + << "'.\n"; + + return -1; +} + +int NXTransCongestion(int fd) +{ + if (control != NULL && proxy != NULL) + { + #ifdef DUMP + + int congestion = proxy -> getCongestion(proxyFD); + + *logofs << "NXTransCongestion: Returning " << congestion + << " as current congestion level.\n" << logofs_flush; + + return congestion; + + #endif + + return (proxy -> getCongestion(proxyFD)); + } + + return 0; +} + +int NXTransHandler(int fd, int type, void (*handler)(void *parameter, + int reason), void *parameter) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + switch (type) + { + case NX_HANDLER_FLUSH: + { + flushCallback = handler; + flushParameter = parameter; + + break; + } + case NX_HANDLER_STATISTICS: + { + // + // Reporting of statistics by the agent + // still needs to be implemented. + // + + statisticsCallback = handler; + statisticsParameter = parameter; + + break; + } + default: + { + #ifdef TEST + *logofs << "NXTransHandler: WARNING! Failed to set " + << "the NX callback for event '" << type << "' to '" + << (void *) handler << "' and parameter '" + << parameter << "'.\n" << logofs_flush; + #endif + + return 0; + } + } + + #ifdef TEST + *logofs << "NXTransHandler: Set the NX " + << "callback for event '" << type << "' to '" + << (void *) handler << "' and parameter '" + << parameter << "'.\n" << logofs_flush; + #endif + + return 1; +} + +int NXTransRead(int fd, char *data, int size) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + if (control != NULL && agent != NULL && + fd == agentFD[0]) + { + #ifdef DUMP + *logofs << "NXTransRead: Dequeuing " << size << " bytes " + << "from FD#" << agentFD[0] << ".\n" << logofs_flush; + #endif + + int result = agent -> dequeueData(data, size); + + #ifdef DUMP + + if (result < 0 && EGET() == EAGAIN) + { + *logofs << "NXTransRead: WARNING! Dequeuing from FD#" + << agentFD[0] << " would block.\n" << logofs_flush; + } + else + { + *logofs << "NXTransRead: Dequeued " << result << " bytes " + << "to FD#" << agentFD[0] << ".\n" << logofs_flush; + } + + #endif + + return result; + } + else + { + #ifdef DUMP + *logofs << "NXTransRead: Reading " << size << " bytes " + << "from FD#" << fd << ".\n" << logofs_flush; + #endif + + return read(fd, data, size); + } +} + +int NXTransReadVector(int fd, struct iovec *iovdata, int iovsize) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + if (control != NULL && agent != NULL && + fd == agentFD[0]) + { + #if defined(DUMP) + + if (control -> ProxyStage >= stage_operational && + agent -> localReadable() > 0) + { + *logofs << "NXTransReadVector: WARNING! Agent has data readable.\n" + << logofs_flush; + } + + #endif + + char *base; + + int length; + int result; + + struct iovec *vector = iovdata; + int count = iovsize; + + ESET(0); + + int i = 0; + int total = 0; + + for (; i < count; i++, vector++) + { + length = vector -> iov_len; + base = (char *) vector -> iov_base; + + while (length > 0) + { + #ifdef DUMP + *logofs << "NXTransReadVector: Dequeuing " << length + << " bytes " << "from FD#" << agentFD[0] << ".\n" + << logofs_flush; + #endif + + result = agent -> dequeueData(base, length); + + #ifdef DUMP + + if (result < 0 && EGET() == EAGAIN) + { + *logofs << "NXTransReadVector: WARNING! Dequeuing from FD#" + << agentFD[0] << " would block.\n" << logofs_flush; + } + else + { + *logofs << "NXTransReadVector: Dequeued " << result + << " bytes " << "from FD#" << agentFD[0] << ".\n" + << logofs_flush; + } + + #endif + + if (result < 0 && total == 0) + { + return result; + } + else if (result <= 0) + { + return total; + } + + ESET(0); + + length -= result; + total += result; + base += result; + } + } + + return total; + } + else + { + #ifdef DUMP + *logofs << "NXTransReadVector: Reading vector with " + << iovsize << " elements from FD#" << fd << ".\n" + << logofs_flush; + #endif + + return readv(fd, iovdata, iovsize); + } +} + +int NXTransReadable(int fd, int *readable) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + if (control == NULL || agent == NULL || + fd != agentFD[0]) + { + #ifdef DUMP + + int result = GetBytesReadable(fd, readable); + + if (result == -1) + { + *logofs << "NXTransReadable: Error detected on FD#" + << fd << ".\n" << logofs_flush; + } + else + { + *logofs << "NXTransReadable: Returning " << *readable + << " bytes as readable from FD#" << fd + << ".\n" << logofs_flush; + } + + return result; + + #else + + return GetBytesReadable(fd, readable); + + #endif + } + + int result = agent -> dequeuableData(); + + switch (result) + { + case 0: + { + // + // The client might have enqueued data to our side + // and is now checking for the available events. As + // _XEventsQueued() may omit to call _XSelect(), we + // handle here the new data that is coming from the + // proxy to avoid spinning through this function + // again. + // + + if (proxy != NULL && proxy -> canRead() == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "NXTransReadable: WARNING! Trying to " + << "read to generate new agent data.\n" + << logofs_flush; + #endif + + // + // Set the context as the function + // can cause a cleanup. + // + + if (setjmp(context) == 1) + { + return -1; + } + + if (proxy -> handleRead() < 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "NXTransReadable: Failure reading " + << "messages from proxy FD#" << proxyFD + << ".\n" << logofs_flush; + #endif + + HandleShutdown(); + } + + // + // Call again the routine. By reading + // new control messages from the proxy + // the agent channel may be gone. + // + + return NXTransReadable(fd, readable); + } + + #ifdef DUMP + *logofs << "NXTransReadable: Returning " << 0 + << " bytes as readable from FD#" << fd + << " with result 0.\n" << logofs_flush; + #endif + + *readable = 0; + + return 0; + } + case -1: + { + #ifdef DUMP + *logofs << "NXTransReadable: Returning " << 0 + << " bytes as readable from FD#" << fd + << " with result -1.\n" << logofs_flush; + #endif + + *readable = 0; + + return -1; + } + default: + { + #ifdef DUMP + *logofs << "NXTransReadable: Returning " << result + << " bytes as readable from FD#" << fd + << " with result 0.\n" << logofs_flush; + #endif + + *readable = result; + + return 0; + } + } +} + +int NXTransWrite(int fd, char *data, int size) +{ + // + // Be sure we have a valid log file. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + if (control != NULL && agent != NULL && + fd == agentFD[0]) + { + int result; + + if (proxy != NULL) + { + if (proxy -> canRead(agentFD[1]) == 0) + { + #if defined(DUMP) || defined(TEST) + *logofs << "NXTransWrite: WARNING! Delayed enqueuing to FD#" + << agentFD[0] << " with proxy unable to read.\n" + << logofs_flush; + #endif + + ESET(EAGAIN); + + return -1; + } + + // + // Set the context as the function + // can cause a cleanup. + // + + if (setjmp(context) == 1) + { + return -1; + } + + // + // Don't enqueue the data to the transport + // but let the channel borrow the buffer. + // + + #ifdef DUMP + *logofs << "NXTransWrite: Letting the channel borrow " + << size << " bytes from FD#" << agentFD[0] + << ".\n" << logofs_flush; + #endif + + result = proxy -> handleRead(agentFD[1], data, size); + + if (result == 1) + { + result = size; + } + else + { + if (result == 0) + { + ESET(EAGAIN); + } + else + { + ESET(EPIPE); + } + + result = -1; + } + } + else + { + // + // We don't have a proxy connection, yet. + // Enqueue the data to the agent transport. + // + + #ifdef DUMP + *logofs << "NXTransWrite: Enqueuing " << size << " bytes " + << "to FD#" << agentFD[0] << ".\n" << logofs_flush; + #endif + + result = agent -> enqueueData(data, size); + } + + #ifdef DUMP + + if (result < 0) + { + if (EGET() == EAGAIN) + { + *logofs << "NXTransWrite: WARNING! Enqueuing to FD#" + << agentFD[0] << " would block.\n" + << logofs_flush; + } + else + { + *logofs << "NXTransWrite: WARNING! Error enqueuing to FD#" + << agentFD[0] << ".\n" << logofs_flush; + } + } + else + { + *logofs << "NXTransWrite: Enqueued " << result << " bytes " + << "to FD#" << agentFD[0] << ".\n" << logofs_flush; + } + + #endif + + return result; + } + else + { + #ifdef DUMP + *logofs << "NXTransWrite: Writing " << size << " bytes " + << "to FD#" << fd << ".\n" << logofs_flush; + #endif + + return write(fd, data, size); + } +} + +int NXTransWriteVector(int fd, struct iovec *iovdata, int iovsize) +{ + // + // Be sure we have a valid log file and a + // jump context because we will later call + // functions that can perform a cleanup. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + int result = 0; + + if (control != NULL && agent != NULL && + fd == agentFD[0]) + { + // + // See the comment in NXTransWrite(). + // + + if (proxy != NULL) + { + if (proxy -> canRead(agentFD[1]) == 0) + { + #if defined(DUMP) || defined(TEST) + *logofs << "NXTransWriteVector: WARNING! Delayed enqueuing to FD#" + << agentFD[0] << " with proxy unable to read.\n" + << logofs_flush; + #endif + + ESET(EAGAIN); + + return -1; + } + } + + // + // Set the context as the function + // can cause a cleanup. + // + + if (setjmp(context) == 1) + { + return -1; + } + + char *base; + + int length; + + struct iovec *vector = iovdata; + int count = iovsize; + + ESET(0); + + int i = 0; + int total = 0; + + for (; i < count; i++, vector++) + { + length = vector -> iov_len; + base = (char *) vector -> iov_base; + + while (length > 0) + { + if (proxy != NULL) + { + // + // Don't enqueue the data to the transport + // but let the channel borrow the buffer. + // + + #ifdef DUMP + *logofs << "NXTransWriteVector: Letting the channel borrow " + << length << " bytes from FD#" << agentFD[0] + << ".\n" << logofs_flush; + #endif + + result = proxy -> handleRead(agentFD[1], base, length); + + if (result == 1) + { + result = length; + } + else + { + if (result == 0) + { + ESET(EAGAIN); + } + else + { + ESET(EPIPE); + } + + result = -1; + } + } + else + { + // + // We don't have a proxy connection, yet. + // Enqueue the data to the agent transport. + // + + #ifdef DUMP + *logofs << "NXTransWriteVector: Enqueuing " << length + << " bytes " << "to FD#" << agentFD[0] << ".\n" + << logofs_flush; + #endif + + result = agent -> enqueueData(base, length); + } + + #ifdef DUMP + + if (result < 0) + { + if (EGET() == EAGAIN) + { + *logofs << "NXTransWriteVector: WARNING! Enqueuing to FD#" + << agentFD[0] << " would block.\n" + << logofs_flush; + } + else + { + *logofs << "NXTransWriteVector: WARNING! Error enqueuing to FD#" + << agentFD[0] << ".\n" << logofs_flush; + } + } + else + { + *logofs << "NXTransWriteVector: Enqueued " << result + << " bytes " << "to FD#" << agentFD[0] << ".\n" + << logofs_flush; + } + + #endif + + if (result < 0 && total == 0) + { + return result; + } + else if (result <= 0) + { + return total; + } + + ESET(0); + + length -= result; + total += result; + base += result; + } + } + + return total; + } + else + { + #ifdef DUMP + *logofs << "NXTransWriteVector: Writing vector with " + << iovsize << " elements to FD#" << fd << ".\n" + << logofs_flush; + #endif + + return writev(fd, iovdata, iovsize); + } +} + +int NXTransPolicy(int fd, int type) +{ + if (control != NULL) + { + if (usePolicy == -1) + { + #if defined(TEST) || defined(INFO) + *logofs << "NXTransPolicy: Setting flush policy on " + << "proxy FD#" << proxyFD << " to '" + << DumpPolicy(type == NX_POLICY_DEFERRED ? + policy_deferred : policy_immediate) + << "'.\n" << logofs_flush; + #endif + + control -> FlushPolicy = (type == NX_POLICY_DEFERRED ? + policy_deferred : policy_immediate); + + if (proxy != NULL) + { + proxy -> handleFlush(); + } + + return 1; + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "NXTransPolicy: Ignoring the agent " + << "setting with user policy set to '" + << DumpPolicy(control -> FlushPolicy) + << "'.\n" << logofs_flush; + #endif + + return 0; + } + } + + return 0; +} + +int NXTransFlushable(int fd) +{ + if (proxy == NULL || agent == NULL || + fd != agentFD[0]) + { + #ifdef DUMP + *logofs << "NXTransFlushable: Returning 0 bytes as " + << "flushable for unrecognized FD#" << fd + << ".\n" << logofs_flush; + #endif + + return 0; + } + else + { + #if defined(DUMP) || defined(INFO) + *logofs << "NXTransFlushable: Returning " << proxy -> + getFlushable(proxyFD) << " as bytes flushable on " + << "proxy FD#" << proxyFD << ".\n" + << logofs_flush; + #endif + + return proxy -> getFlushable(proxyFD); + } +} + +int NXTransFlush(int fd) +{ + if (proxy != NULL) + { + #if defined(TEST) || defined(INFO) + *logofs << "NXTransFlush: Requesting an immediate flush of " + << "proxy FD#" << proxyFD << ".\n" + << logofs_flush; + #endif + + return proxy -> handleFlush(); + } + + return 0; +} + +int NXTransChannel(int fd, int channelFd, int type) +{ + if (proxy != NULL) + { + // + // Set the context as the function + // can cause a cleanup. + // + + if (setjmp(context) == 1) + { + return -1; + } + + #if defined(TEST) || defined(INFO) + *logofs << "NXTransChannel: Going to create a new channel " + << "with type '" << type << "' on FD#" << channelFd + << ".\n" << logofs_flush; + #endif + + int result = -1; + + switch (type) + { + case NX_CHANNEL_X11: + { + if (useUnixSocket == 1 || useTcpSocket == 1 || + useAgentSocket == 1 || useAuxSocket == 1) + { + result = proxy -> handleNewConnection(channel_x11, channelFd); + } + + break; + } + case NX_CHANNEL_CUPS: + { + if (useCupsSocket == 1) + { + result = proxy -> handleNewConnection(channel_cups, channelFd); + } + + break; + } + case NX_CHANNEL_SMB: + { + if (useSmbSocket == 1) + { + result = proxy -> handleNewConnection(channel_smb, channelFd); + } + + break; + } + case NX_CHANNEL_MEDIA: + { + if (useMediaSocket == 1) + { + result = proxy -> handleNewConnection(channel_media, channelFd); + } + + break; + } + case NX_CHANNEL_HTTP: + { + if (useHttpSocket == 1) + { + result = proxy -> handleNewConnection(channel_http, channelFd); + } + + break; + } + case NX_CHANNEL_FONT: + { + if (useFontSocket == 1) + { + result = proxy -> handleNewConnection(channel_font, channelFd); + } + + break; + } + case NX_CHANNEL_SLAVE: + { + if (useSlaveSocket == 1) + { + result = proxy -> handleNewConnection(channel_slave, channelFd); + } + + break; + } + default: + { + #ifdef WARNING + *logofs << "NXTransChannel: WARNING! Unrecognized channel " + << "type '" << type << "'.\n" << logofs_flush; + #endif + + break; + } + } + + #ifdef WARNING + + if (result != 1) + { + *logofs << "NXTransChannel: WARNING! Could not create the " + << "new channel with type '" << type << "' on FD#" + << channelFd << ".\n" << logofs_flush; + } + + #endif + + return result; + } + + return 0; +} + +const char *NXTransFile(int type) +{ + char *name = NULL; + + switch (type) + { + case NX_FILE_SESSION: + { + name = sessionFileName; + + break; + } + case NX_FILE_ERRORS: + { + name = errorsFileName; + + break; + } + case NX_FILE_OPTIONS: + { + name = optionsFileName; + + break; + } + case NX_FILE_STATS: + { + name = statsFileName; + + break; + } + } + + if (name != NULL && *name != '\0') + { + return name; + } + + return NULL; +} + +long NXTransTime() +{ + static T_timestamp last = getTimestamp(); + + T_timestamp now = getTimestamp(); + + long diff = diffTimestamp(last, now); + + last = now; + + return diff; +} + +int NXTransAlert(int code, int local) +{ + if (proxy != NULL) + { + #if defined(DUMP) || defined(INFO) + *logofs << "NXTransAlert: Requesting a NX dialog with code " + << code << " and local " << local << ".\n" + << logofs_flush; + #endif + + if (local == 0) + { + // + // Set the context as the function + // can cause a cleanup. + // + + if (setjmp(context) == 1) + { + return -1; + } + + proxy -> handleAlert(code); + } + else + { + // + // Show the alert at the next loop. + // + + HandleAlert(code, local); + } + + return 1; + } + #if defined(DUMP) || defined(INFO) + else + { + if (logofs == NULL) + { + logofs = &cerr; + } + + *logofs << "NXTransAlert: Can't request an alert without " + << "a valid NX transport.\n" << logofs_flush; + } + #endif + + return 0; +} + +// +// Prepare the file sets and the timeout +// for a later execution of the select(). +// + +int NXTransPrepare(int *setFDs, fd_set *readSet, + fd_set *writeSet, struct timeval *selectTs) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + // + // Control is NULL if the NX transport was + // reset or was never created. If control + // is valid then prepare to jump back when + // the transport is destroyed. + // + + if (control == NULL || setjmp(context) == 1) + { + return 0; + } + + #if defined(TEST) || defined(INFO) + *logofs << "\nNXTransPrepare: Going to prepare the NX transport.\n" + << logofs_flush; + #endif + + if (control -> ProxyStage < stage_operational) + { + handleNegotiationInLoop(*setFDs, *readSet, *writeSet, *selectTs); + } + else + { + #if defined(TEST) || defined(INFO) + + if (isTimestamp(*selectTs) == 0) + { + *logofs << "Loop: WARNING! Preparing the select with requested " + << "timeout of " << selectTs -> tv_sec << " S and " + << (double) selectTs -> tv_usec / 1000 << " Ms.\n" + << logofs_flush; + } + else + { + *logofs << "Loop: Preparing the select with requested " + << "timeout of " << selectTs -> tv_sec << " S and " + << (double) selectTs -> tv_usec / 1000 << " Ms.\n" + << logofs_flush; + } + + #endif + + // + // Set descriptors of listening sockets. + // + + handleSetListenersInLoop(*readSet, *setFDs); + + // + // Set descriptors of both proxy and X + // connections. + // + + handleSetReadInLoop(*readSet, *setFDs, *selectTs); + + // + // Find out which file descriptors have + // data to write. + // + + handleSetWriteInLoop(*writeSet, *setFDs, *selectTs); + } + + // + // Prepare the masks for handling the memory- + // to-memory transport. This is required even + // during session negotiation. + // + + if (agent != NULL) + { + handleSetAgentInLoop(*setFDs, *readSet, *writeSet, *selectTs); + } + + // + // Register time spent handling messages. + // + + nowTs = getNewTimestamp(); + + diffTs = diffTimestamp(startTs, nowTs); + + #ifdef TEST + *logofs << "Loop: Mark - 0 - at " << strMsTimestamp() + << " with " << diffTs << " Ms elapsed.\n" + << logofs_flush; + #endif + + // + // TODO: Should add the read time in two + // parts otherwise the limits are checked + // before the counters are updated with + // time spent in the last loop. + // + + if (control -> ProxyStage >= stage_operational) + { + statistics -> addReadTime(diffTs); + } + + startTs = nowTs; + + #ifdef DEBUG + *logofs << "Loop: New timestamp is " << strMsTimestamp(startTs) + << ".\n" << logofs_flush; + #endif + + return 1; +} + +// +// Let's say that we call select() to find out +// if any of the handled descriptors has data, +// but actually things are a bit more complex +// than that. +// + +int NXTransSelect(int *resultFDs, int *errorFDs, int *setFDs, fd_set *readSet, + fd_set *writeSet, struct timeval *selectTs) +{ + #ifdef TIME + + static T_timestamp lastTs; + + #endif + + if (logofs == NULL) + { + logofs = &cerr; + } + + // + // Control is NULL if the NX transport was + // reset or never created. If control is + // valid then prepare for jumping back in + // the case of an error. + // + + if (control == NULL || setjmp(context) == 1) + { + *resultFDs = select(*setFDs, readSet, writeSet, NULL, selectTs); + + *errorFDs = errno; + + return 0; + } + + #if defined(TEST) || defined(INFO) + *logofs << "\nNXTransSelect: Going to select the NX descriptors.\n" + << logofs_flush; + #endif + + #if defined(TEST) || defined(INFO) + + handleCheckSelectInLoop(*setFDs, *readSet, *writeSet, *selectTs); + + #endif + + #ifdef TIME + + diffTs = diffTimestamp(lastTs, getNewTimestamp()); + + if (diffTs > 20) + { + *logofs << "Loop: TIME! Spent " << diffTs + << " Ms handling messages for proxy FD#" + << proxyFD << ".\n" << logofs_flush; + } + + lastTs = getNewTimestamp(); + + #endif + + #if defined(TEST) || defined(INFO) + + if (isTimestamp(*selectTs) == 0) + { + *logofs << "Loop: WARNING! Executing the select with requested " + << "timeout of " << selectTs -> tv_sec << " S and " + << (double) selectTs -> tv_usec / 1000 << " Ms.\n" + << logofs_flush; + } + else if (proxy != NULL && proxy -> getFlushable(proxyFD) > 0) + { + *logofs << "Loop: WARNING! Proxy FD#" << proxyFD + << " has " << proxy -> getFlushable(proxyFD) + << " bytes to write but timeout is " + << selectTs -> tv_sec << " S and " + << selectTs -> tv_usec / 1000 << " Ms.\n" + << logofs_flush; + } + + #endif + + // + // Wait for the selected sockets + // or the timeout. + // + + ESET(0); + + *resultFDs = select(*setFDs, readSet, writeSet, NULL, selectTs); + + *errorFDs = EGET(); + + #ifdef TIME + + diffTs = diffTimestamp(lastTs, getNewTimestamp()); + + if (diffTs > 100) + { + *logofs << "Loop: TIME! Spent " << diffTs + << " Ms waiting for new data for proxy FD#" + << proxyFD << ".\n" << logofs_flush; + } + + lastTs = getNewTimestamp(); + + #endif + + // + // Check the result of the select. + // + + #if defined(TEST) || defined(INFO) + + handleCheckResultInLoop(*resultFDs, *errorFDs, *setFDs, *readSet, *writeSet, *selectTs, startTs); + + #endif + + // + // Get time spent in select. The accouting is done + // in milliseconds. This is a real problem on fast + // machines where each loop is unlikely to take + // more than 500 us, so consider that the results + // can be inaccurate. + // + + nowTs = getNewTimestamp(); + + diffTs = diffTimestamp(startTs, nowTs); + + #ifdef TEST + *logofs << "Loop: Out of select after " << diffTs << " Ms " + << "at " << strMsTimestamp(nowTs) << " with result " + << *resultFDs << ".\n" << logofs_flush; + #endif + + startTs = nowTs; + + #ifdef DEBUG + *logofs << "Loop: New timestamp is " << strMsTimestamp(startTs) + << ".\n" << logofs_flush; + #endif + + if (control -> ProxyStage >= stage_operational) + { + statistics -> addIdleTime(diffTs); + } + + if (*resultFDs < 0) + { + // + // Check if the call was interrupted or if any of the + // managed descriptors has become invalid. This can + // happen to the X11 code, before the descriptor is + // removed from the managed set. + // + + #ifdef __sun + + if (*errorFDs == EINTR || *errorFDs == EBADF || + *errorFDs == EINVAL) + + #else + + if (*errorFDs == EINTR || *errorFDs == EBADF) + + #endif + + { + #ifdef TEST + + if (*errorFDs == EINTR) + { + *logofs << "Loop: Select failed due to EINTR error.\n" + << logofs_flush; + } + else + { + *logofs << "Loop: WARNING! Call to select failed. Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + } + + #endif + } + else + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to select failed. Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Call to select failed. Error is " + << EGET() << " '" << ESTR() << "'.\n"; + + HandleCleanup(); + } + } + + return 1; +} + +// +// Perform the required actions on all +// the descriptors having I/O pending. +// + +int NXTransExecute(int *resultFDs, int *errorFDs, int *setFDs, fd_set *readSet, + fd_set *writeSet, struct timeval *selectTs) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + // + // Control is NULL if the NX transport was + // reset or never created. If control is + // valid then prepare for jumping back in + // the case of an error. + // + + if (control == NULL || setjmp(context) == 1) + { + return 0; + } + + #if defined(TEST) || defined(INFO) + *logofs << "\nNXTransExecute: Going to execute I/O on the NX descriptors.\n" + << logofs_flush; + #endif + + if (control -> ProxyStage >= stage_operational) + { + // + // Check if I/O is possible on the proxy and + // local agent descriptors. + // + + if (agent != NULL) + { + handleAgentInLoop(*resultFDs, *errorFDs, *setFDs, *readSet, *writeSet, *selectTs); + } + + #ifdef TEST + *logofs << "Loop: Mark - 1 - at " << strMsTimestamp() + << " with " << diffTimestamp(startTs, getTimestamp()) + << " Ms elapsed.\n" << logofs_flush; + #endif + + // + // Rotate the channel that will be handled + // first. + // + + handleRotateInLoop(); + + // + // Flush any data on newly writable sockets. + // + + handleWritableInLoop(*resultFDs, *writeSet); + + #ifdef TEST + *logofs << "Loop: Mark - 2 - at " << strMsTimestamp() + << " with " << diffTimestamp(startTs, getTimestamp()) + << " Ms elapsed.\n" << logofs_flush; + #endif + + // + // Check if any socket has become readable. + // + + handleReadableInLoop(*resultFDs, *readSet); + + #ifdef TEST + *logofs << "Loop: Mark - 3 - at " << strMsTimestamp() + << " with " << diffTimestamp(startTs, getTimestamp()) + << " Ms elapsed.\n" << logofs_flush; + #endif + + // + // Handle the scheduled events on channels. + // + // - Restart, if possible, any client that was + // put to sleep. + // + // - Check if there are pointer motion events to + // flush. This applies only to X server side. + // + // - Check if any channel has exited the conges- + // tion state. + // + // - Check if there are images that are currently + // being streamed. + // + + handleEventsInLoop(); + + #ifdef TEST + *logofs << "Loop: Mark - 4 - at " << strMsTimestamp() + << " with " << diffTimestamp(startTs, getTimestamp()) + << " Ms elapsed.\n" << logofs_flush; + #endif + + // + // Check if user sent a signal to produce + // statistics. + // + + handleStatisticsInLoop(); + + // + // We may have flushed the proxy link or + // handled data coming from the remote. + // Post-process the masks and set the + // selected agent descriptors as ready. + // + + if (agent != NULL) + { + handleAgentLateInLoop(*resultFDs, *errorFDs, *setFDs, *readSet, *writeSet, *selectTs); + } + + #ifdef TEST + *logofs << "Loop: Mark - 5 - at " << strMsTimestamp() + << " with " << diffTimestamp(startTs, getTimestamp()) + << " Ms elapsed.\n" << logofs_flush; + #endif + + // + // Check if there is any data to flush. + // Agents should flush the proxy link + // explicitly. + // + + handleFlushInLoop(); + + #ifdef TEST + *logofs << "Loop: Mark - 6 - at " << strMsTimestamp() + << " with " << diffTimestamp(startTs, getTimestamp()) + << " Ms elapsed.\n" << logofs_flush; + #endif + } + + // + // Check if we have an alert to show. + // + + handleAlertInLoop(); + + if (control -> ProxyStage >= stage_operational) + { + // + // Check if it's time to give up. + // + + handleCheckSessionInLoop(); + + // + // Check if local proxy is consuming + // too many resources. + // + + handleCheckBitrateInLoop(); + + // + // Check coherency of internal state. + // + + #if defined(TEST) || defined(INFO) + + handleCheckStateInLoop(*setFDs); + + #endif + + #ifdef TEST + *logofs << "Loop: Mark - 7 - at " << strMsTimestamp() + << " with " << diffTimestamp(startTs, getTimestamp()) + << " Ms elapsed.\n" << logofs_flush; + #endif + } + + // + // Truncate the logs if needed. + // + + handleLogReopenInLoop(logsTs, nowTs); + + return 1; +} + +// +// Initialize the connection parameters and +// prepare for negotiating the link with the +// remote proxy. +// + +int InitBeforeNegotiation() +{ + // + // Disable limits on core dumps. + // + + SetCore(); + + // + // Install the signal handlers. + // + + InstallSignals(); + + // + // Track how much time we spent in initialization. + // + + nowTs = getNewTimestamp(); + + startTs = nowTs; + initTs = nowTs; + + #ifdef TEST + *logofs << "Loop: INIT! Taking mark for initialization at " + << strMsTimestamp(initTs) << ".\n" + << logofs_flush; + #endif + + // + // If not explicitly specified, determine if local + // mode is client or server according to parameters + // provided so far. + // + + if (WE_SET_PROXY_MODE == 0) + { + cerr << "Error" << ": Please specify either the -C or -S option.\n"; + + HandleCleanup(); + } + + // + // Start a watchdog. If initialization cannot + // be completed before timeout, then clean up + // everything and exit. + // + + if (control -> ProxyMode == proxy_client) + { + #ifdef TEST + *logofs << "Loop: Starting watchdog process with timeout of " + << control -> InitTimeout / 1000 << " seconds.\n" + << logofs_flush; + #endif + + lastWatchdog = NXTransWatchdog(control -> InitTimeout); + + if (IsFailed(lastWatchdog)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't start the NX watchdog process.\n" + << logofs_flush; + #endif + + SetNotRunning(lastWatchdog); + } + #ifdef TEST + else + { + *logofs << "Loop: Watchdog started with pid '" + << lastWatchdog << "'.\n" << logofs_flush; + } + #endif + } + + // + // Print preliminary info. + // + + PrintProcessInfo(); + + // + // Set cups, multimedia and other + // auxiliary ports. + // + + SetPorts(); + + // + // Increase the number of maximum open + // file descriptors for this process. + // + + SetDescriptors(); + + // + // Set local endianess. + // + + unsigned int test = 1; + + setHostBigEndian(*((unsigned char *) (&test)) == 0); + + #ifdef TEST + *logofs << "Loop: Local host is " + << (hostBigEndian() ? "big endian" : "little endian") + << ".\n" << logofs_flush; + #endif + + if (control -> ProxyMode == proxy_client) + { + // + // Listen on sockets that mimic an X display to + // which X clients will be able to connect (e.g. + // unix:8 and/or localhost:8). + // + + if (useTcpSocket == 1) + { + SetupTcpSocket(); + } + + if (useUnixSocket == 1) + { + SetupUnixSocket(); + } + } + else + { + // + // Don't listen for X connections. + // + + useUnixSocket = 0; + useTcpSocket = 0; + useAgentSocket = 0; + + // + // Get ready to open the local display. + // + + SetupDisplaySocket(xServerAddrFamily, xServerAddr, xServerAddrLength); + } + + // + // If we are the NX server-side proxy we need to + // complete our initializazion. We will mandate + // our parameters at the time the NX client will + // connect. + // + + if (control -> ProxyMode == proxy_client) + { + SetParameters(); + } + + return 1; +} + +int SetupProxyConnection() +{ + + if (proxyFD == -1) + { + + char *socketUri = NULL; + + // Let's make sure, the default value for listenSocket is properly set. Doing this + // here, because we have to make sure that we call it after the connectSocket + // declaration is really really complete. + + if (listenSocket.disabled() && connectSocket.disabled()) + { + char listenPortValue[20] = { 0 }; + sprintf(listenPortValue, "%ld", (long)(proxyPort + DEFAULT_NX_PROXY_PORT_OFFSET)); + + SetAndValidateChannelEndPointArg("local", "listen", listenPortValue, listenSocket); + } + + #ifdef TEST + connectSocket.getSpec(&socketUri); + *logofs << "Loop: connectSocket is "<< ( connectSocket.enabled() ? "enabled" : "disabled") << ". " + << "The socket URI is '"<< ( socketUri != NULL ? socketUri : "") << "'.\n" << logofs_flush; + listenSocket.getSpec(&socketUri); + *logofs << "Loop: listenSocket is "<< ( listenSocket.enabled() ? "enabled" : "disabled") << ". " + << "The socket URI is '"<< ( socketUri != NULL ? socketUri : "") << "'.\n" << logofs_flush; + free(socketUri); + socketUri = NULL; + #endif + + if (WE_INITIATE_CONNECTION) + { + if (connectSocket.getSpec(&socketUri)) + { + #ifdef TEST + *logofs << "Loop: Going to connect to '" << socketUri + << "'.\n" << logofs_flush; + #endif + free(socketUri); + + proxyFD = ConnectToRemote(connectSocket); + + #ifdef TEST + *logofs << "Loop: Connected to remote proxy on FD#" + << proxyFD << ".\n" << logofs_flush; + #endif + + cerr << "Info" << ": Connected to remote proxy on FD#" + << proxyFD << ".\n"; + } + } + else + { + + if (listenSocket.isTCPSocket() && (listenSocket.getTCPPort() < 0)) + { + listenSocket.setSpec(DEFAULT_NX_PROXY_PORT_OFFSET + proxyPort); + } + + if (listenSocket.getSpec(&socketUri)) + { + #ifdef TEST + *logofs << "Loop: Going to wait for connection at '" + << socketUri << "'.\n" << logofs_flush; + #endif + free(socketUri); + + proxyFD = WaitForRemote(listenSocket); + + #ifdef TEST + if (WE_LISTEN_FORWARDER) + { + *logofs << "Loop: Connected to remote forwarder on FD#" + << proxyFD << ".\n" << logofs_flush; + } + else + { + *logofs << "Loop: Connected to remote proxy on FD#" + << proxyFD << ".\n" << logofs_flush; + } + #endif + + } + } + } + #ifdef TEST + else + { + *logofs << "Loop: Using the inherited connection on FD#" + << proxyFD << ".\n" << logofs_flush; + } + #endif + + // + // Set TCP_NODELAY on proxy descriptor + // to reduce startup time. Option will + // later be disabled if needed. + // + // either listenSocket or connectSocket is used here... + + if(listenSocket.isTCPSocket() || connectSocket.isTCPSocket()) + + SetNoDelay(proxyFD, 1); + + // + // We need non-blocking input since the + // negotiation phase. + // + + SetNonBlocking(proxyFD, 1); + + return 1; +} + +// +// Create the required proxy and channel classes +// and get ready for handling the encoded traffic. +// + +int InitAfterNegotiation() +{ + #ifdef TEST + *logofs << "Loop: Connection with remote proxy completed.\n" + << logofs_flush; + #endif + + cerr << "Info" << ": Connection with remote proxy completed.\n" + << logofs_flush; + + // + // If we are the server proxy we completed + // our initializazion phase according to + // the values provided by the client side. + // + + if (control -> ProxyMode == proxy_server) + { + SetParameters(); + } + + // + // Set up the listeners for the additional + // services. + // + + SetupServiceSockets(); + + // + // Create the proxy class and the statistics + // repository and pass all the configuration + // data we negotiated with the remote peer. + // + + SetupProxyInstance(); + + // + // We completed both parsing of user's parameters + // and handlshaking with remote proxy. Now print + // a brief summary including the most significant + // control values. + // + + PrintConnectionInfo(); + + // + // Cancel the initialization watchdog. + // + + if (IsRunning(lastWatchdog)) + { + KillProcess(lastWatchdog, "watchdog", SIGTERM, 1); + + SetNotRunning(lastWatchdog); + + lastSignal = 0; + } + + // + // Start the house-keeper process. It will + // remove the oldest persistent caches, if + // the amount of storage exceed the limits + // set by the user. + // + + StartKeeper(); + + // + // Set the log size check timestamp. + // + + nowTs = getNewTimestamp(); + + logsTs = nowTs; + + // + // TODO: Due to the way the new NX transport is working, + // the accounting of time spent handling messages must + // be rewritten. In particular, at the moment it only + // shows the time spent encoding and decoding messages + // in the main loop, after executing a select. It doesn't + // take into account the time spent in the NXTrans* calls + // where messages can be encoded and decoded implicitly, + // on demand of the agent. When the agent transport is + // in use, these calls constitute the vast majority of + // the encoding activity. The result is that the number + // of KB encoded per second shown by the proxy statistics + // is actually much lower than the real throughput gene- + // rated by the proxy. + // + + #ifdef TEST + *logofs << "Loop: INIT! Completed initialization at " + << strMsTimestamp(nowTs) << " with " + << diffTimestamp(initTs, nowTs) << " Ms " + << "since the init mark.\n" << logofs_flush; + #endif + + initTs = getNewTimestamp(); + + // + // We can now start handling binary data from + // our peer proxy. + // + + if (agent == NULL) + { + cerr << "Session" << ": Session started at '" + << strTimestamp() << "'.\n"; + } + + return 1; +} + +int SetMode(int mode) +{ + // + // Set the local proxy mode. + // + + if (control -> ProxyMode == proxy_undefined) + { + if (mode == NX_MODE_CLIENT) + { + #ifdef TEST + *logofs << "Loop: INIT! Initializing with mode " + << "NX_MODE_CLIENT at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + control -> ProxyMode = proxy_client; + } + else if (mode == NX_MODE_SERVER) + { + #ifdef TEST + *logofs << "Loop: INIT! Initializing with mode " + << "NX_MODE_SERVER at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + control -> ProxyMode = proxy_server; + } + else + { + cerr << "Error" << ": Please specify either " + << "the -C or -S option.\n"; + + HandleCleanup(); + } + } + + return 1; +} + +int SetupProxyInstance() +{ + if (control -> ProxyMode == proxy_client) + { + proxy = new ClientProxy(proxyFD); + } + else + { + proxy = new ServerProxy(proxyFD); + } + + if (proxy == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error creating the NX proxy.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error creating the NX proxy.\n"; + + HandleCleanup(); + } + + // + // Create the statistics repository. + // + + statistics = new Statistics(proxy); + + if (statistics == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error creating the NX statistics.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error creating the NX statistics.\n"; + + HandleCleanup(); + } + + // + // If user gave us a proxy cookie than create the + // X11 authorization repository and find the real + // cookie to be used for our X display. + // + + SetupAuthInstance(); + + // + // Reset the static members in channels. + // + + proxy -> handleChannelConfiguration(); + + // + // Inform the proxies about the ports where they + // will have to forward the network connections. + // + + proxy -> handleDisplayConfiguration(displayHost, xServerAddrFamily, + xServerAddr, xServerAddrLength); + + proxy -> handlePortConfiguration(cupsPort, smbPort, mediaPort, + httpPort, fontPort); + + // + // We handed over the sockaddr structure we + // created when we set up the display socket + // to the proxy. + // + + xServerAddr = NULL; + + // + // Set socket options on proxy link, then propagate link + // configuration to proxy. This includes translating some + // control parameters in 'local' and 'remote'. Finally + // adjust cache parameters according to pack method and + // session type selected by user. + // + + if (proxy -> handleSocketConfiguration() < 0 || + proxy -> handleLinkConfiguration() < 0 || + proxy -> handleCacheConfiguration() < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error configuring the NX transport.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error configuring the NX transport.\n"; + + HandleCleanup(); + } + + // + // Load the message stores from the persistent + // cache. + // + + proxy -> handleLoad(load_if_first); + + // + // Inform the proxy that from now on it can + // start handling the encoded data. + // + + proxy -> setOperational(); + + // + // Are we going to use an internal IPC connection + // with an agent? In this case create the channel + // by using the socket descriptor provided by the + // caller at the proxy initialization. + // + + SetupAgentInstance(); + + // + // Check if we need to verify the existence of + // a matching client cache at shutdown. + // + + #ifdef MATCH + + control -> PersistentCacheCheckOnShutdown = 1; + + #endif + + // + // Flush any data produced so far. + // + + proxy -> handleFlush(); + + #if defined(TEST) || defined(INFO) + + if (proxy -> getFlushable(proxyFD) > 0) + { + *logofs << "Loop: WARNING! Proxy FD#" << proxyFD << " has data " + << "to flush after setup of the NX transport.\n" + << logofs_flush; + } + + #endif + + return 1; +} + +int SetupAuthInstance() +{ + // + // If user gave us a proxy cookie, then create the + // X11 authorization repository and find the real + // cookie to be used for our X display. + // + + if (control -> ProxyMode == proxy_server) + { + if (authCookie != NULL && *authCookie != '\0') + { + if (useLaunchdSocket == 1) + { + // + // If we are going to retrieve the X11 autho- + // rization through the launchd service, make + // a connection to its socket to trigger the + // X server starting. + // + + sockaddr_un launchdAddrUnix; + + unsigned int launchdAddrLength = sizeof(sockaddr_un); + + int launchdAddrFamily = AF_UNIX; + + launchdAddrUnix.sun_family = AF_UNIX; + + const int launchdAddrNameLength = 108; + + int success = -1; + + strncpy(launchdAddrUnix.sun_path, displayHost, launchdAddrNameLength); + + *(launchdAddrUnix.sun_path + launchdAddrNameLength - 1) = '\0'; + + #ifdef TEST + *logofs << "Loop: Connecting to launchd service " + << "on Unix port '" << displayHost << "'.\n" << logofs_flush; + #endif + + int launchdFd = socket(launchdAddrFamily, SOCK_STREAM, PF_UNSPEC); + + if (launchdFd < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to socket failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + } + else if ((success = connect(launchdFd, (sockaddr *) &launchdAddrUnix, launchdAddrLength)) < 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Connection to launchd service " + << "on Unix port '" << displayHost << "' failed " + << "with error " << EGET() << ", '" << ESTR() << "'.\n" + << logofs_flush; + #endif + } + + if (launchdFd >= 0) + { + close(launchdFd); + } + + // + // The real cookie will not be available + // until the X server starts. Query for the + // cookie in a loop, unless the connection + // to the launchd service failed. + // + + int attempts = (success < 0 ? 1 : 10); + + for (int i = 0; i < attempts; i++) + { + delete auth; + + auth = new Auth(displayHost, authCookie); + + if (auth != NULL && auth -> isFake() == 1) + { + usleep(200000); + + continue; + } + + break; + } + } + else + { + auth = new Auth(displayHost, authCookie); + } + + if (auth == NULL || auth -> isValid() != 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error creating the X authorization.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error creating the X authorization.\n"; + + HandleCleanup(); + } + else if (auth -> isFake() == 1) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Could not retrieve the X server " + << "authentication cookie.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Failed to read data from the X " + << "auth command.\n"; + + cerr << "Warning" << ": Generated a fake cookie for X " + << "authentication.\n"; + } + } + else + { + #ifdef TEST + *logofs << "Loop: No proxy cookie was provided for " + << "authentication.\n" << logofs_flush; + #endif + + cerr << "Info" << ": No proxy cookie was provided for " + << "authentication.\n"; + + #ifdef TEST + *logofs << "Loop: Forwarding the real X authorization " + << "cookie.\n" << logofs_flush; + #endif + + cerr << "Info" << ": Forwarding the real X authorization " + << "cookie.\n"; + } + } + + return 1; +} + +int SetupAgentInstance() +{ + if (control -> ProxyMode == proxy_client && + useAgentSocket == 1) + { + // + // This will temporarily disable signals to safely + // load the cache, then will send a control packet + // to the remote end, telling that cache has to be + // loaded, so it's important that proxy is already + // set in operational state. + // + + int result; + + if (agent != NULL) + { + result = proxy -> handleNewAgentConnection(agent); + } + else + { + result = proxy -> handleNewConnection(channel_x11, agentFD[1]); + } + + if (result < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error creating the NX agent connection.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error creating the NX agent connection.\n"; + + HandleCleanup(); + } + } + + return 1; +} + +int SetupTcpSocket() +{ + // + // Open TCP socket emulating local display. + // + + return ListenConnectionTCP((loopbackBind ? "localhost" : "*"), X_TCP_PORT + proxyPort, "X11"); +} + +int SetupUnixSocket() +{ + // + // Open UNIX domain socket for display. + // + + if (!control->TempPath) { + #ifdef PANIC + *logofs << "Loop: PANIC! Temporal path is null.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Temporal path is null.\n"; + HandleCleanup(); + } + + unsigned int required = snprintf(unixSocketName, DEFAULT_STRING_LENGTH, "%s/.X11-unix", control->TempPath); + if (required < sizeof(unixSocketName)) { + + // No need to execute the following actions conditionally + mkdir(unixSocketName, (0777 | S_ISVTX)); + chmod(unixSocketName, (0777 | S_ISVTX)); + + required = snprintf(unixSocketName, DEFAULT_STRING_LENGTH, "%s/.X11-unix/X%d", control->TempPath, proxyPort); + if (required < sizeof(unixSocketName)) { + + unixFD = ListenConnectionUnix(unixSocketName, "x11"); + if (unixFD >= 0) + chmod(unixSocketName, 0777); + return unixFD; + } + } + + unixSocketName[0] = '\0'; // Just in case! + + #ifdef PANIC + *logofs << "Loop: PANIC! path for unix socket is too long.\n" << logofs_flush; + #endif + + cerr << "Error" << ": path for Unix socket is too long.\n"; + HandleCleanup(); +} + +// +// The following is a dumb copy-paste. The +// nxcompsh library should offer a better +// implementation. +// + +int SetupDisplaySocket(int &xServerAddrFamily, sockaddr *&xServerAddr, + unsigned int &xServerAddrLength) +{ + xServerAddrFamily = AF_INET; + xServerAddr = NULL; + xServerAddrLength = 0; + + char *display; + + if (*displayHost == '\0') + { + // + // Assume DISPLAY as the X server to which + // we will forward the proxied connections. + // This means that NX parameters have been + // passed through other means. + // + + display = getenv("DISPLAY"); + + if (display == NULL || *display == '\0') + { + #ifdef PANIC + *logofs << "Loop: PANIC! Host X server DISPLAY is not set.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Host X server DISPLAY is not set.\n"; + + HandleCleanup(); + } + else if (strncasecmp(display, "nx/nx,", 6) == 0 || + strncasecmp(display, "nx,", 3) == 0 || + strncasecmp(display, "nx/nx:", 6) == 0 || + strncasecmp(display, "nx:", 3) == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! NX transport on host X server '" + << display << "' not supported.\n" << logofs_flush; + #endif + + cerr << "Error" << ": NX transport on host X server '" + << display << "' not supported.\n"; + + cerr << "Error" << ": Please run the local proxy specifying " + << "the host X server to connect to.\n"; + + HandleCleanup(); + } + else if (strlen(display) >= DEFAULT_STRING_LENGTH) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Host X server DISPLAY cannot exceed " + << DEFAULT_STRING_LENGTH << " characters.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Host X server DISPLAY cannot exceed " + << DEFAULT_STRING_LENGTH << " characters.\n"; + + HandleCleanup(); + } + + strcpy(displayHost, display); + } + + display = new char[strlen(displayHost) + 1]; + + if (display == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Out of memory handling DISPLAY variable.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Out of memory handling DISPLAY variable.\n"; + + HandleCleanup(); + } + + strcpy(display, displayHost); + + #ifdef __APPLE__ + + if ((strncasecmp(display, "/tmp/launch", 11) == 0) || (strncasecmp(display, "/private/tmp/com.apple.launchd", 30) == 0)) + { + #ifdef TEST + *logofs << "Loop: Using launchd service on socket '" + << display << "'.\n" << logofs_flush; + #endif + + useLaunchdSocket = 1; + } + + #endif + + char *separator = strrchr(display, ':'); + + if ((separator == NULL) || !isdigit(*(separator + 1))) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid display '" << display << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid display '" << display << "'.\n"; + + HandleCleanup(); + } + + *separator = '\0'; + + xPort = atoi(separator + 1); + + #ifdef TEST + *logofs << "Loop: Using local X display '" << displayHost + << "' with host '" << display << "' and port '" + << xPort << "'.\n" << logofs_flush; + #endif + + #ifdef __APPLE__ + + if (separator == display || strcmp(display, "unix") == 0 || + useLaunchdSocket == 1) + + #else + + if (separator == display || strcmp(display, "unix") == 0) + + #endif + { + // + // UNIX domain port. + // + + #ifdef TEST + *logofs << "Loop: Using real X server on UNIX domain socket.\n" + << logofs_flush; + #endif + + sockaddr_un *xServerAddrUNIX = new sockaddr_un; + + xServerAddrFamily = AF_UNIX; + xServerAddrUNIX -> sun_family = AF_UNIX; + + // + // The scope of this function is to fill either the sockaddr_un + // (when the display is set to the Unix Domain socket) or the + // sockaddr_in structure (when connecting by TCP) only once, so + // that the structure will be later used at the time the server + // proxy will try to forward the connection to the X server. We + // don't need to verify that the socket does exist at the pre- + // sent moment. The method that forwards the connection will + // perform the required checks and will retry, if needed. Anyway + // we need to select the name of the socket, so we check if the + // well-known directory exists and take that as an indication of + // where the socket will be created. + // + + // Try abstract X11 socket first (via a test connect), if that fails + // fall back to Unix domain socket file. + + #ifdef __linux__ + int testSocketFD; + testSocketFD = socket(xServerAddrFamily, SOCK_STREAM, PF_UNSPEC); + + int len = sprintf(unixSocketName + 1, "/tmp/.X11-unix/X%d", xPort); + unixSocketName[0] = '\0'; + + sockaddr_un *xServerAddrABSTRACT = new sockaddr_un; + memset(xServerAddrABSTRACT, 0, xServerAddrLength); + xServerAddrABSTRACT -> sun_family = AF_UNIX; + memcpy(xServerAddrABSTRACT -> sun_path, unixSocketName, len+1); + xServerAddrLength = len +3; + + int ret = connect(testSocketFD, (struct sockaddr *) xServerAddrABSTRACT, xServerAddrLength); + if (ret == 0) { + + cerr << "Info" << ": Using abstract X11 socket in kernel namespace " + << "for accessing DISPLAY=:" << xPort << ".\n"; + + close(testSocketFD); + xServerAddr = (sockaddr *) xServerAddrABSTRACT; + return 1; + + } else { + + cerr << "Info" << ": Falling back to file system X11 socket " + << "for accessing DISPLAY=:" << xPort << ".\n"; + + #endif + + struct stat statInfo; + + char unixSocketDir[DEFAULT_STRING_LENGTH]; + + snprintf(unixSocketDir, DEFAULT_STRING_LENGTH - 1, "%s/.X11-unix", + control -> TempPath); + + #ifdef __APPLE__ + + if (useLaunchdSocket == 1) + { + char *slash = rindex(display, '/'); + + if (slash != NULL) + { + *slash = '\0'; + } + + snprintf(unixSocketDir, DEFAULT_STRING_LENGTH - 1, "%s", display); + } + + #endif + + *(unixSocketDir + DEFAULT_STRING_LENGTH - 1) = '\0'; + + #ifdef TEST + *logofs << "Loop: Assuming X socket in directory '" + << unixSocketDir << "'.\n" << logofs_flush; + #endif + + if (stat(unixSocketDir, &statInfo) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't determine the location of " + << "the X display socket.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't determine the location of " + << "the X display socket.\n"; + + #ifdef PANIC + *logofs << "Loop: PANIC! Error " << EGET() << " '" << ESTR() + << "' checking '" << unixSocketDir << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error " << EGET() << " '" << ESTR() + << "' checking '" << unixSocketDir << "'.\n"; + + HandleCleanup(); + } + + sprintf(unixSocketName, "%s/X%d", unixSocketDir, xPort); + + #ifdef __APPLE__ + + if (useLaunchdSocket == 1) + { + strncpy(unixSocketName, displayHost, DEFAULT_STRING_LENGTH - 1); + } + + #endif + + #ifdef TEST + *logofs << "Loop: Assuming X socket name '" << unixSocketName + << "'.\n" << logofs_flush; + #endif + + strcpy(xServerAddrUNIX -> sun_path, unixSocketName); + + xServerAddr = (sockaddr *) xServerAddrUNIX; + xServerAddrLength = sizeof(sockaddr_un); + + #ifdef __linux__ + + } + #endif + } + else + { + // + // TCP port. + // + + #ifdef TEST + *logofs << "Loop: Using real X server on TCP port.\n" + << logofs_flush; + #endif + + xServerAddrFamily = AF_INET; + + int xServerIPAddr = GetHostAddress(display); + + if (xServerIPAddr == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Unknown display host '" << display + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unknown display host '" << display + << "'.\n"; + + HandleCleanup(); + } + + sockaddr_in *xServerAddrTCP = new sockaddr_in; + + xServerAddrTCP -> sin_family = AF_INET; + xServerAddrTCP -> sin_port = htons(X_TCP_PORT + xPort); + xServerAddrTCP -> sin_addr.s_addr = xServerIPAddr; + + xServerAddr = (sockaddr *) xServerAddrTCP; + xServerAddrLength = sizeof(sockaddr_in); + } + + delete [] display; + + return 1; +} + +int SetupServiceSockets() +{ + if (control -> ProxyMode == proxy_client) + { + if (useCupsSocket) + { + if ((cupsFD = ListenConnection(cupsPort, "CUPS")) < 0) + { + useCupsSocket = 0; + } + } + + if (useAuxSocket) + { + if ((auxFD = ListenConnection(auxPort, "auxiliary X11")) < 0) + { + useAuxSocket = 0; + } + } + + if (useSmbSocket) + { + if ((smbFD = ListenConnection(smbPort, "SMB")) < 0) + { + useSmbSocket = 0; + } + } + + if (useMediaSocket) + { + if ((mediaFD = ListenConnection(mediaPort, "media")) < 0) + { + useMediaSocket = 0; + } + } + + if (useHttpSocket) + { + if ((httpFD = ListenConnection(httpPort, "http")) < 0) + { + useHttpSocket = 0; + } + } + + useFontSocket = 0; + } + else + { + // + // Get ready to listen for the font server connections + // + + if (useFontSocket) + { + // Since ProtoStep7 (#issue 108) + int port = atoi(fontPort); + + if ((fontFD = ListenConnectionTCP("localhost", port, "font")) < 0) + { + useFontSocket = 0; + } + } + + useCupsSocket = 0; + useAuxSocket = 0; + useSmbSocket = 0; + useMediaSocket = 0; + useHttpSocket = 0; + } + + // + // Slave channels can be originated + // by both sides. + // + + if (useSlaveSocket) + { + // Since ProtoStep7 (#issue 108) + if ((slaveFD = ListenConnection(slavePort, "slave")) < 0) + { + useSlaveSocket = 0; + } + } + + return 1; +} + +int ListenConnectionAny(sockaddr *addr, socklen_t addrlen, const char *label) +{ + int newFD = socket(addr->sa_family, SOCK_STREAM, PF_UNSPEC); + + if (newFD == -1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to socket failed for " << label + << " socket. Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to socket failed for " << label + << " socket. Error is " << EGET() << " '" + << ESTR() << "'.\n"; + + goto SetupSocketError; + } + + if (addr->sa_family == AF_INET) + if (SetReuseAddress(newFD) < 0) + { + // SetReuseAddress already warns with an error + goto SetupSocketError; + } + + if (bind(newFD, addr, addrlen) == -1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to bind failed for " << label + << ". Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to bind failed for " << label + << ". Error is " << EGET() + << " '" << ESTR() << "'.\n"; + goto SetupSocketError; + } + + if (listen(newFD, 8) == -1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to listen failed for " << label + << ". Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to listen failed for " << label + << ". Error is " << EGET() + << " '" << ESTR() << "'.\n"; + + goto SetupSocketError; + } + + return newFD; + +SetupSocketError: + + if (newFD != -1) + { + close(newFD); + } + + // + // May optionally return. The session would + // continue without the service. The problem + // with this approach is that it would make + // harder to track problems with allocation + // of ports in clients and server. + // + + HandleCleanup(); + return -1; +} + +int ListenConnectionUnix(const char *path, const char *label) +{ + + sockaddr_un unixAddr; + unixAddr.sun_family = AF_UNIX; +#ifdef UNIX_PATH_MAX + if (strlen(path) >= UNIX_PATH_MAX) +#else + if (strlen(path) >= sizeof(unixAddr.sun_path)) +#endif + { + #ifdef PANIC + *logofs << "Loop: PANIC! Socket path \"" << path << "\" for " + << label << " is too long.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Socket path \"" << path << "\" for " + << label << " is too long.\n"; + + HandleCleanup(); + return -1; + } + + strcpy(unixAddr.sun_path, path); + return ListenConnectionAny((sockaddr *)&unixAddr, sizeof(unixAddr), label); +} + +int ListenConnectionTCP(const char *host, long port, const char *label) +{ + sockaddr_in tcpAddr; + tcpAddr.sin_family = AF_INET; + tcpAddr.sin_port = htons(port); + + if (loopbackBind || + !host || + !strcmp(host, "") || + !strcmp(host, "localhost")) { + tcpAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + } + else if(strcmp(host, "*") == 0) { + tcpAddr.sin_addr.s_addr = htonl(INADDR_ANY); + } + else { + int ip = tcpAddr.sin_addr.s_addr = GetHostAddress(host); + if (ip == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Unknown " << label << " host '" << host + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unknown " << label << " host '" << host + << "'.\n"; + + HandleCleanup(); + return -1; + } + } + + return ListenConnectionAny((sockaddr *)&tcpAddr, sizeof(tcpAddr), label); +} + +int ListenConnection(ChannelEndPoint &endpoint, const char *label) +{ + char *unixPath, *host; + long port; + if (endpoint.getUnixPath(&unixPath)) { + return ListenConnectionUnix(unixPath, label); + } + else if (endpoint.getTCPHostAndPort(&host, &port)) { + return ListenConnectionTCP(host, port, label); + } + return -1; +} + +static int AcceptConnection(int fd, int domain, const char *label) +{ + struct sockaddr newAddr; + + socklen_t addrLen = sizeof(newAddr); + + #ifdef TEST + + if (domain == AF_UNIX) + { + *logofs << "Loop: Going to accept new Unix " << label + << " connection on FD#" << fd << ".\n" + << logofs_flush; + } + else + { + *logofs << "Loop: Going to accept new TCP " << label + << " connection on FD#" << fd << ".\n" + << logofs_flush; + } + + #endif + + int newFD = accept(fd, &newAddr, &addrLen); + + if (newFD < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to accept failed for " + << label << " connection. Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to accept failed for " + << label << " connection. Error is " << EGET() + << " '" << ESTR() << "'.\n"; + } + + return newFD; +} + +void HandleShutdown() +{ + if (proxy -> getShutdown() == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! No shutdown of proxy link " + << "performed by remote proxy.\n" + << logofs_flush; + #endif + + // + // Close the socket before showing the alert. + // It seems that the closure of the socket can + // sometimes take several seconds, even after + // the connection is broken. The result is that + // the dialog can be shown long after the user + // has gone after the failed session. Note that + // disabling the linger timeout does not seem + // to make any difference. + // + + CleanupSockets(); + + cerr << "Error" << ": Connection with remote peer broken.\n"; + + #ifdef TEST + *logofs << "Loop: Bytes received so far are " + << (unsigned long long) statistics -> getBytesIn() + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Please check the state of your " + << "network and retry.\n"; + + handleTerminatingInLoop(); + + if (control -> ProxyMode == proxy_server) + { + #ifdef TEST + *logofs << "Loop: Showing the proxy abort dialog.\n" + << logofs_flush; + #endif + + HandleAlert(ABORT_PROXY_CONNECTION_ALERT, 1); + + handleAlertInLoop(); + } + } + #ifdef TEST + else + { + *logofs << "Loop: Finalized the remote proxy shutdown.\n" + << logofs_flush; + } + #endif + + HandleCleanup(); +} + + +void WaitCleanup() +{ + T_timestamp selectTs; + + while (NXTransRunning(NX_FD_ANY)) + { + setTimestamp(selectTs, control -> PingTimeout); + + NXTransContinue(&selectTs); + } +} + +int KillProcess(int pid, const char *label, int signal, int wait) +{ + if (pid > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Killing the " << label << " process '" + << pid << "' from process with pid '" << getpid() + << "' with signal '" << DumpSignal(signal) + << "'.\n" << logofs_flush; + #endif + + signal = (signal == 0 ? SIGTERM : signal); + + if (kill(pid, signal) < 0 && EGET() != ESRCH) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Couldn't kill the " << label + << " process with pid '" << pid << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Couldn't kill the " << label + << " process with pid '" << pid << "'.\n"; + } + + if (wait == 1) + { + WaitChild(pid, label, 1); + } + + return 1; + } + else + { + #ifdef TEST + *logofs << "Loop: No " << label << " process " + << "to kill with pid '" << pid + << "'.\n" << logofs_flush; + #endif + + return 0; + } +} + +int CheckProcess(int pid, const char *label) +{ + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Checking the " << label << " process '" + << pid << "' from process with pid '" << getpid() + << "'.\n" << logofs_flush; + #endif + + if (kill(pid, SIGCONT) < 0 && EGET() == ESRCH) + { + #ifdef WARNING + *logofs << "Loop: WARNING! The " << label << " process " + << "with pid '" << pid << "' has exited.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": The " << label << " process " + << "with pid '" << pid << "' has exited.\n"; + + return 0; + } + + return 1; +} + +int StartKeeper() +{ + #if defined(TEST) || defined(INFO) + + if (IsRunning(lastKeeper) == 1 || + IsRestarting(lastKeeper) == 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! The house-keeping process is " + << "alreay running with pid '" << lastKeeper + << "'.\n" << logofs_flush; + #endif + + HandleCleanup(); + } + + #endif + + // + // Don't care harvesting the persistent caches if + // the memory cache is not enabled. If the memory + // cache is not enabled neither we produced per- + // sistent caches. The user can still delete any + // persistent cache produced by the previous runs + // by using the client GUI. + // + // TODO: At the moment the user doesn't have a way + // to specify the amount of disk space to use for + // the persistent caches, but only the amount of + // space to use for images. + // + + if (control -> LocalTotalStorageSize > 0) + { + #ifdef TEST + *logofs << "Loop: Starting the house-keeping process with " + << "storage size " << control -> PersistentCacheDiskLimit + << ".\n" << logofs_flush; + #endif + + lastKeeper = NXTransKeeper(control -> PersistentCacheDiskLimit, + 0, control -> RootPath); + + if (IsFailed(lastKeeper)) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Failed to start the NX keeper process.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Failed to start the NX keeper process.\n"; + + SetNotRunning(lastKeeper); + } + #ifdef TEST + else + { + *logofs << "Loop: Keeper started with pid '" + << lastKeeper << "'.\n" << logofs_flush; + } + #endif + } + #ifdef TEST + else + { + *logofs << "Loop: Nothing to do for the keeper process " + << "with persistent cache not enabled.\n" + << logofs_flush; + } + #endif + + return 1; +} + +void HandleCleanupForReconnect() +{ + #ifdef TEST + *logofs << "Loop: Going to clean up system resources for Reconnect " + << "in process '" << getpid() << "'.\n" + << logofs_flush; + #endif + handleTerminatedInLoop(); + DisableSignals(); + if (control) + CleanupChildren(); + CleanupListeners(); + CleanupSockets(); + CleanupKeeper(); + CleanupStreams(); + CleanupLocal(); + CleanupGlobal(); + RestoreSignals(); + ServerCache::lastInitReply.set(0,NULL); + ServerCache::lastKeymap.set(0,NULL); + ServerCache::getKeyboardMappingLastMap.set(0,NULL); +} +void HandleCleanup(int code) +{ + #ifdef TEST + *logofs << "Loop: Going to clean up system resources " + << "in process '" << getpid() << "'.\n" + << logofs_flush; + #endif + + handleTerminatedInLoop(); + + // + // Suspend any signal while cleaning up. + // + + DisableSignals(); + + if (getpid() == lastProxy) + { + // + // Terminate all the children. + // + + CleanupChildren(); + + // + // Close all listeners. + // + + CleanupListeners(); + + // + // Close all sockets. + // + + CleanupSockets(); + + // + // Release the global objects. + // + + CleanupGlobal(); + + // + // Restore the original signal handlers. + // + + RestoreSignals(); + } + + // + // This is our last chance to print a message. If this + // is the process which created the transport we will + // jump back into the loop, letting the caller find out + // that the connection is broken, otherwise we assume + // that this is a child of the proxy and so we will + // safely exit. + // + + #ifdef TEST + + if (getpid() == lastProxy) + { + *logofs << "Loop: Reverting to loop context in process with " + << "pid '" << getpid() << "' at " << strMsTimestamp() + << ".\n" << logofs_flush; + } + else + { + *logofs << "Loop: Exiting from child process with pid '" + << getpid() << "' at " << strMsTimestamp() + << ".\n" << logofs_flush; + } + + #endif + + if (getpid() == lastProxy) + { + // + // Reset all values to their default. + // + + CleanupLocal(); + + CleanupStreams(); + + longjmp(context, 1); + } + else + { + // + // Give a last chance to the process + // to cleanup the ancillary classes. + // + + CleanupKeeper(); + + CleanupStreams(); + + exit(code); + } +} + +void CleanupKeeper() +{ + if (keeper != NULL) + { + #ifdef TEST + *logofs << "Loop: Freeing up keeper in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + delete keeper; + + keeper = NULL; + } +} + +void CleanupStreams() +{ + // + // TODO: The cleanup procedure skips deletion of + // the I/O streams under Windows. This is intended + // to avoid a strange segfault occurring randomly, + // at the time the proxy is being shut down. + // + + #ifndef __CYGWIN32__ + + #ifdef TEST + *logofs << "Loop: Freeing up streams in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + if (logofs != NULL && logofs != &cerr && + *errorsFileName != '\0') + { + *logofs << flush; + + delete logofs; + + // + // Let the log go again to the standard + // error. + // + + logofs = &cerr; + } + + if (statofs != NULL && statofs != &cerr && + *statsFileName != '\0') + { + *statofs << flush; + + delete statofs; + + statofs = NULL; + } + + if (errofs != NULL) + { + *errofs << flush; + + if (errofs == &cerr) + { + errofs = NULL; + } + else if (errsbuf != NULL) + { + cerr.rdbuf(errsbuf); + + errsbuf = NULL; + + delete errofs; + } + + errofs = NULL; + } + + #endif /* #ifndef __CYGWIN32__ */ + + // + // Reset these as they can't be reset + // in CleanupLocal(). + // + + *sessionFileName = '\0'; + *errorsFileName = '\0'; + *optionsFileName = '\0'; + *statsFileName = '\0'; +} + +void CleanupChildren() +{ + // + // Remove any watchdog. + // + + if (IsRunning(lastWatchdog)) + { + KillProcess(lastWatchdog, "watchdog", SIGTERM, 1); + + SetNotRunning(lastWatchdog); + + lastSignal = 0; + } + + // + // Kill the cache house-keeping process. + // + + if (IsRunning(lastKeeper)) + { + KillProcess(lastKeeper, "house-keeping", SIGTERM, 1); + + SetNotRunning(lastKeeper); + } + + // + // Let any running dialog to continue until it is + // closed by the user. In general this is the exp- + // ected behaviour, as for example when we are + // exiting because the link was abrouptedly shut + // down. + // + + if (IsRunning(lastDialog)) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: WARNING! Leaving the dialog process '" + << lastDialog << "' running in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + SetNotRunning(lastDialog); + } + + // + // Give user a chance to start a new session. + // + + if (control -> EnableRestartOnShutdown == 1) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Respawning the NX client " + << "on display '" << displayHost << "'.\n" + << logofs_flush; + #endif + + NXTransClient(displayHost); + } + + for (int i = 0; i < control -> KillDaemonOnShutdownNumber; i++) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Killing the NX daemon with " + << "pid '" << control -> KillDaemonOnShutdown[i] + << "'.\n" << logofs_flush; + #endif + + KillProcess(control -> KillDaemonOnShutdown[i], "daemon", SIGTERM, 0); + } +} + +void CleanupGlobal() +{ + if (proxy != NULL) + { + #ifdef TEST + *logofs << "Loop: Freeing up proxy in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + delete proxy; + + proxy = NULL; + } + + if (agent != NULL) + { + #ifdef TEST + *logofs << "Loop: Freeing up agent in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + delete agent; + + agent = NULL; + } + + if (auth != NULL) + { + #ifdef TEST + *logofs << "Loop: Freeing up auth data in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + delete auth; + + auth = NULL; + } + + if (statistics != NULL) + { + #ifdef TEST + *logofs << "Loop: Freeing up statistics in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + delete statistics; + + statistics = NULL; + } + + if (control != NULL) + { + #ifdef TEST + *logofs << "Loop: Freeing up control in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + delete control; + + control = NULL; + } +} + +void CleanupConnections() +{ + if (proxy -> getChannels(channel_x11) != 0) + { + #ifdef TEST + *logofs << "Loop: Closing any remaining X connections.\n" + << logofs_flush; + #endif + + proxy -> handleCloseAllXConnections(); + + #ifdef TEST + *logofs << "Loop: Closing any remaining listener.\n" + << logofs_flush; + #endif + + proxy -> handleCloseAllListeners(); + } + + proxy -> handleFinish(); +} + +void CleanupListeners() +{ + if (useTcpSocket == 1) + { + if (tcpFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing TCP listener in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(tcpFD); + + tcpFD = -1; + } + + useTcpSocket = 0; + } + + if (useUnixSocket == 1) + { + if (unixFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing UNIX listener in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(unixFD); + + unixFD = -1; + } + + if (*unixSocketName != '\0') + { + #ifdef TEST + *logofs << "Loop: Going to remove the Unix domain socket '" + << unixSocketName << "' in process " << "with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + unlink(unixSocketName); + } + + useUnixSocket = 0; + } + + if (useAgentSocket == 1) + { + // + // There is no listener for the + // agent descriptor. + // + + useAgentSocket = 0; + } + + if (useCupsSocket == 1) + { + if (cupsFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing CUPS listener in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(cupsFD); + + cupsFD = -1; + } + + useCupsSocket = 0; + } + + if (useAuxSocket == 1) + { + if (auxFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing auxiliary X11 listener " + << "in process " << "with pid '" << getpid() + << "'.\n" << logofs_flush; + #endif + + close(auxFD); + + auxFD = -1; + } + + useAuxSocket = 0; + } + + if (useSmbSocket == 1) + { + if (smbFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing SMB listener in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(smbFD); + + smbFD = -1; + } + + useSmbSocket = 0; + } + + if (useMediaSocket == 1) + { + if (mediaFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing multimedia listener in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(mediaFD); + + mediaFD = -1; + } + + useMediaSocket = 0; + } + + if (useHttpSocket == 1) + { + if (httpFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing http listener in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(httpFD); + + httpFD = -1; + } + + useHttpSocket = 0; + } + + if (useFontSocket == 1) + { + if (fontFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing font server listener in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(fontFD); + + fontFD = -1; + } + + useFontSocket = 0; + } + + if (useSlaveSocket == 1) + { + if (slaveFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing slave listener in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(slaveFD); + + slaveFD = -1; + } + + useSlaveSocket = 0; + } +} + +void CleanupSockets() +{ + if (proxyFD != -1) + { + #ifdef TEST + *logofs << "Loop: Closing proxy FD in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(proxyFD); + + proxyFD = -1; + } + + if (agentFD[1] != -1) + { + #ifdef TEST + *logofs << "Loop: Closing agent FD in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + close(agentFD[1]); + + agentFD[0] = -1; + agentFD[1] = -1; + } +} + +void CleanupLocal() +{ + *homeDir = '\0'; + *rootDir = '\0'; + *tempDir = '\0'; + *systemDir = '\0'; + *sessionDir = '\0'; + + *linkSpeedName = '\0'; + *cacheSizeName = '\0'; + *shsegSizeName = '\0'; + *imagesSizeName = '\0'; + *bitrateLimitName = '\0'; + *packMethodName = '\0'; + *productName = '\0'; + + packMethod = -1; + packQuality = -1; + + *sessionType = '\0'; + *sessionId = '\0'; + + parsedOptions = 0; + parsedCommand = 0; + + *remoteData = '\0'; + remotePosition = 0; + + tcpFD = -1; + unixFD = -1; + cupsFD = -1; + auxFD = -1; + smbFD = -1; + mediaFD = -1; + httpFD = -1; + fontFD = -1; + slaveFD = -1; + proxyFD = -1; + + agentFD[0] = -1; + agentFD[1] = -1; + + useUnixSocket = 1; + useTcpSocket = 1; + useCupsSocket = 0; + useAuxSocket = 0; + useSmbSocket = 0; + useMediaSocket = 0; + useHttpSocket = 0; + useFontSocket = 0; + useSlaveSocket = 0; + useAgentSocket = 0; + + useNoDelay = -1; + usePolicy = -1; + useRender = -1; + useTaint = -1; + + *unixSocketName = '\0'; + + *acceptHost = '\0'; + *displayHost = '\0'; + *authCookie = '\0'; + + proxyPort = DEFAULT_NX_PROXY_PORT; + xPort = DEFAULT_NX_X_PORT; + + xServerAddrFamily = -1; + xServerAddrLength = 0; + + delete xServerAddr; + + xServerAddr = NULL; + + listenSocket.disable(); + connectSocket.disable(); + + cupsPort.disable(); + auxPort.disable(); + smbPort.disable(); + mediaPort.disable(); + httpPort.disable(); + slavePort.disable(); + + *fontPort = '\0'; + + *bindHost = '\0'; + bindPort = -1; + + initTs = nullTimestamp(); + startTs = nullTimestamp(); + logsTs = nullTimestamp(); + nowTs = nullTimestamp(); + + diffTs = 0; + + lastProxy = 0; + lastDialog = 0; + lastWatchdog = 0; + lastKeeper = 0; + lastStatus = 0; + lastKill = 0; + lastDestroy = 0; + + lastReadableTs = nullTimestamp(); + + lastAlert.code = 0; + lastAlert.local = 0; + + lastMasks.blocked = 0; + lastMasks.installed = 0; + + memset(&lastMasks.saved, 0, sizeof(sigset_t)); + + for (int i = 0; i < 32; i++) + { + lastMasks.enabled[i] = 0; + lastMasks.forward[i] = 0; + + memset(&lastMasks.action[i], 0, sizeof(struct sigaction)); + } + + lastSignal = 0; + + memset(&lastTimer.action, 0, sizeof(struct sigaction)); + memset(&lastTimer.value, 0, sizeof(struct itimerval)); + + lastTimer.start = nullTimestamp(); + lastTimer.next = nullTimestamp(); +} + +int CheckAbort() +{ + if (lastSignal != 0) + { + #ifdef TEST + *logofs << "Loop: Aborting the procedure due to signal '" + << lastSignal << "', '" << DumpSignal(lastSignal) + << "'.\n" << logofs_flush; + #endif + + cerr << "Info" << ": Aborting the procedure due to signal '" + << lastSignal << "'.\n"; + + lastSignal = 0; + + return 1; + } + + return 0; +} + +void HandleAbort() +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + *logofs << flush; + + handleTerminatingInLoop(); + + if (lastSignal == SIGHUP) + { + lastSignal = 0; + } + + // + // The current default is to just quit the program. + // Code has not been updated to deal with the new + // NX transport loop. + // + + if (control -> EnableCoreDumpOnAbort == 1) + { + if (agent != NULL) + { + cerr << "Session" << ": Terminating session at '" + << strTimestamp() << "'.\n"; + } + + cerr << "Error" << ": Generating a core file to help " + << "the investigations.\n"; + + cerr << "Session" << ": Session terminated at '" + << strTimestamp() << "'.\n"; + + cerr << flush; + + signal(SIGABRT, SIG_DFL); + + raise(SIGABRT); + } + + #ifdef TEST + *logofs << "Loop: Showing the proxy abort dialog.\n" + << logofs_flush; + #endif + + if (control -> ProxyMode == proxy_server) + { + // + // Close the socket before showing the alert. + // It seems that the closure of the socket can + // sometimes take several seconds, even after + // the connection is broken. + // + + CleanupSockets(); + + if (lastKill == 0) + { + HandleAlert(ABORT_PROXY_CONNECTION_ALERT, 1); + } + else + { + HandleAlert(ABORT_PROXY_SHUTDOWN_ALERT, 1); + } + + handleAlertInLoop(); + } + + HandleCleanup(); +} + +void HandleAlert(int code, int local) +{ + if (lastAlert.code == 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Requesting an alert dialog with code " + << code << " and local " << local << ".\n" + << logofs_flush; + #endif + + lastAlert.code = code; + lastAlert.local = local; + } + #if defined(TEST) || defined(INFO) + else + { + *logofs << "Loop: WARNING! Alert dialog already requested " + << "with code " << lastAlert.code << ".\n" + << logofs_flush; + } + #endif + + return; +} + +void FlushCallback(int length) +{ + if (flushCallback != NULL) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Reporting a flush request at " + << strMsTimestamp() << " with " << length + << " bytes written.\n" << logofs_flush; + #endif + + (*flushCallback)(flushParameter, length); + } + #if defined(TEST) || defined(INFO) + else if (control -> ProxyMode == proxy_client) + { + *logofs << "Loop: WARNING! Can't find a flush " + << "callback in process with pid '" << getpid() + << "'.\n" << logofs_flush; + } + #endif +} + +void KeeperCallback() +{ + if (IsRunning(lastKeeper) == 0) + { + // + // Let the house-keeping process take care + // of the persistent image cache. + // + + if (control -> ImageCacheEnableLoad == 1 || + control -> ImageCacheEnableSave == 1) + { + #ifdef TEST + *logofs << "Loop: Starting the house-keeping process with " + << "image storage size " << control -> ImageCacheDiskLimit + << ".\n" << logofs_flush; + #endif + + lastKeeper = NXTransKeeper(0, control -> ImageCacheDiskLimit, + control -> RootPath); + + if (IsFailed(lastKeeper)) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Can't start the NX keeper process.\n" + << logofs_flush; + #endif + + SetNotRunning(lastKeeper); + } + #ifdef TEST + else + { + *logofs << "Loop: Keeper started with pid '" + << lastKeeper << "'.\n" << logofs_flush; + } + #endif + } + #ifdef TEST + else + { + *logofs << "Loop: Nothing to do for the keeper process " + << "with image cache not enabled.\n" + << logofs_flush; + } + #endif + } + #ifdef TEST + else + { + *logofs << "Loop: Nothing to do with the keeper process " + << "already running.\n" << logofs_flush; + } + #endif +} + +void InstallSignals() +{ + #ifdef TEST + *logofs << "Loop: Installing signals in process with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + for (int i = 0; i < 32; i++) + { + if (CheckSignal(i) == 1 && + lastMasks.enabled[i] == 0) + { + InstallSignal(i, NX_SIGNAL_ENABLE); + } + } + + lastMasks.installed = 1; +} + +void RestoreSignals() +{ + #ifdef TEST + *logofs << "Loop: Restoring signals in process with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + if (lastMasks.installed == 1) + { + // + // Need to keep monitoring the children. + // + + for (int i = 0; i < 32; i++) + { + if (lastMasks.enabled[i] == 1) + { + RestoreSignal(i); + } + } + } + + lastMasks.installed = 0; + + if (lastMasks.blocked == 1) + { + EnableSignals(); + } +} + +void DisableSignals() +{ + if (lastMasks.blocked == 0) + { + sigset_t newMask; + + sigemptyset(&newMask); + + // + // Block also the other signals that may be + // installed by the agent, that are those + // signals for which the function returns 2. + // + + for (int i = 0; i < 32; i++) + { + if (CheckSignal(i) > 0) + { + #ifdef DUMP + *logofs << "Loop: Disabling signal " << i << " '" + << DumpSignal(i) << "' in process with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + sigaddset(&newMask, i); + } + } + + sigprocmask(SIG_BLOCK, &newMask, &lastMasks.saved); + + lastMasks.blocked++; + } + #ifdef TEST + else + { + *logofs << "Loop: WARNING! Signals were already blocked in " + << "process with pid '" << getpid() << "'.\n" + << logofs_flush; + } + #endif +} + +void EnableSignals() +{ + if (lastMasks.blocked == 1) + { + #ifdef TEST + *logofs << "Loop: Enabling signals in process with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + sigprocmask(SIG_SETMASK, &lastMasks.saved, NULL); + + lastMasks.blocked = 0; + } + else + { + #ifdef WARNING + *logofs << "Loop: WARNING! Signals were not blocked in " + << "process with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Signals were not blocked in " + << "process with pid '" << getpid() << "'.\n"; + } +} + +void InstallSignal(int signal, int action) +{ + if (lastMasks.enabled[signal] == 1) + { + if (action == NX_SIGNAL_FORWARD) + { + #ifdef TEST + *logofs << "Loop: Forwarding handler for signal " << signal + << " '" << DumpSignal(signal) << "' in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + lastMasks.forward[signal] = 1; + + return; + } + #ifdef TEST + else + { + *logofs << "Loop: Reinstalling handler for signal " << signal + << " '" << DumpSignal(signal) << "' in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + } + #endif + } + #ifdef TEST + else + { + *logofs << "Loop: Installing handler for signal " << signal + << " '" << DumpSignal(signal) << "' in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + } + #endif + + if (signal == SIGALRM && isTimestamp(lastTimer.start)) + { + ResetTimer(); + } + + struct sigaction newAction; + + memset(&newAction, 0, sizeof(newAction)); + + newAction.sa_handler = HandleSignal; + + sigemptyset(&(newAction.sa_mask)); + + if (signal == SIGCHLD) + { + newAction.sa_flags = SA_NOCLDSTOP; + } + else + { + newAction.sa_flags = 0; + } + + sigaction(signal, &newAction, &lastMasks.action[signal]); + + lastMasks.enabled[signal] = 1; + + if (action == NX_SIGNAL_FORWARD) + { + lastMasks.forward[signal] = 1; + } +} + +void RestoreSignal(int signal) +{ + if (lastMasks.enabled[signal] == 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Signal '" << DumpSignal(signal) + << " not installed in process with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Signal '" << DumpSignal(signal) + << " not installed in process with pid '" + << getpid() << "'.\n"; + + return; + } + + #ifdef TEST + *logofs << "Loop: Restoring handler for signal " << signal + << " '" << DumpSignal(signal) << "' in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + if (signal == SIGALRM && isTimestamp(lastTimer.start)) + { + ResetTimer(); + } + + sigaction(signal, &lastMasks.action[signal], NULL); + + lastMasks.enabled[signal] = 0; + lastMasks.forward[signal] = 0; +} + +void HandleSignal(int signal) +{ + if (logofs == NULL) + { + logofs = &cerr; + } + + #if defined(UNSAFE) && (defined(TEST) || defined(INFO)) + + if (lastSignal != 0) + { + *logofs << "Loop: WARNING! Last signal is '" << lastSignal + << "', '" << DumpSignal(signal) << "' and not zero " + << "in process with pid '" << getpid() << "'.\n" + << logofs_flush; + } + + *logofs << "Loop: Signal '" << signal << "', '" + << DumpSignal(signal) << "' received in process " + << "with pid '" << getpid() << "'.\n" << logofs_flush; + + #endif + + if (getpid() != lastProxy && handler != NULL) + { + #if defined(UNSAFE) && (defined(TEST) || defined(INFO)) + *logofs << "Loop: Calling slave handler in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + if ((*handler)(signal) == 0) + { + return; + } + } + + switch (signal) + { + case SIGUSR1: + { + if (proxy != NULL && lastSignal == 0) + { + lastSignal = SIGUSR1; + } + + break; + } + case SIGUSR2: + { + if (proxy != NULL && lastSignal == 0) + { + lastSignal = SIGUSR2; + } + + break; + } + case SIGPIPE: + { + // + // It can happen that SIGPIPE is delivered + // to the proxy even in the case some other + // descriptor is unexpectedly closed. + // + // if (agentFD[1] != -1) + // { + // cerr << "Info" << ": Received signal 'SIGPIPE'. " + // << "Closing agent conection.\n"; + // + // shutdown(agentFD[1], SHUT_RDWR); + // } + // + + break; + } + case SIGALRM: + { + // + // Nothing to do. Just wake up the + // process on blocking operations. + // + + break; + } + case SIGCHLD: + { + // + // Check if any of our children has exited. + // + + if (HandleChildren() != 0) + { + signal = 0; + } + + // + // Don't save this signal or it will override + // any previous signal sent by child before + // exiting. + // + + break; + } + + #ifdef __CYGWIN32__ + + case 12: + { + // + // Nothing to do. This signal is what is delivered + // by the Cygwin library when trying use a shared + // memory function if the daemon is not running. + // + + #ifdef TEST + *logofs << "Loop: WARNING! Received signal '12' in " + << "process with pid '" << getpid() << "'.\n" + << logofs_flush; + + *logofs << "Loop: WARNING! Please check that the " + << "cygserver daemon is running.\n" + << logofs_flush; + #endif + + break; + } + + #endif + + default: + { + // + // Register the signal so we can handle it + // inside the main loop. We will probably + // dispose any resource and exit. + // + + if (getpid() == lastProxy) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Registering end of session request " + << "due to signal '" << signal << "', '" + << DumpSignal(signal) << "'.\n" + << logofs_flush; + #endif + + lastSignal = signal; + } + else + { + // + // This is a child, so exit immediately. + // + + HandleCleanup(); + } + } + } + + if (signal != 0 && lastMasks.forward[signal] == 1) + { + if (lastMasks.action[signal].sa_handler != NULL && + lastMasks.action[signal].sa_handler != HandleSignal) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Forwarding signal '" << signal << "', '" + << DumpSignal(signal) << "' to previous handler.\n" + << logofs_flush; + #endif + + lastMasks.action[signal].sa_handler(signal); + } + #ifdef WARNING + else if (lastMasks.action[signal].sa_handler == NULL) + { + *logofs << "Loop: WARNING! Parent requested to forward " + << "signal '" << signal << "', '" << DumpSignal(signal) + << "' but didn't set a handler.\n" << logofs_flush; + } + #endif + } +} + +int HandleChildren() +{ + // + // Try to waitpid() for each child because the + // call might have return ECHILD and so we may + // have lost any of the processes. + // + + if (IsRunning(lastDialog) && HandleChild(lastDialog) == 1) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Resetting pid of last dialog process " + << "in handler.\n" << logofs_flush; + #endif + + SetNotRunning(lastDialog); + + if (proxy != NULL) + { + proxy -> handleResetAlert(); + } + + return 1; + } + + if (IsRunning(lastWatchdog) && HandleChild(lastWatchdog) == 1) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Watchdog is gone. Setting the last " + << "signal to SIGHUP.\n" << logofs_flush; + #endif + + lastSignal = SIGHUP; + + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Resetting pid of last watchdog process " + << "in handler.\n" << logofs_flush; + #endif + + SetNotRunning(lastWatchdog); + + return 1; + } + + // + // The house-keeping process exits after a + // number of iterations to keep the memory + // pollution low. It is restarted on demand + // by the lower layers, using the callback + // function. + // + + if (IsRunning(lastKeeper) && HandleChild(lastKeeper) == 1) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Resetting pid of last house-keeping " + << "process in handler.\n" << logofs_flush; + #endif + + SetNotRunning(lastKeeper); + + return 1; + } + + // + // The pid will be checked by the code + // that registered the child. + // + + if (IsRunning(lastChild)) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Resetting pid of last child process " + << "in handler.\n" << logofs_flush; + #endif + + SetNotRunning(lastChild); + + return 1; + } + + proxy->checkSlaves(); + + // + // This can actually happen either because we + // reset the pid of the child process as soon + // as we kill it, or because of a child process + // of our parent. + // + + #if defined(UNSAFE) && (defined(TEST) || defined(INFO)) + *logofs << "Loop: Ignoring signal received for the " + << "unregistered child.\n" << logofs_flush; + #endif + + return 0; +} + +int HandleChild(int child) +{ + int pid; + + int status = 0; + int options = WNOHANG | WUNTRACED; + + while ((pid = waitpid(child, &status, options)) && + pid == -1 && EGET() == EINTR); + + return CheckChild(pid, status); +} + +int WaitChild(int child, const char* label, int force) +{ + int pid; + + int status = 0; + int options = WUNTRACED; + + for (;;) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Waiting for the " << label + << " process '" << child << "' to die.\n" + << logofs_flush; + #endif + + pid = waitpid(child, &status, options); + + if (pid == -1 && EGET() == EINTR) + { + if (force == 0) + { + return 0; + } + + #ifdef WARNING + *logofs << "Loop: WARNING! Ignoring signal while " + << "waiting for the " << label << " process '" + << child << "' to die.\n" + << logofs_flush; + #endif + + continue; + } + + break; + } + + return (EGET() == ECHILD ? 1 : CheckChild(pid, status)); +} + +int CheckChild(int pid, int status) +{ + lastStatus = 0; + + if (pid > 0) + { + if (WIFSTOPPED(status)) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Child process '" << pid << "' was stopped " + << "with signal " << (WSTOPSIG(status)) << ".\n" + << logofs_flush; + #endif + + return 0; + } + else + { + if (WIFEXITED(status)) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Child process '" << pid << "' exited " + << "with status '" << (WEXITSTATUS(status)) + << "'.\n" << logofs_flush; + #endif + + lastStatus = WEXITSTATUS(status); + } + else if (WIFSIGNALED(status)) + { + if (CheckSignal(WTERMSIG(status)) != 1) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Child process '" << pid + << "' died because of signal " << (WTERMSIG(status)) + << ", '" << DumpSignal(WTERMSIG(status)) << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Child process '" << pid + << "' died because of signal " << (WTERMSIG(status)) + << ", '" << DumpSignal(WTERMSIG(status)) << "'.\n"; + } + #if defined(UNSAFE) && defined(TEST) + else + { + *logofs << "Loop: Child process '" << pid + << "' died because of signal " << (WTERMSIG(status)) + << ", '" << DumpSignal(WTERMSIG(status)) << "'.\n" + << logofs_flush; + } + #endif + + lastStatus = 1; + } + + return 1; + } + } + else if (pid < 0) + { + if (EGET() != ECHILD) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to waitpid failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to waitpid failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + HandleCleanup(); + } + + // + // This can happen when the waitpid() is + // blocking, as the SIGCHLD is received + // within the call. + // + + #ifdef TEST + *logofs << "Loop: No more children processes running.\n" + << logofs_flush; + #endif + + return 1; + } + + return 0; +} + +void RegisterChild(int child) +{ + #if defined(TEST) || defined(INFO) + + if (IsNotRunning(lastChild)) + { + *logofs << "Loop: Registering child process '" << child + << "' in process with pid '" << getpid() + << "'.\n" << logofs_flush; + } + else + { + *logofs << "Loop: WARNING! Overriding registered child '" + << lastChild << "' with new child '" << child + << "' in process with pid '" << getpid() + << "'.\n" << logofs_flush; + } + + #endif + + lastChild = child; +} + +int CheckParent(const char *name, const char *type, int parent) +{ + if (parent != getppid() || parent == 1) + { + #ifdef WARNING + *logofs << name << ": WARNING! Parent process appears " + << "to be dead. Exiting " << type << ".\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Parent process appears " + << "to be dead. Exiting " << type << ".\n"; + + return 0; + } + + return 1; +} + +void HandleTimer(int signal) +{ + if (signal == SIGALRM) + { + if (isTimestamp(lastTimer.start)) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Timer expired at " << strMsTimestamp() + << " in process with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + if (proxy != NULL) + { + proxy -> handleTimer(); + } + + ResetTimer(); + } + else + { + #ifdef PANIC + *logofs << "Loop: PANIC! Inconsistent timer state " + << " in process with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Inconsistent timer state " + << " in process with pid '" << getpid() << "'.\n"; + } + } + else + { + #ifdef PANIC + *logofs << "Loop: PANIC! Inconsistent signal '" + << signal << "', '" << DumpSignal(signal) + << "' received in process with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Inconsistent signal '" + << signal << "', '" << DumpSignal(signal) + << "' received in process with pid '" + << getpid() << "'.\n"; + } +} + +void SetTimer(int value) +{ + getNewTimestamp(); + + if (isTimestamp(lastTimer.start)) + { + int diffTs = diffTimestamp(lastTimer.start, getTimestamp()); + + if (diffTs > lastTimer.next.tv_usec / 1000 * 2) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Timer missed to expire at " + << strMsTimestamp() << " in process with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Timer missed to expire at " + << strMsTimestamp() << " in process with pid '" + << getpid() << "'.\n"; + + HandleTimer(SIGALRM); + } + else + { + #ifdef TEST + *logofs << "Loop: Timer already running at " + << strMsTimestamp() << " in process with pid '" + << getpid() << "'.\n" << logofs_flush; + #endif + + return; + } + } + + // + // Save the former handler. + // + + struct sigaction action; + + memset(&action, 0, sizeof(action)); + + action.sa_handler = HandleTimer; + + sigemptyset(&action.sa_mask); + + action.sa_flags = 0; + + sigaction(SIGALRM, &action, &lastTimer.action); + + // + // Start the timer. + // + + lastTimer.next = getTimestamp(value); + + struct itimerval timer; + + timer.it_interval = lastTimer.next; + timer.it_value = lastTimer.next; + + #ifdef TEST + *logofs << "Loop: Timer set to " << lastTimer.next.tv_sec + << " S and " << lastTimer.next.tv_usec / 1000 + << " Ms at " << strMsTimestamp() << " in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + if (setitimer(ITIMER_REAL, &timer, &lastTimer.value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to setitimer failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to setitimer failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + lastTimer.next = nullTimestamp(); + + return; + } + + lastTimer.start = getTimestamp(); +} + +void ResetTimer() +{ + if (isTimestamp(lastTimer.start) == 0) + { + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Timer not running in process " + << "with pid '" << getpid() << "'.\n" + << logofs_flush; + #endif + + return; + } + + #if defined(UNSAFE) && defined(TEST) + *logofs << "Loop: Timer reset at " << strMsTimestamp() + << " in process with pid '" << getpid() + << "'.\n" << logofs_flush; + #endif + + // + // Restore the old signal mask and timer. + // + + if (setitimer(ITIMER_REAL, &lastTimer.value, NULL) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to setitimer failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to setitimer failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + } + + if (sigaction(SIGALRM, &lastTimer.action, NULL) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to sigaction failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to sigaction failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + } + + lastTimer.start = lastTimer.next = nullTimestamp(); +} + +// +// Open TCP or UNIX file socket to listen for remote proxy +// and block until remote connects. If successful close +// the listening socket and return FD on which the other +// party is connected. +// + +int WaitForRemote(ChannelEndPoint &socketAddress) +{ + char hostLabel[DEFAULT_STRING_LENGTH] = { 0 }; + char *socketUri = NULL; + + int retryAccept = -1; + + int proxyFD = -1; + int newFD = -1; + + int acceptIPAddr = 0; + + if (socketAddress.isTCPSocket()) + { + + // + // Get IP address of host to be awaited. + // + + if (*acceptHost != '\0') + { + acceptIPAddr = GetHostAddress(acceptHost); + + if (acceptIPAddr == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Cannot accept connections from unknown host '" + << acceptHost << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot accept connections from unknown host '" + << acceptHost << "'.\n"; + + goto WaitForRemoteError; + } + snprintf(hostLabel, sizeof(hostLabel), "'%s'", acceptHost); + } + else + { + strcpy(hostLabel, "any host"); + } + + long bindPort; + if (socketAddress.getTCPHostAndPort(NULL, &bindPort)) + { + socketAddress.setSpec(loopbackBind ? "localhost" : "*", bindPort); + } + else + { + // This should never happen + cerr << "Error" << ": Unable to change bind host\n"; + } + } + else if (socketAddress.isUnixSocket()) + strcpy(hostLabel, "this host"); + else + strcpy(hostLabel, "unknown origin (something went wrong!!!)"); + + + proxyFD = ListenConnection(socketAddress, "NX"); + + socketAddress.getSpec(&socketUri); + #ifdef TEST + *logofs << "Loop: Waiting for connection from " + << hostLabel << " on socket '" << socketUri + << "'.\n" << logofs_flush; + #endif + cerr << "Info" << ": Waiting for connection from " + << hostLabel << " on socket '" << socketUri + << "'.\n"; + free(socketUri); + + // + // How many times to loop waiting for connections + // from the selected host? Each loop wait for at + // most 20 seconds so a default value of 3 gives + // a timeout of 1 minute. + // + // TODO: Handling of timeouts and retry attempts + // must be rewritten. + // + + retryAccept = control -> OptionProxyRetryAccept; + + for (;;) + { + fd_set readSet; + + FD_ZERO(&readSet); + FD_SET(proxyFD, &readSet); + + T_timestamp selectTs; + + selectTs.tv_sec = 20; + selectTs.tv_usec = 0; + + int result = select(proxyFD + 1, &readSet, NULL, NULL, &selectTs); + + getNewTimestamp(); + + if (result == -1) + { + if (EGET() == EINTR) + { + if (CheckAbort() != 0) + { + goto WaitForRemoteError; + } + + continue; + } + + #ifdef PANIC + *logofs << "Loop: PANIC! Call to select failed. Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Call to select failed. Error is " + << EGET() << " '" << ESTR() << "'.\n"; + + goto WaitForRemoteError; + } + else if (result > 0 && FD_ISSET(proxyFD, &readSet)) + { + + sockaddr_in newAddrINET; + + if (socketAddress.isUnixSocket()) + { + socklen_t addrLen = sizeof(sockaddr_un); + newFD = accept(proxyFD, NULL, &addrLen); + } + else if (socketAddress.isTCPSocket()) + { + socklen_t addrLen = sizeof(sockaddr_in); + newFD = accept(proxyFD, (sockaddr *) &newAddrINET, &addrLen); + } + if (newFD == -1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to accept failed. Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Call to accept failed. Error is " + << EGET() << " '" << ESTR() << "'.\n"; + + goto WaitForRemoteError; + } + + if (socketAddress.isUnixSocket()) + { + + char * unixPath = NULL; + socketAddress.getUnixPath(&unixPath); + #ifdef TEST + *logofs << "Loop: Accepted connection from this host on Unix file socket '" + << unixPath << "'.\n" + << logofs_flush; + #endif + + cerr << "Info" << ": Accepted connection from this host on Unix file socket '" + << unixPath << "'.\n"; + free(unixPath); + + break; + } + else if (socketAddress.isTCPSocket()) + { + + char *connectedHost = inet_ntoa(newAddrINET.sin_addr); + + if (*acceptHost == '\0' || (int) newAddrINET.sin_addr.s_addr == acceptIPAddr) + { + + #ifdef TEST + + unsigned int connectedPort = ntohs(newAddrINET.sin_port); + + *logofs << "Loop: Accepted connection from '" << connectedHost + << "' with port '" << connectedPort << "'.\n" + << logofs_flush; + #endif + + cerr << "Info" << ": Accepted connection from '" + << connectedHost << "'.\n"; + + break; + } + else + { + #ifdef PANIC + *logofs << "Loop: WARNING! Refusing connection from '" << connectedHost + << "' on port '" << socketAddress.getTCPPort() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Refusing connection from '" + << connectedHost << "'.\n"; + } + + // + // Not the best way to elude a DOS attack... + // + + sleep(5); + + close(newFD); + + } + + } + + if (--retryAccept == 0) + { + if (socketAddress.isUnixSocket()) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Connection via Unix file socket from this host " + << "could not be established.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Connection via Unix file socket from this host " + << "could not be established.\n"; + } + else if (*acceptHost == '\0') + { + #ifdef PANIC + *logofs << "Loop: PANIC! Connection with remote host " + << "could not be established.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Connection with remote host " + << "could not be established.\n"; + } + else + { + #ifdef PANIC + *logofs << "Loop: PANIC! Connection with remote host '" + << acceptHost << "' could not be established.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Connection with remote host '" + << acceptHost << "' could not be established.\n"; + } + + goto WaitForRemoteError; + } + else + { + handleCheckSessionInConnect(); + } + } + + close(proxyFD); + + return newFD; + +WaitForRemoteError: + + close(proxyFD); + + HandleCleanup(); +} + +int PrepareProxyConnectionTCP(char** hostName, long int* portNum, int* timeout, int* proxyFD, int* reason) +{ + + if (!proxyFD) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Implementation error (PrepareProxyConnectionTCP). " + << "'proxyFD' must not be a NULL pointer.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Implementation error (PrepareProxyConnectionTCP). " + << "'proxyFD' must not be a NULL pointer.\n"; + + return -1; + } + + if (!reason) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Implementation error (PrepareProxyConnectionTCP). " + << "'reason' must not be a NULL pointer.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Implementation error (PrepareProxyConnectionTCP). " + << "'reason' must not be a NULL pointer.\n"; + + return -1; + } + + int remoteIPAddr = GetHostAddress(*hostName); + if (remoteIPAddr == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Unknown remote host '" + << *hostName << "'.\n" << logofs_flush; + #endif + cerr << "Error" << ": Unknown remote host '" + << *hostName << "'.\n"; + + HandleCleanup(); + } + + #ifdef TEST + *logofs << "Loop: Connecting to remote host '" + << *hostName << ":" << *portNum << "'.\n" + << logofs_flush; + #endif + + cerr << "Info" << ": Connecting to remote host '" + << *hostName << ":" << *portNum << "'.\n" + << logofs_flush; + + *proxyFD = -1; + *reason = -1; + + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(*portNum); + addr.sin_addr.s_addr = remoteIPAddr; + + *proxyFD = socket(AF_INET, SOCK_STREAM, PF_UNSPEC); + *reason = EGET(); + + if (*proxyFD == -1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to socket failed. " + << "Error is " << *reason << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to socket failed. " + << "Error is " << *reason << " '" << ESTR() + << "'.\n"; + return -1; + + } + else if (SetReuseAddress(*proxyFD) < 0) + { + return -1; + } + + // + // Ensure operation is timed out + // if there is a network problem. + // + + if (timeout) + SetTimer(*timeout); + else + SetTimer(20000); + + int result = connect(*proxyFD, (sockaddr *) &addr, sizeof(sockaddr_in)); + + *reason = EGET(); + + ResetTimer(); + + return result; + +} + +int PrepareProxyConnectionUnix(char** path, int* timeout, int* proxyFD, int* reason) +{ + + if (!proxyFD) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Implementation error (PrepareProxyConnectionUnix). " + << "proxyFD must not be a NULL pointer.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Implementation error (PrepareProxyConnectionUnix). " + << "proxyFD must not be a NULL pointer.\n"; + + return -1; + } + + if (!reason) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Implementation error (PrepareProxyConnectionUnix). " + << "'reason' must not be a NULL pointer.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Implementation error (PrepareProxyConnectionUnix). " + << "'reason' must not be a NULL pointer.\n"; + + return -1; + } + + /* FIXME: Add socket file existence and permission checks */ + + *proxyFD = -1; + *reason = -1; + + sockaddr_un addr; + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, *path, 108 - 1); + + *proxyFD = socket(AF_UNIX, SOCK_STREAM, PF_UNSPEC); + *reason = EGET(); + + if (*proxyFD == -1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Call to socket failed. " + << "Error is " << *reason << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to socket failed. " + << "Error is " << *reason << " '" << ESTR() + << "'.\n"; + + return -1; + } + + // + // Ensure operation is timed out + // if there is a network problem. + // + + if (timeout) + SetTimer(*timeout); + else + SetTimer(20000); + + int result = connect(*proxyFD, (sockaddr *) &addr, sizeof(sockaddr_un)); + + *reason = EGET(); + + ResetTimer(); + + return result; +} + +// +// Connect to remote proxy. If successful +// return FD of connection, else return -1. +// + +int ConnectToRemote(ChannelEndPoint &socketAddress) +{ + + // + // How many times we retry to connect to remote + // host / Unix domain socket in case of failure? + // + + int retryConnect = control -> OptionProxyRetryConnect; + + // + // Show an alert after 20 seconds and use the + // same timeout to interrupt the connect. The + // retry timeout is incremental, starting from + // 100 miliseconds up to 1 second. + // + + int alertTimeout = 20000; + int connectTimeout = 20000; + int retryTimeout = 100; + + T_timestamp lastRetry = getNewTimestamp(); + + int result = -1; + int reason = -1; + int proxyFD = -1; + + char *hostName = NULL; + long int portNum = -1; + char *unixPath = NULL; + + for (;;) + { + + #ifdef DEBUG + *logofs << "Loop: Timer set to " << connectTimeout / 1000 + << " S " << "with retry set to " << retryConnect + << " in process with pid '" << getpid() + << "'.\n" << logofs_flush; + #endif + + if (socketAddress.getUnixPath(&unixPath)) + result = PrepareProxyConnectionUnix(&unixPath, &connectTimeout, &proxyFD, &reason); + else if (socketAddress.getTCPHostAndPort(&hostName, &portNum)) + result = PrepareProxyConnectionTCP(&hostName, &portNum, &connectTimeout, &proxyFD, &reason); + + if (result < 0) + { + close(proxyFD); + + if (CheckAbort() != 0) + { + goto ConnectToRemoteError; + } + else if (--retryConnect == 0) + { + ESET(reason); + + if (socketAddress.isUnixSocket()) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Connection to Unix file socket '" + << unixPath << "' failed. Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Connection to Unix file socket '" + << unixPath << "' failed. Error is " + << EGET() << " '" << ESTR() << "'.\n"; + } + else + { + + #ifdef PANIC + *logofs << "Loop: PANIC! Connection to '" << hostName + << ":" << portNum << "' failed. Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Connection to '" << hostName + << ":" << portNum << "' failed. Error is " + << EGET() << " '" << ESTR() << "'.\n"; + } + goto ConnectToRemoteError; + } + else + { + #ifdef TEST + *logofs << "Loop: Sleeping " << retryTimeout + << " ms before retrying.\n" + << logofs_flush; + #endif + + usleep(retryTimeout * 1000); + + retryTimeout <<= 1; + + if (retryTimeout > 1000 * 1000) + { + retryTimeout = 1000 * 1000; + } + } + + // + // Check if it is time to show an alert dialog. + // + + if (diffTimestamp(lastRetry, getNewTimestamp()) >= + (alertTimeout - control -> LatencyTimeout)) + { + if (IsNotRunning(lastDialog)) + { + handleCheckSessionInConnect(); + + // + // Wait for the dialog process to die + // unless a signal is received. + // + + while (IsRunning(lastDialog)) + { + WaitChild(lastDialog, "dialog", 0); + + if (CheckAbort() != 0) + { + // + // The client ignores the TERM signal + // on Windows. + // + + #ifdef __CYGWIN32__ + + KillProcess(lastDialog, "dialog", SIGKILL, 1); + + #else + + KillProcess(lastDialog, "dialog", SIGTERM, 1); + + #endif + + goto ConnectToRemoteError; + } + } + + lastRetry = getTimestamp(); + } + } + #ifdef TEST + { + *logofs << "Loop: Not showing the dialog with " + << (diffTimestamp(lastRetry, getTimestamp()) / 1000) + << " seconds elapsed.\n" << logofs_flush; + } + #endif + + ESET(reason); + + #ifdef TEST + if (unixPath && unixPath[0] != '\0' ) + { + *logofs << "Loop: Connection to Unix socket file '" + << unixPath << "' failed with error '" + << ESTR() << "'. Retrying.\n" + << logofs_flush; + } + else + { + *logofs << "Loop: Connection to '" << hostName + << ":" << portNum << "' failed with error '" + << ESTR() << "'. Retrying.\n" + << logofs_flush; + } + #endif + } + else + { + // + // Connection was successful. + // + + break; + } + } + + return proxyFD; + +ConnectToRemoteError: + + if (proxyFD != -1) + { + close(proxyFD); + } + + HandleCleanup(); +} + +// +// Make a string of options for the remote +// proxy and write it to the descriptor. +// The string includes the local version. +// + +int SendProxyOptions(int fd) +{ + char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; + + // + // Send the "compatibility" version first, then our + // actual version. Old proxies will take the first + // value and ignore the second. + // + + sprintf(options, "NXPROXY-%s-%i.%i.%i", + control -> NXPROXY_COMPATIBILITY_VERSION, + control -> LocalVersionMajor, + control -> LocalVersionMinor, + control -> LocalVersionPatch); + + // + // If you want to send options from proxy + // initiating the connection use something + // like this: + // + // if (WE_PROVIDE_CREDENTIALS) + // { + // sprintf(options + strlen(options), "%s=%s", option, value); + // } + // + // If you want to send options according to + // local proxy mode use something like this: + // + // if (control -> ProxyMode == proxy_client) + // { + // sprintf(options + strlen(options), "%s=%s", option, value); + // } + // + + // + // Send the authorization cookie if any. We assume + // user can choose to not provide any auth cookie + // and allow any connection to be accepted. + // + + if (WE_PROVIDE_CREDENTIALS && *authCookie != '\0') + { + sprintf(options + strlen(options), " cookie=%s,", authCookie); + } + else + { + sprintf(options + strlen(options), " "); + } + + // + // Now link characteristics and compression + // options. Delta compression, as well as + // preferred pack method, are imposed by + // client proxy. + // + + if (control -> ProxyMode == proxy_client) + { + sprintf(options + strlen(options), "link=%s,pack=%s,cache=%s,", + linkSpeedName, packMethodName, cacheSizeName); + + if (*bitrateLimitName != '\0') + { + sprintf(options + strlen(options), "limit=%s,", + bitrateLimitName); + } + + // + // Let the user disable the render extension + // and let the X client proxy know if it can + // short-circuit the X replies. Also pass + // along the session type to ensure that the + // remote proxy gets the right value. + // + + sprintf(options + strlen(options), "render=%d,taint=%d,", + (control -> HideRender == 0), + control -> TaintReplies); + + if (*sessionType != '\0') + { + sprintf(options + strlen(options), "type=%s,", sessionType); + } + else + { + sprintf(options + strlen(options), "type=default,"); + } + + // + // Add the 'strict' option, if needed. + // + + // Since ProtoStep7 (#issue 108) + if (useStrict != -1) + { + sprintf(options + strlen(options), "strict=%d,", useStrict); + } + + // + // Tell the remote the size of the shared + // memory segment. + // + + // Since ProtoStep7 (#issue 108) + if (*shsegSizeName != '\0') + { + sprintf(options + strlen(options), "shseg=%s,", shsegSizeName); + } + + // + // Send image cache parameters. + // + + sprintf(options + strlen(options), "images=%s,", imagesSizeName); + + sprintf(options + strlen(options), "delta=%d,stream=%d,data=%d ", + control -> LocalDeltaCompression, + control -> LocalStreamCompressionLevel, + control -> LocalDataCompressionLevel); + } + else + { + // + // If no special compression level was selected, + // server side will use compression levels set + // by client. + // + + if (control -> LocalStreamCompressionLevel < 0) + { + sprintf(options + strlen(options), "stream=default,"); + } + else + { + sprintf(options + strlen(options), "stream=%d,", + control -> LocalStreamCompressionLevel); + } + + if (control -> LocalDataCompressionLevel < 0) + { + sprintf(options + strlen(options), "data=default "); + } + else + { + sprintf(options + strlen(options), "data=%d ", + control -> LocalDataCompressionLevel); + } + } + + #ifdef TEST + *logofs << "Loop: Sending remote options '" + << options << "'.\n" << logofs_flush; + #endif + + return WriteLocalData(fd, options, strlen(options)); +} + +int ReadProxyVersion(int fd) +{ + #ifdef TEST + *logofs << "Loop: Going to read the remote proxy version " + << "from FD#" << fd << ".\n" << logofs_flush; + #endif + + // + // Read until the first space in string. + // We expect the remote version number. + // + + char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; + + int result = ReadRemoteData(fd, options, sizeof(options), ' '); + + if (result <= 0) + { + if (result < 0) + { + if (control -> ProxyMode == proxy_server) + { + HandleAlert(ABORT_PROXY_NEGOTIATION_ALERT, 1); + } + + handleAlertInLoop(); + } + + return result; + } + + #ifdef TEST + *logofs << "Loop: Received remote version string '" + << options << "' from FD#" << fd << ".\n" + << logofs_flush; + #endif + + if (strncmp(options, "NXPROXY-", strlen("NXPROXY-")) != 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Parse error in remote options string '" + << options << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Parse error in remote options string '" + << options << "'.\n"; + + return -1; + } + + // + // Try to determine if this is a pre-2.0.0 + // version advertising itself as compatible + // with the 1.2.2. + // + + int major = -1; + int minor = -1; + int patch = -1; + + sscanf(options, "NXPROXY-%i.%i.%i-%i.%i.%i", &(control -> RemoteVersionMajor), + &(control -> RemoteVersionMinor), &(control -> RemoteVersionPatch), + &major, &minor, &patch); + + if (control -> RemoteVersionMajor == 1 && + control -> RemoteVersionMinor == 2 && + control -> RemoteVersionPatch == 2 && + major != -1 && minor != -1 && patch != -1) + { + #ifdef TEST + *logofs << "Loop: Read trailing remote version '" << major + << "." << minor << "." << patch << "'.\n" + << logofs_flush; + #endif + + control -> CompatVersionMajor = major; + control -> CompatVersionMinor = minor; + control -> CompatVersionPatch = patch; + + control -> RemoteVersionMajor = major; + control -> RemoteVersionMinor = minor; + control -> RemoteVersionPatch = patch; + } + else + { + // + // We read the remote version at the first + // round. If the second version is missing, + // we will retain the values read before. + // + + sscanf(options, "NXPROXY-%i.%i.%i-%i.%i.%i", &(control -> CompatVersionMajor), + &(control -> CompatVersionMinor), &(control -> CompatVersionPatch), + &(control -> RemoteVersionMajor), &(control -> RemoteVersionMinor), + &(control -> RemoteVersionPatch)); + } + + *logofs << "Loop: Identified remote version '" << control -> RemoteVersionMajor + << "." << control -> RemoteVersionMinor << "." << control -> RemoteVersionPatch + << "'.\n" << logofs_flush; + + *logofs << "Loop: Remote compatibility version '" << control -> CompatVersionMajor + << "." << control -> CompatVersionMinor << "." << control -> CompatVersionPatch + << "'.\n" << logofs_flush; + + *logofs << "Loop: Local version '" << control -> LocalVersionMajor + << "." << control -> LocalVersionMinor << "." << control -> LocalVersionPatch + << "'.\n" << logofs_flush; + + if (SetVersion() < 0) + { + if (control -> ProxyMode == proxy_server) + { + HandleAlert(WRONG_PROXY_VERSION_ALERT, 1); + } + + handleAlertInLoop(); + + return -1; + } + + return 1; +} + +int ReadProxyOptions(int fd) +{ + #ifdef TEST + *logofs << "Loop: Going to read the remote proxy options " + << "from FD#" << fd << ".\n" << logofs_flush; + #endif + + char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; + + int result = ReadRemoteData(fd, options, sizeof(options), ' '); + + if (result <= 0) + { + return result; + } + + #ifdef TEST + *logofs << "Loop: Received remote options string '" + << options << "' from FD#" << fd << ".\n" + << logofs_flush; + #endif + + // + // Get the remote options, delimited by a space character. + // Note that there will be a further initialization phase + // at the time proxies negotiate cache file to restore. + // + + if (ParseRemoteOptions(options) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Couldn't negotiate a valid " + << "session with remote NX proxy.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Couldn't negotiate a valid " + << "session with remote NX proxy.\n"; + + return -1; + } + + return 1; +} + +int SendProxyCaches(int fd) +{ + #ifdef TEST + *logofs << "Loop: Synchronizing local and remote caches.\n" + << logofs_flush; + #endif + + if (control -> ProxyMode == proxy_client) + { + // + // Prepare a list of caches matching this + // session type and send it to the remote. + // + + #ifdef TEST + *logofs << "Loop: Going to send the list of local caches.\n" + << logofs_flush; + #endif + + SetCaches(); + + int entries = DEFAULT_REMOTE_CACHE_ENTRIES; + + const char prefix = 'C'; + + if (control -> LocalDeltaCompression == 0 || + control -> PersistentCacheEnableLoad == 0) + { + #ifdef TEST + *logofs << "Loop: Writing an empty list to FD#" << fd + << ".\n" << logofs_flush; + #endif + + return WriteLocalData(fd, "cachelist=none ", strlen("cachelist=none ")); + } + + int count = 0; + + #ifdef TEST + *logofs << "Loop: Looking for cache files in directory '" + << control -> PersistentCachePath << "'.\n" << logofs_flush; + #endif + + DIR *cacheDir = opendir(control -> PersistentCachePath); + + if (cacheDir != NULL) + { + dirent *dirEntry; + + int prologue = 0; + + while (((dirEntry = readdir(cacheDir)) != NULL) && (count < entries)) + { + if (*dirEntry -> d_name == prefix && + strlen(dirEntry -> d_name) == (MD5_LENGTH * 2 + 2)) + { + if (prologue == 0) + { + WriteLocalData(fd, "cachelist=", strlen("cachelist=")); + + prologue = 1; + } + else + { + WriteLocalData(fd, ",", strlen(",")); + } + + #ifdef TEST + *logofs << "Loop: Writing entry '" << control -> PersistentCachePath + << "/" << dirEntry -> d_name << "' to FD#" << fd + << ".\n" << logofs_flush; + #endif + + // + // Write cache file name to the socket, + // including leading 'C-' or 'S-'. + // + + WriteLocalData(fd, dirEntry -> d_name, MD5_LENGTH * 2 + 2); + + count++; + } + } + + closedir(cacheDir); + } + + if (count == 0) + { + #ifdef TEST + *logofs << "Loop: Writing an empty list to FD#" << fd + << ".\n" << logofs_flush; + #endif + + return WriteLocalData(fd, "cachelist=none ", strlen("cachelist=none ")); + } + else + { + return WriteLocalData(fd, " ", 1); + } + } + else + { + // + // Send back the selected cache name. + // + + #ifdef TEST + *logofs << "Loop: Going to send the selected cache.\n" + << logofs_flush; + #endif + + char buffer[DEFAULT_STRING_LENGTH]; + + if (control -> PersistentCacheName != NULL) + { + #ifdef TEST + *logofs << "Loop: Name of selected cache file is '" + << control -> PersistentCacheName << "'.\n" + << logofs_flush; + #endif + + sprintf(buffer, "cachefile=%s%s ", + *(control -> PersistentCacheName) == 'C' ? "S-" : "C-", + control -> PersistentCacheName + 2); + } + else + { + #ifdef TEST + *logofs << "Loop: No valid cache file was selected.\n" + << logofs_flush; + #endif + + sprintf(buffer, "cachefile=none "); + } + + #ifdef TEST + *logofs << "Loop: Sending string '" << buffer + << "' as selected cache file.\n" + << logofs_flush; + #endif + + return WriteLocalData(fd, buffer, strlen(buffer)); + } +} + +int ReadProxyCaches(int fd) +{ + if (control -> ProxyMode == proxy_client) + { + #ifdef TEST + *logofs << "Loop: Going to receive the selected proxy cache.\n" + << logofs_flush; + #endif + + // + // We will read the name of cache plus the stop character. + // + + char buffer[DEFAULT_STRING_LENGTH]; + + // + // Leave space for a trailing null. + // + + int result = ReadRemoteData(fd, buffer, sizeof("cachefile=") + MD5_LENGTH * 2 + 3, ' '); + + if (result <= 0) + { + return result; + } + + char *cacheName = strstr(buffer, "cachefile="); + + if (cacheName == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid cache file option '" + << buffer << "' provided by remote proxy.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid cache file option '" + << buffer << "' provided by remote proxy.\n"; + + HandleCleanup(); + } + + cacheName += strlen("cachefile="); + + if (control -> PersistentCacheName != NULL) + { + delete [] control -> PersistentCacheName; + } + + control -> PersistentCacheName = NULL; + + if (strncasecmp(cacheName, "none", strlen("none")) == 0) + { + #ifdef TEST + *logofs << "Loop: No cache file selected by remote proxy.\n" + << logofs_flush; + #endif + } + else if (strlen(cacheName) != MD5_LENGTH * 2 + 3 || + *(cacheName + MD5_LENGTH * 2 + 2) != ' ') + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid cache file name '" + << cacheName << "' provided by remote proxy.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid cache file name '" + << cacheName << "' provided by remote proxy.\n"; + + HandleCleanup(); + } + else + { + // + // It is "C-" + 32 + "\0". + // + + control -> PersistentCacheName = new char[MD5_LENGTH * 2 + 3]; + + *(cacheName + MD5_LENGTH * 2 + 2) = '\0'; + + strcpy(control -> PersistentCacheName, cacheName); + + #ifdef TEST + *logofs << "Loop: Cache file '" << control -> PersistentCacheName + << "' selected by remote proxy.\n" << logofs_flush; + #endif + } + } + else + { + #ifdef TEST + *logofs << "Loop: Going to receive the list of remote caches.\n" + << logofs_flush; + #endif + + SetCaches(); + + int size = ((MD5_LENGTH * 2 + 2) + strlen(",")) * DEFAULT_REMOTE_CACHE_ENTRIES + + strlen("cachelist=") + strlen(" ") + 1; + + char *buffer = new char[size]; + + int result = ReadRemoteData(fd, buffer, size - 1, ' '); + + if (result <= 0) + { + delete [] buffer; + + return result; + } + + #ifdef TEST + *logofs << "Loop: Read list of caches from remote side as '" + << buffer << "'.\n" << logofs_flush; + #endif + + // + // Prepare the buffer. What we want is a list + // like "cache1,cache2,cache2" terminated by + // null. + // + + *(buffer + strlen(buffer) - 1) = '\0'; + + if (strncasecmp(buffer, "cachelist=", strlen("cachelist=")) != 0) + { + #ifdef PANIC + *logofs << "Loop: Wrong format for list of cache files " + << "read from FD#" << fd << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Wrong format for list of cache files.\n"; + + delete [] buffer; + + return -1; + } + + control -> PersistentCacheName = GetLastCache(buffer, control -> PersistentCachePath); + + // + // Get rid of list of caches. + // + + delete [] buffer; + } + + return 1; +} + +int ReadForwarderVersion(int fd) +{ + #ifdef TEST + *logofs << "Loop: Going to negotiate the forwarder version.\n" + << logofs_flush; + #endif + + // + // Check if we actually expect the session cookie. + // + + if (*authCookie == '\0') + { + #ifdef TEST + *logofs << "Loop: No authentication cookie required " + << "from FD#" << fd << ".\n" << logofs_flush; + #endif + + return 1; + } + + char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; + + int result = ReadRemoteData(fd, options, sizeof(options), ' '); + + if (result <= 0) + { + return result; + } + + #ifdef TEST + *logofs << "Loop: Received forwarder version string '" << options + << "' from FD#" << fd << ".\n" << logofs_flush; + #endif + + if (strncmp(options, "NXSSH-", strlen("NXSSH-")) != 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Parse error in forwarder options string '" + << options << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Parse error in forwarder options string '" + << options << "'.\n"; + + return -1; + } + + // + // Accept whatever forwarder version. + // + + sscanf(options, "NXSSH-%i.%i.%i", &(control -> RemoteVersionMajor), + &(control -> RemoteVersionMinor), &(control -> RemoteVersionPatch)); + + #ifdef TEST + *logofs << "Loop: Read forwarder version '" << control -> RemoteVersionMajor + << "." << control -> RemoteVersionMinor << "." << control -> RemoteVersionPatch + << "'.\n" << logofs_flush; + #endif + + return 1; +} + +int ReadForwarderOptions(int fd) +{ + // + // Get the forwarder cookie. + // + + if (*authCookie == '\0') + { + #ifdef TEST + *logofs << "Loop: No authentication cookie required " + << "from FD#" << fd << ".\n" << logofs_flush; + #endif + + return 1; + } + + char options[DEFAULT_REMOTE_OPTIONS_LENGTH]; + + int result = ReadRemoteData(fd, options, sizeof(options), ' '); + + if (result <= 0) + { + return result; + } + + #ifdef TEST + *logofs << "Loop: Received forwarder options string '" + << options << "' from FD#" << fd << ".\n" + << logofs_flush; + #endif + + if (ParseForwarderOptions(options) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Couldn't negotiate a valid " + << "cookie with the NX forwarder.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Couldn't negotiate a valid " + << "cookie with the NX forwarder.\n"; + + return -1; + } + + return 1; +} + +int ReadRemoteData(int fd, char *buffer, int size, char stop) +{ + #ifdef TEST + *logofs << "Loop: Going to read remote data from FD#" + << fd << ".\n" << logofs_flush; + #endif + + if (size >= MAXIMUM_REMOTE_OPTIONS_LENGTH) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Maximum remote options buffer " + << "limit exceeded.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Maximum remote options buffer " + << "limit exceeded.\n"; + + HandleCleanup(); + } + + while (remotePosition < (size - 1)) + { + int result = read(fd, remoteData + remotePosition, 1); + + getNewTimestamp(); + + if (result <= 0) + { + if (result == -1) + { + if (EGET() == EAGAIN) + { + #ifdef TEST + *logofs << "Loop: Reading data from FD#" << fd + << " would block.\n" << logofs_flush; + #endif + + return 0; + } + else if (EGET() == EINTR) + { + if (CheckAbort() != 0) + { + return -1; + } + + continue; + } + } + + #ifdef PANIC + *logofs << "Loop: PANIC! The remote NX proxy closed " + << "the connection.\n" << logofs_flush; + #endif + + cerr << "Error" << ": The remote NX proxy closed " + << "the connection.\n"; + + return -1; + } + else if (*(remoteData + remotePosition) == stop) + { + #ifdef TEST + *logofs << "Loop: Read stop character from FD#" + << fd << ".\n" << logofs_flush; + #endif + + remotePosition++; + + // + // Copy the fake terminating null + // in the buffer. + // + + *(remoteData + remotePosition) = '\0'; + + memcpy(buffer, remoteData, remotePosition + 1); + + #ifdef TEST + *logofs << "Loop: Remote string '" << remoteData + << "' read from FD#" << fd << ".\n" + << logofs_flush; + #endif + + int t = remotePosition; + + remotePosition = 0; + + return t; + } + else + { + // + // Make sure string received + // from far end is printable. + // + + if (isgraph(*(remoteData + remotePosition)) == 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Non printable character decimal '" + << (unsigned int) *(remoteData + remotePosition) + << "' received in remote data from FD#" + << fd << ".\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Non printable character decimal '" + << (unsigned int) *(remoteData + remotePosition) + << "' received in remote data from FD#" + << fd << ".\n" << logofs_flush; + + *(remoteData + remotePosition) = ' '; + } + + #ifdef DEBUG + *logofs << "Loop: Read a further character " + << "from FD#" << fd << ".\n" + << logofs_flush; + #endif + + remotePosition++; + } + } + + *(remoteData + remotePosition) = '\0'; + + #ifdef PANIC + *logofs << "Loop: PANIC! Stop character missing " + << "from FD#" << fd << " after " << remotePosition + << " characters read in string '" << remoteData + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Stop character missing " + << "from FD#" << fd << " after " << remotePosition + << " characters read in string '" << remoteData + << "'.\n"; + + memcpy(buffer, remoteData, remotePosition); + + remotePosition = 0; + + return -1; +} + +static int +hexval(char c) { + if ((c >= '0') && (c <= '9')) + return c - '0'; + if ((c >= 'a') && (c <= 'f')) + return c - 'a' + 10; + if ((c >= 'A') && (c <= 'F')) + return c - 'A' + 10; + return -1; +} + +static void +URLDecodeInPlace(char *str) { + if (str) { + char *to = str; + while (str[0]) { + if ((str[0] == '%') && + (hexval(str[1]) >= 0) && + (hexval(str[2]) >= 0)) { + *(to++) = hexval(str[1]) * 16 + hexval(str[2]); + str += 3; + } + else + *(to++) = *(str++); + } + *to = '\0'; + } +} + +int WriteLocalData(int fd, const char *buffer, int size) +{ + int position = 0; + int ret = 0; + fd_set writeSet; + struct timeval selectTs = {30, 0}; + + while (position < size) + { + + // A write to a non-blocking socket may fail with EAGAIN. The problem is + // that cache data is done in several writes, and there's no easy way + // to handle failure without rewriting a significant amount of code. + // + // Bailing out of the outer loop would result in restarting the sending + // of the entire cache list, which would confuse the other side. + + FD_ZERO(&writeSet); + FD_SET(fd, &writeSet); + + ret = select(fd+1, NULL, &writeSet, NULL, &selectTs); + + #ifdef DEBUG + *logofs << "Loop: WriteLocalData: select() returned with a code of " << ret << " and remaining timeout of " + << selectTs.tv_sec << " sec, " << selectTs.tv_usec << "usec\n" << logofs_flush; + #endif + + if ( ret < 0 ) + { + *logofs << "Loop: Error in select() when writing data to FD#" << fd << ": " << strerror(EGET()) << "\n" << logofs_flush; + + if ( EGET() == EINTR ) + continue; + + return -1; + } + else if ( ret == 0 ) + { + *logofs << "Loop: Timeout expired in select() when writing data to FD#" << fd << ": " << strerror(EGET()) << "\n" << logofs_flush; + return -1; + } + + int result = write(fd, buffer + position, size - position); + + getNewTimestamp(); + + if (result <= 0) + { + if (result < 0 && (EGET() == EINTR || EGET() == EAGAIN || EGET() == EWOULDBLOCK)) + { + continue; + } + + #ifdef TEST + *logofs << "Loop: Error writing data to FD#" + << fd << ".\n" << logofs_flush; + #endif + + return -1; + } + + position += result; + } + + return position; +} + +// +// Parse the string passed by calling process in +// the environment. This is not necessarily the +// content of DISPLAY variable, but can be the +// parameters passed when creating the process +// or thread. +// + +int ParseEnvironmentOptions(const char *env, int force) +{ + // + // Be sure log file is valid. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + // + // Be sure we have a parameters repository + // and a context to jump into because this + // can be called before creating the proxy. + // + + if (control == NULL) + { + control = new Control(); + } + + if (setjmp(context) == 1) + { + #ifdef TEST + *logofs << "Loop: Out of the long jump while parsing " + << "the environment options.\n" + << logofs_flush; + #endif + + return -1; + } + + if (force == 0 && parsedOptions == 1) + { + #ifdef TEST + *logofs << "Loop: Skipping a further parse of environment " + << "options string '" << (env != NULL ? env : "") + << "'.\n" << logofs_flush; + #endif + + return 1; + } + + if (env == NULL || *env == '\0') + { + #ifdef TEST + *logofs << "Loop: Nothing to do with empty environment " + << "options string '" << (env != NULL ? env : "") + << "'.\n" << logofs_flush; + #endif + + return 0; + } + + #ifdef TEST + *logofs << "Loop: Going to parse the environment options " + << "string '" << env << "'.\n" + << logofs_flush; + #endif + + parsedOptions = 1; + + // + // Copy the string passed as parameter + // because we need to modify it. + // + + char opts[DEFAULT_DISPLAY_OPTIONS_LENGTH]; + + #ifdef VALGRIND + + memset(opts, '\0', DEFAULT_DISPLAY_OPTIONS_LENGTH); + + #endif + + if (strlen(env) >= DEFAULT_DISPLAY_OPTIONS_LENGTH) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Environment options string '" << env + << "' exceeds length of " << DEFAULT_DISPLAY_OPTIONS_LENGTH + << " characters.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Environment options string '" << env + << "' exceeds length of " << DEFAULT_DISPLAY_OPTIONS_LENGTH + << " characters.\n"; + + return -1; + } + + strcpy(opts, env); + + char *nextOpts = opts; + + // + // Ensure that DISPLAY environment variable + // (roughly) follows the X convention for + // transport notation. + // + + if (strncasecmp(opts, "nx/nx,:", 7) == 0 || + strncasecmp(opts, "nx,:", 4) == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Parse error in options string '" + << opts << "' at 'nx,:'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Parse error in options string '" + << opts << "' at 'nx,:'.\n"; + + return -1; + } + else if (strncasecmp(opts, "nx/nx,", 6) == 0) + { + nextOpts += 6; + } + else if (strncasecmp(opts, "nx,", 3) == 0) + { + nextOpts += 3; + } + else if (strncasecmp(opts, "nx:", 3) == 0) + { + nextOpts += 3; + } + else if (force == 0) + { + #ifdef TEST + *logofs << "Loop: Ignoring host X server display string '" + << opts << "'.\n" << logofs_flush; + #endif + + return 0; + } + + // + // Save here the name of the options file and + // parse it after all the other options. + // + + char fileOptions[DEFAULT_STRING_LENGTH] = { 0 }; + + // + // The options string is intended to be a series + // of name/value tuples in the form name=value + // separated by the ',' character ended by a ':' + // followed by remote NX proxy port. + // + + char *name; + char *value; + + value = strrchr(nextOpts, ':'); + + if (value != NULL) + { + char *check = value + 1; + + if (*check == '\0' || isdigit(*check) == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify NX port in string '" + << value << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify NX port in string '" + << value << "'.\n"; + + return -1; + } + + proxyPort = atoi(check); + + // + // Get rid of the port specification. + // + + *value = '\0'; + } + else if (proxyPort == DEFAULT_NX_PROXY_PORT && force == 0) + { + // + // Complain only if user didn't specify + // the port on the command line. + // + + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify NX port in string '" + << opts << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify NX port in string '" + << opts << "'.\n"; + + return -1; + } + + #ifdef TEST + *logofs << "Loop: Parsing options string '" + << nextOpts << "'.\n" << logofs_flush; + #endif + + // + // Now all the other optional parameters. + // + + name = strtok(nextOpts, "="); + + char connectHost[DEFAULT_STRING_LENGTH] = { 0 }; + long connectPort = -1; + + while (name) + { + value = strtok(NULL, ","); + URLDecodeInPlace(value); + + if (CheckArg("environment", name, value) < 0) + { + return -1; + } + + if (strcasecmp(name, "options") == 0) + { + strncpy(fileOptions, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "display") == 0) + { + strncpy(displayHost, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "link") == 0) + { + + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else if (ParseLinkOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify 'link' option in string '" + << value << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify 'link' option in string '" + << value << "'.\n"; + if (ParseLinkOption("adsl") < 0) + return -1; + } + } + else if (strcasecmp(name, "limit") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else if (ParseBitrateOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify option 'limit' in string '" + << value << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify option 'limit' in string '" + << value << "'.\n"; + + return -1; + } + } + else if (strcasecmp(name, "type") == 0) + { + // + // Type of session, for example "desktop", + // "application", "windows", etc. + // + + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else + { + if (strcasecmp(value, "default") == 0) + { + *sessionType = '\0'; + } + else + { + strncpy(sessionType, value, DEFAULT_STRING_LENGTH - 1); + } + } + } + else if (strcasecmp(name, "listen") == 0) + { + char *socketUri = NULL; + if (connectSocket.getSpec(&socketUri)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't handle 'listen' and 'connect' parameters " + << "at the same time.\n" << logofs_flush; + + *logofs << "Loop: PANIC! Refusing 'listen' parameter with 'connect' being '" + << socketUri << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't handle 'listen' and 'connect' parameters " + << "at the same time.\n"; + + cerr << "Error" << ": Refusing 'listen' parameter with 'connect' being '" + << socketUri << "'.\n"; + + free(socketUri); + return -1; + } + + SetAndValidateChannelEndPointArg("local", name, value, listenSocket); + + } + else if (strcasecmp(name, "loopback") == 0) + { + loopbackBind = ValidateArg("local", name, value); + } + else if (strcasecmp(name, "accept") == 0) + { + char *socketUri = NULL; + if (connectSocket.getSpec(&socketUri)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't handle 'accept' and 'connect' parameters " + << "at the same time.\n" << logofs_flush; + + *logofs << "Loop: PANIC! Refusing 'accept' parameter with 'connect' being '" + << socketUri << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't handle 'accept' and 'connect' parameters " + << "at the same time.\n"; + + cerr << "Error" << ": Refusing 'accept' parameter with 'connect' being '" + << socketUri << "'.\n"; + + free(socketUri); + return -1; + } + + strncpy(acceptHost, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "connect") == 0) + { + if (*acceptHost != '\0') + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't handle 'connect' and 'accept' parameters " + << "at the same time.\n" << logofs_flush; + + *logofs << "Loop: PANIC! Refusing 'connect' parameter with 'accept' being '" + << acceptHost << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't handle 'connect' and 'accept' parameters " + << "at the same time.\n"; + + cerr << "Error" << ": Refusing 'connect' parameter with 'accept' being '" + << acceptHost << "'.\n"; + + return -1; + } + if ((strncmp(value, "tcp:", 4) == 0) || (strncmp(value, "unix:", 5) == 0)) + SetAndValidateChannelEndPointArg("local", name, value, connectSocket); + else + // if the "connect" parameter does not start with "unix:" or "tcp:" assume + // old parameter usage style (providing hostname string only). + strcpy(connectHost, value); + } + else if (strcasecmp(name, "port") == 0) + { + connectPort = ValidateArg("local", name, value); + } + else if (strcasecmp(name, "retry") == 0) + { + control -> OptionProxyRetryConnect = ValidateArg("local", name, value); + control -> OptionServerRetryConnect = ValidateArg("local", name, value); + } + else if (strcasecmp(name, "session") == 0) + { + strncpy(sessionFileName, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "errors") == 0) + { + // + // The old name of the parameter was 'log' + // but the default name for the file is + // 'errors' so it is more logical to use + // the same name. + // + + strncpy(errorsFileName, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "root") == 0) + { + strncpy(rootDir, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "id") == 0) + { + strncpy(sessionId, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "stats") == 0) + { + control -> EnableStatistics = 1; + + strncpy(statsFileName, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "cookie") == 0) + { + LowercaseArg("local", name, value); + + strncpy(authCookie, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "nodelay") == 0) + { + useNoDelay = ValidateArg("local", name, value); + } + else if (strcasecmp(name, "policy") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else + { + usePolicy = ValidateArg("local", name, value); + } + } + else if (strcasecmp(name, "render") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else + { + useRender = ValidateArg("local", name, value); + } + } + else if (strcasecmp(name, "taint") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else + { + useTaint = ValidateArg("local", name, value); + } + } + else if (strcasecmp(name, "delta") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else + { + control -> LocalDeltaCompression = ValidateArg("local", name, value); + } + } + else if (strcasecmp(name, "data") == 0) + { + control -> LocalDataCompressionLevel = ValidateArg("local", name, value); + + if (control -> LocalDataCompressionLevel == 0) + { + control -> LocalDataCompression = 0; + } + else + { + control -> LocalDataCompression = 1; + } + } + else if (strcasecmp(name, "stream") == 0) + { + control -> LocalStreamCompressionLevel = ValidateArg("local", name, value); + + if (control -> LocalStreamCompressionLevel == 0) + { + control -> LocalStreamCompression = 0; + } + else + { + control -> LocalStreamCompression = 1; + } + } + else if (strcasecmp(name, "memory") == 0) + { + control -> LocalMemoryLevel = ValidateArg("local", name, value); + } + else if (strcasecmp(name, "cache") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else if (ParseCacheOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify cache size for string '" + << value << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify cache size for string '" + << value << "'.\n"; + + return -1; + } + } + else if (strcasecmp(name, "images") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else if (ParseImagesOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify images cache size for string '" + << value << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify images cache size for string '" + << value << "'.\n"; + + return -1; + } + } + else if (strcasecmp(name, "shseg") == 0) + { + // + // The 'shmem' option is used by the agent, together + // with 'shpix' literal. We make the 'shseg' option + // specific to the proxy and use it to determine the + // size of the shared memory segment, or otherwise 0, + // if the use of the shared memory extension should + // not be enabled on the real X server. + // + + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else if (ParseShmemOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify size of shared memory " + << "segment in string '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify size of shared memory " + << "segment in string '" << value << "'.\n"; + + return -1; + } + } + else if (strcasecmp(name, "load") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else + { + control -> PersistentCacheEnableLoad = ValidateArg("local", name, value); + + if (control -> PersistentCacheEnableLoad > 0) + { + control -> PersistentCacheEnableLoad = 1; + } + else + { + if (control -> PersistentCacheName != NULL) + { + delete [] control -> PersistentCacheName; + } + + control -> PersistentCacheName = NULL; + + control -> PersistentCacheEnableLoad = 0; + } + } + } + else if (strcasecmp(name, "save") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else + { + control -> PersistentCacheEnableSave = ValidateArg("local", name, value); + + if (control -> PersistentCacheEnableSave > 0) + { + control -> PersistentCacheEnableSave = 1; + } + else + { + if (control -> PersistentCacheName != NULL) + { + delete [] control -> PersistentCacheName; + } + + control -> PersistentCacheName = NULL; + + control -> PersistentCacheEnableSave = 0; + } + } + } + else if (strcasecmp(name, "cups") == 0) + { + SetAndValidateChannelEndPointArg("local", name, value, cupsPort); + } + else if (strcasecmp(name, "sync") == 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! No 'sync' channel in current version. " + << "Assuming 'cups' channel.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": No 'sync' channel in current version. " + << "Assuming 'cups' channel.\n"; + + SetAndValidateChannelEndPointArg("local", name, value, cupsPort); + } + else if (strcasecmp(name, "keybd") == 0 || + strcasecmp(name, "aux") == 0) + { + SetAndValidateChannelEndPointArg("local", name, value, auxPort); + } + else if (strcasecmp(name, "samba") == 0 || + strcasecmp(name, "smb") == 0) + { + SetAndValidateChannelEndPointArg("local", name, value, smbPort); + } + else if (strcasecmp(name, "media") == 0) + { + SetAndValidateChannelEndPointArg("local", name, value, mediaPort); + } + else if (strcasecmp(name, "http") == 0) + { + SetAndValidateChannelEndPointArg("local", name, value, httpPort); + } + else if (strcasecmp(name, "font") == 0) + { + strncpy(fontPort, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "slave") == 0) + { + SetAndValidateChannelEndPointArg("local", name, value, slavePort); + } + else if (strcasecmp(name, "mask") == 0) + { + control -> ChannelMask = ValidateArg("local", name, value); + } + else if (strcasecmp(name, "timeout") == 0) + { + int timeout = ValidateArg("local", name, value); + + if (timeout == 0) + { + #ifdef TEST + *logofs << "Loop: Disabling timeout on broken " + << "proxy connection.\n" << logofs_flush; + #endif + + control -> ProxyTimeout = 0; + } + else + { + control -> ProxyTimeout = timeout * 1000; + } + } + else if (strcasecmp(name, "cleanup") == 0) + { + int cleanup = ValidateArg("local", name, value); + + if (cleanup == 0) + { + #ifdef TEST + *logofs << "Loop: Disabling grace timeout on " + << "proxy shutdown.\n" << logofs_flush; + #endif + + control -> CleanupTimeout = 0; + } + else + { + control -> CleanupTimeout = cleanup * 1000; + } + } + else if (strcasecmp(name, "pack") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else if (ParsePackOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify pack method for string '" + << value << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify pack method for string '" + << value << "'.\n"; + if (ParsePackOption("nopack")<0) + return -1; + } + } + else if (strcasecmp(name, "core") == 0) + { + control -> EnableCoreDumpOnAbort = ValidateArg("local", name, value); + } + else if (strcasecmp(name, "kill") == 0) + { + if (control -> KillDaemonOnShutdownNumber < + control -> KillDaemonOnShutdownLimit) + { + #ifdef TEST + *logofs << "Loop: WARNING! Adding process with pid '" + << ValidateArg("local", name, value) << " to the " + << "daemons to kill at shutdown.\n" + << logofs_flush; + #endif + + control -> KillDaemonOnShutdown[control -> + KillDaemonOnShutdownNumber] = + ValidateArg("local", name, value); + + control -> KillDaemonOnShutdownNumber++; + } + else + { + #ifdef WARNING + *logofs << "Loop: WARNING! Number of daemons to kill " + << "at shutdown exceeded.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Number of daemons to kill " + << "at shutdown exceeded.\n"; + } + } + else if (strcasecmp(name, "strict") == 0) + { + if (control -> ProxyMode == proxy_server) + { + PrintOptionIgnored("local", name, value); + } + else + { + useStrict = ValidateArg("local", name, value); + } + } + else if (strcasecmp(name, "encryption") == 0) + { + useEncryption = ValidateArg("local", name, value); + } + else if (strcasecmp(name, "product") == 0) + { + strncpy(productName, value, DEFAULT_STRING_LENGTH - 1); + } + else if (strcasecmp(name, "rootless") == 0 || + strcasecmp(name, "geometry") == 0 || + strcasecmp(name, "resize") == 0 || + strcasecmp(name, "fullscreen") == 0 || + strcasecmp(name, "keyboard") == 0 || + strcasecmp(name, "clipboard") == 0 || + strcasecmp(name, "streaming") == 0 || + strcasecmp(name, "backingstore") == 0 || + strcasecmp(name, "sleep") == 0 || + strcasecmp(name, "tolerancechecks") == 0) + { + #ifdef DEBUG + *logofs << "Loop: Ignoring agent option '" << name + << "' with value '" << value << "'.\n" + << logofs_flush; + #endif + } + else if (strcasecmp(name, "composite") == 0 || + strcasecmp(name, "shmem") == 0 || + strcasecmp(name, "shpix") == 0 || + strcasecmp(name, "kbtype") == 0 || + strcasecmp(name, "client") == 0 || + strcasecmp(name, "shadow") == 0 || + strcasecmp(name, "shadowuid") == 0 || + strcasecmp(name, "shadowmode") == 0 || + strcasecmp(name, "clients") == 0 || + strcasecmp(name, "xinerama") == 0) + { + #ifdef DEBUG + *logofs << "Loop: Ignoring agent option '" << name + << "' with value '" << value << "'.\n" + << logofs_flush; + #endif + } + else if (strcasecmp(name, "defer") == 0 || + strcasecmp(name, "tile") == 0 || + strcasecmp(name, "menu") == 0 || + strcasecmp(name, "state") == 0 ) + { + #ifdef DEBUG + *logofs << "Loop: Ignoring agent option '" << name + << "' with value '" << value << "'.\n" + << logofs_flush; + #endif + } + else + { + #ifdef WARNING + *logofs << "Loop: WARNING! Ignoring unknown option '" + << name << "' with value '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Ignoring unknown option '" + << name << "' with value '" << value << "'.\n"; + } + + name = strtok(NULL, "="); + + } // End of while (name) ... + + // Assemble the connectSocket channel end point if parameter values have been old-school... + if (connectSocket.disabled() && (connectHost[0] != '\0') && (proxyPort > 0 || connectPort > 0)) + { + if (connectPort < 0) + connectPort = proxyPort + DEFAULT_NX_PROXY_PORT_OFFSET; + + char tcpHostAndPort[DEFAULT_STRING_LENGTH] = { 0 }; + sprintf(tcpHostAndPort, "tcp:%s:%ld", connectHost, connectPort); + SetAndValidateChannelEndPointArg("local", name, tcpHostAndPort, connectSocket); + } + + #ifdef TEST + *logofs << "Loop: Completed parsing of string '" + << env << "'.\n" << logofs_flush; + #endif + + if ((*fileOptions != '\0') && (strncmp(fileOptions, "/dev/", 5) != 0) && (strncmp(fileOptions, "/proc/", 6) != 0) && (strncmp(fileOptions, "/sys/", 5) != 0)) + { + if (strcmp(fileOptions, optionsFileName) != 0) + { + #ifdef TEST + *logofs << "Loop: Reading options from '" << fileOptions + << "'.\n" << logofs_flush; + #endif + + if (ParseFileOptions(fileOptions) < 0) + { + return -1; + } + } + #ifdef WARNING + else + { + *logofs << "Loop: WARNING! Name of the options file " + << "specified multiple times. Not parsing " + << "again.\n" << logofs_flush; + } + #endif + + if (*optionsFileName == '\0') + { + strncpy(optionsFileName, value, DEFAULT_STRING_LENGTH - 1); + + #ifdef TEST + *logofs << "Loop: Assuming name of options file '" + << optionsFileName << "'.\n" + << logofs_flush; + #endif + } + } + + // + // If port where proxy is acting as an X server + // was not specified assume the same port where + // proxy is listening for the remote peer. + // + + if (xPort == DEFAULT_NX_X_PORT) + { + xPort = proxyPort; + } + + return 1; +} + +// +// Parse the command line options passed by user when +// running proxy in stand alone mode. Note that passing +// parameters this way is strongly discouraged. These +// command line switch can change (and they do often). +// Please, use the form "option=value" instead and set +// the DISPLAY environment variable. +// + +int ParseCommandLineOptions(int argc, const char **argv) +{ + // + // Be sure log file is valid. + // + + if (logofs == NULL) + { + logofs = &cerr; + } + + if (setjmp(context) == 1) + { + #ifdef TEST + *logofs << "Loop: Out of the long jump while parsing " + << "the command line options.\n" + << logofs_flush; + #endif + + return -1; + } + + // + // Be sure we have a parameters repository + // + + if (control == NULL) + { + control = new Control(); + } + + if (parsedCommand == 1) + { + #ifdef TEST + *logofs << "Loop: Skipping a further parse of command line options.\n" + << logofs_flush; + #endif + + return 1; + } + + #ifdef TEST + *logofs << "Loop: Going to parse the command line options.\n" + << logofs_flush; + #endif + + parsedCommand = 1; + + // + // Print out arguments. + // + + #ifdef TEST + + *logofs << "Loop: Argc is " << argc << ".\n" << logofs_flush; + + for (int argi = 0; argi < argc; argi++) + { + *logofs << "Loop: Argv[" << argi << "] is " << argv[argi] + << ".\n" << logofs_flush; + } + + #endif + + // + // Shall use getopt here. + // + + for (int argi = 1; argi < argc; argi++) + { + const char *nextArg = argv[argi]; + + if (*nextArg == '-') + { + switch (*(nextArg + 1)) + { + case 'h': + { + PrintUsageInfo(nextArg, 0); + + return -1; + } + case 'C': + { + // + // Start proxy in CLIENT mode. + // + + if (WE_SET_PROXY_MODE == 0) + { + #ifdef TEST + *logofs << "Loop: Setting local proxy mode to proxy_client.\n" + << logofs_flush; + #endif + + control -> ProxyMode = proxy_client; + } + else if (control -> ProxyMode != proxy_client) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't redefine local proxy to " + << "client mode.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't redefine local proxy to " + << "client mode.\n"; + + return -1; + } + + break; + } + case 'S': + { + // + // Start proxy in SERVER mode. + // + + if (WE_SET_PROXY_MODE == 0) + { + #ifdef TEST + *logofs << "Loop: Setting local proxy mode to proxy_server.\n" + << logofs_flush; + #endif + + control -> ProxyMode = proxy_server; + } + else if (control -> ProxyMode != proxy_server) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't redefine local proxy to " + << "server mode.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't redefine local proxy to " + << "server mode.\n"; + + return -1; + } + + break; + } + case 'v': + { + PrintVersionInfo(); + + return -1; + } + default: + { + PrintUsageInfo(nextArg, 1); + + // + // Function GetArg() is not used anymore. + // Add a dummy call to avoid the warning. + // + + if (0) + { + GetArg(argi, argc, argv); + } + + return -1; + } + } + } + else + { + if (nextArg) + { + // + // Try to parse the option as a remote host:port + // specification as in 'localhost:8'. Such a + // parameter can be specified at the end of the + // command line at the connecting side. + // + + char cHost[DEFAULT_STRING_LENGTH] = { '\0' }; + long cPort = 0; + + if (ParseHostOption(nextArg, cHost, cPort) > 0) + { + // + // Assume port is at a proxied display offset. + // + + proxyPort = cPort; + + cPort += DEFAULT_NX_PROXY_PORT_OFFSET; + connectSocket.setSpec(cHost, cPort); + + } + else if (ParseEnvironmentOptions(nextArg, 1) < 0) + { + return -1; + } + } + } + } + + return 1; +} + +// +// Set the variable to the values of host and +// port where this proxy is going to hook to +// an existing proxy. +// + +int ParseBindOptions(char **host, int *port) +{ + if (*bindHost != '\0') + { + *host = bindHost; + *port = bindPort; + + return 1; + } + else + { + return 0; + } +} + +// +// Read options from file and merge with environment. +// + +int ParseFileOptions(const char *file) +{ + char *fileName; + + if (*file != '/' && *file != '.') + { + char *filePath = GetSessionPath(); + + if (filePath == NULL) + { + cerr << "Error" << ": Cannot determine directory for NX option file.\n"; + + HandleCleanup(); + } + + fileName = new char[strlen(filePath) + strlen("/") + + strlen(file) + 1]; + + strcpy(fileName, filePath); + + strcat(fileName, "/"); + strcat(fileName, file); + + delete [] filePath; + } + else + { + fileName = new char[strlen(file) + 1]; + + strcpy(fileName, file); + } + + #ifdef TEST + *logofs << "Loop: Going to read options from file '" + << fileName << "'.\n" << logofs_flush; + #endif + + FILE *filePtr = fopen(fileName, "r"); + + if (filePtr == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't open options file '" << fileName + << "'. Error is " << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't open options file '" << fileName + << "'. Error is " << EGET() << " '" << ESTR() << "'.\n"; + + delete [] fileName; + + return -1; + } + + char options[DEFAULT_DISPLAY_OPTIONS_LENGTH]; + + #ifdef VALGRIND + + memset(options, '\0', DEFAULT_DISPLAY_OPTIONS_LENGTH); + + #endif + + if (fgets(options, DEFAULT_DISPLAY_OPTIONS_LENGTH, filePtr) == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't read options from file '" << fileName + << "'. Error is " << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't read options from file '" << fileName + << "'. Error is " << EGET() << " '" << ESTR() << "'.\n"; + + fclose(filePtr); + + delete [] fileName; + + return -1; + } + + fclose(filePtr); + + // + // Purge the newline and the other non- + // printable characters in the string. + // + + char *next = options; + + while (*next != '\0') + { + if (isprint(*next) == 0) + { + *next = '\0'; + } + + next++; + } + + #ifdef TEST + *logofs << "Loop: Read options '" << options << "' from file '" + << fileName << "'.\n" << logofs_flush; + #endif + + if (ParseEnvironmentOptions(options, 1) < 0) + { + delete [] fileName; + + return -1; + } + + delete [] fileName; + + return 1; +} + +// +// Parse the option string passed from the +// remote proxy at startup. +// + +int ParseRemoteOptions(char *opts) +{ + #ifdef TEST + *logofs << "Loop: Going to parse the remote options " + << "string '" << opts << "'.\n" + << logofs_flush; + #endif + + char *name; + char *value; + + // + // The options string is intended to be a series + // of name/value tuples in the form name=value + // separated by the ',' character. + // + + int hasCookie = 0; + int hasLink = 0; + int hasPack = 0; + int hasCache = 0; + int hasImages = 0; + int hasDelta = 0; + int hasStream = 0; + int hasData = 0; + int hasType = 0; + + // + // Get rid of the terminating space. + // + + if (*(opts + strlen(opts) - 1) == ' ') + { + *(opts + strlen(opts) - 1) = '\0'; + } + + name = strtok(opts, "="); + + while (name) + { + value = strtok(NULL, ","); + + if (CheckArg("remote", name, value) < 0) + { + return -1; + } + + if (strcasecmp(name, "cookie") == 0) + { + if (WE_PROVIDE_CREDENTIALS) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Ignoring remote option 'cookie' " + << "with value '" << value << "' when initiating " + << "connection.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Ignoring remote option 'cookie' " + << "with value '" << value << "' when initiating " + << "connection.\n"; + } + else if (strncasecmp(authCookie, value, strlen(authCookie)) != 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Authentication cookie '" << value + << "' doesn't match '" << authCookie << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Authentication cookie '" << value + << "' doesn't match '" << authCookie << "'.\n"; + + return -1; + } + + hasCookie = 1; + } + else if (strcasecmp(name, "link") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + if (*linkSpeedName != '\0' && strcasecmp(linkSpeedName, value) != 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Overriding option 'link' " + << "with new value '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Overriding option 'link' " + << "with new value '" << value << "'.\n"; + } + + if (ParseLinkOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify remote 'link' " + << "option in string '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify remote 'link' " + << "option in string '" << value << "'.\n"; + + return -1; + } + } + + hasLink = 1; + } + else if (strcasecmp(name, "pack") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + if (*packMethodName != '\0' && strcasecmp(packMethodName, value) != 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Overriding option 'pack' " + << "with remote value '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Overriding option 'pack' " + << "with remote value '" << value << "'.\n"; + } + + if (ParsePackOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid pack option '" + << value << "' requested by remote.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid pack option '" + << value << "' requested by remote.\n"; + + return -1; + } + } + + hasPack = 1; + } + else if (strcasecmp(name, "cache") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + // + // Cache size is sent as a hint of how much memory + // the remote proxy is going to consume. A very low + // powered thin client could choose to refuse the + // connection. + // + + if (ParseCacheOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify remote 'cache' " + << "option in string '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify remote 'cache' " + << "option in string '" << value << "'.\n"; + + return -1; + } + } + + hasCache = 1; + } + else if (strcasecmp(name, "images") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + // + // Images cache size is sent as a hint. + // There is no obbligation for the local + // proxy to use the persistent cache. + // + + if (ParseImagesOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify remote 'images' " + << "option in string '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify remote 'images' " + << "option in string '" << value << "'.\n"; + + return -1; + } + } + + hasImages = 1; + } + else if (strcasecmp(name, "limit") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + if (*bitrateLimitName != '\0' && + strcasecmp(bitrateLimitName, value) != 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Overriding option 'limit' " + << "with new value '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Overriding option 'limit' " + << "with new value '" << value << "'.\n"; + } + + if (ParseBitrateOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify 'limit' " + << "option in string '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify 'limit' " + << "option in string '" << value << "'.\n"; + + return -1; + } + } + + } + else if (strcasecmp(name, "render") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + useRender = ValidateArg("remote", name, value); + } + + } + else if (strcasecmp(name, "taint") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + useTaint = ValidateArg("remote", name, value); + } + + } + else if (strcasecmp(name, "type") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + if (strcasecmp(value, "default") == 0) + { + *sessionType = '\0'; + } + else + { + strncpy(sessionType, value, DEFAULT_STRING_LENGTH - 1); + } + } + + hasType = 1; + } + else if (strcasecmp(name, "strict") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + useStrict = ValidateArg("remote", name, value); + } + + } + else if (strcasecmp(name, "shseg") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else if (ParseShmemOption(value) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't identify size of shared memory " + << "segment in string '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify size of shared memory " + << "segment in string '" << value << "'.\n"; + + return -1; + } + + } + else if (strcasecmp(name, "delta") == 0) + { + if (control -> ProxyMode == proxy_client) + { + PrintOptionIgnored("remote", name, value); + } + else + { + control -> RemoteDeltaCompression = ValidateArg("remote", name, value); + + // + // Follow for delta compression the + // same settings as the client proxy. + // + + control -> LocalDeltaCompression = control -> RemoteDeltaCompression; + } + + hasDelta = 1; + } + else if (strcasecmp(name, "stream") == 0) + { + // + // If remote side didn't choose its own + // stream compression level then assume + // local settings. + // + + if (strcasecmp(value, "default") == 0) + { + // + // This applies only at client side. + // + + control -> RemoteStreamCompression = + control -> LocalStreamCompression; + + control -> RemoteStreamCompressionLevel = + control -> LocalStreamCompressionLevel; + } + else + { + control -> RemoteStreamCompressionLevel = ValidateArg("remote", name, value); + + if (control -> RemoteStreamCompressionLevel > 0) + { + control -> RemoteStreamCompression = 1; + } + else + { + control -> RemoteStreamCompression = 0; + } + + if (control -> LocalStreamCompressionLevel < 0) + { + control -> LocalStreamCompressionLevel = ValidateArg("remote", name, value); + + if (control -> LocalStreamCompressionLevel > 0) + { + control -> LocalStreamCompression = 1; + } + else + { + control -> LocalStreamCompression = 0; + } + } + } + + hasStream = 1; + } + else if (strcasecmp(name, "data") == 0) + { + // + // Apply the same to data compression level. + // + + if (strcasecmp(value, "default") == 0) + { + control -> RemoteDataCompression = + control -> LocalDataCompression; + + control -> RemoteDataCompressionLevel = + control -> LocalDataCompressionLevel; + } + else + { + control -> RemoteDataCompressionLevel = ValidateArg("remote", name, value); + + if (control -> RemoteDataCompressionLevel > 0) + { + control -> RemoteDataCompression = 1; + } + else + { + control -> RemoteDataCompression = 0; + } + + if (control -> LocalDataCompressionLevel < 0) + { + control -> LocalDataCompressionLevel = ValidateArg("remote", name, value); + + if (control -> LocalDataCompressionLevel > 0) + { + control -> LocalDataCompression = 1; + } + else + { + control -> LocalDataCompression = 0; + } + } + } + + hasData = 1; + } + else if (strcasecmp(name, "flush") == 0) + { + // + // This option has no effect in recent + // versions. + // + + #ifdef DEBUG + *logofs << "Loop: Ignoring obsolete remote option '" + << name << "' with value '" << value + << "'.\n" << logofs_flush; + #endif + } + else + { + #ifdef WARNING + *logofs << "Loop: WARNING! Ignoring unknown remote option '" + << name << "' with value '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Ignoring unknown remote option '" + << name << "' with value '" << value << "'.\n"; + } + + name = strtok(NULL, "="); + + } // End of while (name) ... + + // + // If we are client side, we need remote 'stream' + // and 'data' options. If we are server, we need + // all the above plus 'link' and some others. + // + + char missing[DEFAULT_STRING_LENGTH]; + + *missing = '\0'; + + if (control -> ProxyMode == proxy_client) + { + if (hasStream == 0) + { + strcpy(missing, "stream"); + } + else if (hasData == 0) + { + strcpy(missing, "data"); + } + } + else + { + // + // Don't complain if the optional 'flush', + // 'render' and 'taint' options are not + // provided. + // + + if (hasLink == 0) + { + strcpy(missing, "link"); + } + else if (hasCache == 0) + { + strcpy(missing, "cache"); + } + else if (hasPack == 0) + { + strcpy(missing, "pack"); + } + else if (hasDelta == 0) + { + strcpy(missing, "delta"); + } + else if (hasStream == 0) + { + strcpy(missing, "stream"); + } + else if (hasData == 0) + { + strcpy(missing, "data"); + } + else if (hasType == 0) + { + strcpy(missing, "type"); + } + else if (hasImages == 0) + { + strcpy(missing, "images"); + } + } + + if (WE_PROVIDE_CREDENTIALS == 0) + { + // + // Can be that user doesn't have requested to + // check the authorization cookie provided by + // the connecting peer. + // + + if (hasCookie == 0 && *authCookie != '\0') + { + strcpy(missing, "cookie"); + } + } + + if (*missing != '\0') + { + #ifdef PANIC + *logofs << "Loop: PANIC! The remote peer didn't specify the option '" + << missing << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": The remote peer didn't specify the option '" + << missing << "'.\n"; + + return -1; + } + + return 1; +} + +// +// Parse the cookie provided by the NX proxy +// connection forwarder. +// + +int ParseForwarderOptions(char *opts) +{ + #ifdef TEST + *logofs << "Loop: Going to parse the forwarder options " + << "string '" << opts << "'.\n" + << logofs_flush; + #endif + + char *name; + char *value; + + int hasCookie = 0; + + // + // Get rid of the terminating space. + // + + if (*(opts + strlen(opts) - 1) == ' ') + { + *(opts + strlen(opts) - 1) = '\0'; + } + + name = strtok(opts, "="); + + while (name) + { + value = strtok(NULL, ","); + + if (CheckArg("forwarder", name, value) < 0) + { + return -1; + } + + if (strcasecmp(name, "cookie") == 0) + { + if (strncasecmp(authCookie, value, strlen(authCookie)) != 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! The NX forwarder cookie '" << value + << "' doesn't match '" << authCookie << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": The NX forwarder cookie '" << value + << "' doesn't match '" << authCookie << "'.\n"; + + return -1; + } + + hasCookie = 1; + } + else + { + #ifdef WARNING + *logofs << "Loop: WARNING! Ignoring unknown forwarder option '" + << name << "' with value '" << value << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Ignoring unknown forwarder option '" + << name << "' with value '" << value << "'.\n"; + } + + name = strtok(NULL, "="); + + } // End of while (name) ... + + if (hasCookie == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! The NX forwarder didn't provide " + << "the authentication cookie.\n" << logofs_flush; + #endif + + cerr << "Error" << ": The NX forwarder didn't provide " + << "the authentication cookie.\n"; + + return -1; + } + + return 1; +} + +int SetCore() +{ + #ifdef COREDUMPS + + rlimit rlim; + + if (getrlimit(RLIMIT_CORE, &rlim)) + { + #ifdef TEST + *logofs << "Loop: Cannot read RLIMIT_CORE. Error is '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + return -1; + } + + if (rlim.rlim_cur < rlim.rlim_max) + { + rlim.rlim_cur = rlim.rlim_max; + + if (setrlimit(RLIMIT_CORE, &rlim)) + { + #ifdef TEST + *logofs << "Loop: Cannot set RLIMIT_CORE. Error is '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + return -2; + } + } + + #ifdef TEST + *logofs << "Loop: RLIMIT_CORE is "<< rlim.rlim_max + << ".\n" << logofs_flush; + #endif + + #endif // #ifdef COREDUMPS + + return 1; +} + +char *GetLastCache(char *listBuffer, const char *searchPath) +{ + if (listBuffer == NULL || searchPath == NULL || + strncmp(listBuffer, "cachelist=", strlen("cachelist=")) != 0) + { + #ifdef TEST + *logofs << "Loop: Invalid parameters '" << listBuffer << "' and '" + << (searchPath != NULL ? searchPath : "") + << "'. Can't select any cache.\n" << logofs_flush; + #endif + + return NULL; + } + + char *selectedName = new char[MD5_LENGTH * 2 + 3]; + + *selectedName = '\0'; + + const char *localPrefix; + const char *remotePrefix; + + if (control -> ProxyMode == proxy_client) + { + localPrefix = "C-"; + remotePrefix = "S-"; + } + else + { + localPrefix = "S-"; + remotePrefix = "C-"; + } + + // + // Get rid of prefix. + // + + listBuffer += strlen("cachelist="); + + char *fileName; + + fileName = strtok(listBuffer, ","); + + // + // It is "/path/to/file" + "/" + "C-" + 32 + "\0". + // + + char fullPath[strlen(searchPath) + MD5_LENGTH * 2 + 4]; + + time_t selectedTime = 0; + + struct stat fileStat; + + while (fileName) + { + if (strncmp(fileName, "none", strlen("none")) == 0) + { + #ifdef TEST + *logofs << "Loop: No cache files seem to be available.\n" + << logofs_flush; + #endif + + delete [] selectedName; + + return NULL; + } + else if (strlen(fileName) != MD5_LENGTH * 2 + 2 || + strncmp(fileName, remotePrefix, 2) != 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Bad cache file name '" + << fileName << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Bad cache file name '" + << fileName << "'.\n"; + + delete [] selectedName; + + HandleCleanup(); + } + + #ifdef TEST + *logofs << "Loop: Parsing remote cache name '" + << fileName << "'.\n" << logofs_flush; + #endif + + // + // Prefix, received as "S-", becomes + // "C-" and viceversa. + // + + *fileName = *localPrefix; + + strcpy(fullPath, searchPath); + strcat(fullPath, "/"); + strcat(fullPath, fileName); + + if (stat(fullPath, &fileStat) == 0) + { + #ifdef TEST + *logofs << "Loop: Found a matching cache '" + << fullPath << "'.\n" << logofs_flush; + #endif + + if (fileStat.st_mtime >= selectedTime) + { + strcpy(selectedName, fileName); + + selectedTime = fileStat.st_mtime; + } + } + #ifdef TEST + else + { + *logofs << "Loop: Can't get stats of file '" + << fullPath << "'.\n" << logofs_flush; + } + #endif + + fileName = strtok(NULL, ","); + } + + if (*selectedName != '\0') + { + return selectedName; + } + else + { + delete [] selectedName; + + return NULL; + } +} + +char *GetTempPath() +{ + if (*tempDir == '\0') + { + // + // Check the NX_TEMP environment, first, + // then the TEMP variable. + // + + const char *tempEnv = getenv("NX_TEMP"); + + if (tempEnv == NULL || *tempEnv == '\0') + { + #ifdef TEST + *logofs << "Loop: WARNING! No environment for NX_TEMP.\n" + << logofs_flush; + #endif + + tempEnv = getenv("TEMP"); + + if (tempEnv == NULL || *tempEnv == '\0') + { + #ifdef TEST + *logofs << "Loop: WARNING! No environment for TEMP.\n" + << logofs_flush; + #endif + + tempEnv = "/tmp"; + } + } + + if (strlen(tempEnv) > DEFAULT_STRING_LENGTH - 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value for the NX " + << "temporary directory '" << tempEnv + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value for the NX " + << "temporary directory '" << tempEnv + << "'.\n"; + + HandleCleanup(); + } + + strcpy(tempDir, tempEnv); + + #ifdef TEST + *logofs << "Loop: Assuming temporary NX directory '" + << tempDir << "'.\n" << logofs_flush; + #endif + } + + char *tempPath = new char[strlen(tempDir) + 1]; + + if (tempPath == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't allocate memory " + << "for the temp path.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory " + << "for the temp path.\n"; + + HandleCleanup(); + } + + strcpy(tempPath, tempDir); + + return tempPath; +} + +char *GetClientPath() +{ + if (*clientDir == '\0') + { + // + // Check the NX_CLIENT environment. + // + + const char *clientEnv = getenv("NX_CLIENT"); + + if (clientEnv == NULL || *clientEnv == '\0') + { + #ifdef TEST + *logofs << "Loop: WARNING! No environment for NX_CLIENT.\n" + << logofs_flush; + #endif + + // + // Try to guess the location of the client. + // + + clientEnv = "/usr/NX/bin/nxclient"; + + #ifdef __APPLE__ + + clientEnv = "/Applications/NX Client for OSX.app/Contents/MacOS/nxclient"; + + #endif + + #ifdef __CYGWIN32__ + + clientEnv = "C:\\Program Files\\NX Client for Windows\\nxclient"; + + #endif + } + + if (strlen(clientEnv) > DEFAULT_STRING_LENGTH - 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value for the NX " + << "client directory '" << clientEnv + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value for the NX " + << "client directory '" << clientEnv + << "'.\n"; + + HandleCleanup(); + } + + strcpy(clientDir, clientEnv); + + #ifdef TEST + *logofs << "Loop: Assuming NX client location '" + << clientDir << "'.\n" << logofs_flush; + #endif + } + + char *clientPath = new char[strlen(clientDir) + 1]; + + if (clientPath == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't allocate memory " + << "for the client path.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory " + << "for the client path.\n"; + + HandleCleanup(); + } + + strcpy(clientPath, clientDir); + + return clientPath; +} + +char *GetSystemPath() +{ + if (*systemDir == '\0') + { + // + // Check the NX_SYSTEM environment. + // + + const char *systemEnv = getenv("NX_SYSTEM"); + + if (systemEnv == NULL || *systemEnv == '\0') + { + #ifdef TEST + *logofs << "Loop: WARNING! No environment for NX_SYSTEM.\n" + << logofs_flush; + #endif + + systemEnv = "/usr/NX"; + } + + if (strlen(systemEnv) > DEFAULT_STRING_LENGTH - 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value for the NX " + << "system directory '" << systemEnv + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value for the NX " + << "system directory '" << systemEnv + << "'.\n"; + + HandleCleanup(); + } + + strcpy(systemDir, systemEnv); + + #ifdef TEST + *logofs << "Loop: Assuming system NX directory '" + << systemDir << "'.\n" << logofs_flush; + #endif + } + + char *systemPath = new char[strlen(systemDir) + 1]; + + if (systemPath == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't allocate memory " + << "for the system path.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory " + << "for the system path.\n"; + + HandleCleanup(); + } + + strcpy(systemPath, systemDir); + + return systemPath; +} + +char *GetHomePath() +{ + if (*homeDir == '\0') + { + // + // Check the NX_HOME environment. + // + + const char *homeEnv = getenv("NX_HOME"); + + if (homeEnv == NULL || *homeEnv == '\0') + { + #ifdef TEST + *logofs << "Loop: WARNING! No environment for NX_HOME.\n" + << logofs_flush; + #endif + + homeEnv = getenv("HOME"); + + if (homeEnv == NULL || *homeEnv == '\0') + { + #ifdef PANIC + *logofs << "Loop: PANIC! No environment for HOME.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": No environment for HOME.\n"; + + HandleCleanup(); + } + } + + if (strlen(homeEnv) > DEFAULT_STRING_LENGTH - 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value for the NX " + << "home directory '" << homeEnv + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value for the NX " + << "home directory '" << homeEnv + << "'.\n"; + + HandleCleanup(); + } + + strcpy(homeDir, homeEnv); + + #ifdef TEST + *logofs << "Loop: Assuming NX user's home directory '" + << homeDir << "'.\n" << logofs_flush; + #endif + } + + char *homePath = new char[strlen(homeDir) + 1]; + + if (homePath == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't allocate memory " + << "for the home path.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory " + << "for the home path.\n"; + + HandleCleanup(); + } + + strcpy(homePath, homeDir); + + return homePath; +} + +char *GetRootPath() +{ + if (*rootDir == '\0') + { + // + // Check the NX_ROOT environment. + // + + const char *rootEnv = getenv("NX_ROOT"); + + if (rootEnv == NULL || *rootEnv == '\0') + { + #ifdef TEST + *logofs << "Loop: WARNING! No environment for NX_ROOT.\n" + << logofs_flush; + #endif + + // + // We will determine the root NX directory + // based on the NX_HOME or HOME directory + // settings. + // + + const char *homeEnv = GetHomePath(); + + if (strlen(homeEnv) > DEFAULT_STRING_LENGTH - + strlen("/.nx") - 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value for the NX " + << "home directory '" << homeEnv + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value for the NX " + << "home directory '" << homeEnv + << "'.\n"; + + HandleCleanup(); + } + + #ifdef TEST + *logofs << "Loop: Assuming NX root directory in " + << "the user's home '" << homeEnv + << "'.\n" << logofs_flush; + #endif + + strcpy(rootDir, homeEnv); + strcat(rootDir, "/.nx"); + + delete [] homeEnv; + + // + // Create the NX root directory. + // + + struct stat dirStat; + + if ((stat(rootDir, &dirStat) == -1) && (EGET() == ENOENT)) + { + if (mkdir(rootDir, 0700) < 0 && (EGET() != EEXIST)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't create directory '" + << rootDir << ". Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't create directory '" + << rootDir << ". Error is " << EGET() << " '" + << ESTR() << "'.\n"; + + HandleCleanup(); + } + } + } + else + { + if (strlen(rootEnv) > DEFAULT_STRING_LENGTH - 1) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value for the NX " + << "root directory '" << rootEnv + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value for the NX " + << "root directory '" << rootEnv + << "'.\n"; + + HandleCleanup(); + } + + strcpy(rootDir, rootEnv); + } + + #ifdef TEST + *logofs << "Loop: Assuming NX root directory '" + << rootDir << "'.\n" << logofs_flush; + #endif + } + + char *rootPath = new char[strlen(rootDir) + 1]; + + if (rootPath == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't allocate memory " + << "for the root path.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory " + << "for the root path.\n"; + + HandleCleanup(); + } + + strcpy(rootPath, rootDir); + + return rootPath; +} + +char *GetCachePath() +{ + char *rootPath = GetRootPath(); + + char *cachePath; + + if (*sessionType != '\0') + { + cachePath = new char[strlen(rootPath) + strlen("/cache-") + + strlen(sessionType) + 1]; + } + else + { + cachePath = new char[strlen(rootPath) + strlen("/cache") + 1]; + } + + strcpy(cachePath, rootPath); + + if (*sessionType != '\0') + { + strcat(cachePath, "/cache-"); + + strcat(cachePath, sessionType); + } + else + { + strcat(cachePath, "/cache"); + } + + // + // Create the cache directory if needed. + // + + struct stat dirStat; + + if ((stat(cachePath, &dirStat) == -1) && (EGET() == ENOENT)) + { + if (mkdir(cachePath, 0700) < 0 && (EGET() != EEXIST)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't create directory '" << cachePath + << ". Error is " << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't create directory '" << cachePath + << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; + + delete [] rootPath; + delete [] cachePath; + + return NULL; + } + } + + delete [] rootPath; + + return cachePath; +} + +char *GetImagesPath() +{ + char *rootPath = GetRootPath(); + + char *imagesPath = new char[strlen(rootPath) + strlen("/images") + 1]; + + strcpy(imagesPath, rootPath); + + strcat(imagesPath, "/images"); + + // + // Create the cache directory if needed. + // + + struct stat dirStat; + + if ((stat(imagesPath, &dirStat) == -1) && (EGET() == ENOENT)) + { + if (mkdir(imagesPath, 0700) < 0 && (EGET() != EEXIST)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't create directory '" << imagesPath + << ". Error is " << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't create directory '" << imagesPath + << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; + + delete [] rootPath; + delete [] imagesPath; + + return NULL; + } + } + + // + // Create 16 directories in the path to + // hold the images whose name begins with + // the corresponding hexadecimal digit. + // + + char *digitPath = new char[strlen(imagesPath) + 5]; + + strcpy(digitPath, imagesPath); + + // + // Image paths have format "[path][/I-c][\0]", + // where c is the first digit of the checksum. + // + + for (char digit = 0; digit < 16; digit++) + { + sprintf(digitPath + strlen(imagesPath), "/I-%01X", digit); + + if ((stat(digitPath, &dirStat) == -1) && (EGET() == ENOENT)) + { + if (mkdir(digitPath, 0700) < 0 && (EGET() != EEXIST)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't create directory '" << digitPath + << ". Error is " << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't create directory '" << digitPath + << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; + + delete [] rootPath; + delete [] imagesPath; + delete [] digitPath; + + return NULL; + } + } + } + + delete [] rootPath; + delete [] digitPath; + + return imagesPath; +} + +char *GetSessionPath() +{ + if (*sessionDir == '\0') + { + char *rootPath = GetRootPath(); + + strcpy(sessionDir, rootPath); + + if (control -> ProxyMode == proxy_client) + { + strcat(sessionDir, "/C-"); + } + else + { + strcat(sessionDir, "/S-"); + } + + if (*sessionId == '\0') + { + char port[DEFAULT_STRING_LENGTH]; + + sprintf(port, "%d", proxyPort); + + strcpy(sessionId, port); + } + + strcat(sessionDir, sessionId); + + struct stat dirStat; + + if ((stat(sessionDir, &dirStat) == -1) && (EGET() == ENOENT)) + { + if (mkdir(sessionDir, 0700) < 0 && (EGET() != EEXIST)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't create directory '" << sessionDir + << ". Error is " << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't create directory '" << sessionDir + << ". Error is " << EGET() << " '" << ESTR() << "'.\n"; + + delete [] rootPath; + + return NULL; + } + } + + #ifdef TEST + *logofs << "Loop: Root of NX session is '" << sessionDir + << "'.\n" << logofs_flush; + #endif + + delete [] rootPath; + } + + char *sessionPath = new char[strlen(sessionDir) + 1]; + + strcpy(sessionPath, sessionDir); + + return sessionPath; +} + +// +// Identify requested link characteristics +// and set control parameters accordingly. +// + +int ParseLinkOption(const char *opt) +{ + // + // Normalize the user input. + // + + if (strcasecmp(opt, "modem") == 0 || + strcasecmp(opt, "33k") == 0 || + strcasecmp(opt, "56k") == 0) + { + strcpy(linkSpeedName, "MODEM"); + } + else if (strcasecmp(opt, "isdn") == 0 || + strcasecmp(opt, "64k") == 0 || + strcasecmp(opt, "128k") == 0) + { + strcpy(linkSpeedName, "ISDN"); + } + else if (strcasecmp(opt, "adsl") == 0 || + strcasecmp(opt, "256k") == 0 || + strcasecmp(opt, "640k") == 0) + { + strcpy(linkSpeedName, "ADSL"); + } + else if (strcasecmp(opt, "wan") == 0 || + strcasecmp(opt, "1m") == 0 || + strcasecmp(opt, "2m") == 0 || + strcasecmp(opt, "34m") == 0) + { + strcpy(linkSpeedName, "WAN"); + } + else if (strcasecmp(opt, "lan") == 0 || + strcasecmp(opt, "10m") == 0 || + strcasecmp(opt, "100m") == 0 || + strcasecmp(opt, "local") == 0) + { + strcpy(linkSpeedName, "LAN"); + } + + if (strcasecmp(linkSpeedName, "modem") != 0 && + strcasecmp(linkSpeedName, "isdn") != 0 && + strcasecmp(linkSpeedName, "adsl") != 0 && + strcasecmp(linkSpeedName, "wan") != 0 && + strcasecmp(linkSpeedName, "lan") != 0) + { + return -1; + } + + return 1; +} + +int ParsePackOption(const char *opt) +{ + #ifdef DEBUG + *logofs << "Loop: Pack method is " << packMethod + << " quality is " << packQuality << ".\n" + << logofs_flush; + #endif + + #ifdef DEBUG + *logofs << "Loop: Parsing pack method '" << opt + << "'.\n" << logofs_flush; + #endif + + if (strcasecmp(opt, "0") == 0 || + strcasecmp(opt, "none") == 0 || + strcasecmp(opt, "nopack") == 0 || + strcasecmp(opt, "no-pack") == 0) + { + packMethod = PACK_NONE; + } + else if (strcasecmp(opt, "8") == 0) + { + packMethod = PACK_MASKED_8_COLORS; + } + else if (strcasecmp(opt, "64") == 0) + { + packMethod = PACK_MASKED_64_COLORS; + } + else if (strcasecmp(opt, "256") == 0) + { + packMethod = PACK_MASKED_256_COLORS; + } + else if (strcasecmp(opt, "512") == 0) + { + packMethod = PACK_MASKED_512_COLORS; + } + else if (strcasecmp(opt, "4k") == 0) + { + packMethod = PACK_MASKED_4K_COLORS; + } + else if (strcasecmp(opt, "32k") == 0) + { + packMethod = PACK_MASKED_32K_COLORS; + } + else if (strcasecmp(opt, "64k") == 0) + { + packMethod = PACK_MASKED_64K_COLORS; + } + else if (strcasecmp(opt, "256k") == 0) + { + packMethod = PACK_MASKED_256K_COLORS; + } + else if (strcasecmp(opt, "2m") == 0) + { + packMethod = PACK_MASKED_2M_COLORS; + } + else if (strcasecmp(opt, "16m") == 0) + { + packMethod = PACK_MASKED_16M_COLORS; + } + else if (strncasecmp(opt, "8-jpeg", strlen("8-jpeg")) == 0) + { + packMethod = PACK_JPEG_8_COLORS; + } + else if (strncasecmp(opt, "64-jpeg", strlen("64-jpeg")) == 0) + { + packMethod = PACK_JPEG_64_COLORS; + } + else if (strncasecmp(opt, "256-jpeg", strlen("256-jpeg")) == 0) + { + packMethod = PACK_JPEG_256_COLORS; + } + else if (strncasecmp(opt, "512-jpeg", strlen("512-jpeg")) == 0) + { + packMethod = PACK_JPEG_512_COLORS; + } + else if (strncasecmp(opt, "4k-jpeg", strlen("4k-jpeg")) == 0) + { + packMethod = PACK_JPEG_4K_COLORS; + } + else if (strncasecmp(opt, "32k-jpeg", strlen("32k-jpeg")) == 0) + { + packMethod = PACK_JPEG_32K_COLORS; + } + else if (strncasecmp(opt, "64k-jpeg", strlen("64k-jpeg")) == 0) + { + packMethod = PACK_JPEG_64K_COLORS; + } + else if (strncasecmp(opt, "256k-jpeg", strlen("256k-jpeg")) == 0) + { + packMethod = PACK_JPEG_256K_COLORS; + } + else if (strncasecmp(opt, "2m-jpeg", strlen("2m-jpeg")) == 0) + { + packMethod = PACK_JPEG_2M_COLORS; + } + else if (strncasecmp(opt, "16m-jpeg", strlen("16m-jpeg")) == 0) + { + packMethod = PACK_JPEG_16M_COLORS; + } + else if (strncasecmp(opt, "8-png", strlen("8-png")) == 0) + { + packMethod = PACK_PNG_8_COLORS; + } + else if (strncasecmp(opt, "64-png", strlen("64-png")) == 0) + { + packMethod = PACK_PNG_64_COLORS; + } + else if (strncasecmp(opt, "256-png", strlen("256-png")) == 0) + { + packMethod = PACK_PNG_256_COLORS; + } + else if (strncasecmp(opt, "512-png", strlen("512-png")) == 0) + { + packMethod = PACK_PNG_512_COLORS; + } + else if (strncasecmp(opt, "4k-png", strlen("4k-png")) == 0) + { + packMethod = PACK_PNG_4K_COLORS; + } + else if (strncasecmp(opt, "32k-png", strlen("32k-png")) == 0) + { + packMethod = PACK_PNG_32K_COLORS; + } + else if (strncasecmp(opt, "64k-png", strlen("64k-png")) == 0) + { + packMethod = PACK_PNG_64K_COLORS; + } + else if (strncasecmp(opt, "256k-png", strlen("256k-png")) == 0) + { + packMethod = PACK_PNG_256K_COLORS; + } + else if (strncasecmp(opt, "2m-png", strlen("2m-png")) == 0) + { + packMethod = PACK_PNG_2M_COLORS; + } + else if (strncasecmp(opt, "16m-png", strlen("16m-png")) == 0) + { + packMethod = PACK_PNG_16M_COLORS; + } + else if (strncasecmp(opt, "16m-rgb", strlen("16m-rgb")) == 0 || + strncasecmp(opt, "rgb", strlen("rgb")) == 0) + { + packMethod = PACK_RGB_16M_COLORS; + } + else if (strncasecmp(opt, "16m-rle", strlen("16m-rle")) == 0 || + strncasecmp(opt, "rle", strlen("rle")) == 0) + { + packMethod = PACK_RLE_16M_COLORS; + } + else if (strncasecmp(opt, "16m-bitmap", strlen("16m-bitmap")) == 0 || + strncasecmp(opt, "bitmap", strlen("bitmap")) == 0) + { + packMethod = PACK_BITMAP_16M_COLORS; + } + else if (strncasecmp(opt, "lossy", strlen("lossy")) == 0) + { + packMethod = PACK_LOSSY; + } + else if (strncasecmp(opt, "lossless", strlen("lossless")) == 0) + { + packMethod = PACK_LOSSLESS; + } + else if (strncasecmp(opt, "adaptive", strlen("adaptive")) == 0) + { + packMethod = PACK_ADAPTIVE; + } + else + { + return -1; + } + + if (packMethod == PACK_NONE) + { + strcpy(packMethodName, "none"); + } + else + { + strcpy(packMethodName, opt); + } + + if (packMethod == PACK_RGB_16M_COLORS || + packMethod == PACK_RLE_16M_COLORS || + packMethod == PACK_BITMAP_16M_COLORS || + (packMethod >= PACK_JPEG_8_COLORS && + packMethod <= PACK_JPEG_16M_COLORS) || + (packMethod >= PACK_PNG_8_COLORS && + packMethod <= PACK_PNG_16M_COLORS) || + packMethod == PACK_LOSSY || + packMethod == PACK_LOSSLESS || + packMethod == PACK_ADAPTIVE) + { + const char *dash = strrchr(opt, '-'); + + if (dash != NULL && strlen(dash) == 2 && + *(dash + 1) >= '0' && *(dash + 1) <= '9') + { + packQuality = atoi(dash + 1); + + #ifdef DEBUG + *logofs << "Loop: Using pack quality '" + << packQuality << "'.\n" << logofs_flush; + #endif + } + } + else + { + packQuality = 0; + } + + return 1; +} + +int ParsePackMethod(const int method, const int quality) +{ + switch (method) + { + case PACK_NONE: + { + strcpy(packMethodName, "none"); + + break; + } + case PACK_MASKED_8_COLORS: + { + strcpy(packMethodName, "8"); + + break; + } + case PACK_MASKED_64_COLORS: + { + strcpy(packMethodName, "64"); + + break; + } + case PACK_MASKED_256_COLORS: + { + strcpy(packMethodName, "256"); + + break; + } + case PACK_MASKED_512_COLORS: + { + strcpy(packMethodName, "512"); + + break; + } + case PACK_MASKED_4K_COLORS: + { + strcpy(packMethodName, "4k"); + + break; + } + case PACK_MASKED_32K_COLORS: + { + strcpy(packMethodName, "32k"); + + break; + } + case PACK_MASKED_64K_COLORS: + { + strcpy(packMethodName, "64k"); + + break; + } + case PACK_MASKED_256K_COLORS: + { + strcpy(packMethodName, "256k"); + + break; + } + case PACK_MASKED_2M_COLORS: + { + strcpy(packMethodName, "2m"); + + break; + } + case PACK_MASKED_16M_COLORS: + { + strcpy(packMethodName, "16m"); + + break; + } + case PACK_JPEG_8_COLORS: + { + strcpy(packMethodName, "8-jpeg"); + + break; + } + case PACK_JPEG_64_COLORS: + { + strcpy(packMethodName, "64-jpeg"); + + break; + } + case PACK_JPEG_256_COLORS: + { + strcpy(packMethodName, "256-jpeg"); + + break; + } + case PACK_JPEG_512_COLORS: + { + strcpy(packMethodName, "512-jpeg"); + + break; + } + case PACK_JPEG_4K_COLORS: + { + strcpy(packMethodName, "4k-jpeg"); + + break; + } + case PACK_JPEG_32K_COLORS: + { + strcpy(packMethodName, "32k-jpeg"); + + break; + } + case PACK_JPEG_64K_COLORS: + { + strcpy(packMethodName, "64k-jpeg"); + + break; + } + case PACK_JPEG_256K_COLORS: + { + strcpy(packMethodName, "256k-jpeg"); + + break; + } + case PACK_JPEG_2M_COLORS: + { + strcpy(packMethodName, "2m-jpeg"); + + break; + } + case PACK_JPEG_16M_COLORS: + { + strcpy(packMethodName, "16m-jpeg"); + + break; + } + case PACK_PNG_8_COLORS: + { + strcpy(packMethodName, "8-png"); + + break; + } + case PACK_PNG_64_COLORS: + { + strcpy(packMethodName, "64-png"); + + break; + } + case PACK_PNG_256_COLORS: + { + strcpy(packMethodName, "256-png"); + + break; + } + case PACK_PNG_512_COLORS: + { + strcpy(packMethodName, "512-png"); + + break; + } + case PACK_PNG_4K_COLORS: + { + strcpy(packMethodName, "4k-png"); + + break; + } + case PACK_PNG_32K_COLORS: + { + strcpy(packMethodName, "32k-png"); + + break; + } + case PACK_PNG_64K_COLORS: + { + strcpy(packMethodName, "64k-png"); + + break; + } + case PACK_PNG_256K_COLORS: + { + strcpy(packMethodName, "256k-png"); + + break; + } + case PACK_PNG_2M_COLORS: + { + strcpy(packMethodName, "2m-png"); + + break; + } + case PACK_PNG_16M_COLORS: + { + strcpy(packMethodName, "16m-png"); + + break; + } + case PACK_RGB_16M_COLORS: + { + strcpy(packMethodName, "16m-rgb"); + + break; + } + case PACK_RLE_16M_COLORS: + { + strcpy(packMethodName, "16m-rle"); + + break; + } + case PACK_BITMAP_16M_COLORS: + { + strcpy(packMethodName, "16m-bitmap"); + + break; + } + case PACK_LOSSY: + { + strcpy(packMethodName, "lossy"); + + break; + } + case PACK_LOSSLESS: + { + strcpy(packMethodName, "lossless"); + + break; + } + case PACK_ADAPTIVE: + { + strcpy(packMethodName, "adaptive"); + + break; + } + default: + { + return -1; + } + } + + if (quality < 0 || quality > 9) + { + return -1; + } + + if (packMethod == PACK_RGB_16M_COLORS || + packMethod == PACK_RLE_16M_COLORS || + packMethod == PACK_BITMAP_16M_COLORS || + (packMethod >= PACK_JPEG_8_COLORS && + packMethod <= PACK_JPEG_16M_COLORS) || + (packMethod >= PACK_PNG_8_COLORS && + packMethod <= PACK_PNG_16M_COLORS) || + packMethod == PACK_LOSSY || + packMethod == PACK_LOSSLESS || + packMethod == PACK_ADAPTIVE) + { + sprintf(packMethodName + strlen(packMethodName), + "-%d", quality); + } + + packMethod = method; + packQuality = quality; + + control -> PackMethod = packMethod; + control -> PackQuality = packQuality; + + return 1; +} + +int SetDirectories() +{ + // + // Determine the location of the user's NX + // directory and the other relevant paths. + // The functions below will check the pa- + // rameters passed to the program and will + // query the environment, if needed. + // + + control -> HomePath = GetHomePath(); + control -> RootPath = GetRootPath(); + control -> SystemPath = GetSystemPath(); + control -> TempPath = GetTempPath(); + control -> ClientPath = GetClientPath(); + + return 1; +} + +int SetLogs() +{ + // + // So far we used stderr (or stdout under + // WIN32). Now use the files selected by + // the user. + // + + if (*statsFileName == '\0') + { + strcpy(statsFileName, "stats"); + + #ifdef TEST + *logofs << "Loop: Assuming default statistics file '" + << statsFileName << "'.\n" << logofs_flush; + #endif + } + #ifdef TEST + else + { + *logofs << "Loop: Name selected for statistics is '" + << statsFileName << "'.\n" << logofs_flush; + } + #endif + + if (OpenLogFile(statsFileName, statofs) < 0) + { + HandleCleanup(); + } + + #ifndef MIXED + + if (*errorsFileName == '\0') + { + strcpy(errorsFileName, "errors"); + + #ifdef TEST + *logofs << "Loop: Assuming default log file name '" + << errorsFileName << "'.\n" << logofs_flush; + #endif + } + #ifdef TEST + else + { + *logofs << "Loop: Name selected for log file is '" + << errorsFileName << "'.\n" << logofs_flush; + } + #endif + + // + // Share the bebug output with the nxssh binder + // process. The file must be made writable by + // everybody because the nxssh process is run by + // nxserver as the nx user. + // + + #ifdef BINDER + + strcpy(errorsFileName, "/tmp/errors"); + + ostream *tmpfs = new ofstream(errorsFileName, ios::out); + + delete tmpfs; + + chmod(errorsFileName, S_IRUSR | S_IWUSR | S_IRGRP | + S_IWGRP | S_IROTH | S_IWOTH); + + #endif + + if (OpenLogFile(errorsFileName, logofs) < 0) + { + HandleCleanup(); + } + + // + // By default the session log is the standard error + // of the process. It is anyway required to set the + // option when running inside SSH, otherwise the + // output will go to the same file as the SSH log, + // depending where the NX client has redirected the + // output. + // + + if (*sessionFileName != '\0') + { + #ifdef TEST + *logofs << "Loop: Name selected for session file is '" + << sessionFileName << "'.\n" << logofs_flush; + #endif + + if (errofs != NULL) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Unexpected value for stream errofs.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Unexpected value for stream errofs.\n"; + } + + if (errsbuf != NULL) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Unexpected value for buffer errsbuf.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Unexpected value for buffer errsbuf.\n"; + } + + errofs = NULL; + errsbuf = NULL; + + if (OpenLogFile(sessionFileName, errofs) < 0) + { + HandleCleanup(); + } + + // + // Redirect the standard error to the file. + // + + errsbuf = cerr.rdbuf(errofs -> rdbuf()); + } + + #endif + + return 1; +} + +int SetPorts() +{ + // + // Depending on the proxy side, we need to determine on which + // port to listen for the given protocol or to which port we + // will have to forward the connection. Three possibilities + // are given for each supported protocol: + // + // Port <= 0: Disable port forwarding. + // Port == 1: Use the default port. + // Port > 1: Use the specified port. + // + // At the connectiong side the user should always explicitly + // set the ports where the connections will be forwarded. This + // is both for security reasons and because, when running both + // proxies on the same host, there is a concrete possibility + // that, by using the default ports, the connection will be + // forwarded to the same port where the peer proxy is listen- + // ing, causing a loop. + // + + useCupsSocket = 0; + if (cupsPort.enabled()) { + if (control -> ProxyMode == proxy_client) { + cupsPort.setDefaultTCPPort(DEFAULT_NX_CUPS_PORT_OFFSET + proxyPort); + useCupsSocket = 1; + } + else + cupsPort.setDefaultTCPPort(631); + } + +#ifdef TEST + *logofs << "Loop: cups port: " << cupsPort << "\n" + << logofs_flush; +#endif + + useAuxSocket = 0; + if (auxPort.enabled()) { + if (control -> ProxyMode == proxy_client) { + auxPort.setDefaultTCPPort(DEFAULT_NX_AUX_PORT_OFFSET + proxyPort); + useAuxSocket = 1; + } + else { + auxPort.setDefaultTCPPort(1); + + if (auxPort.getTCPPort() != 1) { + +#ifdef WARNING + *logofs << "Loop: WARNING! Overriding auxiliary X11 " + << "port with new value '" << 1 << "'.\n" + << logofs_flush; +#endif + + cerr << "Warning" << ": Overriding auxiliary X11 " + << "port with new value '" << 1 << "'.\n"; + + auxPort.setSpec("1"); + } + } + } + +#ifdef TEST + *logofs << "Loop: aux port: " << auxPort << "\n" + << logofs_flush; +#endif + + useSmbSocket = 0; + if (smbPort.enabled()) { + if (control -> ProxyMode == proxy_client) { + auxPort.setDefaultTCPPort(DEFAULT_NX_SMB_PORT_OFFSET + proxyPort); + useAuxSocket = 1; + } + else + auxPort.setDefaultTCPPort(139); + } + + +#ifdef TEST + *logofs << "Loop: smb port: " << smbPort << "\n" + << logofs_flush; +#endif + + useMediaSocket = 0; + if (mediaPort.enabled()) { + if (control -> ProxyMode == proxy_client) { + mediaPort.setDefaultTCPPort(DEFAULT_NX_MEDIA_PORT_OFFSET + proxyPort); + useMediaSocket = 1; + } + else if (mediaPort.getTCPPort() == 1) { +#ifdef PANIC + *logofs << "Loop: PANIC! No port specified for multimedia connections.\n" + << logofs_flush; +#endif + + cerr << "Error" << ": No port specified for multimedia connections.\n"; + + HandleCleanup(); + } + } + +#ifdef TEST + *logofs << "Loop: Using multimedia port '" << mediaPort + << "'.\n" << logofs_flush; +#endif + + useHttpSocket = 0; + if (httpPort.enabled()) { + if (control -> ProxyMode == proxy_client) { + httpPort.setDefaultTCPPort(DEFAULT_NX_HTTP_PORT_OFFSET + proxyPort); + useHttpSocket = 1; + } + else + httpPort.setDefaultTCPPort(80); + } + +#ifdef TEST + *logofs << "Loop: Using HTTP port '" << httpPort + << "'.\n" << logofs_flush; +#endif + + if (ParseFontPath(fontPort) <= 0) + { + #ifdef TEST + *logofs << "Loop: Disabling font server connections.\n" + << logofs_flush; + #endif + + *fontPort = '\0'; + + useFontSocket = 0; + } + else + { + // + // We don't know yet if the remote proxy supports + // the font server connections. If needed, we will + // disable the font server connections at later + // time. + // + + if (control -> ProxyMode == proxy_server) + { + useFontSocket = 1; + } + else + { + useFontSocket = 0; + } + + #ifdef TEST + *logofs << "Loop: Using font server port '" << fontPort + << "'.\n" << logofs_flush; + #endif + } + + useSlaveSocket = 0; + if (slavePort.enabled()) { + useSlaveSocket = 1; + if (control -> ProxyMode == proxy_client) + slavePort.setDefaultTCPPort(DEFAULT_NX_SLAVE_PORT_CLIENT_OFFSET + proxyPort); + else + slavePort.setDefaultTCPPort(DEFAULT_NX_SLAVE_PORT_SERVER_OFFSET + proxyPort); + } + +#ifdef TEST + *logofs << "Loop: Using slave port '" << slavePort + << "'.\n" << logofs_flush; +#endif + + return 1; +} + +int SetDescriptors() +{ + unsigned int limit = 0; + + #ifdef RLIMIT_NOFILE + + rlimit limits; + + if (getrlimit(RLIMIT_NOFILE, &limits) == 0) + { + if (limits.rlim_max == RLIM_INFINITY) + { + limit = 0; + } + else + { + limit = (unsigned int) limits.rlim_max; + } + } + + #endif + + #ifdef _SC_OPEN_MAX + + if (limit == 0) + { + limit = sysconf(_SC_OPEN_MAX); + } + + #endif + + #ifdef FD_SETSIZE + + if (limit > FD_SETSIZE) + { + limit = FD_SETSIZE; + } + + #endif + + #ifdef RLIMIT_NOFILE + + if (limits.rlim_cur < limit) + { + limits.rlim_cur = limit; + + setrlimit(RLIMIT_NOFILE, &limits); + } + + #endif + + if (limit == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Cannot determine number of available " + << "file descriptors.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot determine number of available " + << "file descriptors.\n"; + + return -1; + } + + return 1; +} + +// +// Find the directory containing the caches +// matching the session type. +// + +int SetCaches() +{ + if ((control -> PersistentCachePath = GetCachePath()) == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error getting or creating the cache path.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error getting or creating the cache path.\n"; + + HandleCleanup(); + } + + #ifdef TEST + *logofs << "Loop: Path of cache files is '" << control -> PersistentCachePath + << "'.\n" << logofs_flush; + #endif + + return 1; +} + +// +// Initialize all configuration parameters. +// + +int SetParameters() +{ + // + // Find out the type of session. + // + + SetSession(); + + // + // Initialize the network and compression + // parameters according to the settings + // suggested by the user. + // + + SetLink(); + + // + // Set compression according to link speed. + // + + SetCompression(); + + // + // Be sure that we have a literal for current + // cache size. Value will reflect control's + // default unless we already parsed a 'cache' + // option. Server side has no control on size + // of cache but is informed at session nego- + // tiation about how much memory is going to + // be used. + // + + SetStorage(); + + // + // Set size of shared memory segments. + // + + SetShmem(); + + // + // Make adjustments to cache based + // on the pack method. + // + + SetPack(); + + // + // Set disk-based image cache. + // + + SetImages(); + + // + // Set CPU and bandwidth limits. + // + + SetLimits(); + + return 1; +} + +// +// According to session literal determine +// the type of traffic that is going to be +// transported. Literals should be better +// standardized in future NX versions. +// + +int SetSession() +{ + if (strncmp(sessionType, "agent", strlen("agent")) == 0 || + strncmp(sessionType, "desktop", strlen("desktop")) == 0 || + strncmp(sessionType, "rootless", strlen("rootless")) == 0 || + strncmp(sessionType, "console", strlen("console")) == 0 || + strncmp(sessionType, "default", strlen("default")) == 0 || + strncmp(sessionType, "gnome", strlen("gnome")) == 0 || + strncmp(sessionType, "kde", strlen("kde")) == 0 || + strncmp(sessionType, "cde", strlen("cde")) == 0 || + strncmp(sessionType, "xdm", strlen("xdm")) == 0) + { + control -> SessionMode = session_agent; + } + else if (strncmp(sessionType, "win", strlen("win")) == 0 || + strncmp(sessionType, "vnc", strlen("vnc")) == 0) + { + control -> SessionMode = session_agent; + } + else if (strncmp(sessionType, "shadow", strlen("shadow")) == 0) + { + control -> SessionMode = session_shadow; + } + else if (strncmp(sessionType, "proxy", strlen("proxy")) == 0 || + strncmp(sessionType, "application", strlen("application")) == 0 || + strncmp(sessionType, "raw", strlen("raw")) == 0) + { + control -> SessionMode = session_proxy; + } + else + { + // + // If the session type is not passed or + // it is not among the recognized strings, + // we assume that the proxy is connected + // to the agent. + // + + // + // Since ProtoStep8 (#issue 108) and also + // with older "unix-" sessions + // + + if (*sessionType != '\0') + { + #ifdef WARNING + *logofs << "Loop: WARNING! Unrecognized session type '" + << sessionType << "'. Assuming agent session.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Unrecognized session type '" + << sessionType << "'. Assuming agent session.\n"; + } + + control -> SessionMode = session_agent; + } + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Assuming session type '" + << DumpSession(control -> SessionMode) << "' with " + << "string '" << sessionType << "'.\n" + << logofs_flush; + #endif + + // + // By default the policy is immediate. Agents + // will set a different policy, if they like. + // Anyway we need to check if the user has + // provided a custom flush policy. + // + + if (usePolicy != -1) + { + if (usePolicy > 0) + { + control -> FlushPolicy = policy_deferred; + } + else + { + control -> FlushPolicy = policy_immediate; + } + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: WARNING! Forcing flush policy to '" + << DumpPolicy(control -> FlushPolicy) + << ".\n" << logofs_flush; + #endif + } + else + { + control -> FlushPolicy = policy_immediate; + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Setting initial flush policy to '" + << DumpPolicy(control -> FlushPolicy) + << "'.\n" << logofs_flush; + #endif + } + + // + // Check if the proxy library is run inside + // another program providing encryption, as + // it is the case of the SSH client. + // + + if (useEncryption != -1) + { + if (useEncryption > 0) + { + control -> LinkEncrypted = 1; + } + else + { + control -> LinkEncrypted = 0; + } + } + + if (control -> LinkEncrypted == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Proxy running as part of an " + << "encrypting client.\n" + << logofs_flush; + #endif + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Assuming proxy running as a " + << "standalone program.\n" + << logofs_flush; + #endif + } + + // + // Check if the system administrator has + // enabled the respawn of the client at + // the end of session. + // + + if (control -> ProxyMode == proxy_server) + { + struct stat fileStat; + + char fileName[DEFAULT_STRING_LENGTH]; + + snprintf(fileName, DEFAULT_STRING_LENGTH - 1, + "%s/share/noexit", control -> SystemPath); + + *(fileName + DEFAULT_STRING_LENGTH - 1) = '\0'; + + if (stat(fileName, &fileStat) == 0) + { + #ifdef TEST + *logofs << "Loop: Enabling respawn of client at session shutdown.\n" + << logofs_flush; + #endif + + control -> EnableRestartOnShutdown = 1; + } + } + + return 1; +} + +int SetStorage() +{ + // + // If differential compression is disabled + // we don't need a cache at all. + // + + if (control -> LocalDeltaCompression == 0) + { + control -> ClientTotalStorageSize = 0; + control -> ServerTotalStorageSize = 0; + } + + // + // Set a a cache size literal. + // + + int size = control -> getUpperStorageSize(); + + if (size / 1024 > 0) + { + sprintf(cacheSizeName, "%dk", size / 1024); + } + else + { + sprintf(cacheSizeName, "%d", size); + } + + if (control -> ProxyMode == proxy_client) + { + control -> LocalTotalStorageSize = + control -> ClientTotalStorageSize; + + control -> RemoteTotalStorageSize = + control -> ServerTotalStorageSize; + } + else + { + control -> LocalTotalStorageSize = + control -> ServerTotalStorageSize; + + control -> RemoteTotalStorageSize = + control -> ClientTotalStorageSize; + } + + #ifdef DEBUG + *logofs << "Loop: Storage size limit is " + << control -> ClientTotalStorageSize + << " at client and " + << control -> ServerTotalStorageSize + << " at server.\n" + << logofs_flush; + #endif + + #ifdef DEBUG + *logofs << "Loop: Storage local limit set to " + << control -> LocalTotalStorageSize + << " remote limit set to " + << control -> RemoteTotalStorageSize + << ".\n" << logofs_flush; + #endif + + // + // Never reserve for split store more than + // half the memory available for messages. + // + + if (size > 0 && control -> + SplitTotalStorageSize > size / 2) + { + #ifdef TEST + *logofs << "Loop: Reducing size of split store to " + << size / 2 << " bytes.\n" + << logofs_flush; + #endif + + control -> SplitTotalStorageSize = size / 2; + } + + // + // Don't load render from persistent + // cache if extension is hidden or + // not supported by agent. + // + + if (control -> HideRender == 1) + { + #ifdef TEST + *logofs << "Loop: Not loading render extension " + << "from persistent cache.\n" + << logofs_flush; + #endif + + control -> PersistentCacheLoadRender = 0; + } + + return 1; +} + +int SetShmem() +{ + // + // If not set, adjust the size of the shared + // memory segment according to size of the + // message cache. + // + + if (*shsegSizeName == '\0') + { + int size = control -> getUpperStorageSize(); + + const int mega = 1048576; + + if (size > 0) + { + if (size <= 1 * mega) + { + size = 0; + } + else if (size <= 2 * mega) + { + size = 524288; + } + else if (size < 4 * mega) + { + size = 1048576; + } + else + { + size = size / 4; + } + + if (size > 4194304) + { + size = 4194304; + } + + control -> ShmemClientSize = size; + control -> ShmemServerSize = size; + } + else + { + // + // The delta compression is disabled. + // Use a default segment size of 2 MB. + // + + control -> ShmemServerSize = 2 * mega; + } + } + + // + // Client side shared memory support is + // not useful and not implemented. + // + + if (control -> ShmemServerSize >= 524288) + { + control -> ShmemServer = 1; + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Set initial shared memory size " + << "to " << control -> ShmemServerSize + << " bytes.\n" << logofs_flush; + #endif + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Disabled use of the shared memory " + << "extension.\n" << logofs_flush; + #endif + + control -> ShmemServer = 0; + } + + // For android, no shared memory available + control -> ShmemServer = 0; + control -> ShmemClientSize = 0; + + return 1; +} + +// +// Adjust the pack method according to the +// type of the session. +// + +int SetPack() +{ + #ifdef TEST + *logofs << "Loop: Setting pack with initial method " + << packMethod << " and quality " << packQuality + << ".\n" << logofs_flush; + #endif + + // + // Check if this is a proxy session and, in + // this case, set the pack method to none. + // Packed images are not supported by plain + // X applications. + // + + if (control -> SessionMode == session_proxy) + { + #ifdef TEST + *logofs << "Loop: WARNING! Disabling pack with proxy session.\n" + << logofs_flush; + #endif + + packMethod = PACK_NONE; + } + + // + // Adjust the internal settings according + // to the newly selected pack method. + // + + ParsePackMethod(packMethod, packQuality); + + // + // Don't load messages from persistent + // cache if packed images are disabled. + // + + if (control -> PackMethod == PACK_NONE) + { + control -> PersistentCacheLoadPacked = 0; + + #ifdef TEST + *logofs << "Loop: Not loading packed images " + << "from persistent cache.\n" + << logofs_flush; + #endif + } + + return 1; +} + +// +// Set the disk-based image cache parameters +// according to the user's wishes. +// + +int SetImages() +{ + // + // Be sure we disable the image cache if we + // are connecting to plain X clients. + // + + if (control -> SessionMode == session_proxy) + { + #ifdef TEST + *logofs << "Loop: Disabling image cache with " + << "session '" << DumpSession(control -> + SessionMode) << "'.\n" << logofs_flush; + #endif + + sprintf(imagesSizeName, "0"); + + control -> ImageCacheEnableLoad = 0; + control -> ImageCacheEnableSave = 0; + + return 1; + } + + int size = control -> ImageCacheDiskLimit; + + if (size / 1024 > 0) + { + sprintf(imagesSizeName, "%dk", size / 1024); + } + else + { + sprintf(imagesSizeName, "%d", size); + } + + if (size > 0) + { + control -> ImageCacheEnableLoad = 1; + control -> ImageCacheEnableSave = 1; + + if (control -> ProxyMode == proxy_server) + { + if ((control -> ImageCachePath = GetImagesPath()) == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error getting or creating image cache path.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error getting or creating image cache path.\n"; + + HandleCleanup(); + } + + #ifdef TEST + *logofs << "Loop: Path of image cache files is '" << control -> ImageCachePath + << "'.\n" << logofs_flush; + #endif + } + } + else + { + #ifdef TEST + *logofs << "Loop: Disabling the persistent image cache.\n" + << logofs_flush; + #endif + + control -> ImageCacheEnableLoad = 0; + control -> ImageCacheEnableSave = 0; + } + + return 1; +} + +int SetVersion() +{ + // + // Normalize the different proxy versions. + // + + int local = (control -> LocalVersionMajor << 24) | + (control -> LocalVersionMinor << 16) | + control -> LocalVersionPatch; + + int remote = (control -> RemoteVersionMajor << 24) | + (control -> RemoteVersionMinor << 16) | + control -> RemoteVersionPatch; + + int major = -1; + int minor = -1; + int patch = -1; + + if (control -> RemoteVersionMajor <= 1) + { + // + // The remote proxy uses a different + // logic to determine the version so + // we default to the compatibility + // version. + // + + major = control -> CompatVersionMajor; + minor = control -> CompatVersionMinor; + patch = control -> CompatVersionPatch; + + #ifdef TEST + *logofs << "Loop: Using compatibility version '" + << major << "." << minor << "." << patch + << "'.\n" << logofs_flush; + #endif + } + else if (control -> LocalVersionMajor > + control -> RemoteVersionMajor) + { + // + // We use a more recent version. Let's + // negotiate the version based on the + // version supported by the remote. + // + + major = control -> RemoteVersionMajor; + minor = control -> RemoteVersionMinor; + patch = control -> RemoteVersionPatch; + + #ifdef TEST + *logofs << "Loop: Using remote version '" + << major << "." << minor << "." << patch + << "'.\n" << logofs_flush; + #endif + } + else + { + // + // We support a major version that is + // equal or older than the remote. We + // assume the smaller version between + // the two, including the minor and + // the patch numbers. + // + + if (local > remote) + { + major = control -> RemoteVersionMajor; + minor = control -> RemoteVersionMinor; + patch = control -> RemoteVersionPatch; + + #ifdef TEST + *logofs << "Loop: Using remote version '" + << major << "." << minor << "." << patch + << "'.\n" << logofs_flush; + #endif + } + else + { + major = control -> LocalVersionMajor; + minor = control -> LocalVersionMinor; + patch = control -> LocalVersionPatch; + + #ifdef TEST + *logofs << "Loop: Using local version '" + << major << "." << minor << "." << patch + << "'.\n" << logofs_flush; + #endif + } + } + + // + // Handle versions from 3.5.0. The protocol + // step 10 is the minimum supported version. + // + + int step = 0; + + if (major == 3) + { + if (minor >= 5) + { + step = 10; + } + } + else if (major > 3) + { + step = 10; + } + + if (step == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Unable to set the protocol step value from " + << "the negotiated protocol version " << major << "." << minor + << "." << patch << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unable to set the protocol step value from " + << "the negotiated protocol version " << major << "." << minor + << "." << patch << ".\n"; + + #ifdef PANIC + *logofs << "Loop: PANIC! Incompatible remote version " + << control -> RemoteVersionMajor << "." << control -> RemoteVersionMinor + << "." << control -> RemoteVersionPatch << " with local version " + << control -> LocalVersionMajor << "." << control -> LocalVersionMinor + << "." << control -> LocalVersionPatch << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Incompatible remote version " + << control -> RemoteVersionMajor << "." << control -> RemoteVersionMinor + << "." << control -> RemoteVersionPatch << " with local version " + << control -> LocalVersionMajor << "." << control -> LocalVersionMinor + << "." << control -> LocalVersionPatch << ".\n"; + + return -1; + } + + #ifdef TEST + *logofs << "Loop: Using NX protocol step " + << step << ".\n" << logofs_flush; + #endif + + control -> setProtoStep(step); + + // + // Ignore the differences in patch version + // and print a warning if the local version + // is different or obsolete compared to + // the remote. + // + + local &= 0xffff0000; + remote &= 0xffff0000; + + if (local != remote) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Connected to remote version " + << control -> RemoteVersionMajor << "." << control -> RemoteVersionMinor + << "." << control -> RemoteVersionPatch << " with local version " + << control -> LocalVersionMajor << "." << control -> LocalVersionMinor + << "." << control -> LocalVersionPatch << ".\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Connected to remote version " + << control -> RemoteVersionMajor << "." << control -> RemoteVersionMinor + << "." << control -> RemoteVersionPatch << " with local version " + << control -> LocalVersionMajor << "." << control -> LocalVersionMinor + << "." << control -> LocalVersionPatch << ".\n" << logofs_flush; + } + + if (local < remote) + { + cerr << "Warning" << ": Consider checking https://github.com/ArcticaProject/nx-libs/releases for updates.\n"; + } + + // + // Now that we are aware of the remote + // version, let's adjust the options to + // be compatible with the remote proxy. + // + + if (control -> ProxyMode == proxy_client) + { + // + // Since ProtoStep8 (#issue 108) + // + // Now it's assumed that the remote is + // able to handle the selected pack + // method + // + + #ifdef TEST + *logofs << __FILE__ << " : " << __LINE__ << " - " + << "step = " << control -> getProtoStep() + << " packMethod = " << packMethod + << " packQuality = " << packQuality + << ".\n" << logofs_flush; + #endif + + // + // Update the pack method name. + // + + ParsePackMethod(packMethod, packQuality); + } + + // + // At the moment the image cache is not used by the + // agent. Proxy versions older than 3.0.0 assumed + // that it was enabled and sent specific bits as part + // of the encoding. Conversely, it is advisable to + // disable the cache right now. By not enabling the + // the image cache, the house-keeping process will + // only take care of cleaning up the "cache-" direc- + // tories. + // + + // + // Considering that compatibility with older versions + // has been set to cover as far as 3.5.0, the cache can + // be disabled at this point without any concern + // + + // Since ProtoStep8 (#issue 108) + #ifdef TEST + *logofs << "Loop: Disabling image cache with protocol " + << "step '" << control -> getProtoStep() + << "'.\n" << logofs_flush; + #endif + + sprintf(imagesSizeName, "0"); + + control -> ImageCacheEnableLoad = 0; + control -> ImageCacheEnableSave = 0; + + return 1; +} + +// +// Identify the requested link settings +// and update the control parameters +// accordingly. +// + +int SetLink() +{ + #ifdef TEST + *logofs << "Loop: Setting link with initial value " + << linkSpeedName << ".\n" << logofs_flush; + #endif + + if (*linkSpeedName == '\0') + { + strcpy(linkSpeedName, "lan"); + } + + #ifdef TEST + *logofs << "Loop: Link speed is " << linkSpeedName + << ".\n" << logofs_flush; + #endif + + if (strcasecmp(linkSpeedName, "modem") == 0) + { + SetLinkModem(); + } + else if (strcasecmp(linkSpeedName, "isdn") == 0) + { + SetLinkIsdn(); + } + else if (strcasecmp(linkSpeedName, "adsl") == 0) + { + SetLinkAdsl(); + } + else if (strcasecmp(linkSpeedName, "wan") == 0) + { + SetLinkWan(); + } + else if (strcasecmp(linkSpeedName, "lan") == 0) + { + SetLinkLan(); + } + else + { + return -1; + } + + // + // Set TCP_NODELAY according to the user's + // wishes. + // + + if (useNoDelay != -1) + { + control -> OptionProxyClientNoDelay = useNoDelay; + control -> OptionProxyServerNoDelay = useNoDelay; + } + + // + // Select the image compression method. + // + + if (packMethod == -1) + { + packMethod = control -> PackMethod; + } + + if (packQuality == -1) + { + packQuality = control -> PackQuality; + } + + if (ParsePackMethod(packMethod, packQuality) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Unrecognized pack method id " + << packMethod << " with quality " << packQuality + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unrecognized pack method id " + << packMethod << " with quality " << packQuality + << ".\n"; + + HandleCleanup(); + } + + // + // Check if the user disabled the ability + // to generate simple replies at the client + // side. + // + + if (control -> SessionMode == session_proxy) + { + if (useTaint != -1) + { + control -> TaintReplies = (useTaint == 1); + } + else + { + #ifdef WARNING + *logofs << "Loop: WARNING! Forcing taint of replies " + << "with a proxy session.\n" + << logofs_flush; + #endif + + control -> TaintReplies = 1; + } + } + else + { + // + // There is no need to taint the + // replies if we have an agent. + // + + control -> TaintReplies = 0; + } + + // + // Be sure that the requests needing a reply + // are flushed immediately. Normal X clients + // use so many replies to make the queuing + // completely useless. + // + + if (control -> SessionMode == session_proxy) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Forcing flush on priority " + << "with a proxy session.\n" + << logofs_flush; + #endif + + control -> FlushPriority = 1; + } + + return 1; +} + +// +// Parameters for MODEM 28.8/33.6/56 Kbps. +// + +int SetLinkModem() +{ + #ifdef TEST + *logofs << "Loop: Setting parameters for MODEM.\n" + << logofs_flush; + #endif + + control -> LinkMode = LINK_TYPE_MODEM; + + control -> TokenSize = 256; + control -> TokenLimit = 24; + + control -> SplitMode = 1; + control -> SplitTotalSize = 128; + control -> SplitTotalStorageSize = 1048576; + + control -> SplitTimeout = 50; + control -> MotionTimeout = 50; + control -> IdleTimeout = 50; + + control -> PackMethod = PACK_ADAPTIVE; + control -> PackQuality = 3; + + return 1; +} + +// +// Parameters for ISDN 64/128 Kbps. +// + +int SetLinkIsdn() +{ + #ifdef TEST + *logofs << "Loop: Setting parameters for ISDN.\n" + << logofs_flush; + #endif + + control -> LinkMode = LINK_TYPE_ISDN; + + control -> TokenSize = 384; + control -> TokenLimit = 24; + + control -> SplitMode = 1; + control -> SplitTotalSize = 128; + control -> SplitTotalStorageSize = 1048576; + + control -> SplitTimeout = 50; + control -> MotionTimeout = 20; + control -> IdleTimeout = 50; + + control -> PackMethod = PACK_ADAPTIVE; + control -> PackQuality = 5; + + return 1; +} + +// +// Parameters for ADSL 256 Kbps. +// + +int SetLinkAdsl() +{ + #ifdef TEST + *logofs << "Loop: Setting parameters for ADSL.\n" + << logofs_flush; + #endif + + control -> LinkMode = LINK_TYPE_ADSL; + + control -> TokenSize = 1536; + control -> TokenLimit = 24; + + control -> SplitMode = 1; + control -> SplitTotalSize = 128; + control -> SplitTotalStorageSize = 1048576; + + control -> SplitTimeout = 50; + control -> MotionTimeout = 10; + control -> IdleTimeout = 50; + + control -> PackMethod = PACK_ADAPTIVE; + control -> PackQuality = 7; + + return 1; +} + +// +// Parameters for XDSL/FDDI/ATM 1/2/34 Mbps WAN. +// + +int SetLinkWan() +{ + #ifdef TEST + *logofs << "Loop: Setting parameters for WAN.\n" + << logofs_flush; + #endif + + control -> LinkMode = LINK_TYPE_WAN; + + control -> TokenSize = 1536; + control -> TokenLimit = 24; + + control -> SplitMode = 1; + control -> SplitTotalSize = 128; + control -> SplitTotalStorageSize = 1048576; + + control -> SplitTimeout = 50; + control -> MotionTimeout = 5; + control -> IdleTimeout = 50; + + control -> PackMethod = PACK_ADAPTIVE; + control -> PackQuality = 9; + + return 1; +} + +// +// Parameters for LAN 10/100 Mbps. +// + +int SetLinkLan() +{ + #ifdef TEST + *logofs << "Loop: Setting parameters for LAN.\n" + << logofs_flush; + #endif + + control -> LinkMode = LINK_TYPE_LAN; + + control -> TokenSize = 1536; + control -> TokenLimit = 24; + + control -> SplitMode = 1; + control -> SplitTotalSize = 128; + control -> SplitTotalStorageSize = 1048576; + + control -> SplitTimeout = 50; + control -> MotionTimeout = 0; + control -> IdleTimeout = 50; + + control -> PackMethod = PACK_ADAPTIVE; + control -> PackQuality = 9; + + return 1; +} + +// +// Identify the requested link type and set +// the control parameters accordingly. +// + +int SetCompression() +{ + if (strcasecmp(linkSpeedName, "modem") == 0) + { + SetCompressionModem(); + } + else if (strcasecmp(linkSpeedName, "isdn") == 0) + { + SetCompressionIsdn(); + } + else if (strcasecmp(linkSpeedName, "adsl") == 0) + { + SetCompressionAdsl(); + } + else if (strcasecmp(linkSpeedName, "wan") == 0) + { + SetCompressionWan(); + } + else if (strcasecmp(linkSpeedName, "lan") == 0) + { + SetCompressionLan(); + } + else + { + return -1; + } + + if (control -> LocalDeltaCompression < 0) + { + control -> LocalDeltaCompression = 1; + } + + // + // If we didn't set remote delta compression + // (as it should always be the case at client + // side) assume value of local side. + // + + if (control -> RemoteDeltaCompression < 0) + { + control -> RemoteDeltaCompression = + control -> LocalDeltaCompression; + } + + // + // If we didn't set remote compression levels + // assume values of local side. + // + + if (control -> RemoteStreamCompression < 0) + { + control -> RemoteStreamCompressionLevel = + control -> LocalStreamCompressionLevel; + + if (control -> RemoteStreamCompressionLevel > 0) + { + control -> RemoteStreamCompression = 1; + } + else + { + control -> RemoteStreamCompression = 0; + } + } + + if (control -> RemoteDataCompression < 0) + { + control -> RemoteDataCompressionLevel = + control -> LocalDataCompressionLevel; + + if (control -> RemoteDataCompressionLevel > 0) + { + control -> RemoteDataCompression = 1; + } + else + { + control -> RemoteDataCompression = 0; + } + } + + return 1; +} + +// +// Compression for MODEM. +// + +int SetCompressionModem() +{ + if (control -> LocalDataCompression < 0) + { + control -> LocalDataCompression = 1; + control -> LocalDataCompressionLevel = 1; + } + + if (control -> LocalDataCompressionThreshold < 0) + { + control -> LocalDataCompressionThreshold = 32; + } + + if (control -> LocalStreamCompression < 0) + { + control -> LocalStreamCompression = 1; + control -> LocalStreamCompressionLevel = 9; + } + + return 1; +} + +// +// Compression for ISDN. +// + +int SetCompressionIsdn() +{ + if (control -> LocalDataCompression < 0) + { + control -> LocalDataCompression = 1; + control -> LocalDataCompressionLevel = 1; + } + + if (control -> LocalDataCompressionThreshold < 0) + { + control -> LocalDataCompressionThreshold = 32; + } + + if (control -> LocalStreamCompression < 0) + { + control -> LocalStreamCompression = 1; + control -> LocalStreamCompressionLevel = 6; + } + + return 1; +} + +// +// Compression for ADSL. +// + +int SetCompressionAdsl() +{ + if (control -> LocalDataCompression < 0) + { + control -> LocalDataCompression = 1; + control -> LocalDataCompressionLevel = 1; + } + + if (control -> LocalDataCompressionThreshold < 0) + { + control -> LocalDataCompressionThreshold = 32; + } + + if (control -> LocalStreamCompression < 0) + { + control -> LocalStreamCompression = 1; + control -> LocalStreamCompressionLevel = 4; + } + + return 1; +} + +// +// Compression for WAN. +// + +int SetCompressionWan() +{ + if (control -> LocalDataCompression < 0) + { + control -> LocalDataCompression = 1; + control -> LocalDataCompressionLevel = 1; + } + + if (control -> LocalDataCompressionThreshold < 0) + { + control -> LocalDataCompressionThreshold = 32; + } + + if (control -> LocalStreamCompression < 0) + { + control -> LocalStreamCompression = 1; + control -> LocalStreamCompressionLevel = 1; + } + + return 1; +} + +// +// Compression for LAN. +// + +int SetCompressionLan() +{ + // + // Disable delta compression if not + // explicitly enabled. + // + + if (control -> LocalDeltaCompression < 0) + { + control -> LocalDeltaCompression = 0; + } + + if (control -> LocalDataCompression < 0) + { + control -> LocalDataCompression = 0; + control -> LocalDataCompressionLevel = 0; + } + + if (control -> LocalDataCompressionThreshold < 0) + { + control -> LocalDataCompressionThreshold = 0; + } + + if (control -> LocalStreamCompression < 0) + { + control -> LocalStreamCompression = 0; + control -> LocalStreamCompressionLevel = 0; + } + + return 1; +} + +int SetLimits() +{ + // + // Check if the user requested strict + // control flow parameters. + // + + if (useStrict == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: LIMIT! Decreasing the token limit " + << "to " << control -> TokenLimit / 2 + << " with option 'strict'.\n" + << logofs_flush; + #endif + + control -> TokenLimit /= 2; + } + + #ifdef STRICT + + control -> TokenLimit = 1; + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: WARNING! LIMIT! Setting the token limit " + << "to " << control -> TokenLimit + << " to simulate the proxy congestion.\n" + << logofs_flush; + #endif + + #endif + + // + // Reduce the size of the log file. + // + + #ifdef QUOTA + + control -> FileSizeLimit = 8388608; + + #endif + + // + // Check the bitrate limits. + // + + if (control -> LocalBitrateLimit == -1) + { + if (control -> ProxyMode == proxy_client) + { + control -> LocalBitrateLimit = + control -> ClientBitrateLimit; + } + else + { + control -> LocalBitrateLimit = + control -> ServerBitrateLimit; + } + } + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: LIMIT! Setting client bitrate limit " + << "to " << control -> ClientBitrateLimit + << " server bitrate limit to " << control -> + ServerBitrateLimit << " with local limit " + << control -> LocalBitrateLimit << ".\n" + << logofs_flush; + #endif + + return 1; +} + +// +// These functions are used to parse literal +// values provided by the user and set the +// control parameters accordingly. +// + +int ParseCacheOption(const char *opt) +{ + int size = ParseArg("", "cache", opt); + + if (size < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value '" + << opt << "' for option 'cache'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value '" + << opt << "' for option 'cache'.\n"; + + return -1; + } + + #ifdef TEST + *logofs << "Loop: Setting size of cache to " + << size << " bytes.\n" << logofs_flush; + #endif + + control -> ClientTotalStorageSize = size; + control -> ServerTotalStorageSize = size; + + strcpy(cacheSizeName, opt); + + if (size == 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Disabling NX delta compression.\n" + << logofs_flush; + #endif + + control -> LocalDeltaCompression = 0; + + #ifdef WARNING + *logofs << "Loop: WARNING! Disabling use of NX persistent cache.\n" + << logofs_flush; + #endif + + control -> PersistentCacheEnableLoad = 0; + control -> PersistentCacheEnableSave = 0; + } + + return 1; +} + +int ParseImagesOption(const char *opt) +{ + int size = ParseArg("", "images", opt); + + if (size < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value '" + << opt << "' for option 'images'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value '" + << opt << "' for option 'images'.\n"; + + return -1; + } + + #ifdef TEST + *logofs << "Loop: Setting size of images cache to " + << size << " bytes.\n" << logofs_flush; + #endif + + control -> ImageCacheDiskLimit = size; + + strcpy(imagesSizeName, opt); + + return 1; +} + +int ParseShmemOption(const char *opt) +{ + int size = ParseArg("", "shseg", opt); + + if (size < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value '" + << opt << "' for option 'shseg'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value '" + << opt << "' for option 'shseg'.\n"; + + return -1; + } + + control -> ShmemClientSize = size; + control -> ShmemServerSize = size; + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Set shared memory size to " + << control -> ShmemServerSize << " bytes.\n" + << logofs_flush; + #endif + + strcpy(shsegSizeName, opt); + + return 1; +} + +int ParseBitrateOption(const char *opt) +{ + int bitrate = ParseArg("", "limit", opt); + + if (bitrate < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid value '" + << opt << "' for option 'limit'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Invalid value '" + << opt << "' for option 'limit'.\n"; + + return -1; + } + + strcpy(bitrateLimitName, opt); + + if (bitrate == 0) + { + #ifdef TEST + *logofs << "Loop: Disabling bitrate limit on proxy link.\n" + << logofs_flush; + #endif + + control -> LocalBitrateLimit = 0; + } + else + { + #ifdef TEST + *logofs << "Loop: Setting bitrate to " << bitrate + << " bits per second.\n" << logofs_flush; + #endif + + // + // Internal representation is in bytes + // per second. + // + + control -> LocalBitrateLimit = bitrate >> 3; + } + + return 1; +} + +int ParseHostOption(const char *opt, char *host, long &port) +{ + #ifdef TEST + *logofs << "Loop: Trying to parse options string '" << opt + << "' as a remote NX host.\n" << logofs_flush; + #endif + + if (opt == NULL || *opt == '\0') + { + #ifdef PANIC + *logofs << "Loop: PANIC! No host parameter provided.\n" + << logofs_flush; + #endif + + return 0; + } + else if (strlen(opt) >= DEFAULT_STRING_LENGTH) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Host parameter exceeds length of " + << DEFAULT_STRING_LENGTH << " characters.\n" + << logofs_flush; + #endif + + return 0; + } + + // + // Look for a host name followed + // by a colon followed by port. + // + + int newPort = port; + + const char *separator = strrchr(opt, ':'); + + if (separator != NULL) + { + const char *check = separator + 1; + + while (*check != '\0' && *check != ',' && + *check != '=' && isdigit(*check) != 0) + { + check++; + } + + newPort = atoi(separator + 1); + + if (newPort < 0 || *check != '\0') + { + #ifdef TEST + *logofs << "Loop: Can't identify remote NX port in string '" + << separator << "'.\n" << logofs_flush; + #endif + + return 0; + } + } + else if (newPort < 0) + { + // + // Complain if port was not passed + // by other means. + // + + #ifdef TEST + *logofs << "Loop: Can't identify remote NX port in string '" + << opt << "'.\n" << logofs_flush; + #endif + + return 0; + } + else + { + separator = opt + strlen(opt); + } + + char newHost[DEFAULT_STRING_LENGTH] = { 0 }; + + strncpy(newHost, opt, strlen(opt) - strlen(separator)); + + *(newHost + strlen(opt) - strlen(separator)) = '\0'; + + const char *check = newHost; + + while (*check != '\0' && *check != ',' && + *check != '=') + { + check++; + } + + if (*check != '\0') + { + #ifdef TEST + *logofs << "Loop: Can't identify remote NX host in string '" + << newHost << "'.\n" << logofs_flush; + #endif + + return 0; + } + else if (*acceptHost != '\0') + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't manage to connect and accept connections " + << "at the same time.\n" << logofs_flush; + + *logofs << "Loop: PANIC! Refusing remote NX host with string '" + << opt << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't manage to connect and accept connections " + << "at the same time.\n"; + + cerr << "Error" << ": Refusing remote NX host with string '" + << opt << "'.\n"; + + return -1; + } + + if (*host != '\0' && strcmp(host, newHost) != 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Overriding remote NX host '" + << host << "' with new value '" << newHost + << "'.\n" << logofs_flush; + #endif + } + + strcpy(host, newHost); + + if (port != -1 && port != newPort) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Overriding remote NX port '" + << port << "' with new value '" << newPort + << "'.\n" << logofs_flush; + #endif + } + + #ifdef TEST + *logofs << "Loop: Parsed options string '" << opt + << "' with host '" << newHost << "' and port '" + << newPort << "'.\n" << logofs_flush; + #endif + + port = newPort; + + return 1; +} + +int ParseFontPath(char *path) +{ + char oldPath[DEFAULT_STRING_LENGTH]; + + strcpy(oldPath, path); + + if (path == NULL || *path == '\0' || strcmp(path, "0") == 0) + { + return 0; + } + + #ifdef TEST + *logofs << "Loop: Parsing font server option '" << path + << "'.\n" << logofs_flush; + #endif + + // + // Convert the value to our default port. + // + + if (strcmp(fontPort, "1") == 0) + { + if (control -> ProxyMode == proxy_server) + { + snprintf(fontPort, DEFAULT_STRING_LENGTH - 1, "%d", + DEFAULT_NX_FONT_PORT_OFFSET + proxyPort); + } + else + { + // + // Let the client use the well-known + // "unix/:7100" font path. + // + + snprintf(fontPort, DEFAULT_STRING_LENGTH - 1, "unix/:7100"); + } + } + + // + // Check if a simple numaric value was given. + // + + if (atoi(path) > 0) + { + #ifdef TEST + *logofs << "Loop: Assuming numeric TCP port '" << atoi(path) + << "' for font server.\n" << logofs_flush; + #endif + + return 1; + } + + // + // Let's assume that a port specification "unix/:7100" + // corresponds to "$TEMP/.font-unix/fs7100" and a port + // "unix/:-1" corresponds to "$TEMP/.font-unix/fs-1". + // + + if (strncmp("unix/:", path, 6) == 0) + { + snprintf(path, DEFAULT_STRING_LENGTH - 1, "%s/.font-unix/fs%s", + control -> TempPath, oldPath + 6); + + *(path + DEFAULT_STRING_LENGTH - 1) = '\0'; + + #ifdef TEST + *logofs << "Loop: Assuming Unix socket '" << path + << "' for font server.\n" << logofs_flush; + #endif + } + else if (strncmp("tcp/:", path, 5) == 0) + { + snprintf(path, DEFAULT_STRING_LENGTH - 1, "%d", atoi(oldPath + 5)); + + *(path + DEFAULT_STRING_LENGTH - 1) = '\0'; + + if (atoi(path) <= 0) + { + goto ParseFontPathError; + } + + #ifdef TEST + *logofs << "Loop: Assuming TCP port '" << atoi(path) + << "' for font server.\n" << logofs_flush; + #endif + } + else + { + // + // Accept an absolute file path as + // a valid Unix socket. + // + + if (*path != '/') + { + goto ParseFontPathError; + } + + #ifdef TEST + *logofs << "Loop: Assuming Unix socket '" << path + << "' for font server.\n" << logofs_flush; + #endif + } + + return 1; + +ParseFontPathError: + + #ifdef TEST + *logofs << "Loop: Unable to determine the font server " + << "port in string '" << path << "'.\n" + << logofs_flush; + #endif + + return -1; +} + +int OpenLogFile(char *name, ostream *&stream) +{ + if (name == NULL || *name == '\0') + { + #ifdef TEST + *logofs << "Loop: WARNING! No name provided for output. Using standard error.\n" + << logofs_flush; + #endif + + if (stream == NULL) + { + stream = &cerr; + } + + return 1; + } + + if (stream == NULL || stream == &cerr) + { + if (*name != '/' && *name != '.') + { + char *filePath = GetSessionPath(); + + if (filePath == NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Cannot determine directory of NX session file.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Cannot determine directory of NX session file.\n"; + + return -1; + } + + if (strlen(filePath) + strlen("/") + + strlen(name) + 1 > DEFAULT_STRING_LENGTH) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Full name of NX file '" << name + << " would exceed length of " << DEFAULT_STRING_LENGTH + << " characters.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Full name of NX file '" << name + << " would exceed length of " << DEFAULT_STRING_LENGTH + << " characters.\n"; + + return -1; + } + + char *file = new char[strlen(filePath) + strlen("/") + + strlen(name) + 1]; + + // + // Transform name in a fully qualified name. + // + + strcpy(file, filePath); + strcat(file, "/"); + strcat(file, name); + + strcpy(name, file); + + delete [] filePath; + delete [] file; + } + + mode_t fileMode = umask(0077); + + for (;;) + { + if ((stream = new ofstream(name, ios::app)) != NULL) + { + break; + } + + usleep(200000); + } + + umask(fileMode); + } + else + { + #ifdef PANIC + *logofs << "Loop: PANIC! Bad stream provided for output.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Bad stream provided for output.\n"; + + return -1; + } + + return 1; +} + +int ReopenLogFile(char *name, ostream *&stream, int limit) +{ + if (*name != '\0' && limit >= 0) + { + struct stat fileStat; + + if (limit > 0) + { + // + // This is used for the log file, if the + // size exceeds the limit. + // + + if (stat(name, &fileStat) != 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Can't get stats of file '" + << name << "'. Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + return 0; + } + else if (fileStat.st_size < (long) limit) + { + return 0; + } + } + + #ifdef TEST + *logofs << "Loop: Deleting file '" << name + << "' with size " << fileStat.st_size + << ".\n" << logofs_flush; + #endif + + // + // Create a new stream over the previous + // file. Trying to delete the file fails + // to work on recent Cygwin installs. + // + + *stream << flush; + + delete stream; + + mode_t fileMode = umask(0077); + + for (;;) + { + if ((stream = new ofstream(name, ios::out)) != NULL) + { + break; + } + + usleep(200000); + } + + umask(fileMode); + + #ifdef TEST + *logofs << "Loop: Reopened file '" << name + << "'.\n" << logofs_flush; + #endif + } + + return 1; +} + +void PrintProcessInfo() +{ + if (agent == NULL) + { + + cerr << endl; + + PrintVersionInfo(); + + cerr << endl; + + cerr << GetCopyrightInfo() + << endl + << GetOtherCopyrightInfo() + << endl + << "See https://github.com/ArcticaProject/nx-libs for more information." << endl << endl; + } + + // + // People get confused by the fact that client + // mode is running on NX server and viceversa. + // Let's adopt an user-friendly naming conven- + // tion here. + // + + cerr << "Info: Proxy running in " + << (control -> ProxyMode == proxy_client ? "client" : "server") + << " mode with pid '" << getpid() << "'.\n"; + + if (agent == NULL) + { + cerr << "Session" << ": Starting session at '" + << strTimestamp() << "'.\n"; + } + + #ifdef TEST + + if (*errorsFileName != '\0') + { + cerr << "Info" << ": Using errors file '" << errorsFileName << "'.\n"; + } + + if (*statsFileName != '\0') + { + cerr << "Info" << ": Using stats file '" << statsFileName << "'.\n"; + } + + #endif +} + +void PrintConnectionInfo() +{ + cerr << "Info" << ": Using " + << linkSpeedName << " link parameters " + << control -> TokenSize + << "/" << control -> TokenLimit + << "/" << control -> FlushPolicy + 1 + << "/" << control -> FlushPriority + << ".\n"; + + if (control -> ProxyMode == proxy_client) + { + cerr << "Info" << ": Using agent parameters " + << control -> PingTimeout + << "/" << control -> MotionTimeout + << "/" << control -> IdleTimeout + << "/" << control -> TaintReplies + << "/" << control -> HideRender + << ".\n"; + } + + if (control -> LocalDeltaCompression == 1) + { + cerr << "Info" << ": Using cache parameters " + << control -> MinimumMessageSize + << "/" << control -> MaximumMessageSize / 1024 << "KB" + << "/" << control -> ClientTotalStorageSize / 1024 << "KB" + << "/" << control -> ServerTotalStorageSize / 1024 << "KB" + << ".\n"; + } + + if (control -> ImageCacheEnableLoad == 1 || + control -> ImageCacheEnableSave == 1) + { + cerr << "Info" << ": Using image streaming parameters " + << control -> SplitTimeout + << "/" << control -> SplitTotalSize + << "/" << control -> SplitTotalStorageSize / 1024 << "KB" + << "/" << control -> SplitDataThreshold + << "/" << control -> SplitDataPacketLimit + << ".\n"; + + cerr << "Info" << ": Using image cache parameters " + << control -> ImageCacheEnableLoad + << "/" << control -> ImageCacheEnableSave + << "/" << control -> ImageCacheDiskLimit / 1024 << "KB" + << ".\n"; + } + + cerr << "Info" << ": Using pack method '" + << packMethodName << "' with session '" + << sessionType << "'.\n"; + + if (*productName != '\0') + { + cerr << "Info" << ": Using product '" << productName + << "'.\n" << logofs_flush; + } + + if (control -> LocalDeltaCompression == 0) + { + cerr << "Info" << ": Not using NX delta compression.\n"; + } + + if (control -> LocalDataCompression == 1 || + control -> RemoteDataCompression == 1) + { + cerr << "Info" << ": Using ZLIB data compression " + << control -> LocalDataCompressionLevel + << "/" << control -> RemoteDataCompressionLevel + << "/" << control -> LocalDataCompressionThreshold + << ".\n"; + } + else + { + cerr << "Info" << ": Not using ZLIB data compression.\n"; + } + + if (control -> LocalStreamCompression == 1 || + control -> RemoteStreamCompression == 1) + { + cerr << "Info" << ": Using ZLIB stream compression " + << control -> LocalStreamCompressionLevel + << "/" << control -> RemoteStreamCompressionLevel + << ".\n"; + } + else + { + cerr << "Info" << ": Not using ZLIB stream compression.\n"; + } + + if (control -> LocalBitrateLimit > 0) + { + cerr << "Info" << ": Using bandwidth limit of " + << bitrateLimitName << " bits per second.\n"; + } + + if (control -> PersistentCacheName != NULL) + { + cerr << "Info" << ": Using cache file '" + << control -> PersistentCachePath << "/" + << control -> PersistentCacheName << "'.\n"; + } + else + { + if (control -> PersistentCacheEnableLoad == 0 || + control -> LocalDeltaCompression == 0) + { + cerr << "Info" << ": Not using a persistent cache.\n"; + } + else + { + cerr << "Info" << ": No suitable cache file found.\n"; + } + } + + if (control -> ProxyMode == proxy_client && + (useUnixSocket > 0 || useTcpSocket > 0 || + useAgentSocket > 0)) + { + cerr << "Info" << ": Listening to X11 connections " + << "on display ':" << xPort << "'.\n"; + } + else if (control -> ProxyMode == proxy_server) + { + cerr << "Info" << ": Forwarding X11 connections " + << "to display '" << displayHost << "'.\n"; + } + + if (control -> ProxyMode == proxy_client && + useCupsSocket > 0 && cupsPort.enabled()) + { + cerr << "Info" << ": Listening to CUPS connections " + << "on port '" << cupsPort << "'.\n"; + } + else if (control -> ProxyMode == proxy_server && + cupsPort.enabled()) + { + cerr << "Info" << ": Forwarding CUPS connections " + << "to port '" << cupsPort << "'.\n"; + } + + if (control -> ProxyMode == proxy_client && + useAuxSocket > 0 && auxPort.enabled()) + { + cerr << "Info" << ": Listening to auxiliary X11 connections " + << "on port '" << auxPort << "'.\n"; + } + else if (control -> ProxyMode == proxy_server && + auxPort.enabled()) + { + cerr << "Info" << ": Forwarding auxiliary X11 connections " + << "to display '" << displayHost << "'.\n"; + } + + if (control -> ProxyMode == proxy_client && + useSmbSocket > 0 && smbPort.enabled()) + { + cerr << "Info" << ": Listening to SMB connections " + << "on port '" << smbPort << "'.\n"; + } + else if (control -> ProxyMode == proxy_server && + smbPort.enabled()) + { + cerr << "Info" << ": Forwarding SMB connections " + << "to port '" << smbPort << "'.\n"; + } + + if (control -> ProxyMode == proxy_client && + useMediaSocket > 0 && mediaPort.enabled()) + { + cerr << "Info" << ": Listening to multimedia connections " + << "on port '" << mediaPort << "'.\n"; + } + else if (control -> ProxyMode == proxy_server && + mediaPort.enabled()) + { + cerr << "Info" << ": Forwarding multimedia connections " + << "to port '" << mediaPort << "'.\n"; + } + + if (control -> ProxyMode == proxy_client && + useHttpSocket > 0 && httpPort.enabled()) + { + cerr << "Info" << ": Listening to HTTP connections " + << "on port '" << httpPort << "'.\n"; + } + else if (control -> ProxyMode == proxy_server && + httpPort.enabled()) + { + cerr << "Info" << ": Forwarding HTTP connections " + << "to port '" << httpPort << "'.\n"; + } + + if (control -> ProxyMode == proxy_server && + useFontSocket > 0 && *fontPort != '\0') + { + cerr << "Info" << ": Listening to font server connections " + << "on port '" << fontPort << "'.\n"; + } + else if (control -> ProxyMode == proxy_client && + *fontPort != '\0') + { + cerr << "Info" << ": Forwarding font server connections " + << "to port '" << fontPort << "'.\n"; + } + + if (useSlaveSocket > 0 && slavePort.enabled()) + { + cerr << "Info" << ": Listening to slave connections " + << "on port '" << slavePort << "'.\n"; + } +} + +void PrintVersionInfo() +{ + cerr << "NXPROXY - " << "Version " + << control -> LocalVersionMajor << "." + << control -> LocalVersionMinor << "." + << control -> LocalVersionPatch << "." + << control -> LocalVersionMaintenancePatch; + + cerr << endl; +} + +void PrintCopyrightInfo() +{ + cerr << endl; + + PrintVersionInfo(); + + cerr << endl; + + cerr << GetCopyrightInfo(); + + // + // Print third party's copyright info. + // + + cerr << endl; + + cerr << GetOtherCopyrightInfo(); + + cerr << endl; +} + +void PrintOptionIgnored(const char *type, const char *name, const char *value) +{ + if (control -> ProxyMode == proxy_server) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Ignoring " << type + << " option '" << name << "' with value '" + << value << "' at " << "NX client side.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Ignoring " << type + << " option '" << name << "' with value '" + << value << "' at " << "NX client side.\n"; + } + else + { + #ifdef WARNING + *logofs << "Loop: WARNING! Ignoring " << type + << " option '" << name << "' with value '" + << value << "' at " << "NX server side.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Ignoring " << type + << " option '" << name << "' with value '" + << value << "' at " << "NX server side.\n"; + } +} + +const char *GetOptions(const char *options) +{ + if (options != NULL) + { + if (strncasecmp(options, "nx/nx,", 6) != 0 && + strncasecmp(options, "nx,", 3) != 0 && + strncasecmp(options, "nx:", 3) != 0) + { + #ifdef TEST + *logofs << "Loop: PANIC! Display options string '" << options + << "' must start with 'nx' or 'nx/nx' prefix.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Display options string '" << options + << "' must start with 'nx' or 'nx/nx' prefix.\n"; + + HandleCleanup(); + } + } + else + { + options = getenv("DISPLAY"); + } + + return options; +} + +const char *GetArg(int &argi, int argc, const char **argv) +{ + // + // Skip "-" and flag character. + // + + const char *arg = argv[argi] + 2; + + if (*arg == 0) + { + if (argi + 1 == argc) + { + return NULL; + } + else + { + argi++; + + return (*argv[argi] == '-' ? NULL : argv[argi]); + } + } + else + { + return (*arg == '-' ? NULL : arg); + } +} + +int CheckArg(const char *type, const char *name, const char *value) +{ + #ifdef TEST + *logofs << "Loop: Parsing " << type << " option '" << name + << "' with value '" << (value ? value : "(null)") + << "'.\n" << logofs_flush; + #endif + + if (value == NULL || strstr(value, "=") != NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error in " << type << " option '" + << name << "'. No value found.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error in " << type << " option '" + << name << "'. No value found.\n"; + + return -1; + } + else if (strstr(name, ",") != NULL) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Parse error at " << type << " option '" + << name << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Parse error at " << type << " option '" + << name << "'.\n"; + + return -1; + } + else if (strlen(value) >= DEFAULT_STRING_LENGTH) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Value '" << value << "' of " + << type << " option '" << name << "' exceeds length of " + << DEFAULT_STRING_LENGTH << " characters.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Value '" << value << "' of " + << type << " option '" << name << "' exceeds length of " + << DEFAULT_STRING_LENGTH << " characters.\n"; + + return -1; + } + + return 1; +} + +int ParseArg(const char *type, const char *name, const char *value) +{ + if (strcasecmp(value, "0") == 0) + { + return 0; + } + + // + // Find the base factor. + // + + double base; + + const char *id = value + strlen(value) - 1; + + if (strcasecmp(id, "g") == 0) + { + base = 1024 * 1024 * 1024; + } + else if (strcasecmp(id, "m") == 0) + { + base = 1024 * 1024; + } + else if (strcasecmp(id, "k") == 0) + { + base = 1024; + } + else if (strcasecmp(id, "b") == 0 || isdigit(*id) == 1) + { + base = 1; + } + else + { + return -1; + } + + char *string = new char[strlen(value)]; + + strncpy(string, value, strlen(value) - 1); + + *(string + (strlen(value) - 1)) = '\0'; + + #ifdef TEST + + *logofs << "Loop: Parsing integer option '" << name + << "' from string '" << string << "' with base set to "; + + switch (tolower(*id)) + { + case 'k': + case 'm': + case 'g': + { + *logofs << (char) toupper(*id); + } + break; + } + + *logofs << ".\n" << logofs_flush; + + #endif + + double result = atof(string) * base; + + if (result < 0 || result > (((unsigned) -1) >> 1)) + { + delete [] string; + + return -1; + } + + delete [] string; + + #ifdef TEST + *logofs << "Loop: Integer option parsed to '" + << (int) result << "'.\n" << logofs_flush; + #endif + + return (int) result; +} + +void SetAndValidateChannelEndPointArg(const char *type, const char *name, const char *value, + ChannelEndPoint &endPoint) { + endPoint.setSpec(value); + if (!endPoint.validateSpec()) { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid " << type + << " option '" << name << "' with value '" + << value << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid " << type + << " option '" << name << "' with value '" + << value << "'.\n"; + + HandleCleanup(); + } +} + + +int ValidateArg(const char *type, const char *name, const char *value) +{ + int number = atoi(value); + + if (number < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Invalid " << type + << " option '" << name << "' with value '" + << value << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid " << type + << " option '" << name << "' with value '" + << value << "'.\n"; + + HandleCleanup(); + } + + return number; +} + +int LowercaseArg(const char *type, const char *name, char *value) +{ + char *next = value; + + while (*next != '\0') + { + *next = tolower(*next); + + next++; + } + + return 1; +} + +int CheckSignal(int signal) +{ + // + // Return 1 if the signal needs to be handled + // by the proxy, 2 if the signal just needs to + // be blocked to avoid interrupting a system + // call. + // + + switch (signal) + { + case SIGCHLD: + case SIGUSR1: + case SIGUSR2: + case SIGHUP: + case SIGINT: + case SIGTERM: + case SIGPIPE: + case SIGALRM: + { + return 1; + } + case SIGVTALRM: + case SIGWINCH: + case SIGIO: + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + { + return 2; + } + default: + { + #ifdef __CYGWIN32__ + + // + // This signal can be raised by the Cygwin + // library. + // + + if (signal == 12) + { + return 1; + } + + #endif + + return 0; + } + } +} + +static void PrintUsageInfo(const char *option, int error) +{ + if (error == 1) + { + cerr << "Error" << ": Invalid command line option '" << option << "'.\n"; + } + + cerr << GetUsageInfo(); + + if (error == 1) + { + cerr << "Error" << ": NX transport initialization failed.\n"; + } +} + +static void handleCheckSessionInLoop() +{ + // + // Check if we completed the shutdown procedure + // and the remote confirmed the shutdown. The + // tear down should be always initiated by the + // agent, but the X server side may unilateral- + // ly shut down the link without our permission. + // + + if (proxy -> getShutdown() > 0) + { + #ifdef TEST + *logofs << "Loop: End of NX transport requested " + << "by remote.\n" << logofs_flush; + #endif + + handleTerminatingInLoop(); + + if (control -> ProxyMode == proxy_server) + { + #ifdef TEST + *logofs << "Loop: Bytes received so far are " + << (unsigned long long) statistics -> getBytesIn() + << ".\n" << logofs_flush; + #endif + + if (statistics -> getBytesIn() < 1024) + { + cerr << "Info" << ": Your session was closed before reaching " + << "a usable state.\n"; + cerr << "Info" << ": This can be due to the local X server " + << "refusing access to the client.\n"; + cerr << "Info" << ": Please check authorization provided " + << "by the remote X application.\n"; + } + } + + #ifdef TEST + *logofs << "Loop: Shutting down the NX transport.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + else if (proxy -> handlePing() < 0) + { + #ifdef TEST + *logofs << "Loop: Failure handling the ping for " + << "proxy FD#" << proxyFD << ".\n" + << logofs_flush; + #endif + + HandleShutdown(); + } + + // + // Check if the watchdog has exited and we didn't + // get the SIGCHLD. This can happen if the parent + // has overridden our signal handlers. + // + + if (IsRunning(lastWatchdog) && CheckProcess(lastWatchdog, "watchdog") == 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Watchdog is gone unnoticed. " + << "Setting the last signal to SIGTERM.\n" + << logofs_flush; + #endif + + lastSignal = SIGTERM; + + #ifdef WARNING + *logofs << "Loop: WARNING! Resetting pid of last " + << "watchdog process.\n" << logofs_flush; + #endif + + SetNotRunning(lastWatchdog); + } + + // + // Let the client proxy find out if the agent's + // channel is gone. This is the normal shutdown + // procedure in the case of an internal connect- + // ion to the agent. + // + + int cleanup = 0; + + if (control -> ProxyMode == proxy_client && + agent != NULL && proxy -> getType(agentFD[1]) == + channel_none && lastKill == 0 && lastDestroy == 1) + { + #ifdef TEST + *logofs << "Loop: End of NX transport requested " + << "by agent.\n" << logofs_flush; + #endif + + #ifdef TEST + *logofs << "Loop: Bytes sent so far are " + << (unsigned long long) statistics -> getBytesOut() + << ".\n" << logofs_flush; + #endif + + if (statistics -> getBytesOut() < 1024) + { + cerr << "Info" << ": Your session has died before reaching " + << "an usable state.\n"; + cerr << "Info" << ": This can be due to the remote X server " + << "refusing access to the client.\n"; + cerr << "Info" << ": Please check the authorization provided " + << "by your X application.\n"; + } + + cleanup = 1; + } + + // + // Check if the user requested the end of the + // session by sending a signal to the proxy. + // All signals are handled in the main loop + // so we need to reset the value to get ready + // for the next iteration. + // + + int signal = 0; + + if (lastSignal != 0) + { + switch (lastSignal) + { + case SIGCHLD: + case SIGUSR1: + case SIGUSR2: + { + break; + } + default: + { + signal = lastSignal; + + cleanup = 1; + + break; + } + } + + lastSignal = 0; + } + + if (cleanup == 1) + { + // + // The first time termination signal is received + // disable all further connections, close down any + // X channel and wait for a second signal. + // + + if (lastKill == 0) + { + // + // Don't print a message if cleanup is + // due to normal termination of agent. + // + + if (signal != 0) + { + #ifdef TEST + *logofs << "Loop: End of NX transport requested by signal '" + << signal << "' '" << DumpSignal(signal) + << "'.\n" << logofs_flush; + #endif + + handleTerminatingInLoop(); + } + + // + // Disable any further connection. + // + + CleanupListeners(); + + // + // Close all the remaining X channels and + // let proxies save their persistent cache + // on disk. + // + + CleanupConnections(); + + // + // We'll need to wait for the X channels + // to be shut down before waiting for the + // cleanup signal. + // + + lastKill = 1; + } + else if (lastKill == 2) + { + #ifdef TEST + *logofs << "Loop: Shutting down the NX transport.\n" + << logofs_flush; + #endif + + proxy -> handleShutdown(); + + HandleCleanup(); + } + } + + if (lastKill == 1 && proxy -> getChannels(channel_x11) == 0) + { + // + // Save the message stores to the + // persistent cache. + // + + proxy -> handleSave(); + + // + // Run a watchdog process so we can finally + // give up at the time the watchdog exits. + // + + if (IsNotRunning(lastWatchdog)) + { + int timeout = control -> CleanupTimeout; + + if (timeout > 0) + { + if (proxy -> getChannels() == 0) + { + timeout = 500; + } + + #ifdef TEST + *logofs << "Loop: Starting watchdog process with timeout " + << "of " << timeout << " Ms.\n" + << logofs_flush; + #endif + } + #ifdef TEST + else + { + *logofs << "Loop: Starting watchdog process without " + << "a timeout.\n" << logofs_flush; + } + #endif + + lastWatchdog = NXTransWatchdog(timeout); + + if (IsFailed(lastWatchdog)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't start the NX watchdog " + << "process in shutdown.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't start the NX watchdog " + << "process in shutdown.\n"; + + HandleCleanup(); + } + #ifdef TEST + else + { + *logofs << "Loop: Watchdog started with pid '" + << lastWatchdog << "'.\n" << logofs_flush; + } + #endif + } + else + { + #ifdef PANIC + *logofs << "Loop: PANIC! Previous watchdog detected " + << "in shutdown with pid '" << lastWatchdog + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Previous watchdog detected " + << "in shutdown with pid '" << lastWatchdog + << "'.\n"; + + HandleCleanup(); + } + + if (control -> CleanupTimeout > 0) + { + #ifdef TEST + *logofs << "Loop: Waiting the cleanup timeout to complete.\n" + << logofs_flush; + #endif + + cerr << "Info" << ": Waiting the cleanup timeout to complete.\n"; + } + else + { + // + // The NX server will kill the watchdog + // process after having shut down the + // service channels. + // + + cerr << "Info" << ": Watchdog running with pid '" << lastWatchdog + << "'.\n"; + + #ifdef TEST + *logofs << "Loop: Waiting the watchdog process to complete.\n" + << logofs_flush; + #endif + + cerr << "Info" << ": Waiting the watchdog process to complete.\n"; + } + + lastKill = 2; + } +} + +static void handleCheckBitrateInLoop() +{ + static long int slept = 0; + + #ifdef TEST + *logofs << "Loop: Bitrate is " << statistics -> getBitrateInShortFrame() + << " B/s and " << statistics -> getBitrateInLongFrame() + << " B/s in " << control -> ShortBitrateTimeFrame / 1000 + << "/" << control -> LongBitrateTimeFrame / 1000 + << " seconds timeframes.\n" << logofs_flush; + #endif + + // + // This can be improved. We may not jump out + // of the select often enough to guarantee + // the necessary accuracy. + // + + if (control -> LocalBitrateLimit > 0) + { + #ifdef TEST + *logofs << "Loop: Calculating bandwidth usage with limit " + << control -> LocalBitrateLimit << ".\n" + << logofs_flush; + #endif + + int reference = (statistics -> getBitrateInLongFrame() + + statistics -> getBitrateInShortFrame()) / 2; + + if (reference > control -> LocalBitrateLimit) + { + double ratio = ((double) reference) / + ((double) control -> LocalBitrateLimit); + + if (ratio > 1.2) + { + ratio = 1.2; + } + + slept += (unsigned int) (pow(50000, ratio) / 1000); + + if (slept > 2000) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Sleeping due to " + << "reference bitrate of " << reference + << " B/s.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Sleeping due to " + << "reference bitrate of " << reference + << " B/s.\n"; + + slept %= 2000; + } + + T_timestamp idleTs = getNewTimestamp(); + + usleep((unsigned int) pow(50000, ratio)); + + int diffTs = diffTimestamp(idleTs, getNewTimestamp()); + + statistics -> addIdleTime(diffTs); + + statistics -> subReadTime(diffTs); + } + } +} + +#if defined(TEST) || defined(INFO) + +static void handleCheckStateInLoop(int &setFDs) +{ + int fdLength; + int fdPending; + int fdSplits; + + for (int j = 0; j < setFDs; j++) + { + if (j != proxyFD) + { + fdPending = proxy -> getPending(j); + + if (fdPending > 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Buffer for descriptor FD#" + << j << " has pending bytes to read.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + + fdLength = proxy -> getLength(j); + + if (fdLength > 0) + { + #ifdef TEST + *logofs << "Loop: WARNING! Buffer for descriptor FD#" + << j << " has " << fdLength << " bytes to write.\n" + << logofs_flush; + #endif + } + } + } + + fdPending = proxy -> getPending(proxyFD); + + if (fdPending > 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Buffer for proxy descriptor FD#" + << proxyFD << " has pending bytes to read.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + + fdLength = proxy -> getFlushable(proxyFD); + + if (fdLength > 0) + { + if (control -> FlushPolicy == policy_immediate && + proxy -> getBlocked(proxyFD) == 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Buffer for proxy descriptor FD#" + << proxyFD << " has " << fdLength << " bytes " + << "to write with policy 'immediate'.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + else + { + #ifdef TEST + *logofs << "Loop: WARNING! Buffer for proxy descriptor FD#" + << proxyFD << " has " << fdLength << " bytes " + << "to write.\n" << logofs_flush; + #endif + } + } + + fdSplits = proxy -> getSplitSize(); + + if (fdSplits > 0) + { + #ifdef WARNING + *logofs << "Loop: WARNING! Proxy descriptor FD#" << proxyFD + << " has " << fdSplits << " splits to send.\n" + << logofs_flush; + #endif + } +} + +static void handleCheckSelectInLoop(int &setFDs, fd_set &readSet, + fd_set &writeSet, T_timestamp selectTs) +{ + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Maximum descriptors is [" + << setFDs << "] at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + int i; + + if (setFDs > 0) + { + i = 0; + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Selected for read are "; + #endif + + for (int j = 0; j < setFDs; j++) + { + if (FD_ISSET(j, &readSet)) + { + #if defined(TEST) || defined(INFO) + *logofs << "[" << j << "]" << logofs_flush; + #endif + + i++; + } + } + + if (i > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << ".\n" << logofs_flush; + #endif + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "[none].\n" << logofs_flush; + #endif + } + + i = 0; + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Selected for write are "; + #endif + + for (int j = 0; j < setFDs; j++) + { + if (FD_ISSET(j, &writeSet)) + { + #if defined(TEST) || defined(INFO) + *logofs << "[" << j << "]" << logofs_flush; + #endif + + i++; + } + } + + if (i > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << ".\n" << logofs_flush; + #endif + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "[none].\n" << logofs_flush; + #endif + } + } + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Select timeout is " + << selectTs.tv_sec << " S and " + << (double) selectTs.tv_usec / 1000 + << " Ms.\n" << logofs_flush; + #endif +} + +static void handleCheckResultInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, + fd_set &writeSet, struct timeval &selectTs, + struct timeval &startTs) +{ + int diffTs = diffTimestamp(startTs, getNewTimestamp()); + + #if defined(TEST) || defined(INFO) + + if (diffTs >= (control -> PingTimeout - + (control -> LatencyTimeout * 4))) + { + *logofs << "Loop: Select result is [" << resultFDs + << "] at " << strMsTimestamp() << " with no " + << "communication within " << diffTs + << " Ms.\n" << logofs_flush; + } + else + { + *logofs << "Loop: Select result is [" << resultFDs + << "] error is [" << errorFDs << "] at " + << strMsTimestamp() << " after " << diffTs + << " Ms.\n" << logofs_flush; + } + + #endif + + int i; + + if (resultFDs > 0) + { + i = 0; + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Selected for read are "; + #endif + + for (int j = 0; j < setFDs; j++) + { + if (FD_ISSET(j, &readSet)) + { + #if defined(TEST) || defined(INFO) + *logofs << "[" << j << "]" << logofs_flush; + #endif + + i++; + } + } + + if (i > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << ".\n" << logofs_flush; + #endif + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "[none].\n" << logofs_flush; + #endif + } + + i = 0; + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Selected for write are "; + #endif + + for (int j = 0; j < setFDs; j++) + { + if (FD_ISSET(j, &writeSet)) + { + #if defined(TEST) || defined(INFO) + *logofs << "[" << j << "]" << logofs_flush; + #endif + + i++; + } + } + + if (i > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << ".\n" << logofs_flush; + #endif + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "[none].\n" << logofs_flush; + #endif + } + } +} + +#endif + +static void handleCheckSessionInConnect() +{ + #ifdef TEST + *logofs << "Loop: Going to check session in connect.\n" + << logofs_flush; + #endif + + if (control -> ProxyMode == proxy_client) + { + HandleAlert(FAILED_PROXY_CONNECTION_CLIENT_ALERT, 1); + } + else if (IsNotRunning(lastDialog)) + { + HandleAlert(FAILED_PROXY_CONNECTION_SERVER_ALERT, 1); + } + + handleAlertInLoop(); +} + +static void handleStatisticsInLoop() +{ + if (lastSignal == 0) + { + return; + } + + int mode = NO_STATS; + + if (control -> EnableStatistics == 1) + { + if (lastSignal == SIGUSR1) + { + // + // Print overall statistics. + // + + mode = TOTAL_STATS; + } + else if (lastSignal == SIGUSR2) + { + // + // Print partial statistics. + // + + mode = PARTIAL_STATS; + } + + if (mode == TOTAL_STATS || mode == PARTIAL_STATS) + { + #ifdef TEST + *logofs << "Loop: Going to request proxy statistics " + << "with signal '" << DumpSignal(lastSignal) + << "'.\n" << logofs_flush; + #endif + + if (proxy != NULL) + { + if (ReopenLogFile(statsFileName, statofs, 0) < 0) + { + HandleCleanup(); + } + + proxy -> handleStatistics(mode, statofs); + } + } + } +} + +static void handleNegotiationInLoop(int &setFDs, fd_set &readSet, + fd_set &writeSet, T_timestamp &selectTs) +{ + int yield = 0; + + while (yield == 0) + { + #ifdef TEST + *logofs << "Loop: Going to run a new negotiation loop " + << "with stage " << control -> ProxyStage + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + switch (control -> ProxyStage) + { + case stage_undefined: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_undefined" << "'.\n" + << logofs_flush; + #endif + + control -> ProxyStage = stage_initializing; + + break; + } + case stage_initializing: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_initializing" << "'.\n" + << logofs_flush; + #endif + + InitBeforeNegotiation(); + + control -> ProxyStage = stage_connecting; + + break; + } + case stage_connecting: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_connecting" << "'.\n" + << logofs_flush; + #endif + + SetupProxyConnection(); + + control -> ProxyStage = stage_connected; + + break; + } + case stage_connected: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_connected" << "'.\n" + << logofs_flush; + #endif + + // + // Server side proxy must always be the one that + // sends its version and options first, so, in + // some way, client side can be the the one that + // has the last word on the matter. + // + + if (control -> ProxyMode == proxy_server) + { + // + // Check if we have been listening for a + // forwarder. In this case it will have to + // authenticate itself. + // + + if (WE_LISTEN_FORWARDER) + { + control -> ProxyStage = stage_waiting_forwarder_version; + + break; + } + + control -> ProxyStage = stage_sending_proxy_options; + } + else + { + // + // The X client side is the side that has to wait + // for the authorization cookie and any remote + // option. + // + + control -> ProxyStage = stage_waiting_proxy_version; + } + + break; + } + case stage_sending_proxy_options: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_sending_proxy_options" << "'.\n" + << logofs_flush; + #endif + + if (SendProxyOptions(proxyFD) < 0) + { + goto handleNegotiationInLoopError; + } + + if (control -> ProxyMode == proxy_server) + { + control -> ProxyStage = stage_waiting_proxy_version; + } + else + { + control -> ProxyStage = stage_sending_proxy_caches; + } + + break; + } + case stage_waiting_forwarder_version: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_waiting_forwarder_version" << "'.\n" + << logofs_flush; + #endif + + int result = ReadForwarderVersion(proxyFD); + + if (result == 0) + { + yield = 1; + } + else if (result == 1) + { + control -> ProxyStage = stage_waiting_forwarder_options; + } + else + { + goto handleNegotiationInLoopError; + } + + break; + } + case stage_waiting_forwarder_options: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_waiting_forwarder_options" << "'.\n" + << logofs_flush; + #endif + + int result = ReadForwarderOptions(proxyFD); + + if (result == 0) + { + yield = 1; + } + else if (result == 1) + { + control -> ProxyStage = stage_sending_proxy_options; + } + else + { + goto handleNegotiationInLoopError; + } + + break; + } + case stage_waiting_proxy_version: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_waiting_proxy_version" << "'.\n" + << logofs_flush; + #endif + + int result = ReadProxyVersion(proxyFD); + + if (result == 0) + { + yield = 1; + } + else if (result == 1) + { + control -> ProxyStage = stage_waiting_proxy_options; + } + else + { + goto handleNegotiationInLoopError; + } + + break; + } + case stage_waiting_proxy_options: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_waiting_proxy_options" << "'.\n" + << logofs_flush; + #endif + + int result = ReadProxyOptions(proxyFD); + + if (result == 0) + { + yield = 1; + } + else if (result == 1) + { + if (control -> ProxyMode == proxy_server) + { + control -> ProxyStage = stage_waiting_proxy_caches; + } + else + { + control -> ProxyStage = stage_sending_proxy_options; + } + } + else + { + goto handleNegotiationInLoopError; + } + + break; + } + case stage_sending_proxy_caches: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_sending_proxy_caches" << "'.\n" + << logofs_flush; + #endif + + if (SendProxyCaches(proxyFD) < 0) + { + goto handleNegotiationInLoopError; + } + + if (control -> ProxyMode == proxy_server) + { + control -> ProxyStage = stage_operational; + } + else + { + control -> ProxyStage = stage_waiting_proxy_caches; + } + + break; + } + case stage_waiting_proxy_caches: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_waiting_proxy_caches" << "'.\n" + << logofs_flush; + #endif + + int result = ReadProxyCaches(proxyFD); + + if (result == 0) + { + yield = 1; + } + else if (result == 1) + { + if (control -> ProxyMode == proxy_server) + { + control -> ProxyStage = stage_sending_proxy_caches; + } + else + { + control -> ProxyStage = stage_operational; + } + } + else + { + goto handleNegotiationInLoopError; + } + + break; + } + case stage_operational: + { + #ifdef TEST + *logofs << "Loop: Handling negotiation with '" + << "stage_operational" << "'.\n" + << logofs_flush; + #endif + + InitAfterNegotiation(); + + yield = 1; + + break; + } + default: + { + #ifdef PANIC + *logofs << "Loop: PANIC! Unmanaged case '" << control -> ProxyStage + << "' while handling negotiation.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unmanaged case '" << control -> ProxyStage + << "' while handling negotiation.\n"; + + HandleCleanup(); + } + } + } + + // + // Check if the user requested the end of + // the session. + // + + if (CheckAbort() != 0) + { + HandleCleanup(); + } + + // + // Select the proxy descriptor so that we + // can proceed negotiating the session. + // + + FD_SET(proxyFD, &readSet); + + if (proxyFD >= setFDs) + { + setFDs = proxyFD + 1; + } + + setMinTimestamp(selectTs, control -> PingTimeout); + + #ifdef TEST + *logofs << "Loop: Selected proxy FD#" << proxyFD << " in negotiation " + << "phase with timeout of " << selectTs.tv_sec << " S and " + << selectTs.tv_usec << " Ms.\n" << logofs_flush; + #endif + + return; + +handleNegotiationInLoopError: + + #ifdef PANIC + *logofs << "Loop: PANIC! Failure negotiating the session in stage '" + << control -> ProxyStage << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failure negotiating the session in stage '" + << control -> ProxyStage << "'.\n"; + + + if (control -> ProxyMode == proxy_server && + control -> ProxyStage == stage_waiting_proxy_version) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Wrong version or invalid session " + << "authentication cookie.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Wrong version or invalid session " + << "authentication cookie.\n"; + } + + handleTerminatingInLoop(); + + HandleCleanup(); +} + +static void handleTerminatingInLoop() +{ + if (getpid() == lastProxy) + { + if (control -> ProxyStage < stage_terminating) + { + if (agent == NULL) + { + cerr << "Session" << ": Terminating session at '" + << strTimestamp() << "'.\n"; + } + + control -> ProxyStage = stage_terminating; + } + } +} + +static void handleTerminatedInLoop() +{ + if (getpid() == lastProxy) + { + if (control -> ProxyStage < stage_terminated) + { + if (agent == NULL) + { + cerr << "Session" << ": Session terminated at '" + << strTimestamp() << "'.\n"; + } + + control -> ProxyStage = stage_terminated; + } + } +} + +static void handleAlertInLoop() +{ + if (lastAlert.code == 0) + { + return; + } + + // + // Since ProtoStep7 (#issue 108) + // + // Now the remote proxy should always + // be able to handle the alert + // + + if (lastAlert.local == 0) + { + if (proxy != NULL) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Requesting a remote alert with code '" + << lastAlert.code << "'.\n" << logofs_flush; + #endif + + if (proxy -> handleAlert(lastAlert.code) < 0) + { + HandleShutdown(); + } + } + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Handling a local alert with code '" + << lastAlert.code << "'.\n" << logofs_flush; + #endif + + if (control -> ProxyMode == proxy_client) + { + // + // If we are at X client side and server + // proxy is not responding, we don't have + // any possibility to interact with user. + // + + if (lastAlert.code != CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT && + lastAlert.code != RESTART_DEAD_PROXY_CONNECTION_CLIENT_ALERT && + lastAlert.code != FAILED_PROXY_CONNECTION_CLIENT_ALERT) + { + // + // Let the server proxy show the dialog. + // + + if (proxy != NULL && + proxy -> handleAlert(lastAlert.code) < 0) + { + HandleShutdown(); + } + } + } + else + { + char caption[DEFAULT_STRING_LENGTH]; + + strcpy(caption, ALERT_CAPTION_PREFIX); + + int length = strlen(sessionId); + + // + // Get rid of the trailing MD5 from session id. + // + + if (length > (MD5_LENGTH * 2 + 1) && + *(sessionId + (length - (MD5_LENGTH * 2 + 1))) == '-') + { + strncat(caption, sessionId, length - (MD5_LENGTH * 2 + 1)); + } + else + { + strcat(caption, sessionId); + } + + // + // Use the display to which we are forwarding + // the remote X connections. + // + + char *display = displayHost; + + int replace = 1; + int local = 1; + + const char *message; + const char *type; + + switch (lastAlert.code) + { + case CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT: + { + message = CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT_STRING; + type = CLOSE_DEAD_X_CONNECTION_CLIENT_ALERT_TYPE; + + break; + } + case CLOSE_DEAD_X_CONNECTION_SERVER_ALERT: + { + message = CLOSE_DEAD_X_CONNECTION_SERVER_ALERT_STRING; + type = CLOSE_DEAD_X_CONNECTION_SERVER_ALERT_TYPE; + + break; + } + case CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT: + { + message = CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT_STRING; + type = CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT_TYPE; + + break; + } + case RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT: + { + message = RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT_STRING; + type = RESTART_DEAD_PROXY_CONNECTION_SERVER_ALERT_TYPE; + + break; + } + case CLOSE_UNRESPONSIVE_X_SERVER_ALERT: + { + message = CLOSE_UNRESPONSIVE_X_SERVER_ALERT_STRING; + type = CLOSE_UNRESPONSIVE_X_SERVER_ALERT_TYPE; + + break; + } + case WRONG_PROXY_VERSION_ALERT: + { + message = WRONG_PROXY_VERSION_ALERT_STRING; + type = WRONG_PROXY_VERSION_ALERT_TYPE; + + break; + } + case FAILED_PROXY_CONNECTION_SERVER_ALERT: + { + message = FAILED_PROXY_CONNECTION_SERVER_ALERT_STRING; + type = FAILED_PROXY_CONNECTION_SERVER_ALERT_TYPE; + + break; + } + case MISSING_PROXY_CACHE_ALERT: + { + message = MISSING_PROXY_CACHE_ALERT_STRING; + type = MISSING_PROXY_CACHE_ALERT_TYPE; + + break; + } + case ABORT_PROXY_CONNECTION_ALERT: + { + message = ABORT_PROXY_CONNECTION_ALERT_STRING; + type = ABORT_PROXY_CONNECTION_ALERT_TYPE; + + break; + } + case DISPLACE_MESSAGE_ALERT: + { + message = DISPLACE_MESSAGE_ALERT_STRING; + type = DISPLACE_MESSAGE_ALERT_TYPE; + + break; + } + case GREETING_MESSAGE_ALERT: + { + message = GREETING_MESSAGE_ALERT_STRING; + type = GREETING_MESSAGE_ALERT_TYPE; + + break; + } + case START_RESUME_SESSION_ALERT: + { + message = START_RESUME_SESSION_ALERT_STRING; + type = START_RESUME_SESSION_ALERT_TYPE; + + break; + } + case FAILED_RESUME_DISPLAY_ALERT: + { + message = FAILED_RESUME_DISPLAY_ALERT_STRING; + type = FAILED_RESUME_DISPLAY_ALERT_TYPE; + + break; + } + case FAILED_RESUME_DISPLAY_BROKEN_ALERT: + { + message = FAILED_RESUME_DISPLAY_BROKEN_STRING; + type = FAILED_RESUME_DISPLAY_BROKEN_TYPE; + + break; + } + case FAILED_RESUME_VISUALS_ALERT: + { + message = FAILED_RESUME_VISUALS_ALERT_STRING; + type = FAILED_RESUME_VISUALS_ALERT_TYPE; + + break; + } + case FAILED_RESUME_COLORMAPS_ALERT: + { + message = FAILED_RESUME_COLORMAPS_ALERT_STRING; + type = FAILED_RESUME_COLORMAPS_ALERT_TYPE; + + break; + } + case FAILED_RESUME_PIXMAPS_ALERT: + { + message = FAILED_RESUME_PIXMAPS_ALERT_STRING; + type = FAILED_RESUME_PIXMAPS_ALERT_TYPE; + + break; + } + case FAILED_RESUME_DEPTHS_ALERT: + { + message = FAILED_RESUME_DEPTHS_ALERT_STRING; + type = FAILED_RESUME_DEPTHS_ALERT_TYPE; + + break; + } + case FAILED_RESUME_RENDER_ALERT: + { + message = FAILED_RESUME_RENDER_ALERT_STRING; + type = FAILED_RESUME_RENDER_ALERT_TYPE; + + break; + } + case FAILED_RESUME_FONTS_ALERT: + { + message = FAILED_RESUME_FONTS_ALERT_STRING; + type = FAILED_RESUME_FONTS_ALERT_TYPE; + + break; + } + case INTERNAL_ERROR_ALERT: + { + message = INTERNAL_ERROR_ALERT_STRING; + type = INTERNAL_ERROR_ALERT_TYPE; + + break; + } + case ABORT_PROXY_NEGOTIATION_ALERT: + { + message = ABORT_PROXY_NEGOTIATION_ALERT_STRING; + type = ABORT_PROXY_NEGOTIATION_ALERT_TYPE; + + break; + } + case ABORT_PROXY_SHUTDOWN_ALERT: + { + message = ABORT_PROXY_SHUTDOWN_ALERT_STRING; + type = ABORT_PROXY_SHUTDOWN_ALERT_TYPE; + + break; + } + case FAILED_XDMCP_CONNECTION_ALERT: + { + message = FAILED_XDMCP_CONNECTION_ALERT_STRING; + type = FAILED_XDMCP_CONNECTION_ALERT_TYPE; + + break; + } + default: + { + if (lastAlert.code > LAST_PROTO_STEP_7_ALERT) + { + #ifdef WARNING + *logofs << "Loop: WARNING! An unrecognized alert type '" + << lastAlert.code << "' was requested.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": An unrecognized alert type '" + << lastAlert.code << "' was requested.\n"; + } + #ifdef WARNING + else + { + *logofs << "Loop: WARNING! Ignoring obsolete alert type '" + << lastAlert.code << "'.\n" << logofs_flush; + } + #endif + + message = NULL; + type = NULL; + + replace = 0; + + break; + } + } + + if (replace == 1 && IsRunning(lastDialog)) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Killing the previous dialog with pid '" + << lastDialog << "'.\n" << logofs_flush; + #endif + + // + // The client ignores the TERM signal + // on Windows. + // + + #ifdef __CYGWIN32__ + + KillProcess(lastDialog, "dialog", SIGKILL, 0); + + #else + + KillProcess(lastDialog, "dialog", SIGTERM, 0); + + #endif + + SetNotRunning(lastDialog); + + if (proxy != NULL) + { + proxy -> handleResetAlert(); + } + } + + if (message != NULL && type != NULL) + { + lastDialog = NXTransDialog(caption, message, 0, type, local, display); + + if (IsFailed(lastDialog)) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Can't start the NX dialog process.\n" + << logofs_flush; + #endif + + SetNotRunning(lastDialog); + } + #if defined(TEST) || defined(INFO) + else + { + *logofs << "Loop: Dialog started with pid '" + << lastDialog << "'.\n" << logofs_flush; + } + #endif + } + #if defined(TEST) || defined(INFO) + else + { + *logofs << "Loop: No new dialog required for code '" + << lastAlert.code << "'.\n" << logofs_flush; + } + #endif + } + } + + // + // Reset state. + // + + lastAlert.code = 0; + lastAlert.local = 0; +} + +static inline void handleSetAgentInLoop(int &setFDs, fd_set &readSet, + fd_set &writeSet, struct timeval &selectTs) +{ + #ifdef TEST + *logofs << "Loop: Preparing the masks for the agent descriptors.\n" + << logofs_flush; + #endif + + agent -> saveChannelState(); + + agent -> saveReadMask(&readSet); + agent -> saveWriteMask(&writeSet); + + if (control -> ProxyStage >= stage_operational) + { + if (agent -> remoteCanRead(&readSet) || + agent -> remoteCanWrite(&writeSet) || + agent -> localCanRead() || + agent -> proxyCanRead()) + { + #ifdef TEST + *logofs << "Loop: Setting a null timeout with agent descriptors ready.\n" + << logofs_flush; + #endif + + // + // Force a null timeout so we'll bail out + // of the select immediately. We will ac- + // comodate the result code later. + // + + selectTs.tv_sec = 0; + selectTs.tv_usec = 0; + } + } + + #ifdef TEST + *logofs << "Loop: Clearing the read and write agent descriptors.\n" + << logofs_flush; + #endif + + agent -> clearReadMask(&readSet); + agent -> clearWriteMask(&writeSet); +} + +static inline void handleAgentInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, + fd_set &writeSet, struct timeval &selectTs) +{ + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Setting proxy and local agent descriptors.\n" + << logofs_flush; + #endif + + // + // Check if I/O is possible on the local + // agent or the proxy descriptor. + // + + if (resultFDs >= 0) + { + // + // Save if the proxy can read from the + // the agent descriptor. + // + + agent -> saveChannelState(); + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Values were resultFDs " << resultFDs + << " errorFDs " << errorFDs << " setFDs " + << setFDs << ".\n" << logofs_flush; + #endif + + if (agent -> localCanRead() == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Setting agent descriptor FD#" << agent -> + getLocalFd() << " as ready to read.\n" + << logofs_flush; + #endif + + agent -> setLocalRead(&readSet, &resultFDs); + } + + #if defined(TEST) || defined(INFO) + + if (agent -> proxyCanRead(&readSet) == 0 && + agent -> proxyCanRead() == 1) + { + *logofs << "Loop: WARNING! Can read from proxy FD#" + << proxyFD << " but the descriptor " + << "is not selected.\n" << logofs_flush; + } + + if (agent -> proxyCanRead(&readSet) == 1) + { + *logofs << "Loop: Setting proxy descriptor FD#" << agent -> + getProxyFd() << " as ready to read.\n" + << logofs_flush; + } + + #endif + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Values are now resultFDs " << resultFDs + << " errorFDs " << errorFDs << " setFDs " + << setFDs << ".\n" << logofs_flush; + #endif + } +} + +static inline void handleAgentLateInLoop(int &resultFDs, int &errorFDs, int &setFDs, fd_set &readSet, + fd_set &writeSet, struct timeval &selectTs) +{ + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Setting remote agent descriptors.\n" + << logofs_flush; + #endif + + // + // We reset the masks before calling our select. + // We now set the descriptors that are ready but + // only if they were set in the original mask. + // We do this after having executed our loop as + // we may have produced more data and the agent + // descriptors may have become readable or writ- + // able in the meanwhile. + // + + if (resultFDs >= 0) + { + // + // Save if the proxy can read from the + // the agent descriptor. + // + + agent -> saveChannelState(); + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Values were resultFDs " << resultFDs + << " errorFDs " << errorFDs << " setFDs " + << setFDs << ".\n" << logofs_flush; + #endif + + if (agent -> remoteCanRead(agent -> + getSavedReadMask()) == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Setting agent descriptor FD#" << agent -> + getRemoteFd() << " as ready to read.\n" + << logofs_flush; + #endif + + agent -> setRemoteRead(&readSet, &resultFDs); + } + + if (agent -> remoteCanWrite(agent -> + getSavedWriteMask()) == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Setting agent descriptor FD#" << agent -> + getRemoteFd() << " as ready to write.\n" + << logofs_flush; + #endif + + agent -> setRemoteWrite(&writeSet, &resultFDs); + } + + #if defined(TEST) || defined(INFO) + *logofs << "Loop: Values are now resultFDs " << resultFDs + << " errorFDs " << errorFDs << " setFDs " + << setFDs << ".\n" << logofs_flush; + #endif + } +} + +static inline void handleReadableInLoop(int &resultFDs, fd_set &readSet) +{ + if (resultFDs > 0) + { + T_channel_type type = channel_none; + + const char *label = NULL; + int domain = -1; + int fd = -1; + + if (tcpFD != -1 && FD_ISSET(tcpFD, &readSet)) + { + type = channel_x11; + label = "X"; + domain = AF_INET; + fd = tcpFD; + + resultFDs--; + } + + if (unixFD != -1 && FD_ISSET(unixFD, &readSet)) + { + type = channel_x11; + label = "X"; + domain = AF_UNIX; + fd = unixFD; + + resultFDs--; + } + + if (cupsFD != -1 && FD_ISSET(cupsFD, &readSet)) + { + type = channel_cups; + label = "CUPS"; + domain = AF_INET; + fd = cupsFD; + + resultFDs--; + } + + if (auxFD != -1 && FD_ISSET(auxFD, &readSet)) + { + // + // Starting from version 1.5.0 we create real X + // connections for the keyboard channel, so they + // can use the fake authorization cookie. This + // means that there is not such a thing like a + // channel_aux anymore. + // + + type = channel_x11; + label = "auxiliary X11"; + domain = AF_INET; + fd = auxFD; + + resultFDs--; + } + + if (smbFD != -1 && FD_ISSET(smbFD, &readSet)) + { + type = channel_smb; + label = "SMB"; + domain = AF_INET; + fd = smbFD; + + resultFDs--; + } + + if (mediaFD != -1 && FD_ISSET(mediaFD, &readSet)) + { + type = channel_media; + label = "media"; + domain = AF_INET; + fd = mediaFD; + + resultFDs--; + } + + if (httpFD != -1 && FD_ISSET(httpFD, &readSet)) + { + type = channel_http; + label = "HTTP"; + domain = AF_INET; + fd = httpFD; + + resultFDs--; + } + + if (fontFD != -1 && FD_ISSET(fontFD, &readSet)) + { + type = channel_font; + label = "font server"; + domain = AF_INET; + fd = fontFD; + + resultFDs--; + } + + if (slaveFD != -1 && FD_ISSET(slaveFD, &readSet)) + { + type = channel_slave; + label = "slave"; + domain = AF_INET; + fd = slaveFD; + + resultFDs--; + } + + if (type != channel_none) + { + int newFD = AcceptConnection(fd, domain, label); + + if (newFD != -1) + { + if (proxy -> handleNewConnection(type, newFD) < 0) + { + #ifdef PANIC + *logofs << "Loop: PANIC! Error creating new " << label + << " connection.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Error creating new " << label + << " connection.\n"; + + close(newFD); + + // + // Don't kill the proxy in the case of an error. + // + // HandleCleanup(); + // + } + else if (proxy -> getReadable(newFD) > 0) + { + // + // Add the descriptor, so we can try + // to read immediately. + // + + #ifdef TEST + *logofs << "Loop: Trying to read immediately " + << "from descriptor FD#" << newFD + << ".\n" << logofs_flush; + #endif + + FD_SET(newFD, &readSet); + + resultFDs++; + } + #ifdef TEST + else + { + *logofs << "Loop: Nothing to read immediately " + << "from descriptor FD#" << newFD + << ".\n" << logofs_flush; + } + #endif + } + } + } + + #ifdef DEBUG + *logofs << "Loop: Going to check the readable descriptors.\n" + << logofs_flush; + #endif + + if (proxy -> handleRead(resultFDs, readSet) < 0) + { + #ifdef TEST + *logofs << "Loop: Failure reading from descriptors " + << "for proxy FD#" << proxyFD << ".\n" + << logofs_flush; + #endif + + HandleShutdown(); + } +} + +static inline void handleWritableInLoop(int &resultFDs, fd_set &writeSet) +{ + #ifdef DEBUG + *logofs << "Loop: Going to check the writable descriptors.\n" + << logofs_flush; + #endif + + if (resultFDs > 0 && proxy -> handleFlush(resultFDs, writeSet) < 0) + { + #ifdef TEST + *logofs << "Loop: Failure writing to descriptors " + << "for proxy FD#" << proxyFD << ".\n" + << logofs_flush; + #endif + + HandleShutdown(); + } +} + +static inline void handleFlushInLoop() +{ + #ifdef DEBUG + *logofs << "Loop: Going to flush any data to the proxy.\n" + << logofs_flush; + #endif + + if (agent == NULL || control -> + FlushPolicy == policy_immediate) + { + #if defined(TEST) || defined(INFO) + + if (usePolicy == -1 && control -> + ProxyMode == proxy_client) + { + *logofs << "Loop: WARNING! Flushing the proxy link " + << "on behalf of the agent.\n" << logofs_flush; + } + + #endif + + if (proxy -> handleFlush() < 0) + { + #ifdef TEST + *logofs << "Loop: Failure flushing the proxy FD#" + << proxyFD << ".\n" << logofs_flush; + #endif + + HandleShutdown(); + } + } +} + +static inline void handleRotateInLoop() +{ + #ifdef DEBUG + *logofs << "Loop: Going to rotate channels " + << "for proxy FD#" << proxyFD << ".\n" + << logofs_flush; + #endif + + proxy -> handleRotate(); +} + +static inline void handleEventsInLoop() +{ + #ifdef DEBUG + *logofs << "Loop: Going to check channel events " + << "for proxy FD#" << proxyFD << ".\n" + << logofs_flush; + #endif + + if (proxy -> handleEvents() < 0) + { + #ifdef TEST + *logofs << "Loop: Failure handling channel events " + << "for proxy FD#" << proxyFD << ".\n" + << logofs_flush; + #endif + + HandleShutdown(); + } +} + +static void handleLogReopenInLoop(T_timestamp &logsTs, T_timestamp &nowTs) +{ + // + // If need to limit the size of the + // log file, check the size at each + // loop. + // + + #ifndef QUOTA + + if (diffTimestamp(logsTs, nowTs) > control -> FileSizeCheckTimeout) + + #endif + { + #ifdef DEBUG + *logofs << "Loop: Checking size of log file '" + << errorsFileName << "'.\n" << logofs_flush; + #endif + + #ifndef MIXED + + if (ReopenLogFile(errorsFileName, logofs, control -> FileSizeLimit) < 0) + { + HandleShutdown(); + } + + #endif + + // + // Reset to current timestamp. + // + + logsTs = nowTs; + } +} + +static inline void handleSetReadInLoop(fd_set &readSet, int &setFDs, struct timeval &selectTs) +{ + proxy -> setReadDescriptors(&readSet, setFDs, selectTs); +} + +static inline void handleSetWriteInLoop(fd_set &writeSet, int &setFDs, struct timeval &selectTs) +{ + proxy -> setWriteDescriptors(&writeSet, setFDs, selectTs); +} + +static void handleSetListenersInLoop(fd_set &readSet, int &setFDs) +{ + // + // Set descriptors of listening sockets. + // + + if (control -> ProxyMode == proxy_client) + { + if (useTcpSocket == 1) + { + FD_SET(tcpFD, &readSet); + + if (tcpFD >= setFDs) + { + setFDs = tcpFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener tcpFD " << tcpFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } + + if (useUnixSocket == 1) + { + FD_SET(unixFD, &readSet); + + if (unixFD >= setFDs) + { + setFDs = unixFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener unixFD " << unixFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } + + if (useCupsSocket == 1) + { + FD_SET(cupsFD, &readSet); + + if (cupsFD >= setFDs) + { + setFDs = cupsFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener cupsFD " << cupsFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } + + if (useAuxSocket == 1) + { + FD_SET(auxFD, &readSet); + + if (auxFD >= setFDs) + { + setFDs = auxFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener auxFD " << auxFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } + + if (useSmbSocket == 1) + { + FD_SET(smbFD, &readSet); + + if (smbFD >= setFDs) + { + setFDs = smbFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener smbFD " << smbFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } + + if (useMediaSocket == 1) + { + FD_SET(mediaFD, &readSet); + + if (mediaFD >= setFDs) + { + setFDs = mediaFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener mediaFD " << mediaFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } + + if (useHttpSocket == 1) + { + FD_SET(httpFD, &readSet); + + if (httpFD >= setFDs) + { + setFDs = httpFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener httpFD " << httpFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } + } + else + { + if (useFontSocket == 1) + { + FD_SET(fontFD, &readSet); + + if (fontFD >= setFDs) + { + setFDs = fontFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener fontFD " << fontFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } + } + + if (useSlaveSocket == 1) + { + FD_SET(slaveFD, &readSet); + + if (slaveFD >= setFDs) + { + setFDs = slaveFD + 1; + } + + #ifdef DEBUG + *logofs << "Loop: Selected listener slaveFD " << slaveFD + << " with setFDs " << setFDs << ".\n" + << logofs_flush; + #endif + } +} diff --git a/nxcomp/src/MD5.c b/nxcomp/src/MD5.c new file mode 100644 index 000000000..7255ca5c0 --- /dev/null +++ b/nxcomp/src/MD5.c @@ -0,0 +1,403 @@ +/* + Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.c is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order + either statically or dynamically; added missing #include + in library. + 2002-03-11 lpd Corrected argument list for main(), and added int return + type, in test program and T value program. + 2002-02-21 lpd Added missing #include in test program. + 2000-07-03 lpd Patched to eliminate warnings about "constant is + unsigned in ANSI C, signed in traditional"; made test program + self-checking. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). + 1999-05-03 lpd Original version. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "MD5.h" + +#include + +/* + * Try to determine the CPU endianess + * at compile time. + */ + +#if defined(__linux) || defined(__CYGWIN32__) + +#include + +#if (__BYTE_ORDER == __LITTLE_ENDIAN) +#define ARCH_IS_BIG_ENDIAN 0 +#else +#define ARCH_IS_BIG_ENDIAN 1 +#endif + +#endif /* #if defined(__linux) || defined(__CYGWIN32__) */ + +#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#ifdef ARCH_IS_BIG_ENDIAN +# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) +#else +# define BYTE_ORDER 0 +#endif + +#define T_MASK ((md5_word_t)~0) +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) +#define T3 0x242070db +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) +#define T6 0x4787c62a +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) +#define T9 0x698098d8 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) +#define T13 0x6b901122 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) +#define T16 0x49b40821 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) +#define T19 0x265e5a51 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) +#define T22 0x02441453 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) +#define T25 0x21e1cde6 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) +#define T28 0x455a14ed +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) +#define T31 0x676f02d9 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) +#define T35 0x6d9d6122 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) +#define T38 0x4bdecfa9 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) +#define T41 0x289b7ec6 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) +#define T44 0x04881d05 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) +#define T47 0x1fa27cf8 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) +#define T50 0x432aff97 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) +#define T53 0x655b59c3 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) +#define T57 0x6fa87e4f +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) +#define T60 0x4e0811a1 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) +#define T63 0x2ad7d2bb +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) + + +static void +md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) +{ + md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t t; +#if BYTE_ORDER > 0 + /* Define storage only for big-endian CPUs. */ + md5_word_t X[16]; +#else + /* Define storage for little-endian or both types of CPUs. */ + md5_word_t xbuf[16]; + const md5_word_t *X; +#endif + + { +#if BYTE_ORDER == 0 + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static const int w = 1; + + if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ +#endif +#if BYTE_ORDER <= 0 /* little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - (const md5_byte_t *)0) & 3)) { + /* data are properly aligned */ + X = (const md5_word_t *)data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } +#endif +#if BYTE_ORDER == 0 + else /* dynamic big-endian */ +#endif +#if BYTE_ORDER >= 0 /* big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const md5_byte_t *xp = data; + int i; + +# if BYTE_ORDER == 0 + X = xbuf; /* (dynamic only) */ +# else +# define xbuf X /* (static only) */ +# endif + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } +#endif + } + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); +#undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); +#undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); +#undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ +#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); +#undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; +} + +void +md5_init(md5_state_t *pms) +{ + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; +} + +void +md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) +{ + const md5_byte_t *p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + md5_word_t nbits = (md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += nbytes >> 29; + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +void +md5_finish(md5_state_t *pms, md5_byte_t digest[16]) +{ + static const md5_byte_t pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} diff --git a/nxcomp/src/Makefile.am b/nxcomp/src/Makefile.am new file mode 100644 index 000000000..2264cb347 --- /dev/null +++ b/nxcomp/src/Makefile.am @@ -0,0 +1,146 @@ +NULL = + +lib_LTLIBRARIES = libXcomp.la + +libXcomp_la_SOURCES = \ + ActionCache.cpp \ + Agent.cpp \ + Alpha.cpp \ + Auth.cpp \ + Bitmap.cpp \ + BlockCache.cpp \ + BlockCacheSet.cpp \ + ChangeGC.cpp \ + ChangeProperty.cpp \ + ChannelCache.cpp \ + Channel.cpp \ + ChannelEndPoint.cpp \ + CharCache.cpp \ + Children.cpp \ + ClearArea.cpp \ + ClientCache.cpp \ + ClientChannel.cpp \ + ClientProxy.cpp \ + ClientReadBuffer.cpp \ + ClientStore.cpp \ + Colormap.cpp \ + ConfigureWindow.cpp \ + Control.cpp \ + CopyArea.cpp \ + CreateGC.cpp \ + CreatePixmap.cpp \ + DecodeBuffer.cpp \ + EncodeBuffer.cpp \ + FillPoly.cpp \ + Fork.cpp \ + GenericChannel.cpp \ + GenericReadBuffer.cpp \ + GenericReply.cpp \ + GenericRequest.cpp \ + GetImage.cpp \ + GetImageReply.cpp \ + GetProperty.cpp \ + GetPropertyReply.cpp \ + ImageText16.cpp \ + ImageText8.cpp \ + IntCache.cpp \ + InternAtom.cpp \ + Jpeg.cpp \ + Keeper.cpp \ + List.cpp \ + ListFontsReply.cpp \ + Loop.cpp \ + Message.cpp \ + MD5.c \ + Misc.cpp \ + OpcodeStore.cpp \ + Pack.c \ + Pgn.cpp \ + Pipe.cpp \ + PolyArc.cpp \ + PolyFillArc.cpp \ + PolyFillRectangle.cpp \ + PolyLine.cpp \ + PolyPoint.cpp \ + PolySegment.cpp \ + PolyText16.cpp \ + PolyText8.cpp \ + Proxy.cpp \ + ProxyReadBuffer.cpp \ + PutImage.cpp \ + PutPackedImage.cpp \ + QueryFontReply.cpp \ + ReadBuffer.cpp \ + RenderAddGlyphs.cpp \ + RenderChangePicture.cpp \ + RenderComposite.cpp \ + RenderCompositeGlyphs.cpp \ + RenderCreateGlyphSet.cpp \ + RenderCreatePicture.cpp \ + RenderExtension.cpp \ + RenderFillRectangles.cpp \ + RenderFreeGlyphSet.cpp \ + RenderFreePicture.cpp \ + RenderGenericRequest.cpp \ + RenderPictureClip.cpp \ + RenderPictureFilter.cpp \ + RenderPictureTransform.cpp \ + RenderTrapezoids.cpp \ + RenderTriangles.cpp \ + Rgb.cpp \ + Rle.cpp \ + SendEvent.cpp \ + SequenceQueue.cpp \ + ServerCache.cpp \ + ServerChannel.cpp \ + ServerProxy.cpp \ + ServerReadBuffer.cpp \ + ServerStore.cpp \ + SetClipRectangles.cpp \ + SetUnpackAlpha.cpp \ + SetUnpackColormap.cpp \ + SetUnpackGeometry.cpp \ + ShapeExtension.cpp \ + Socket.cpp \ + Split.cpp \ + StaticCompressor.cpp \ + Statistics.cpp \ + Timestamp.cpp \ + TranslateCoords.cpp \ + Transport.cpp \ + Unpack.cpp \ + Vars.c \ + Version.c \ + WriteBuffer.cpp \ + XidCache.cpp \ + Z.cpp \ + $(NULL) + +libXcomp_la_LIBADD = \ + @JPEG_LIBS@ \ + @PNG_LIBS@ \ + @Z_LIBS@ \ + $(NULL) + +AM_CXXFLAGS = \ + $(BASE_CXXFLAGS) \ + $(JPEG_CFLAGS) \ + $(PNG_CFLAGS) \ + $(Z_CFLAGS) \ + $(NULL) + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + $(NULL) + +libXcomp_la_LDFLAGS = -version-number @LT_COMP_VERSION@ -no-undefined + +libXcompincludedir = $(includedir)/nx +libXcompinclude_HEADERS = \ + $(top_srcdir)/include/MD5.h \ + $(top_srcdir)/include/NX.h \ + $(top_srcdir)/include/NXalert.h \ + $(top_srcdir)/include/NXpack.h \ + $(top_srcdir)/include/NXproto.h \ + $(top_srcdir)/include/NXvars.h \ + $(NULL) diff --git a/nxcomp/src/Message.cpp b/nxcomp/src/Message.cpp new file mode 100644 index 000000000..b75d90c24 --- /dev/null +++ b/nxcomp/src/Message.cpp @@ -0,0 +1,2343 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "Misc.h" + +// +// We need channel's cache data. +// + +#include "Message.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. You also +// need to define DUMP in Misc.cpp +// if DUMP is defined here. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Define this to log when messages +// are allocated and deallocated. +// + +#undef REFERENCES + +// +// Keep track of how many bytes are +// occupied by cache. +// + +int MessageStore::totalLocalStorageSize_ = 0; +int MessageStore::totalRemoteStorageSize_ = 0; + +// +// These are used for reference count. +// + +#ifdef REFERENCES + +int Message::references_ = 0; +int MessageStore::references_ = 0; + +#endif + +// +// Here are the methods to handle cached messages. +// + +MessageStore::MessageStore(StaticCompressor *compressor) + + : compressor_(compressor) +{ + // + // Public members. + // + + enableCache = MESSAGE_ENABLE_CACHE; + enableData = MESSAGE_ENABLE_DATA; + enableSplit = MESSAGE_ENABLE_SPLIT; + enableCompress = MESSAGE_ENABLE_COMPRESS; + + dataLimit = MESSAGE_DATA_LIMIT; + dataOffset = MESSAGE_DATA_OFFSET; + + cacheSlots = MESSAGE_CACHE_SLOTS; + cacheThreshold = MESSAGE_CACHE_THRESHOLD; + cacheLowerThreshold = MESSAGE_CACHE_LOWER_THRESHOLD; + + #ifdef TEST + *logofs << "MessageStore: Static compressor is at " + << compressor_ << ".\n" << logofs_flush; + #endif + + md5_state_ = new md5_state_t(); + + #ifdef DEBUG + *logofs << "MessageStore: Created MD5 state for object at " + << this << ".\n" << logofs_flush; + #endif + + lastAdded = cacheSlots; + lastHit = 0; + lastRemoved = 0; + lastRated = nothing; + lastAction = is_discarded; + + // + // Private members. + // + + localStorageSize_ = 0; + remoteStorageSize_ = 0; + + #ifdef TEST + *logofs << "MessageStore: Size of total cache is " + << totalLocalStorageSize_ << " bytes at local side and " + << totalRemoteStorageSize_ << " bytes at remote side.\n" + << logofs_flush; + #endif + + messages_ = new T_messages(); + checksums_ = new T_checksums(); + + temporary_ = NULL; + + #ifdef REFERENCES + + references_++; + + *logofs << "MessageStore: Created new store at " + << this << "out of " << references_ + << " allocated stores.\n" << logofs_flush; + + #endif +} + +MessageStore::~MessageStore() +{ + // + // The virtual destructor of specialized class + // must get rid of both messages in container + // and temporary. + // + + #ifdef DEBUG + *logofs << "MessageStore: Deleting MD5 state for object at " + << this << ".\n" << logofs_flush; + #endif + + delete md5_state_; + + delete messages_; + delete checksums_; + + // + // Update the static members tracking + // size of total memory allocated for + // all stores. + // + + totalLocalStorageSize_ -= localStorageSize_; + totalRemoteStorageSize_ -= remoteStorageSize_; + + #ifdef TEST + *logofs << "MessageStore: Size of total cache is " + << totalLocalStorageSize_ << " bytes at local side and " + << totalRemoteStorageSize_ << " bytes at remote side.\n" + << logofs_flush; + #endif + + #ifdef REFERENCES + + references_--; + + *logofs << "MessageStore: Deleted store at " + << this << " out of " << references_ + << " allocated stores.\n" << logofs_flush; + + #endif +} + +// +// Here are the methods to parse and cache +// messages in the message stores. +// + +int MessageStore::parse(Message *message, int split, const unsigned char *buffer, + unsigned int size, T_checksum_action checksumAction, + T_data_action dataAction, int bigEndian) +{ + // + // Save the message size as received on the link. + // This information will be used to create an ap- + // propriate buffer at the time the message will + // be unparsed. + // + + message -> size_ = size; + message -> i_size_ = identitySize(buffer, size); + message -> c_size_ = 0; + + validateSize(size); + + if (checksumAction == use_checksum) + { + beginChecksum(message); + + parseIdentity(message, buffer, size, bigEndian); + + identityChecksum(message, buffer, size, bigEndian); + + parseData(message, split, buffer, size, checksumAction, dataAction, bigEndian); + + endChecksum(message); + } + else + { + parseIdentity(message, buffer, size, bigEndian); + + parseData(message, split, buffer, size, checksumAction, dataAction, bigEndian); + } + + return 1; +} + +int MessageStore::parse(Message *message, const unsigned char *buffer, + unsigned int size, const unsigned char *compressedData, + const unsigned int compressedDataSize, + T_checksum_action checksumAction, + T_data_action dataAction, int bigEndian) +{ + int offset = identitySize(buffer, size); + + message -> size_ = size; + message -> i_size_ = offset; + message -> c_size_ = compressedDataSize + offset; + + validateSize(message -> size_ - offset, compressedDataSize); + + if (checksumAction == use_checksum) + { + beginChecksum(message); + + parseIdentity(message, buffer, size, bigEndian); + + identityChecksum(message, buffer, size, bigEndian); + + parseData(message, buffer, size, compressedData, compressedDataSize, + checksumAction, dataAction, bigEndian); + + endChecksum(message); + } + else + { + parseIdentity(message, buffer, size, bigEndian); + + parseData(message, buffer, size, compressedData, compressedDataSize, + checksumAction, dataAction, bigEndian); + } + + return 1; +} + +int MessageStore::parseData(Message *message, int split, const unsigned char *buffer, + unsigned int size, T_checksum_action checksumAction, + T_data_action dataAction, int bigEndian) +{ + if ((int) size > message -> i_size_) + { + unsigned int dataSize = size - message -> i_size_; + + if (checksumAction == use_checksum) + { + #ifdef DEBUG + *logofs << name() << ": Calculating checksum of object at " + << message << " with data size " << dataSize + << ".\n" << logofs_flush; + #endif + + dataChecksum(message, buffer, size, bigEndian); + } + + if (dataAction == discard_data) + { + #ifdef DEBUG + *logofs << name() << ": Discarded " << dataSize + << " bytes of plain data. Real size is " + << message -> size_ << " compressed size is " + << message -> c_size_ << ".\n" << logofs_flush; + #endif + + return 1; + } + + // + // Accept anyway data beyond the + // expected limit. + // + + #ifdef TEST + + if (dataSize > (unsigned int) dataLimit) + { + *logofs << name() << ": WARNING! Data is " << dataSize + << " bytes. Ignoring the established limit.\n" + << logofs_flush; + } + + #endif + + if (dataSize != message -> data_.size()) + { + #ifdef DEBUG + *logofs << name() << ": Data will be resized from " + << message -> data_.size() << " to hold a plain buffer of " + << dataSize << " bytes.\n" << logofs_flush; + #endif + + message -> data_.clear(); + + message -> data_.resize(dataSize); + } + + if (split == 0) + { + memcpy(message -> data_.begin(), buffer + message -> i_size_, dataSize); + } + #ifdef TEST + else + { + *logofs << name() << ": Not copied " << dataSize + << " bytes of fake data for the split message.\n" + << logofs_flush; + } + #endif + + #ifdef DEBUG + *logofs << name() << ": Parsed " << dataSize + << " bytes of plain data. Real size is " + << message -> size_ << " compressed size is " + << message -> c_size_ << ".\n" << logofs_flush; + #endif + } + + return 1; +} + +// +// Store the data part in compressed format. +// + +int MessageStore::parseData(Message *message, const unsigned char *buffer, + unsigned int size, const unsigned char *compressedData, + const unsigned int compressedDataSize, + T_checksum_action checksumAction, + T_data_action dataAction, int bigEndian) +{ + if ((int) size > message -> i_size_) + { + unsigned int dataSize = size - message -> i_size_; + + if (checksumAction == use_checksum) + { + #ifdef DEBUG + *logofs << name() << ": Calculating checksum of object at " + << message << " with data size " << dataSize + << ".\n" << logofs_flush; + #endif + + dataChecksum(message, buffer, size, bigEndian); + } + + if (dataAction == discard_data) + { + #ifdef DEBUG + *logofs << name() << ": Discarded " << dataSize + << " bytes of compressed data. Real size is " + << message -> size_ << " compressed size is " + << message -> c_size_ << ".\n" << logofs_flush; + #endif + + return 1; + } + + #ifdef WARNING + if (dataSize > (unsigned int) dataLimit) + { + *logofs << name() << ": WARNING! Data is " << dataSize + << " bytes. Ignoring the established limit!\n" + << logofs_flush; + } + #endif + + dataSize = compressedDataSize; + + if (dataSize != message -> data_.size()) + { + #ifdef DEBUG + *logofs << name() << ": Data will be resized from " + << message -> data_.size() << " to hold a compressed buffer of " + << dataSize << " bytes.\n" << logofs_flush; + #endif + + message -> data_.clear(); + + message -> data_.resize(compressedDataSize); + } + + memcpy(message -> data_.begin(), compressedData, compressedDataSize); + + #ifdef DEBUG + *logofs << name() << ": Parsed " << dataSize + << " bytes of compressed data. Real size is " + << message -> size_ << " compressed size is " + << message -> c_size_ << ".\n" << logofs_flush; + #endif + } + + return 1; +} + +int MessageStore::unparseData(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) +{ + // + // Copy data, if any, to the buffer. + // + + if ((int) size > message -> i_size_) + { + // + // Check if message has been stored + // in compressed format. + // + + if (message -> c_size_ == 0) + { + memcpy(buffer + message -> i_size_, message -> data_.begin(), size - message -> i_size_); + + #ifdef DEBUG + *logofs << name() << ": Unparsed " << message -> size_ - message -> i_size_ + << " bytes of data to a buffer of " << message -> size_ - message -> i_size_ + << ".\n" << logofs_flush; + #endif + } + else + { + #ifdef DEBUG + *logofs << name() << ": Using static compressor at " << (void *) compressor_ + << ".\n" << logofs_flush; + #endif + + if (compressor_ -> + decompressBuffer(buffer + message -> i_size_, + size - message -> i_size_, + message -> data_.begin(), + message -> c_size_ - message -> i_size_) < 0) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Data decompression failed.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Data decompression failed.\n"; + + return -1; + } + + #ifdef DEBUG + *logofs << name() << ": Unparsed " << message -> c_size_ - message -> i_size_ + << " bytes of compressed data to a buffer of " + << message -> size_ - message -> i_size_ << ".\n" << logofs_flush; + #endif + } + } + + // + // We could write size to the buffer but this + // is something the channel class is doing by + // itself. + // + // PutUINT(size >> 2, buffer + 2, bigEndian); + // + + return 1; +} + +void MessageStore::dumpData(const Message *message) const +{ + #ifdef DUMP + + *logofs << name() << ": Dumping enumerated data:\n" << logofs_flush; + + DumpData(message -> data_.begin(), message -> data_.size()); + + #endif + + #ifdef DUMP + + *logofs << name() << ": Dumping checksum data:\n" << logofs_flush; + + DumpData(message -> md5_digest_, MD5_LENGTH); + + #endif +} + +T_checksum MessageStore::getChecksum(const unsigned char *buffer, + unsigned int size, int bigEndian) +{ + Message *message = getTemporary(); + + message -> size_ = size; + message -> i_size_ = identitySize(buffer, size); + message -> c_size_ = 0; + + validateSize(size); + + beginChecksum(message); + + // + // We don't need to extract the identity + // data from the buffer. + // + // parseIdentity(message, buffer, size, bigEndian); + // + + identityChecksum(message, buffer, size, bigEndian); + + parseData(message, 0, buffer, size, use_checksum, discard_data, bigEndian); + + endChecksum(message); + + // + // The caller will have to explicitly + // deallocated the memory after use. + // + + T_checksum checksum = new md5_byte_t[MD5_LENGTH]; + + memcpy(checksum, message -> md5_digest_, MD5_LENGTH); + + return checksum; +} + +int MessageStore::clean(T_checksum_action checksumAction) +{ + int position = lastRemoved + 1; + + if (position >= cacheSlots) + { + position = 0; + } + + #ifdef DEBUG + *logofs << name() << ": Searching a message to remove " + << "starting at position " << position + << " with " << checksums_ -> size() + << " elements in cache.\n" + << logofs_flush; + #endif + + while (position != lastRemoved) + { + #ifdef DEBUG + *logofs << name() << ": Examining position " + << position << ".\n" << logofs_flush; + #endif + + if ((*messages_)[position] != NULL) + { + if (getRating((*messages_)[position], rating_for_clean) == 0) + { + break; + } + else + { + untouch((*messages_)[position]); + } + } + + if (++position == cacheSlots) + { + #ifdef DEBUG + *logofs << name() << ": Rolled position at " + << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + position = 0; + } + } + + // + // If no message is a good candidate, + // then try the object at the next slot + // in respect to last element removed. + // + + if (position == lastRemoved) + { + position = lastRemoved + 1; + + if (position >= cacheSlots) + { + position = 0; + } + + if ((*messages_)[position] == NULL || + (*messages_)[position] -> locks_ != 0) + { + #ifdef DEBUG + *logofs << name() << ": WARNING! No message found " + << "to be actually removed.\n" + << logofs_flush; + #endif + + return nothing; + } + + #ifdef DEBUG + *logofs << name() << ": WARNING! Assuming object " + << "at position " << position << ".\n" + << logofs_flush; + #endif + } + + return position; +} + +// +// This is the insertion method used at local side +// side. Cache at remote side side will be kept in +// sync by telling the to other party where to +// store the message. +// + +int MessageStore::findOrAdd(Message *message, T_checksum_action checksumAction, + T_data_action dataAction, int &added, int &locked) +{ + if (checksumAction != use_checksum) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Internal error in context [A]. " + << "Cannot find or add message to repository " + << "without using checksum.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Internal error in context [A]. " + << "Cannot find or add message to repository " + << "without using checksum.\n"; + + HandleAbort(); + } + + // + // Set added to true only if message + // is inserted in cache. + // + + added = 0; + locked = 0; + + // + // First of all figure out where to + // store this object. + // + + #ifdef DEBUG + *logofs << name() << ": Searching an empty slot " + << "with last rated " << lastRated << " and " + << "last added " << lastAdded << ".\n" + << logofs_flush; + #endif + + int position = lastRated; + + if (position == nothing) + { + position = lastAdded + 1; + + if (position >= cacheSlots) + { + position = 0; + } + + #ifdef DEBUG + *logofs << name() << ": Searching an empty slot " + << "starting at position " << position + << " with " << checksums_ -> size() + << " elements in cache.\n" + << logofs_flush; + #endif + + while (position != lastAdded) + { + #ifdef DEBUG + *logofs << name() << ": Examining position " + << position << ".\n" << logofs_flush; + #endif + + if ((*messages_)[position] == NULL) + { + break; + } + else if (getRating((*messages_)[position], rating_for_insert) == 0) + { + break; + } + else + { + untouch((*messages_)[position]); + } + + if (++position == cacheSlots) + { + #ifdef DEBUG + *logofs << name() << ": Rolled position at " + << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + position = 0; + } + } + } + #ifdef DEBUG + else + { + *logofs << name() << ": Using last rated position " + << position << ".\n" << logofs_flush; + } + #endif + + // + // If we made an extensive check but did not + // find neither a free slot or a message to + // replace, assume slot at next position in + // respect to last added. This can happen if + // all objects in repository have got an hit + // recently. + // + + if (position == lastAdded) + { + position = lastAdded + 1; + + if (position >= cacheSlots) + { + position = 0; + } + + #ifdef DEBUG + *logofs << name() << ": WARNING! Assuming slot " + << "at position " << position << ".\n" + << logofs_flush; + #endif + } + #ifdef DEBUG + else + { + *logofs << name() << ": Found candidate slot " + << "at position " << position << ".\n" + << logofs_flush; + } + #endif + + // + // Save the search result so if the message + // is found in cache, we can use the slot + // at next run. + // + + lastRated = position; + + if ((*messages_)[position] != NULL && + (*messages_)[position] -> locks_ != 0) + { + #ifdef WARNING + *logofs << name() << ": WARNING! Insertion at position " + << position << " would replace a locked message. " + << "Forcing channel to discard the message.\n" + << logofs_flush; + #endif + + #ifdef TEST + *logofs << name() << ": Invalidating rating of object " + << "at position " << position << ".\n" + << logofs_flush; + #endif + + return (lastRated = nothing); + } + + if (checksumAction == use_checksum) + { + T_checksum checksum = getChecksum(message); + + #ifdef TEST + *logofs << name() << ": Searching checksum [" + << DumpChecksum(checksum) << "] in repository.\n" + << logofs_flush; + + #endif + + pair result; + + result = checksums_ -> insert(T_checksums::value_type(checksum, position)); + + // + // Message was found in cache or + // insertion couldn't take place. + // + + if (result.second == 0) + { + if (result.first == checksums_ -> end()) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Failed to insert object " + << "in the cache.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to insert object of type " + << name() << " in the cache.\n"; + + return nothing; + } + + // + // Message is in cache. + // + + #ifdef TEST + *logofs << name() << ": Object is already in cache " + << "at position " << (result.first) -> second + << ".\n" << logofs_flush; + #endif + + #ifdef DEBUG + + printStorageSize(); + + #endif + + // + // Message is locked, probably because + // it has not completely recomposed at + // remote side after a split. + // + + if ((*messages_)[(result.first) -> second] -> locks_ != 0) + { + #ifdef TEST + *logofs << name() << ": WARNING! Object at position " + << (result.first) -> second << " is locked.\n" + << logofs_flush; + #endif + + locked = 1; + } + + // + // Object got a hit, so prevent + // its removal. + // + + if (lastRated == (result.first) -> second) + { + #ifdef TEST + *logofs << name() << ": Resetting rating of object " + << "at position " << (result.first) -> second + << ".\n" << logofs_flush; + #endif + + lastRated = nothing; + } + + return (result.first) -> second; + } + + #ifdef DEBUG + *logofs << name() << ": Could not find message in cache.\n" + << logofs_flush; + #endif + } + + // + // Message not found in hash table (or insertion + // of checksum in hash table was not requested). + // Message was added to cache. + // + + added = 1; + + // + // Log data about the missed message. + // + + #ifdef TEST + + if (opcode() == X_PutImage || opcode() == X_NXPutPackedImage) + { + #ifdef WARNING + *logofs << name() << ": WARNING! Dumping identity of " + << "missed image object of type " << name() + << ".\n" << logofs_flush; + #endif + + dumpIdentity(message); + } + + #endif + + if ((*messages_)[position] != NULL) + { + #ifdef DEBUG + *logofs << name() << ": The message replaces " + << "the old one at position " << position + << ".\n" << logofs_flush; + #endif + + remove(position, checksumAction, dataAction); + } + + (*messages_)[position] = message; + + // + // We used the slot. Perform a new + // search at next run. + // + + lastRated = nothing; + + #ifdef TEST + *logofs << name() << ": Stored message object of size " + << plainSize(position) << " (" << message -> size_ + << "/" << message -> c_size_ << ") at position " + << position << ".\n" << logofs_flush; + #endif + + unsigned int localSize; + unsigned int remoteSize; + + storageSize(message, localSize, remoteSize); + + localStorageSize_ += localSize; + remoteStorageSize_ += remoteSize; + + totalLocalStorageSize_ += localSize; + totalRemoteStorageSize_ += remoteSize; + + #ifdef DEBUG + + printStorageSize(); + + #endif + + // + // Set hits and timestamp at insertion in cache. + // + + message -> hits_ = control -> StoreHitsAddBonus; + message -> last_ = (getTimestamp()).tv_sec; + + message -> locks_ = 0; + + #ifdef DEBUG + *logofs << name() << ": Set last hit of object at " + << strMsTimestamp() << " with a bonus of " + << message -> hits_ << ".\n" << logofs_flush; + #endif + + return position; +} + +// +// Add a parsed message to repository. It is normally used +// at decoding side or at encoding side when we load store +// from disk. To handle messages coming from network, the +// encoding side uses the optimized method findOrAdd(). +// + +int MessageStore::add(Message *message, const int position, + T_checksum_action checksumAction, T_data_action dataAction) +{ + if (position < 0 || position >= cacheSlots) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Cannot add a message " + << "at non existing position " << position + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot add a message " + << "at non existing position " << position + << ".\n"; + + HandleAbort(); + } + + if ((*messages_)[position] != NULL) + { + #ifdef DEBUG + *logofs << name() << ": The message will replace " + << "the old one at position " << position + << ".\n" << logofs_flush; + #endif + + remove(position, checksumAction, dataAction); + } + + #ifdef DEBUG + *logofs << name() << ": Inserting object in repository at position " + << position << ".\n" << logofs_flush; + #endif + + (*messages_)[position] = message; + + // + // Get the object's checksum value + // and insert it in the table. + // + + if (checksumAction == use_checksum) + { + #ifdef DEBUG + *logofs << name() << ": Inserting object's checksum in repository.\n"; + #endif + + T_checksum checksum = getChecksum(message); + + checksums_ -> insert(T_checksums::value_type(checksum, position)); + } + + #ifdef DEBUG + *logofs << name() << ": Stored message object of size " + << plainSize(position) << " (" << message -> size_ + << "/" << message -> c_size_ << ") at position " + << position << ".\n" << logofs_flush; + #endif + + unsigned int localSize; + unsigned int remoteSize; + + storageSize(message, localSize, remoteSize); + + localStorageSize_ += localSize; + remoteStorageSize_ += remoteSize; + + totalLocalStorageSize_ += localSize; + totalRemoteStorageSize_ += remoteSize; + + #ifdef DEBUG + + printStorageSize(); + + #endif + + // + // Set hits and timestamp at insertion in cache. + // + + message -> hits_ = control -> StoreHitsAddBonus; + message -> last_ = (getTimestamp()).tv_sec; + + message -> locks_ = 0; + + #ifdef DEBUG + *logofs << name() << ": Set last hit of object at " + << strMsTimestamp() << " with a bonus of " + << message -> hits_ << ".\n" << logofs_flush; + #endif + + return position; +} + +// +// The following functions don't modify data, +// so they are supposed to be called only at +// the encoding side. +// + +void MessageStore::updateData(const int position, unsigned int dataSize, + unsigned int compressedDataSize) +{ + Message *message = (*messages_)[position]; + + validateSize(dataSize, compressedDataSize); + + if (compressedDataSize != 0) + { + unsigned int localSize; + unsigned int remoteSize; + + storageSize(message, localSize, remoteSize); + + localStorageSize_ -= localSize; + remoteStorageSize_ -= remoteSize; + + totalLocalStorageSize_ -= localSize; + totalRemoteStorageSize_ -= remoteSize; + + message -> c_size_ = compressedDataSize + message -> i_size_; + + #ifdef TEST + + if (message -> size_ != (int) (dataSize + message -> i_size_)) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Size of object looks " + << message -> size_ << " bytes while it " + << "should be " << dataSize + message -> i_size_ + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Size of object looks " + << message -> size_ << " bytes while it " + << "should be " << dataSize + message -> i_size_ + << ".\n"; + + HandleAbort(); + } + + #endif + + storageSize(message, localSize, remoteSize); + + localStorageSize_ += localSize; + remoteStorageSize_ += remoteSize; + + totalLocalStorageSize_ += localSize; + totalRemoteStorageSize_ += remoteSize; + + #ifdef DEBUG + + printStorageSize(); + + #endif + } +} + +void MessageStore::updateData(const T_checksum checksum, unsigned int compressedDataSize) +{ + #ifdef TEST + *logofs << name() << ": Searching checksum [" + << DumpChecksum(checksum) << "] in repository.\n" + << logofs_flush; + #endif + + T_checksums::iterator found = checksums_ -> find(checksum); + + if (found != checksums_ -> end()) + { + Message *message = (*messages_)[found -> second]; + + #ifdef TEST + *logofs << name() << ": Message found in cache at " + << "position " << found -> second << " with size " + << message -> size_ << " and compressed size " + << message -> c_size_ << ".\n" << logofs_flush; + #endif + + updateData(found -> second, message -> size_ - + message -> i_size_, compressedDataSize); + } + #ifdef TEST + else if (checksums_ -> size() > 0) + { + *logofs << name() << ": WARNING! Can't locate the " + << "checksum [" << DumpChecksum(checksum) + << "] for the update.\n" << logofs_flush; + } + #endif +} + +// +// This function replaces the data part of the message +// and updates the information about its size. Split +// messages are advertised to the decoding side with +// their uncompressed size, data is then compressed +// before sending the first chunk. This function is +// called by the decoding side after the split message +// is fully recomposed to replace the dummy data and +// set the real size. +// + +void MessageStore::updateData(const int position, const unsigned char *newData, + unsigned int dataSize, unsigned int compressedDataSize) +{ + Message *message = (*messages_)[position]; + + validateSize(dataSize, compressedDataSize); + + #ifdef TEST + + if (message -> size_ != (int) (dataSize + message -> i_size_)) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Data of object looks " + << dataSize << " bytes while it " << "should be " + << message -> size_ - message -> i_size_ + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Data of object looks " + << dataSize << " bytes while it " << "should be " + << message -> size_ - message -> i_size_ + << ".\n"; + + HandleAbort(); + } + + #endif + + // + // A compressed data size of 0 means that + // message's data was not compressed. + // + + if (compressedDataSize != 0) + { + unsigned int localSize; + unsigned int remoteSize; + + storageSize(message, localSize, remoteSize); + + localStorageSize_ -= localSize; + remoteStorageSize_ -= remoteSize; + + totalLocalStorageSize_ -= localSize; + totalRemoteStorageSize_ -= remoteSize; + + if (message -> c_size_ != (int) compressedDataSize + + message -> i_size_) + { + #ifdef TEST + *logofs << name() << ": Resizing data of message at " + << "position " << position << " from " << message -> + c_size_ << " to " << compressedDataSize + + message -> i_size_ << " bytes.\n" + << logofs_flush; + #endif + + message -> data_.clear(); + + message -> data_.resize(compressedDataSize); + } + + memcpy(message -> data_.begin(), newData, compressedDataSize); + + #ifdef TEST + *logofs << name() << ": Data of message at position " + << position << " has size " << message -> data_.size() + << " and capacity " << message -> data_.capacity() + << ".\n" << logofs_flush; + #endif + + message -> c_size_ = compressedDataSize + message -> i_size_; + + storageSize(message, localSize, remoteSize); + + localStorageSize_ += localSize; + remoteStorageSize_ += remoteSize; + + totalLocalStorageSize_ += localSize; + totalRemoteStorageSize_ += remoteSize; + + #ifdef DEBUG + + printStorageSize(); + + #endif + } + else + { + #ifdef TEST + *logofs << name() << ": No changes to data size for message " + << "at position " << position << ".\n" << logofs_flush; + #endif + + memcpy(message -> data_.begin(), newData, dataSize); + } +} + +int MessageStore::remove(const int position, T_checksum_action checksumAction, + T_data_action dataAction) +{ + Message *message; + + if (position < 0 || position >= cacheSlots || + (message = (*messages_)[position]) == NULL) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Cannot remove " + << "a non existing message at position " + << position << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot remove " + << "a non existing message at position " + << position << ".\n"; + + HandleAbort(); + } + + #if defined(TEST) || defined(INFO) + + if (opcode() == X_PutImage || opcode() == X_NXPutPackedImage) + { + #ifdef WARNING + *logofs << name() << ": WARNING! Discarding image object " + << "of type " << name() << " at position " + << position << ".\n" << logofs_flush; + #endif + } + + #endif + + // + // The checksum is only stored at the encoding + // side. + // + + if (checksumAction == use_checksum) + { + #ifdef DEBUG + *logofs << name() << ": Removing checksum for object at " + << "position " << position << ".\n" << logofs_flush; + #endif + + // + // TODO: If we had stored the iterator and + // not the pointer to the message, we could + // have removed the message without having + // to look up the checksum. + // + + T_checksum checksum = getChecksum(message); + + #ifdef TEST + *logofs << name() << ": Searching checksum [" + << DumpChecksum(checksum) << "] in repository.\n" + << logofs_flush; + #endif + + T_checksums::iterator found = checksums_ -> find(checksum); + + if (found == checksums_ -> end()) + { + #ifdef PANIC + *logofs << name() << ": PANIC! No checksum found for " + << "object at position " << position << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": No checksum found for " + << "object at position " << position << ".\n"; + + HandleAbort(); + } + + #ifdef TEST + + else if (position != found -> second) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Value of position for object " + << "doesn't match position " << position << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Value of position for object " + << "doesn't match position " << position << ".\n"; + + HandleAbort(); + } + + #endif + + checksums_ -> erase(found); + } + + #ifdef DEBUG + *logofs << name() << ": Removing message at position " + << position << " of size " << plainSize(position) + << " (" << message -> size_ << "/" << message -> c_size_ + << ").\n" << logofs_flush; + #endif + + unsigned int localSize; + unsigned int remoteSize; + + storageSize(message, localSize, remoteSize); + + localStorageSize_ -= localSize; + remoteStorageSize_ -= remoteSize; + + totalLocalStorageSize_ -= localSize; + totalRemoteStorageSize_ -= remoteSize; + + recycle(message); + + (*messages_)[position] = NULL; + + #ifdef DEBUG + + printStorageSize(); + + #endif + + return position; +} + +// +// This should only be called at encoding side. +// The decoding side can't rely on the counter +// as it is decremented by the encoding side +// every time the repository is searched for a +// message to be removed. +// + +int MessageStore::getRating(Message *message, T_rating type) const +{ + if (message -> locks_ != 0) + { + #ifdef TEST + *logofs << name() << ": Rate set to -1 as locks of object are " + << (int) message -> locks_ << ".\n" + << logofs_flush; + #endif + + return -1; + } + else if ((type == rating_for_clean || + (int) checksums_ -> size() == cacheSlots) && + message -> hits_ <= control -> StoreHitsLoadBonus) + { + // + // We don't have any free slot or we exceeded the + // available storage size. This is likely to happen + // after having loaded objects from persistent cache. + // It's not a bad idea to discard some messages that + // were restored but never referenced. + // + + #ifdef TEST + + if (type == rating_for_clean) + { + *logofs << name() << ": Rate set to 0 with hits " + << message -> hits_ << " as maximum storage size " + << "was exceeded.\n" << logofs_flush; + } + else + { + *logofs << name() << ": Rate set to 0 with hits " + << message -> hits_ << " as there are no available " + << "slots in store.\n" << logofs_flush; + } + + #endif + + return 0; + } + else if (type == rating_for_clean && + (getTimestamp()).tv_sec - message -> last_ >= + control -> StoreTimeLimit) + { + #ifdef TEST + *logofs << name() << ": Rate set to 0 as last hit of object was " + << (getTimestamp()).tv_sec - message -> last_ + << " seconds ago with limit set to " << control -> + StoreTimeLimit << ".\n" << logofs_flush; + #endif + + return 0; + } + else + { + #ifdef TEST + if (message -> hits_ < 0) + { + *logofs << name() << ": PANIC! Rate of object shouldn't be " + << message -> hits_ << ".\n" << logofs_flush; + + cerr << "Error" << ": Rate of object of type " << name() + << " shouldn't be " << message -> hits_ << ".\n"; + + HandleAbort(); + } + #endif + + #ifdef TEST + *logofs << name() << ": Rate of object is " << message -> hits_ + << " with last hit " << (getTimestamp()).tv_sec - + message -> last_ << " seconds ago.\n" + << logofs_flush; + #endif + + return message -> hits_; + } +} + +int MessageStore::touch(Message *message) const +{ + message -> last_ = (getTimestamp()).tv_sec; + + message -> hits_ += control -> StoreHitsTouch; + + if (message -> hits_ > control -> StoreHitsLimit) + { + message -> hits_ = control -> StoreHitsLimit; + } + + #ifdef TEST + *logofs << name() << ": Increased hits of object to " + << message -> hits_ << " at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + return message -> hits_; +} + +int MessageStore::untouch(Message *message) const +{ + message -> hits_ -= control -> StoreHitsUntouch; + + if (message -> hits_ < 0) + { + message -> hits_ = 0; + } + + #ifdef TEST + *logofs << name() << ": Decreased hits of object to " + << message -> hits_ << ".\n" + << logofs_flush; + #endif + + return message -> hits_; +} + +int MessageStore::lock(const int position) const +{ + Message *message = (*messages_)[position]; + + if (message == NULL) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Can't lock the null " + << "object at position " << position + << ".\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef DEBUG + *logofs << name() << ": Increasing locks of object to " + << (int) message -> locks_ + 1 << ".\n" + << logofs_flush; + #endif + + return ++(message -> locks_); +} + +int MessageStore::unlock(const int position) const +{ + Message *message = (*messages_)[position]; + + if (message == NULL) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Can't unlock the null " + << "object at position " << position + << ".\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef DEBUG + *logofs << name() << ": Decreasing locks of object to " + << (int) message -> locks_ - 1 << ".\n" + << logofs_flush; + #endif + + return --(message -> locks_); +} + +int MessageStore::saveStore(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient, T_checksum_action checksumAction, + T_data_action dataAction, int bigEndian) +{ + Message *message; + + #ifdef TEST + *logofs << name() << ": Opcode of this store is " + << (unsigned int) opcode() << " default size of " + << "identity is " << dataOffset << ".\n" + << logofs_flush; + #endif + + unsigned char *identityBuffer = new unsigned char[dataOffset]; + unsigned char *sizeBuffer = new unsigned char[4 * 2]; + unsigned char *positionBuffer = new unsigned char[4]; + unsigned char *opcodeBuffer = new unsigned char[4]; + + #ifdef DUMP + + char *md5ClientDump = new char[dataOffset * 2 + 128]; + + #endif + + unsigned char value; + + int offset; + + int failed = 0; + + for (int position = 0; position < cacheSlots; position++) + { + message = (*messages_)[position]; + + // + // Don't save split messages. + // + + if (message != NULL && message -> locks_ == 0) + { + // + // Use the total size if offset is + // beyond the real end of message. + // + + offset = dataOffset; + + if (offset > message -> size_) + { + offset = message -> size_; + } + + #ifdef TEST + *logofs << name() << ": Going to save message at position " + << position << ".\n" << logofs_flush; + #endif + + value = 1; + + PutULONG(position, positionBuffer, bigEndian); + PutULONG(opcode(), opcodeBuffer, bigEndian); + + md5_append(md5StateClient, positionBuffer, 4); + md5_append(md5StateClient, opcodeBuffer, 4); + + #ifdef DUMP + + *logofs << "Name=" << name() << logofs_flush; + + sprintf(md5ClientDump," Pos=%d Op=%d\n", position, opcode()); + + *logofs << md5ClientDump << logofs_flush; + + #endif + + if (PutData(cachefs, &value, 1) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure writing " << 1 + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, &value, 1); + + PutULONG(message -> size_, sizeBuffer, bigEndian); + PutULONG(message -> c_size_, sizeBuffer + 4, bigEndian); + + // + // Note that the identity size is not saved with + // the message and will be determined from the + // data read when restoring the identity. + // + + if (PutData(cachefs, sizeBuffer, 4 * 2) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure writing " << 4 * 2 + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, sizeBuffer, 4 * 2); + md5_append(md5StateClient, sizeBuffer, 4 * 2); + + #ifdef DUMP + + sprintf(md5ClientDump, "size = %d c_size = %d\n", + message -> size_, message -> c_size_); + + *logofs << md5ClientDump << logofs_flush; + + #endif + + // + // Prepare a clean buffer for unparse. + // + + CleanData(identityBuffer, offset); + + unparseIdentity(message, identityBuffer, offset, bigEndian); + + if (PutData(cachefs, identityBuffer, offset) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure writing " << offset + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, identityBuffer, offset); + md5_append(md5StateClient, identityBuffer, offset); + + #ifdef DUMP + + for (int i = 0; i < offset; i++) + { + sprintf(md5ClientDump + (i * 2), "%02X", identityBuffer[i]); + } + + *logofs << "Identity = " << md5ClientDump << "\n" << logofs_flush; + + #endif + + // + // Set the real identity size before + // saving the data. + // + + offset = message -> i_size_; + + if (offset > message -> size_) + { + offset = message -> size_; + } + + if (checksumAction == use_checksum) + { + if (PutData(cachefs, message -> md5_digest_, MD5_LENGTH) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure writing " << MD5_LENGTH + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, message -> md5_digest_, MD5_LENGTH); + } + else if (dataAction == use_data) + { + int dataSize = (message -> c_size_ == 0 ? + message -> size_ - offset : + message -> c_size_ - offset); + if (dataSize > 0) + { + if (PutData(cachefs, message -> data_.begin(), dataSize) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure writing " << dataSize + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, message -> data_.begin(), dataSize); + } + } + } + else + { + #ifdef TEST + *logofs << name() << ": Not saving message at position " + << position << ".\n" << logofs_flush; + #endif + + value = 0; + + if (PutData(cachefs, &value, 1) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure writing " << 1 + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, &value, 1); + } + } + + if (failed == 1) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Write to persistent cache file failed.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Write to persistent cache file failed.\n"; + } + + delete [] identityBuffer; + delete [] sizeBuffer; + delete [] positionBuffer; + delete [] opcodeBuffer; + + #ifdef DUMP + + delete [] md5ClientDump; + + #endif + + return (failed == 0 ? 1 : -1); +} + +int MessageStore::loadStore(istream *cachefs, md5_state_t *md5StateStream, + T_checksum_action checksumAction, T_data_action dataAction, + int bigEndian) +{ + Message *message; + + #ifdef TEST + *logofs << name() << ": Opcode of this store is " + << (unsigned int) opcode() << " default size of " + << "identity is " << dataOffset << " slots are " + << cacheSlots << ".\n" << logofs_flush; + #endif + + // + // If packed images or the render extension has been + // disabled we don't need to restore these messages + // in the cache. Encoding of RENDER in 1.4.0 is also + // changed so we want to skip messages saved using + // the old format. We want to restore all the other + // messages so we'll need to skip these one by one. + // + + int skip = 0; + + if ((opcode() == X_NXPutPackedImage && + control -> PersistentCacheLoadPacked == 0) || + (opcode() == X_NXInternalRenderExtension && + control -> PersistentCacheLoadRender == 0)) + { + #ifdef TEST + *logofs << name() << ": All messages for OPCODE#" + << (unsigned int) opcode() << " will be discarded.\n" + << logofs_flush; + #endif + + skip = 1; + } + + unsigned char *identityBuffer = new unsigned char[dataOffset]; + unsigned char *sizeBuffer = new unsigned char[4 * 2]; + + unsigned char value; + + int offset; + + int failed = 0; + + for (int position = 0; position < cacheSlots; position++) + { + if (GetData(cachefs, &value, 1) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure reading " << 1 + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, &value, 1); + + if (value == 1) + { + #ifdef TEST + *logofs << name() << ": Going to load message at position " + << position << ".\n" << logofs_flush; + #endif + + if (GetData(cachefs, sizeBuffer, 4 * 2) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure reading " << 4 * 2 + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, sizeBuffer, 4 * 2); + + message = getTemporary(); + + if (message == NULL) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Can't access temporary storage " + << "for message in context [B].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't access temporary storage " + << "for message in context [B].\n"; + + failed = 1; + + break; + } + + message -> size_ = GetULONG(sizeBuffer, bigEndian); + message -> c_size_ = GetULONG(sizeBuffer + 4, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Size is " << message -> size_ + << " compressed size is " << message -> c_size_ + << ".\n" << logofs_flush; + #endif + + // + // Use the total size if offset is + // beyond the real end of message. + // + + offset = dataOffset; + + if (offset > message -> size_) + { + offset = message -> size_; + } + + if (GetData(cachefs, identityBuffer, offset) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure reading " << offset + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, identityBuffer, offset); + + // + // Get the real identity size based on the value + // reported by the message store. The dataOffset + // value is guaranteed to be greater or equal to + // the maximum identity size of the messages in + // the major store. + // + + offset = identitySize(identityBuffer, offset); + + if (offset > message -> size_) + { + offset = message -> size_; + } + + message -> i_size_ = offset; + + // + // Get identity of message from the buffer we just + // created. Don't calculate neither checksum nor + // data, restore them from stream. Don't pass the + // message's size but the default size of identity. + // + + parseIdentity(message, identityBuffer, offset, bigEndian); + + if (checksumAction == use_checksum) + { + if (message -> md5_digest_ == NULL) + { + message -> md5_digest_ = new md5_byte_t[MD5_LENGTH]; + } + + if (GetData(cachefs, message -> md5_digest_, MD5_LENGTH) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure reading " << MD5_LENGTH + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + // + // Add message's checksum to checksum that will + // be saved together with this cache. Checksum + // will be verified when cache file is restored + // to ensure file is not corrupted. + // + + md5_append(md5StateStream, message -> md5_digest_, MD5_LENGTH); + + if (skip == 1) + { + #ifdef TEST + *logofs << name() << ": Discarding message for OPCODE#" + << (unsigned int) opcode() << ".\n" + << logofs_flush; + #endif + + continue; + } + } + else if (dataAction == use_data) + { + // + // Restore the data part. + // + + int dataSize = (message -> c_size_ == 0 ? + message -> size_ - offset : + message -> c_size_ - offset); + + if (dataSize < 0 || dataSize > control -> MaximumMessageSize) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Bad data size " + << dataSize << " loading persistent cache.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Bad data size " << dataSize + << " loading persistent cache.\n"; + + failed = 1; + + break; + } + else if (dataSize > 0) + { + // + // If need to skip the message let anyway + // it to be part of the calculated MD5. + // + + if (skip == 1) + { + unsigned char *dummy = new unsigned char[dataSize]; + + if (dummy == NULL) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Can't allocate dummy buffer " + << "of size " << dataSize << " loading cache.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate dummy buffer " + << "of size " << dataSize << " loading cache.\n"; + + failed = 1; + + break; + } + + if (GetData(cachefs, dummy, dataSize) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure reading " << dataSize + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + md5_append(md5StateStream, dummy, dataSize); + + delete [] dummy; + + #ifdef TEST + *logofs << name() << ": Discarding message for OPCODE#" + << (unsigned int) opcode() << ".\n" + << logofs_flush; + #endif + + continue; + } + else + { + message -> data_.clear(); + + message -> data_.resize(dataSize); + + if (GetData(cachefs, message -> data_.begin(), dataSize) < 0) + { + #ifdef DEBUG + *logofs << name() << ": PANIC! Failure reading " << dataSize + << " bytes.\n" << logofs_flush; + #endif + + failed = 1; + + break; + } + + // + // Add message's data to cache checksum. + // + + md5_append(md5StateStream, message -> data_.begin(), dataSize); + } + } + else + { + // + // We are here if data part is zero. + // + + if (skip == 1) + { + #ifdef TEST + *logofs << name() << ": Discarding message for OPCODE#" + << (unsigned int) opcode() << ".\n" + << logofs_flush; + #endif + + continue; + } + } + } + + int added; + + added = add(message, position, checksumAction, dataAction); + + if (added != position) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Can't store message " + << "in the cache at position " << position + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't store message " + << "in the cache at position " << position + << ".\n"; + + failed = 1; + + break; + } + else + { + // + // Replace default value of hits set by add + // function. Messages read from cache start + // with a lower bonus than fresh messages + // inserted. + // + + message -> hits_ = control -> StoreHitsLoadBonus; + + #ifdef DEBUG + *logofs << name() << ": Updated last hit of object at " + << strMsTimestamp() << " with a bonus of " + << message -> hits_ << ".\n" << logofs_flush; + #endif + + resetTemporary(); + } + } + else if ((*messages_)[position] != NULL) + { + #ifdef TEST + *logofs << name() << ": Going to remove message at position " + << position << ".\n" << logofs_flush; + #endif + + int removed; + + removed = remove(position, checksumAction, dataAction); + + if (removed != position) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Can't remove message from cache " + << "at position " << position << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't remove message from cache " + << "at position " << position << ".\n"; + + failed = 1; + + break; + } + } + #ifdef TEST + else + { + *logofs << name() << ": Not loading message at position " + << position << ".\n" << logofs_flush; + } + #endif + } + + #ifdef WARNING + + if (failed == 1) + { + *logofs << name() << ": WARNING! Read from persistent cache file failed.\n" + << logofs_flush; + } + + #endif + + delete [] identityBuffer; + delete [] sizeBuffer; + + return (failed == 0 ? 1 : -1); +} + +void MessageStore::storageSize(const Message *message, unsigned int &local, + unsigned int &remote) const +{ + local = remote = storage(); + + // + // Encoding side includes 48 bytes for + // the map of checksums and 24 bytes + // of adjustment for total overhead. + // + + local += MD5_LENGTH + 48 + 24; + + // + // At decoding side we include size of + // data part and 24 bytes of adjustment + // for total overhead. + // + + if (message -> c_size_ == 0) + { + remote += message -> size_ + 24; + } + else + { + remote += message -> c_size_ + 24; + } + + // + // Check if we are the encoding or the + // decoding side and, if needed, swap + // the values. + // + + if (message -> md5_digest_ == NULL) + { + unsigned int t = local; + + local = remote; + + remote = t; + } +} + +void MessageStore::printStorageSize() +{ + #ifdef TEST + + *logofs << name() << ": There are " + << checksums_ -> size() << " checksums in this store " + << "out of " << cacheSlots << " slots.\n" + << logofs_flush; + + *logofs << name() << ": Size of this store is " + << localStorageSize_ << " bytes at local side and " + << remoteStorageSize_ << " bytes at remote side.\n" + << logofs_flush; + + *logofs << name() << ": Size of total cache is " + << totalLocalStorageSize_ << " bytes at local side and " + << totalRemoteStorageSize_ << " bytes at remote side.\n" + << logofs_flush; + + #endif +} diff --git a/nxcomp/src/Message.h b/nxcomp/src/Message.h new file mode 100644 index 000000000..30883f101 --- /dev/null +++ b/nxcomp/src/Message.h @@ -0,0 +1,1089 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Message_H +#define Message_H + +#include + +#include "NXproto.h" + +#include "Misc.h" +#include "Control.h" + +#include "Types.h" +#include "Timestamp.h" + +#include "ActionCache.h" + +#include "StaticCompressor.h" + +// +// Forward class declarations. +// + +class ChannelCache; + +class EncodeBuffer; +class DecodeBuffer; + +class WriteBuffer; + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Define this to know how many messages +// are allocated and deallocated. +// + +#undef REFERENCES + +// +// Set default values. We limit the maximum +// size of a request to 262144 but we need to +// consider the replies, whose size may be up +// to 4MB. +// + +#define MESSAGE_ENABLE_CACHE 0 +#define MESSAGE_ENABLE_DATA 0 +#define MESSAGE_ENABLE_SPLIT 0 +#define MESSAGE_ENABLE_COMPRESS 0 + +#define MESSAGE_DATA_LIMIT 4194304 - 4 +#define MESSAGE_DATA_OFFSET 4 + +#define MESSAGE_CACHE_SLOTS 6000 +#define MESSAGE_CACHE_THRESHOLD 50 +#define MESSAGE_CACHE_LOWER_THRESHOLD 5 + +// +// Base message class. +// + +class Message +{ + friend class MessageStore; + friend class RenderExtensionStore; + + public: + + Message() + { + hits_ = 0; + last_ = 0; + locks_ = 0; + + size_ = 0; + c_size_ = 0; + + md5_digest_ = NULL; + + #ifdef REFERENCES + + references_++; + + *logofs << "Message: Created new message at " + << this << " out of " << references_ + << " allocated messages.\n" + << logofs_flush; + + #endif + } + + Message(const Message &message) + { + size_ = message.size_; + c_size_ = message.c_size_; + i_size_ = message.i_size_; + + hits_ = message.hits_; + last_ = message.last_; + locks_ = message.locks_; + + data_ = message.data_; + + #ifdef REFERENCES + + references_++; + + *logofs << "Message: Creating new copied message at " + << this << " out of " << references_ + << " allocated messages.\n" + << logofs_flush; + #endif + + if (message.md5_digest_ != NULL) + { + md5_digest_ = new md5_byte_t[MD5_LENGTH]; + + memcpy(md5_digest_, message.md5_digest_, MD5_LENGTH); + + #ifdef DEBUG + *logofs << "Message: Created MD5 digest for object at " + << this << ".\n" << logofs_flush; + #endif + } + else + { + md5_digest_ = NULL; + } + } + + ~Message() + { + #ifdef DEBUG + if (md5_digest_ != NULL) + { + *logofs << "Message: Deleted MD5 digest for object at " + << this << ".\n" << logofs_flush; + } + #endif + + delete [] md5_digest_; + + #ifdef REFERENCES + + references_--; + + *logofs << "Message: Deleted message at " + << this << " out of " << references_ + << " allocated messages.\n" + << logofs_flush; + #endif + } + + // + // This is the original message size + // including the data part regardless + // data is still stored in the object. + // + + int size_; + + // + // This is the size of the identity. + // + + int i_size_; + + // + // This is the size, including identity, + // after message has been 'updated' to + // reflect storage of data in compressed + // format. + // + + int c_size_; + + protected: + + // + // This is the data part. + // + + T_data data_; + + // + // Time of last hit. + // + + time_t last_; + + // + // This is the number of cache hits + // registered for the object. + // + + short int hits_; + + // + // This is used to mark messages + // that have been split. + // + + short int locks_; + + // + // This is the MD5 checksum. + // + + md5_byte_t *md5_digest_; + + // + // Keep a reference counter + // of allocated objects. + // + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +// +// Repository of messages. +// + +class MessageStore +{ + public: + + // + // Enable or disable cache of messages in store. + // + + int enableCache; + + // + // Does message have a distinct data part. + // + + int enableData; + + // + // Enable or disable split of data part. + // + + int enableSplit; + + // + // Enable or disable compression of data part. + // + + int enableCompress; + + // + // Set starting point of data part in the message. + // + + int dataOffset; + + // + // Set maximum size for the data part of each message. + // + + int dataLimit; + + // + // Set maximum elements in cache. + // + + int cacheSlots; + + // + // Set the percentage of total cache memory which + // a given type of message is allowed to occupy. + // When threshold is exceeded store is cleaned to + // make room for a new message of the same type. + // + + int cacheThreshold; + + // + // Don't clean the store if percentage of cache + // memory occupied by messages of this type is + // below the threshold. + // + + int cacheLowerThreshold; + + // + // Last operation performed on cache. + // + + T_store_action lastAction; + + // + // Position of last element stored in cache. + // + + short int lastAdded; + + // + // Positions of last element found in cache. + // + + short int lastHit; + + // + // Position of last element erased. + // + + short int lastRemoved; + + // + // Used to encode the the action to + // perform on the store and the slot + // involved. + // + + ActionCache lastActionCache; + + // + // Position in cache where next insertion + // is going to take place. + // + + short int lastRated; + + // + // Constructors and destructors. + // + + public: + + MessageStore(StaticCompressor *compressor = NULL); + + virtual ~MessageStore(); + + virtual const char *name() const = 0; + + virtual unsigned char opcode() const = 0; + + virtual unsigned int storage() const = 0; + + // + // These are members that must be specialized. + // + + public: + + virtual Message *create() const = 0; + + virtual Message *create(const Message &message) const = 0; + + virtual void destroy(Message *message) const = 0; + + void validateSize(int size) + { + if (size < control -> MinimumMessageSize || + size > control -> MaximumMessageSize) + { + *logofs << name() << ": PANIC! Invalid size " << size + << " for message.\n" << logofs_flush; + + cerr << "Error" << ": Invalid size " << size + << " for message opcode " << opcode() << ".\n"; + + HandleAbort(); + } + } + + void validateSize(int dataSize, int compressedDataSize) + { + if (dataSize < 0 || dataSize > control -> + MaximumMessageSize - 4 || compressedDataSize < 0 || + compressedDataSize >= dataSize) + { + *logofs << name() << ": PANIC! Invalid data size " + << dataSize << " and compressed data size " + << compressedDataSize << " for message.\n" + << logofs_flush; + + cerr << "Error" << ": Invalid data size " + << dataSize << " and compressed data size " + << compressedDataSize << " for message " + << "opcode " << (unsigned) opcode() << ".\n"; + + HandleAbort(); + } + } + + // + // Determine if the message can be stored + // in the cache. + // + + virtual int validateMessage(const unsigned char *buffer, int size) + { + return (size >= control -> MinimumMessageSize && + size <= control -> MaximumMessageSize); + } + + // + // Get data offset based on major and minor + // opcode of the message. + // + + virtual int identitySize(const unsigned char *buffer, unsigned int size) + { + return dataOffset; + } + + // + // Encode identity and data using the + // specific message encoding. + // + // Some messages do not implement these + // methods because the encoding is done + // directly in the channel loop. Should + // move the encoding methods in in the + // message classes. + // + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const + { + return 1; + } + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const + { + return 1; + } + + // + // Encode differences between message + // in cache and the one to be encoded. + // + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, ChannelCache *channelCache) const + { + } + + // + // Decode differences and update the + // cached version of the same message. + // + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const + { + } + + // + // Post process the message information + // contained in the store by either up- + // dating the size record or the actual + // data part once the message has been + // completely sent to our peer. + // + + void updateData(const int position, unsigned int dataSize, + unsigned int compressedDataSize); + + void updateData(const T_checksum checksum, unsigned int compressedDataSize); + + void updateData(const int position, const unsigned char *newData, + unsigned int dataSize, unsigned int compressedDataSize); + + // + // These members, used internally + // in the message store class, are + // mandatory. + // + + protected: + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const = 0; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const = 0; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const = 0; + + virtual void dumpIdentity(const Message *message) const = 0; + + // + // Design should preserve these from being + // virtual. + // + + int parseData(Message *message, int split, const unsigned char *buffer, + unsigned int size, T_checksum_action checksumAction, + T_data_action dataAction, int bigEndian); + + int parseData(Message *message, const unsigned char *buffer, + unsigned int size, const unsigned char *compressedData, + const unsigned int compressedDataSize, T_checksum_action checksumAction, + T_data_action dataAction, int bigEndian); + + int unparseData(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian); + + // + // Manage efficient allocation of messages + // in the heap. + // + + void recycle(Message *message) + { + #ifdef TEST + + if (message == NULL) + { + *logofs << name() << ": PANIC! Cannot recycle a null message.\n" + << logofs_flush; + + cerr << "Error" << ": Cannot recycle a null message.\n"; + + HandleAbort(); + } + + #endif + + if (temporary_ == NULL) + { + // + // Be careful when reusing the message as + // it can contain valid data that must be + // explicitly deallocated if not needed. + // Note also that you cannot count on the + // initialization made in costructor. + // + + temporary_ = message; + } + else + { + destroy(message); + } + } + + void beginChecksum(Message *message) + { + if (message -> md5_digest_ == NULL) + { + message -> md5_digest_ = new md5_byte_t[MD5_LENGTH]; + + #ifdef DEBUG + *logofs << name() << ": Created MD5 digest structure " + << "for object at " << message << ".\n" + << logofs_flush; + #endif + } + #ifdef DEBUG + else + { + *logofs << name() << ": Using existing MD5 digest structure " + << "for object at " << message << ".\n" + << logofs_flush; + } + #endif + + #ifdef DEBUG + *logofs << name() << ": Prepared MD5 digest for object at " + << message << ".\n" << logofs_flush; + #endif + + md5_init(md5_state_); + } + + void endChecksum(Message *message) + { + md5_finish(md5_state_, message -> md5_digest_); + + #ifdef DEBUG + *logofs << name() << ": Calculated checksum for object at " + << message << ".\n" << logofs_flush; + #endif + } + + void dataChecksum(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) + { + // + // Messages that have a data part starting + // at an offset possibly beyond the end of + // the message, must include the size in + // the identity checksum. + // + + if ((int) size > message -> i_size_) + { + md5_append(md5_state_, buffer + message -> i_size_, + size - message -> i_size_); + } + } + + // + // Repository handling methods. + // + + public: + + // + // Extract identity and data from buffer. + // The size field will be updated at the + // time of data parsing. + // + + int parse(Message *message, int split, const unsigned char *buffer, unsigned int size, + T_checksum_action checksumAction, T_data_action dataAction, int bigEndian); + + int parse(Message *message, const unsigned char *buffer, unsigned int size, + const unsigned char *compressedData, const unsigned int compressedDataSize, + T_checksum_action checksumAction, T_data_action dataAction, int bigEndian); + + // + // From identity and data write the + // final message to the raw buffer. + // + + int unparse(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) + { + return (unparseData(message, buffer, size, bigEndian) && + unparseIdentity(message, buffer, size, bigEndian)); + } + + void dump(const Message *message) const + { + dumpIdentity(message); + + dumpData(message); + } + + void dumpData(const Message *message) const; + + // + // This returns the original message size as it + // was received on the link. It takes in account + // the data part, regardless data is still stored + // in the message object. This information will + // be used at the time message is unparsed. + // + + int plainSize(const int position) const + { + return (*messages_)[position] -> size_; + } + + // + // This returns either the size of identity plus + // the compressed data part or 0 if message is + // stored in uncompressed format. + // + + int compressedSize(const int position) const + { + return (*messages_)[position] -> c_size_; + } + + // + // Returns a pointer to message + // given its position in cache. + // + + Message *get(const int position) const + { + if (position < 0 || position >= cacheSlots) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Requested position " + << position << " is not inside the " + << "container.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Requested position " + << position << " is not inside the" + << "container.\n"; + + HandleAbort(); + } + else if ((*messages_)[position] == NULL) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Message at position " + << position << " is NULL.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Message at position " + << position << " is NULL.\n"; + + HandleAbort(); + } + + return (*messages_)[position]; + } + + // + // This is the method called at encoding + // side to add a message to cache. + // + + int findOrAdd(Message *message, T_checksum_action checksumAction, + T_data_action dataAction, int &added, int &locked); + + // + // Utility interfaces to message insertion + // and deletion. + // + + int add(Message *message, const int position, + T_checksum_action checksumAction, T_data_action dataAction); + + int remove(const int position, T_checksum_action checksumAction, + T_data_action dataAction); + + // + // Make space in the repository by remove + // the first suitable message object. + // + + int clean(T_checksum_action checksumAction); + + // + // Increase or decrease the "rating" of + // the message object. + // + + int touch(Message *message) const; + int untouch(Message *message) const; + + int getTouches(const int position) const + { + Message *message = (*messages_)[position]; + + if (message == NULL) + { + return 0; + } + + return message -> hits_; + } + + // + // Gives a 'weight' to the cached message. A zero + // value means object can be safely removed. A value + // greater than zero means it is advisable to retain + // the object. A negative result means it is mandato- + // ry to keep object in cache. + // + + int getRating(Message *message, T_rating type) const; + + // + // Increase or decrease locks of message at given + // position. A locked message will not be removed + // from the message store until the lock counter + // is zero. + // + + int lock(const int position) const; + int unlock(const int position) const; + + int getLocks(const int position) const + { + Message *message = (*messages_)[position]; + + if (message == NULL) + { + return 0; + } + + return message -> locks_; + } + + T_checksum const getChecksum(const int position) const + { + return getChecksum(get(position)); + } + + T_checksum const getChecksum(const Message *message) const + { + if (message -> md5_digest_ == NULL) + { + #ifdef PANIC + *logofs << name() << ": PANIC! Checksum not initialized " + << "for object at " << message << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Checksum not initialized " + << "for object at " << message << ".\n"; + + HandleAbort(); + } + + #ifdef DEBUG + *logofs << name() << ": Got checksum for object at " + << message << ".\n" << logofs_flush; + #endif + + return message -> md5_digest_; + } + + // + // Calculate the checksum on the fly based the + // opcode in the buffer. Useful in the case a + // message was not processed or was not stored + // in the cache. The returned checksum must be + // explicitly deallocated by the caller, after + // use. + // + + T_checksum getChecksum(const unsigned char *buffer, + unsigned int size, int bigEndian); + + const unsigned char *getData(const Message *message) const + { + return message -> data_.begin(); + } + + int plainSize(const Message *message) const + { + return message -> size_; + } + + int identitySize(Message *message) + { + return message -> i_size_; + } + + int compressedSize(const Message *message) const + { + return message -> c_size_; + } + + Message *getTemporary() + { + if (temporary_ == NULL) + { + temporary_ = create(); + } + + return temporary_; + } + + void resetTemporary() + { + temporary_ = NULL; + } + + // + // On side where we don't have checksums, we + // count how many messages are in the array. + // This is obviously expensive and should be + // only performed when reporting statistics. + // + + int getSize() const + { + int size = checksums_ -> size(); + + if (size == 0) + { + for (int i = 0; i < cacheSlots; i++) + { + if ((*messages_)[i] != NULL) + { + size++; + } + } + } + + return size; + } + + int getLocalStorageSize() const + { + return localStorageSize_; + } + + int getRemoteStorageSize() const + { + return remoteStorageSize_; + } + + int getLocalTotalStorageSize() const + { + return totalLocalStorageSize_; + } + + int getRemoteTotalStorageSize() const + { + return totalRemoteStorageSize_; + } + + static int getCumulativeTotalStorageSize() + { + return (totalLocalStorageSize_ > totalRemoteStorageSize_ ? + totalLocalStorageSize_ : totalRemoteStorageSize_); + } + + int saveStore(ostream *cachefs, md5_state_t *md5_state_stream, + md5_state_t *md5_state_client, T_checksum_action checksumAction, + T_data_action dataAction, int bigEndian); + + int loadStore(istream *cachefs, md5_state_t *md5_state_stream, + T_checksum_action checksumAction, T_data_action dataAction, + int bigEndian); + + protected: + + // + // Estimate the memory requirements of given + // instance of message. Size includes memory + // allocated from heap to store checksum and + // data. + // + + void storageSize(const Message *message, unsigned int &local, + unsigned int &remote) const; + + // + // Just used for debug. + // + + void printStorageSize(); + + // + // Repositories where to save cached messages. + // First is a vector of pointers, the second + // is a hash table used for fast lookups. + // + + T_messages *messages_; + T_checksums *checksums_; + + // + // A message object to be used as a temporary. + // Reuse the temporary object if possible, if + // not, create a new instance. + // + + Message *temporary_; + + // + // Used to calculate message's checksum. + // + + md5_state_t *md5_state_; + + private: + + // + // Used to compress data payload. + // + + StaticCompressor *compressor_; + + // + // Keep track of how many bytes + // are taken by cache. + // + + int localStorageSize_; + int remoteStorageSize_; + + static int totalLocalStorageSize_; + static int totalRemoteStorageSize_; + + // + // Used to track object allocation and deallocation. + // + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +// +// This is an ancillary class of the message +// store, used to encode extensions based on +// the minor opcode. +// + +class MinorMessageStore +{ + public: + + virtual ~MinorMessageStore() + { + } + + virtual const char *name() const = 0; + + virtual int identitySize(const unsigned char *buffer, unsigned int size) = 0; + + virtual int encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const + { + return 1; + } + + virtual int decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, unsigned char type, int bigEndian, + WriteBuffer *writeBuffer, ChannelCache *channelCache) const + { + return 1; + } + + virtual void encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const + { + } + + virtual void decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const + { + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const = 0; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const = 0; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const + { + } + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const + { + } + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, md5_state_t *md5_state, + int bigEndian) const = 0; +}; + +#endif /* Message_H */ + diff --git a/nxcomp/src/Misc.cpp b/nxcomp/src/Misc.cpp new file mode 100644 index 000000000..b40e6409e --- /dev/null +++ b/nxcomp/src/Misc.cpp @@ -0,0 +1,1934 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "NXproto.h" + +#include "MD5.h" + +#include "Misc.h" +#include "Proxy.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#define OPCODES +#undef TEST +#undef DEBUG + +// +// By default nxproxy binds to all network interfaces, setting +// DEFAULT_LOOPBACK_BIND to 1 enables binding to the loopback +// device only. +// + +const int DEFAULT_LOOPBACK_BIND = 0; + +// +// TCP port offset applied to any NX port specification. +// + +const int DEFAULT_NX_PROXY_PORT_OFFSET = 4000; + +// +// Default TCP port used by client proxy to listen to +// X clients and by server proxy to connect to remote. +// + +const int DEFAULT_NX_PROXY_PORT = 8; + +// +// Default X display number that client proxy imitates. +// + +const int DEFAULT_NX_X_PORT = 8; + +// +// Default ports used for listening for cups, samba, http, +// multimedia and auxiliary X connections. Arbitrary ports +// can be used by passing the service's port at the proxy +// startup. By default ports are determined by adding the +// offset below to the offset of the proxied display. For +// example, if the proxy is impersonating the display :8, +// SMB tunnels can be created by connecting to port 3008. +// +// Considering that the NX server uses to start the first +// session at display offset 1000, we must lower the CUPS +// and SMB ports to avoid interference with normal X ses- +// sions run on the server. +// +// Font server connections are used to let the X server on +// the client connect to a font server on the NX server. +// +// Slave channels can be originated by both sides so we need +// different offsets in the case the user runs both proxies +// on the same host. +// + +const int DEFAULT_NX_CUPS_PORT_OFFSET = 2000; +const int DEFAULT_NX_SMB_PORT_OFFSET = 3000; +const int DEFAULT_NX_MEDIA_PORT_OFFSET = 7000; +const int DEFAULT_NX_AUX_PORT_OFFSET = 8000; +const int DEFAULT_NX_HTTP_PORT_OFFSET = 9000; +const int DEFAULT_NX_FONT_PORT_OFFSET = 10000; + +const int DEFAULT_NX_SLAVE_PORT_CLIENT_OFFSET = 11000; +const int DEFAULT_NX_SLAVE_PORT_SERVER_OFFSET = 12000; + +// +// Usage info and copyright. +// + +static const char UsageInfo[] = +"\n\ + Usage: nxproxy [OPTIONS] host:port\n\ +\n\ + -C Specify that nxproxy has to run on the 'X client'\n\ + side, listening for connections and impersonating\n\ + an X server.\n\ +\n\ + -S Specify that nxproxy has to run in 'X server' mode,\n\ + thus forwarding the connections to daemons running\n\ + on the client.\n\ +\n\ + -h Print this message.\n\ +\n\ + -v Print version information.\n\ +\n\ + host:port Put at the end, specifies the host and port of the\n\ + listening proxy.\n\ +\n\ + name=value Set the NX option to the provided value.\n\ +\n\ + Multiple NX options can be specified in the DISPLAY environment\n\ + or on the command line, by using the nx/nx,option=value notation.\n\ +\n\ + Options:\n\ +\n\ + link=s An indication of the link speed that is going to be\n\ + used between the proxies. Usually the compression\n\ + and the other link parameters depend on this setting.\n\ + The value can be either 'modem', 'isdn', 'adsl',\n\ + 'wan', 'lan', 'local' or a bandwidth specification,\n\ + like for example '56k', '1m', '100m', etc.\n\ +\n\ + type=s Type of session, for example 'windows', 'unix-kde'.\n\ + 'unix-application', etc.\n\ +\n\ + display=s Specify the real display where X connections have\n\ + to be forwarded by the proxy running on the client.\n\ +\n\ + listen=n Local port used for accepting the proxy connection.\n\ +\n\ + loopback=b Bind to the loopback device only.\n\ +\n\ + accept=s Name or IP of host that can connect to the proxy.\n\ +\n\ + connect=s Name or IP of host that the proxy will connect to.\n\ +\n\ + port=n Remote port used for the connection.\n\ +\n\ + retry=n Number of connection atempts.\n\ +\n\ + root=s The root directory for the session. Usually is the\n\ + C-* or S-* in the .nx directory in the user's home,\n\ + with '*' being the virtual display.\n\ +\n\ + session=s Name of the session file. The default is the name\n\ + 'session' in the session directory.\n\ +\n\ + errors=s Name of the log file used by the proxy. The default\n\ + is the name 'errors' in the session directory.\n\ +\n\ + stats=s Name of the file where are written the proxy stat-\n\ + istics. The default is a file 'stats' in the session\n\ + directory. The proxy replaces the data in the file\n\ + whenever it receives a SIGUSR1 or SIGUSR2 signal:\n\ +\n\ + SIGUSR1 Gives total statistics, i.e. statistics\n\ + collected since the beginning of the\n\ + session.\n\ +\n\ + SIGUSR2 Gives partial statistics, i.e. statist-\n\ + ics collected since the last time this\n\ + signal was received.\n\ +\n\ + cookie=s Use the provided cookie for authenticating to the\n\ + remote proxy. The same cookie is used as the fake\n\ + value used for the X authorization. The fake cookie\n\ + is replaced on the X server side with the real cookie\n\ + to be used for the display, so that the real cookie\n\ + doesn't have to travel over the net. When not using\n\ + a proxy cookie, any host will be able to connect to\n\ + the proxy. See also the 'accept' parameter.\n\ +\n\ + nodelay=b A boolean indicating if TCP_NODELAY has to be set\n\ + on the proxy link. Old Linux kernels had problems\n\ + with handling TCP_NODELAY on PPP links.\n\ +\n\ + policy=b Let or not the agent decide when it is the best time\n\ + to flush the proxy link. If set to 0, the proxy will\n\ + flush any encoded data immediately. The option has\n\ + only effect on the X client side proxy.\n\ +\n\ + render=b Enable or disable use of the RENDER extension.\n\ +\n\ + taint=b Try to suppress trivial sources of X roundtrips by\n\ + generating the reply on the X client side.\n\ +\n\ + delta=b Enable X differential compression.\n\ +\n\ + data=n Enable or disable the ZLIB data compression. It is\n\ + possible to specify a value between 0 and 9. Usual-\n\ + ly the value is chosen automatically based on the\n\ + requested link setting.\n\ +\n\ + stream=n Enable or disable the ZLIB stream compression. The\n\ + value, between 0 and 9, is usually determined accor-\n\ + ding to the requested link setting.\n\ +\n\ + limit=n Specify a bitrate limit allowed for this session.\n\ +\n\ + memory=n Trigger memory optimizations used to keep small the\n\ + size of X buffers. This is useful on embedded plat-\n\ + forms, or where memory is scarce.\n\ +\n\ + cache=n Size of the in-memory X message cache. Setting the\n\ + value to 0 will disable the memory cache as well\n\ + as the NX differential compression.\n\ +\n\ + images=n Size of the persistent image cache.\n\ +\n\ + shseg=n Enable the use of the MIT-SHM extension between the\n\ + NX client proxy and the real X server. A value greater\n\ + than 1 is assumed to be the size of requested shared\n\ + memory segment. By default, the size of the segment is\n\ + determined based on the size of the in-memory cache.\n\ +\n\ + load=b Enable loading a persistent X message cache at the\n\ + proxy startup.\n\ +\n\ + save=b Enable saving a persistent X message cache at the\n\ + end of session.\n\ +\n\ + cups=n Enable or disable forwarding of CUPS connections,\n\ + by listening on the optional port 'n'.\n\ +\n\ + aux=n Enable or disable forwarding of the auxiliary X chan-\n\ + nel used for controlling the keyboard. The 'keybd=n'\n\ + form is accepted for backward compatibility.\n\ +\n\ + smb=n Enable or disable forwarding of SMB connections. The\n\ + 'samba=n' form is accepted for backward compatibility.\n\ +\n\ + media=n Enable forwarding of audio connections.\n\ +\n\ + http=n Enable forwarding of HTTP connections.\n\ +\n\ + font=n Enable forwarding of reversed connections to a font\n\ + server running on the NX server.\n\ +\n\ + file=n Enable forwarding of file transfer connections.\n\ +\n\ + mask=n Determine the distribution of channel ids between the\n\ + proxies. By default, channels whose ids are multiple\n\ + of 8 (starting from 0) are reserved for the NX client\n\ + side. All the other channels can be allocated by the\n\ + NX server side.\n\ +\n\ + timeout=t Specify the keep-alive timeout used by proxies to\n\ + determine if there is a network problem preventing\n\ + communication with the remote peer. A value of 0\n\ + disables the check.\n\ +\n\ + cleanup=t Specify the number of seconds the proxy has to wait\n\ + at session shutdown before closing all channels.\n\ + The feature is used by the NX server to ensure that\n\ + services are disconnected before shutting down the\n\ + link.\n\ +\n\ + pack=s Determine the method used to compress images.\n\ +\n\ + product=s The product id of the client or server. The value is\n\ + ignored by the proxy, but the client or server can\n\ + provide it to facilitate the support.\n\ +\n\ + core=b Enable production of core dumps when aborting the\n\ + proxy connection.\n\ +\n\ + options=s Specify an additional file containing options that\n\ + has to be merged with option read from the command\n\ + line or the environment.\n\ +\n\ + kill=n Add the given process to the list of daemons that\n\ + must be terminated at session shutdown. Multiple\n\ + 'kill=n' options can be specified. The proxy will\n\ + send them a SIGTERM signal just before exiting.\n\ +\n\ + strict=b Optimize for responsiveness, rather than for the best\n\ + use of all the available bandwidth.\n\ +\n\ + encryption=b Should be set to 1 if the proxy is running as part of\n\ + a program providing encryption of the point to point\n\ + communication.\n\ +\n\ +rootless=b\n\ +geometry=s\n\ +resize=b\n\ +fullscreen=b\n\ +keyboard=s\n\ +clipboard=s\n\ +streaming=n\n\ +backingstore=n\n\ +composite=n\n\ +xinerama=n\n\ +shmem=b\n\ +shpix=b\n\ +kbtype=s\n\ +client=s\n\ +shadow=n\n\ +shadowuid=n\n\ +shadowmode=s\n\ +defer=n\n\ +tile=s\n\ +menu=n\n\ +sleep=n\n\ +tolerancechecks=s\n\ + These options are interpreted by the NX agent. They\n\ + are ignored by the proxy.\n\ +\n\ + Environment:\n\ +\n\ + NX_ROOT The root NX directory is the place where the session\n\ + directory and the cache files are created. This is\n\ + usually overridden by passing the 'root=' option. By\n\ + default, the root NX directory is assumed to be the\n\ + directory '.nx' in the user's home.\n\ +\n\ + NX_SYSTEM The directory where NX programs and libraries reside.\n\ + If not set, the value is assumed to be '/usr/NX'.\n\ + Programs, libraries and data files are respectedly\n\ + searched in the 'bin', 'lib' and 'share' subdirecto-\n\ + ries.\n\ +\n\ + NX_HOME The NX user's home directory. If NX_ROOT is not set\n\ + or invalid, the user's NX directory is created here.\n\ +\n\ + NX_TEMP The directory where the X11 Unix Domain Sockets and\n\ + all temporary files are to be created.\n\ +\n\ + NX_CLIENT The full path to the nxclient executable. If the va-\n\ + riable is not set, the nxclient executable will be\n\ + run assuming that the program is in the system path.\n\ + This can be useful on platforms like Windows and the\n\ + Mac where nxclient is located in a different direct-\n\ + ory compared to the other programs, to make easier\n\ + for the user to execute the program from the shell.\n\ +\n\ + NX_SLAVE_CMD The full path to the slave channel handler. When the\n\ + slave channel is enabled, the agent will listen on a\n\ + port and forward the connection to the NX_SLAVE_CMD\n\ + program. This can be used to implement agent/proxy\n\ + communication for applications such as serial port and\n\ + USB forwarding.\n\ +\n\ + Shell environment:\n\ +\n\ + HOME The variable is checked in the case NX_HOME is not\n\ + set, null or invalid.\n\ +\n\ + TEMP The variable is checked whenever the NX_TEMP direct-\n\ + ory is not set, null or invalid.\n\ +\n\ + PATH The path where all executables are searched, except\n\ + nxclient. If NX_CLIENT is not set, also the client\n\ + executable is searched in the system path.\n\ +\n\ + LD_LIBRARY_PATH\n\ + System-wide library search order. This should be set\n\ + by the program invoking the proxy.\n\ +\n\ + DISPLAY On the X server side, the DISPLAY variable indicates\n\ + the location of the X11 server. When nxcomp is used\n\ + as a transport library, the DISPLAY may represent a\n\ + NX transport specification and options can passed in\n\ + the form nx/nx,option=value...\n\ +\n\ + XAUTHORITY This is the file containing the X11 authorization\n\ + cookie. If not set, the file is assumed to be in\n\ + the user's home (either NX_HOME or HOME).\n\ +\n\ +"; + +const char *GetUsageInfo() +{ + return UsageInfo; +} + +static const char CopyrightInfo[] = +"\ +Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com)\n\ +Copyright (c) 2008-2014 Oleksandr Shneyder \n\ +Copyright (c) 2014-2016 Ulrich Sibiller \n\ +Copyright (c) 2014-2016 Mihai Moldovan \n\ +Copyright (c) 2011-2016 Mike Gabriel \n\ +Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com)\n\ +\n\ +NXCOMP, NX protocol compression and NX extensions to this software\n\ +are copyright of the aforementioned persons and companies.\n\ +\n\ +Redistribution and use of the present software is allowed according\n\ +to terms specified in the file LICENSE.nxcomp which comes in the\n\ +source distribution.\n\ +\n\ +All rights reserved.\n\ +\n\ +NOTE: This software has received contributions from various other\n\ +contributors, only the core maintainers and supporters are listed as\n\ +copyright holders. Please contact us, if you feel you should be listed\n\ +as copyright holder, as well.\n\ +"; + +const char *GetCopyrightInfo() +{ + return CopyrightInfo; +} + +static const char OtherCopyrightInfo[] = +"\ +NX protocol compression is derived from DXPC project.\n\ +\n\ +Copyright (c) 1995,1996 Brian Pane\n\ +Copyright (c) 1996,1997 Zachary Vonler and Brian Pane\n\ +Copyright (c) 1999 Kevin Vigor and Brian Pane\n\ +Copyright (c) 2000,2003 Gian Filippo Pinzari and Brian Pane\n\ +\n\ +All rights reserved.\n\ +"; + +const char *GetOtherCopyrightInfo() +{ + return OtherCopyrightInfo; +} + +int _hostBigEndian = 0; +int _storeBigEndian = 0; + +const unsigned int IntMask[33] = +{ + 0x00000000, + 0x00000001, + 0x00000003, + 0x00000007, + 0x0000000f, + 0x0000001f, + 0x0000003f, + 0x0000007f, + 0x000000ff, + 0x000001ff, + 0x000003ff, + 0x000007ff, + 0x00000fff, + 0x00001fff, + 0x00003fff, + 0x00007fff, + 0x0000ffff, + 0x0001ffff, + 0x0003ffff, + 0x0007ffff, + 0x000fffff, + 0x001fffff, + 0x003fffff, + 0x007fffff, + 0x00ffffff, + 0x01ffffff, + 0x03ffffff, + 0x07ffffff, + 0x0fffffff, + 0x1fffffff, + 0x3fffffff, + 0x7fffffff, + 0xffffffff +}; + +unsigned int GetUINT(unsigned const char *buffer, int bigEndian) +{ + // + // It doesn't work on SPARCs if the buffer + // is not aligned to the word boundary. We + // should check the CPU, not the OS as this + // surely applies to other architectures. + // + + #ifndef __sun + + if (_hostBigEndian == bigEndian) + { + return *((unsigned short *) buffer); + } + + #else + + if (_hostBigEndian == bigEndian && ((unsigned int) buffer) & 0x1 == 0) + { + return *((unsigned short *) buffer); + } + + #endif + + unsigned int result; + + if (bigEndian) + { + result = *buffer; + + result <<= 8; + + result += buffer[1]; + } + else + { + result = buffer[1]; + + result <<= 8; + + result += *buffer; + } + + return result; +} + +unsigned int GetULONG(unsigned const char *buffer, int bigEndian) +{ + // + // It doesn't work on SPARCs if the buffer + // is not aligned to word the boundary. + // + + #ifndef __sun + + if (_hostBigEndian == bigEndian) + { + return *((unsigned int *) buffer); + } + + #else + + if (_hostBigEndian == bigEndian && ((unsigned int) buffer) & 0x3 == 0) + { + return *((unsigned int *) buffer); + } + + #endif + + const unsigned char *next = (bigEndian ? buffer : buffer + 3); + + unsigned int result = 0; + + for (int i = 0; i < 4; i++) + { + result <<= 8; + + result += *next; + + if (bigEndian) + { + next++; + } + else + { + next--; + } + } + + return result; +} + +void PutUINT(unsigned int value, unsigned char *buffer, int bigEndian) +{ + if (_hostBigEndian == bigEndian) + { + *((unsigned short *) buffer) = value; + + return; + } + + if (bigEndian) + { + buffer[1] = (unsigned char) (value & 0xff); + + value >>= 8; + + *buffer = (unsigned char) value; + } + else + { + *buffer = (unsigned char) (value & 0xff); + + value >>= 8; + + buffer[1] = (unsigned char) value; + } +} + +void PutULONG(unsigned int value, unsigned char *buffer, int bigEndian) +{ + if (_hostBigEndian == bigEndian) + { + *((unsigned int *) buffer) = value; + + return; + } + + if (bigEndian) + { + buffer += 3; + + for (int i = 4; i > 0; i--) + { + *buffer-- = (unsigned char) (value & 0xff); + + value >>= 8; + } + } + else + { + for (int i = 4; i > 0; i--) + { + *buffer++ = (unsigned char) (value & 0xff); + + value >>= 8; + } + } +} + +int CheckData(istream *fs) +{ + if (fs == NULL || fs -> fail()) + { + return -1; + } + + return 1; +} + +int CheckData(ostream *fs) +{ + if (fs == NULL || fs -> fail()) + { + return -1; + } + + return 1; +} + +int PutData(ostream *fs, const unsigned char *buffer, int size) +{ + fs -> write((char *) buffer, size); + + #ifdef DEBUG + *logofs << "PutData: Written " << size << " bytes with eof " + << fs -> eof() << " fail " << fs -> fail() << " and bad " + << fs -> bad() << ".\n" << logofs_flush; + #endif + + if (fs -> fail()) + { + return -1; + } + + return size; +} + +int GetData(istream *fs, unsigned char *buffer, int size) +{ + fs -> read((char *) buffer, size); + + #ifdef DEBUG + *logofs << "GetData: Read " << size << " bytes with eof " + << fs -> eof() << " fail " << fs -> fail() + << " and bad " << fs -> bad() << ".\n" + << logofs_flush; + #endif + + #ifdef __APPLE__ + + if (fs -> bad()) + { + return -1; + } + + #else + + if (fs -> fail()) + { + return -1; + } + + #endif + + return size; +} + +int FlushData(ostream *fs) +{ + fs -> flush(); + + if (fs -> fail()) + { + return -1; + } + + return 1; +} + +unsigned int RoundUp2(unsigned int x) +{ + unsigned int y = x / 2; + + y *= 2; + + if (y != x) + { + y += 2; + } + + return y; +} + +unsigned int RoundUp4(unsigned int x) +{ + unsigned int y = x / 4; + + y *= 4; + + if (y != x) + { + y += 4; + } + + return y; +} + +unsigned int RoundUp8(unsigned int x) +{ + unsigned int y = x / 8; + + y *= 8; + + if (y != x) + { + y += 8; + } + + return y; +} + +const char *DumpSignal(int signal) +{ + switch (signal) + { + case SIGCHLD: + { + return "SIGCHLD"; + } + case SIGUSR1: + { + return "SIGUSR1"; + } + case SIGUSR2: + { + return "SIGUSR2"; + } + case SIGHUP: + { + return "SIGHUP"; + } + case SIGINT: + { + return "SIGINT"; + } + case SIGTERM: + { + return "SIGTERM"; + } + case SIGPIPE: + { + return "SIGPIPE"; + } + case SIGALRM: + { + return "SIGALRM"; + } + case SIGVTALRM: + { + return "SIGVTALRM"; + } + case SIGWINCH: + { + return "SIGWINCH"; + } + case SIGIO: + { + return "SIGIO"; + } + case SIGTSTP: + { + return "SIGTSTP"; + } + case SIGTTIN: + { + return "SIGTTIN"; + } + case SIGTTOU: + { + return "SIGTTOU"; + } + case SIGSEGV: + { + return "SIGSEGV"; + } + case SIGABRT: + { + return "SIGABRT"; + } + default: + { + return "Unknown"; + } + } +} + +const char *DumpPolicy(int type) +{ + switch ((T_flush_policy) type) + { + case policy_immediate: + { + return "immediate"; + } + case policy_deferred: + { + return "deferred"; + } + default: + { + #ifdef PANIC + *logofs << "Misc: PANIC! Unknown policy type '" + << type << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unknown policy type '" + << type << "'.\n"; + + HandleCleanup(); + } + } +} + +const char *DumpAction(int type) +{ + T_store_action action = (T_store_action) type; + + if (action == IS_HIT) + { + return "is_hit"; + } + else if (action == IS_ADDED) + { + return "is_added"; + } + else if (action == is_discarded) + { + return "is_discarded"; + } + else if (action == is_removed) + { + return "is_removed"; + } + else + { + #ifdef PANIC + *logofs << "Misc: PANIC! Unknown store action '" + << type << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unknown store action '" + << type << "'.\n"; + + HandleCleanup(); + } +} + +const char *DumpState(int type) +{ + switch ((T_split_state) type) + { + case split_added: + { + return "split_added"; + } + case split_missed: + { + return "split_missed"; + } + case split_loaded: + { + return "split_loaded"; + } + case split_aborted: + { + return "split_aborted"; + } + case split_notified: + { + return "split_notified"; + } + default: + { + #ifdef PANIC + *logofs << "Misc: PANIC! Unknown split state '" + << type << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unknown split state '" + << type << "'.\n"; + + HandleCleanup(); + } + } +} + +const char *DumpControl(int code) +{ + switch ((T_proxy_code) code) + { + case code_new_x_connection: + { + return "code_new_x_connection"; + } + case code_new_cups_connection: + { + return "code_new_cups_connection"; + } + case code_new_aux_connection: + { + return "code_new_aux_connection"; + } + case code_new_smb_connection: + { + return "code_new_smb_connection"; + } + case code_new_media_connection: + { + return "code_new_media_connection"; + } + case code_switch_connection: + { + return "code_switch_connection"; + } + case code_drop_connection: + { + return "code_drop_connection"; + } + case code_finish_connection: + { + return "code_finish_connection"; + } + case code_begin_congestion: + { + return "code_begin_congestion"; + } + case code_end_congestion: + { + return "code_end_congestion"; + } + case code_alert_request: + { + return "code_alert_request"; + } + case code_alert_reply: + { + return "code_alert_reply"; + } + case code_reset_request: + { + return "code_reset_request"; + } + case code_reset_reply: + { + return "code_reset_reply"; + } + case code_load_request: + { + return "code_load_request"; + } + case code_load_reply: + { + return "code_load_reply"; + } + case code_save_request: + { + return "code_save_request"; + } + case code_save_reply: + { + return "code_save_reply"; + } + case code_shutdown_request: + { + return "code_shutdown_request"; + } + case code_shutdown_reply: + { + return "code_shutdown_reply"; + } + case code_control_token_request: + { + return "code_control_token_request"; + } + case code_control_token_reply: + { + return "code_control_token_reply"; + } + case code_configuration_request: + { + return "code_configuration_request"; + } + case code_configuration_reply: + { + return "code_configuration_reply"; + } + case code_statistics_request: + { + return "code_statistics_request"; + } + case code_statistics_reply: + { + return "code_statistics_reply"; + } + case code_new_http_connection: + { + return "code_new_http_connection"; + } + case code_sync_request: + { + return "code_sync_request"; + } + case code_sync_reply: + { + return "code_sync_reply"; + } + case code_new_font_connection: + { + return "code_new_font_connection"; + } + case code_new_slave_connection: + { + return "code_new_slave_connection"; + } + case code_finish_listeners: + { + return "code_finish_listeners"; + } + case code_split_token_request: + { + return "code_split_token_request"; + } + case code_split_token_reply: + { + return "code_split_token_reply"; + } + case code_data_token_request: + { + return "code_data_token_request"; + } + case code_data_token_reply: + { + return "code_data_token_reply"; + } + default: + { + #ifdef WARNING + *logofs << "Misc: WARNING! Unknown control code '" + << code << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Unknown control code '" + << code << "'.\n"; + + return "unknown"; + } + } +} + +const char *DumpSession(int code) +{ + switch ((T_session_mode) code) + { + case session_agent: + { + return "session_agent"; + } + case session_shadow: + { + return "session_shadow"; + } + case session_proxy: + { + return "session_proxy"; + } + default: + { + #ifdef WARNING + *logofs << "Misc: WARNING! Unknown session type '" + << code << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Unknown session type '" + << code << "'.\n"; + + return "unknown"; + } + } +} + +const char *DumpToken(int type) +{ + switch ((T_token_type) type) + { + case token_control: + { + return "token_control"; + } + case token_split: + { + return "token_split"; + } + case token_data: + { + return "token_data"; + } + default: + { + #ifdef WARNING + *logofs << "Misc: WARNING! Unknown token type '" + << type << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Unknown token type '" + << type << "'.\n"; + + return "unknown"; + } + } +} + +// +// Always include this in code as it is generally +// needed to test channels and split store. +// + +const char *DumpChecksum(const void *checksum) +{ + static char string[MD5_LENGTH * 2 + 1]; + + if (checksum != NULL) + { + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + sprintf(string + (i * 2), "%02X", ((unsigned char *) checksum)[i]); + } + } + else + { + strcpy(string, "null"); + } + + return string; +} + +// +// Define OPCODES here and in the channel +// if you want to log the opcode literal. +// + +#ifdef OPCODES + +const char *DumpOpcode(const int &opcode) +{ + switch (opcode) + { + case X_CreateWindow: + { + return "X_CreateWindow"; + } + case X_ChangeWindowAttributes: + { + return "X_ChangeWindowAttributes"; + } + case X_GetWindowAttributes: + { + return "X_GetWindowAttributes"; + } + case X_DestroyWindow: + { + return "X_DestroyWindow"; + } + case X_DestroySubwindows: + { + return "X_DestroySubwindows"; + } + case X_ChangeSaveSet: + { + return "X_ChangeSaveSet"; + } + case X_ReparentWindow: + { + return "X_ReparentWindow"; + } + case X_MapWindow: + { + return "X_MapWindow"; + } + case X_MapSubwindows: + { + return "X_MapSubwindows"; + } + case X_UnmapWindow: + { + return "X_UnmapWindow"; + } + case X_UnmapSubwindows: + { + return "X_UnmapSubwindows"; + } + case X_ConfigureWindow: + { + return "X_ConfigureWindow"; + } + case X_CirculateWindow: + { + return "X_CirculateWindow"; + } + case X_GetGeometry: + { + return "X_GetGeometry"; + } + case X_QueryTree: + { + return "X_QueryTree"; + } + case X_InternAtom: + { + return "X_InternAtom"; + } + case X_GetAtomName: + { + return "X_GetAtomName"; + } + case X_ChangeProperty: + { + return "X_ChangeProperty"; + } + case X_DeleteProperty: + { + return "X_DeleteProperty"; + } + case X_GetProperty: + { + return "X_GetProperty"; + } + case X_ListProperties: + { + return "X_ListProperties"; + } + case X_SetSelectionOwner: + { + return "X_SetSelectionOwner"; + } + case X_GetSelectionOwner: + { + return "X_GetSelectionOwner"; + } + case X_ConvertSelection: + { + return "X_ConvertSelection"; + } + case X_SendEvent: + { + return "X_SendEvent"; + } + case X_GrabPointer: + { + return "X_GrabPointer"; + } + case X_UngrabPointer: + { + return "X_UngrabPointer"; + } + case X_GrabButton: + { + return "X_GrabButton"; + } + case X_UngrabButton: + { + return "X_UngrabButton"; + } + case X_ChangeActivePointerGrab: + { + return "X_ChangeActivePointerGrab"; + } + case X_GrabKeyboard: + { + return "X_GrabKeyboard"; + } + case X_UngrabKeyboard: + { + return "X_UngrabKeyboard"; + } + case X_GrabKey: + { + return "X_GrabKey"; + } + case X_UngrabKey: + { + return "X_UngrabKey"; + } + case X_AllowEvents: + { + return "X_AllowEvents"; + } + case X_GrabServer: + { + return "X_GrabServer"; + } + case X_UngrabServer: + { + return "X_UngrabServer"; + } + case X_QueryPointer: + { + return "X_QueryPointer"; + } + case X_GetMotionEvents: + { + return "X_GetMotionEvents"; + } + case X_TranslateCoords: + { + return "X_TranslateCoords"; + } + case X_WarpPointer: + { + return "X_WarpPointer"; + } + case X_SetInputFocus: + { + return "X_SetInputFocus"; + } + case X_GetInputFocus: + { + return "X_GetInputFocus"; + } + case X_QueryKeymap: + { + return "X_QueryKeymap"; + } + case X_OpenFont: + { + return "X_OpenFont"; + } + case X_CloseFont: + { + return "X_CloseFont"; + } + case X_QueryFont: + { + return "X_QueryFont"; + } + case X_QueryTextExtents: + { + return "X_QueryTextExtents"; + } + case X_ListFonts: + { + return "X_ListFonts"; + } + case X_ListFontsWithInfo: + { + return "X_ListFontsWithInfo"; + } + case X_SetFontPath: + { + return "X_SetFontPath"; + } + case X_GetFontPath: + { + return "X_GetFontPath"; + } + case X_CreatePixmap: + { + return "X_CreatePixmap"; + } + case X_FreePixmap: + { + return "X_FreePixmap"; + } + case X_CreateGC: + { + return "X_CreateGC"; + } + case X_ChangeGC: + { + return "X_ChangeGC"; + } + case X_CopyGC: + { + return "X_CopyGC"; + } + case X_SetDashes: + { + return "X_SetDashes"; + } + case X_SetClipRectangles: + { + return "X_SetClipRectangles"; + } + case X_FreeGC: + { + return "X_FreeGC"; + } + case X_ClearArea: + { + return "X_ClearArea"; + } + case X_CopyArea: + { + return "X_CopyArea"; + } + case X_CopyPlane: + { + return "X_CopyPlane"; + } + case X_PolyPoint: + { + return "X_PolyPoint"; + } + case X_PolyLine: + { + return "X_PolyLine"; + } + case X_PolySegment: + { + return "X_PolySegment"; + } + case X_PolyRectangle: + { + return "X_PolyRectangle"; + } + case X_PolyArc: + { + return "X_PolyArc"; + } + case X_FillPoly: + { + return "X_FillPoly"; + } + case X_PolyFillRectangle: + { + return "X_PolyFillRectangle"; + } + case X_PolyFillArc: + { + return "X_PolyFillArc"; + } + case X_PutImage: + { + return "X_PutImage"; + } + case X_GetImage: + { + return "X_GetImage"; + } + case X_PolyText8: + { + return "X_PolyText8"; + } + case X_PolyText16: + { + return "X_PolyText16"; + } + case X_ImageText8: + { + return "X_ImageText8"; + } + case X_ImageText16: + { + return "X_ImageText16"; + } + case X_CreateColormap: + { + return "X_CreateColormap"; + } + case X_FreeColormap: + { + return "X_FreeColormap"; + } + case X_CopyColormapAndFree: + { + return "X_CopyColormapAndFree"; + } + case X_InstallColormap: + { + return "X_InstallColormap"; + } + case X_UninstallColormap: + { + return "X_UninstallColormap"; + } + case X_ListInstalledColormaps: + { + return "X_ListInstalledColormaps"; + } + case X_AllocColor: + { + return "X_AllocColor"; + } + case X_AllocNamedColor: + { + return "X_AllocNamedColor"; + } + case X_AllocColorCells: + { + return "X_AllocColorCells"; + } + case X_AllocColorPlanes: + { + return "X_AllocColorPlanes"; + } + case X_FreeColors: + { + return "X_FreeColors"; + } + case X_StoreColors: + { + return "X_StoreColors"; + } + case X_StoreNamedColor: + { + return "X_StoreNamedColor"; + } + case X_QueryColors: + { + return "X_QueryColors"; + } + case X_LookupColor: + { + return "X_LookupColor"; + } + case X_CreateCursor: + { + return "X_CreateCursor"; + } + case X_CreateGlyphCursor: + { + return "X_CreateGlyphCursor"; + } + case X_FreeCursor: + { + return "X_FreeCursor"; + } + case X_RecolorCursor: + { + return "X_RecolorCursor"; + } + case X_QueryBestSize: + { + return "X_QueryBestSize"; + } + case X_QueryExtension: + { + return "X_QueryExtension"; + } + case X_ListExtensions: + { + return "X_ListExtensions"; + } + case X_ChangeKeyboardMapping: + { + return "X_ChangeKeyboardMapping"; + } + case X_GetKeyboardMapping: + { + return "X_GetKeyboardMapping"; + } + case X_ChangeKeyboardControl: + { + return "X_ChangeKeyboardControl"; + } + case X_GetKeyboardControl: + { + return "X_GetKeyboardControl"; + } + case X_Bell: + { + return "X_Bell"; + } + case X_ChangePointerControl: + { + return "X_ChangePointerControl"; + } + case X_GetPointerControl: + { + return "X_GetPointerControl"; + } + case X_SetScreenSaver: + { + return "X_SetScreenSaver"; + } + case X_GetScreenSaver: + { + return "X_GetScreenSaver"; + } + case X_ChangeHosts: + { + return "X_ChangeHosts"; + } + case X_ListHosts: + { + return "X_ListHosts"; + } + case X_SetAccessControl: + { + return "X_SetAccessControl"; + } + case X_SetCloseDownMode: + { + return "X_SetCloseDownMode"; + } + case X_KillClient: + { + return "X_KillClient"; + } + case X_RotateProperties: + { + return "X_RotateProperties"; + } + case X_ForceScreenSaver: + { + return "X_ForceScreenSaver"; + } + case X_SetPointerMapping: + { + return "X_SetPointerMapping"; + } + case X_GetPointerMapping: + { + return "X_GetPointerMapping"; + } + case X_SetModifierMapping: + { + return "X_SetModifierMapping"; + } + case X_GetModifierMapping: + { + return "X_GetModifierMapping"; + } + case X_NoOperation: + { + return "X_NoOperation"; + } + case X_NXInternalGenericData: + { + return "X_NXInternalGenericData"; + } + // + // case X_NXInternalGenericReply: + // { + // return "X_NXInternalGenericReply"; + // } + // + case X_NXInternalGenericRequest: + { + return "X_NXInternalGenericRequest"; + } + case X_NXInternalShapeExtension: + { + return "X_NXInternalShapeExtension"; + } + case X_NXGetControlParameters: + { + return "X_NXGetControlParameters"; + } + case X_NXGetCleanupParameters: + { + return "X_NXGetCleanupParameters"; + } + case X_NXGetImageParameters: + { + return "X_NXGetImageParameters"; + } + case X_NXGetUnpackParameters: + { + return "X_NXGetUnpackParameters"; + } + case X_NXGetShmemParameters: + { + return "X_NXGetShmemParameters"; + } + case X_NXGetFontParameters: + { + return "X_NXGetFontParameters"; + } + case X_NXSetExposeParameters: + { + return "X_NXSetExposeParameters"; + } + case X_NXSetCacheParameters: + { + return "X_NXSetCacheParameters"; + } + case X_NXStartSplit: + { + return "X_NXStartSplit"; + } + case X_NXEndSplit: + { + return "X_NXEndSplit"; + } + case X_NXSplitData: + { + return "X_NXSplitData"; + } + case X_NXSplitEvent: + { + return "X_NXSplitEvent"; + } + case X_NXCommitSplit: + { + return "X_NXCommitSplit"; + } + case X_NXFinishSplit: + { + return "X_NXFinishSplit"; + } + case X_NXAbortSplit: + { + return "X_NXAbortSplit"; + } + case X_NXFreeSplit: + { + return "X_NXFreeSplit"; + } + case X_NXSetUnpackGeometry: + { + return "X_NXSetUnpackGeometry"; + } + case X_NXSetUnpackColormap: + { + return "X_NXSetUnpackColormap"; + } + case X_NXSetUnpackAlpha: + { + return "X_NXSetUnpackAlpha"; + } + case X_NXPutPackedImage: + { + return "X_NXPutPackedImage"; + } + case X_NXFreeUnpack: + { + return "X_NXFreeUnpack"; + } + default: + { + if (opcode > 127) + { + return "Extension"; + } + else + { + return "?"; + } + } + } +} + +#else /* #ifdef OPCODES */ + +const char *DumpOpcode(const int &opcode) +{ + return "?"; +} + +#endif /* #ifdef OPCODES */ + +void DumpData(const unsigned char *buffer, unsigned int size) +{ + if (buffer != NULL) + { + unsigned int i = 0; + + while (i < size) + { + *logofs << "[" << i << "]\t"; + + for (unsigned int ii = 0; i < size && ii < 8; i++, ii++) + { + *logofs << (unsigned int) (buffer[i]) << "\t"; + } + + *logofs << "\n" << logofs_flush; + } + } +} + +void DumpChecksum(const unsigned char *buffer, unsigned int size) +{ + if (buffer != NULL) + { + md5_byte_t md5_digest[MD5_LENGTH]; + + md5_state_t md5_state; + + md5_init(&md5_state); + + md5_append(&md5_state, buffer, size); + + md5_finish(&md5_state, md5_digest); + + char md5_string[MD5_LENGTH * 2 + 1]; + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + sprintf(md5_string + (i * 2), "%02X", md5_digest[i]); + } + + *logofs << "[" << md5_string << "]" << logofs_flush; + } +} + +void DumpBlockChecksums(const unsigned char *buffer, + unsigned int size, unsigned int block) +{ + for (unsigned int i = 0; i < (size / block); i++) + { + *logofs << "[" << i * block << "]"; + + DumpChecksum(buffer + (i * block), block); + + *logofs << "\n"; + } + + if (size % block > 0) + { + *logofs << "[" << size / block * block << "]"; + + DumpChecksum(buffer + (size / block * block), size % block); + + *logofs << "\n"; + } +} + +void DumpHexData(const unsigned char *buffer, unsigned int size) +{ + char message [65536]; + char ascii [17]; + + unsigned int index = 0; + unsigned int linescan = 0; + unsigned int index_ascii = 0; + + sprintf (message,"\n#### Start Dump Buffer of [%.5d] Bytes ####\n\n",size); + + *logofs << message << logofs_flush; + + // + // "Index 0 1 2 3 4 5 6 7 8 9 a b c d e f Ascii " + // "----- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------" + // "00000 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................" + // + + sprintf (message,"Index 0 1 2 3 4 5 6 7 8 9 a b c d e f Ascii \n"); + *logofs << message << logofs_flush; + sprintf (message,"----- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------\n"); + *logofs << message << logofs_flush; + + index = 0; + + while (index < size) + { + memset (ascii, ' ', sizeof(ascii)); + + ascii[16] = '\0'; + + sprintf (message,"%.5d ", index); + + for (index_ascii = 0, linescan = index; + ((index < (linescan + 16)) && (index < size)); + index++, index_ascii++) + { + if (isprint(buffer [index])) + { + ascii[index_ascii] = buffer [index]; + } + else + { + ascii[index_ascii] = '.'; + } + + sprintf (&message [strlen (message)],"%.2x ", (unsigned char) buffer [index]); + } + + for (linescan = index_ascii; linescan < 16; linescan++) + { + strcat (&message [strlen (message)], " "); + } + + sprintf (&message [strlen (message)]," %s\n", ascii); + + *logofs << message << logofs_flush; + } + + sprintf (message,"\n#### End Dump Buffer ####\n\n"); + + *logofs << message << logofs_flush; +} diff --git a/nxcomp/src/Misc.h b/nxcomp/src/Misc.h new file mode 100644 index 000000000..997630137 --- /dev/null +++ b/nxcomp/src/Misc.h @@ -0,0 +1,279 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Misc_H +#define Misc_H + +#include +#include + +#include +#include + +#ifdef __sun + +#include + +#endif + +using namespace std; + +// +// This is MD5 length. +// + +#define MD5_LENGTH 16 + +// +// Error handling macros. +// + +#define ESET(e) (errno = (e)) +#define EGET() (errno) +#define ESTR() strerror(errno) + +// +// TCP port offset applied to NX port specification. +// + +extern const int DEFAULT_NX_PROXY_PORT_OFFSET; + +// +// Default TCP port used by client proxy to listen +// to X clients and by server proxy to connect to +// remote. +// + +extern const int DEFAULT_NX_PROXY_PORT; + +// +// Default X display number that client +// proxy imitates. +// + +extern const int DEFAULT_NX_X_PORT; + +// +// Establish the port offsets for the additional +// services. +// + +extern const int DEFAULT_NX_CUPS_PORT_OFFSET; +extern const int DEFAULT_NX_SMB_PORT_OFFSET; +extern const int DEFAULT_NX_MEDIA_PORT_OFFSET; +extern const int DEFAULT_NX_AUX_PORT_OFFSET; +extern const int DEFAULT_NX_HTTP_PORT_OFFSET; +extern const int DEFAULT_NX_FONT_PORT_OFFSET; + +// +// Slave channels can be originated by both sides +// so they need to have different port offsets +// in the case the user runs both proxies on the +// same host. +// + +extern const int DEFAULT_NX_SLAVE_PORT_CLIENT_OFFSET; +extern const int DEFAULT_NX_SLAVE_PORT_SERVER_OFFSET; + +// +// NX proxy binds to all network interfaces by default +// With the -loopback parameter, you can switch +// over to binding to the loopback device only. +// + +extern const int DEFAULT_LOOPBACK_BIND; + +// +// Return strings containing various info. +// + +const char *GetUsageInfo(); +const char *GetCopyrightInfo(); +const char *GetOtherCopyrightInfo(); + +// +// Define this if you want immediate flush of +// the log output. +// + +#define FLUSH_LOGOFS + +// +// Global objects providing shared functions. +// + +class Auth; +class Control; +class Statistics; + +extern Auth *auth; +extern Control *control; +extern Statistics *statistics; + +// +// Log file. +// + +extern ostream *logofs; + +// +// Cleanup code. +// + +void HandleAbort() __attribute__((noreturn)); +void HandleShutdown() __attribute__((noreturn)); + +extern "C" +{ + void HandleCleanup(int code = 0) __attribute__((noreturn)); + void HandleCleanupForReconnect(); +} + +// +// Manage signal handlers. +// + +void DisableSignals(); +void EnableSignals(); + +// +// Manage timers. +// + +void SetTimer(int value); +void ResetTimer(); + +// +// Show a dialog asking the user if he/she +// wants to close the current session. Look +// in the alerts file for the known critical +// events. +// + +void HandleAlert(int code, int local); + +// +// Run the callback registered by the proxy +// or the agent. +// + +void KeeperCallback(); +void FlushCallback(int length); + +// +// Return the string literal corresponding +// the value. +// + +const char *DumpSignal(int signal); +const char *DumpPolicy(int type); +const char *DumpControl(int code); +const char *DumpSession(int code); +const char *DumpAction(int type); +const char *DumpState(int type); +const char *DumpToken(int type); + +// +// Print out content of buffer to log file. +// You need to define DUMP or OPCODES in +// the source to have these compiled. +// + +const char *DumpOpcode(const int &opcode); +const char *DumpChecksum(const void *checksum); + +void DumpData(const unsigned char *data, unsigned int length); +void DumpHexData(const unsigned char *data, unsigned int length); +void DumpChecksum(const unsigned char *data, unsigned int length); +void DumpBlockChecksums(const unsigned char *data, unsigned int length, + unsigned int block); + +// +// Defines logofs_flush as an empty string to +// avoid calling the corresponding ostream's +// flush() function. +// + +#ifdef FLUSH_LOGOFS + +#define logofs_flush "" ; logofs -> flush() + +#else + +#define logofs_flush "" + +#endif + +// +// Is the host where local proxy is running +// big-endian? +// + +extern int _hostBigEndian; +extern int _storeBigEndian; + +inline void setHostBigEndian(int flag) +{ + _hostBigEndian = flag; +} + +inline int hostBigEndian() +{ + return _hostBigEndian; +} + +inline int storeBigEndian() +{ + return _storeBigEndian; +} + +extern const unsigned int IntMask[33]; + +unsigned int GetUINT(unsigned const char *buffer, int bigEndian); +unsigned int GetULONG(unsigned const char *buffer, int bigEndian); +void PutUINT(unsigned int value, unsigned char *buffer, int bigEndian); +void PutULONG(unsigned int value, unsigned char *buffer, int bigEndian); + +inline void CleanData(unsigned char *buffer, int size) +{ + unsigned char *end = buffer + size; + + while (buffer < end) + { + *buffer++ = 0x00; + } +} + +int CheckData(istream *fs); +int CheckData(ostream *fs); +int PutData(ostream *fs, const unsigned char *buffer, int size); +int GetData(istream *fs, unsigned char *buffer, int size); +int FlushData(ostream *fs); + +unsigned int RoundUp2(unsigned int x); +unsigned int RoundUp4(unsigned int x); +unsigned int RoundUp8(unsigned int x); + +#endif /* Misc_H */ diff --git a/nxcomp/src/NXmitshm.h b/nxcomp/src/NXmitshm.h new file mode 100644 index 000000000..939d488fb --- /dev/null +++ b/nxcomp/src/NXmitshm.h @@ -0,0 +1,56 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef NXmitshm_H +#define NXmitshm_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Import opcodes from + * to get rid of weird dependencies from other + * headers of X environment. + */ + +#define X_ShmQueryVersion 0 +#define X_ShmAttach 1 +#define X_ShmDetach 2 +#define X_ShmPutImage 3 +#define X_ShmGetImage 4 +#define X_ShmCreatePixmap 5 + +#define ShmCompletion 0 +#define ShmNumberEvents (ShmCompletion + 1) + +#define BadShmSeg 0 +#define ShmNumberErrors (BadShmSeg + 1) + +#ifdef __cplusplus +} +#endif + +#endif /* NXmitshm_H */ diff --git a/nxcomp/src/NXrender.h b/nxcomp/src/NXrender.h new file mode 100644 index 000000000..280715833 --- /dev/null +++ b/nxcomp/src/NXrender.h @@ -0,0 +1,78 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef NXrender_H +#define NXrender_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Import this from + * to compile under old XFree86 distributions + * when render extension was not present yet. + */ + +#define X_RenderQueryVersion 0 +#define X_RenderQueryPictFormats 1 +#define X_RenderQueryPictIndexValues 2 +#define X_RenderQueryDithers 3 +#define X_RenderCreatePicture 4 +#define X_RenderChangePicture 5 +#define X_RenderSetPictureClipRectangles 6 +#define X_RenderFreePicture 7 +#define X_RenderComposite 8 +#define X_RenderScale 9 +#define X_RenderTrapezoids 10 +#define X_RenderTriangles 11 +#define X_RenderTriStrip 12 +#define X_RenderTriFan 13 +#define X_RenderColorTrapezoids 14 +#define X_RenderColorTriangles 15 +#define X_RenderTransform 16 +#define X_RenderCreateGlyphSet 17 +#define X_RenderReferenceGlyphSet 18 +#define X_RenderFreeGlyphSet 19 +#define X_RenderAddGlyphs 20 +#define X_RenderAddGlyphsFromPicture 21 +#define X_RenderFreeGlyphs 22 +#define X_RenderCompositeGlyphs8 23 +#define X_RenderCompositeGlyphs16 24 +#define X_RenderCompositeGlyphs32 25 +#define X_RenderFillRectangles 26 +/* 0.5 */ +#define X_RenderCreateCursor 27 +/* 0.6 */ +#define X_RenderSetPictureTransform 28 +#define X_RenderQueryFilters 29 +#define X_RenderSetPictureFilter 30 +#define X_RenderCreateAnimCursor 31 + +#ifdef __cplusplus +} +#endif + +#endif /* NXrender_H */ diff --git a/nxcomp/src/OpcodeCache.h b/nxcomp/src/OpcodeCache.h new file mode 100644 index 000000000..e07a1b997 --- /dev/null +++ b/nxcomp/src/OpcodeCache.h @@ -0,0 +1,53 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef OpcodeCache_H +#define OpcodeCache_H + +#include "CharCache.h" + +class OpcodeCache +{ + friend class EncodeBuffer; + friend class DecodeBuffer; + + public: + + OpcodeCache() + { + slot_ = 0; + } + + ~OpcodeCache() + { + } + + private: + + CharCache base_[256]; + unsigned char slot_; +}; + +#endif /* OpcodeCache_H */ diff --git a/nxcomp/src/OpcodeStore.cpp b/nxcomp/src/OpcodeStore.cpp new file mode 100644 index 000000000..21b919c8a --- /dev/null +++ b/nxcomp/src/OpcodeStore.cpp @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "OpcodeStore.h" + +OpcodeStore::OpcodeStore() +{ + // + // Assign values of the specific + // NX opcodes. + // + + getControlParameters = X_NXGetControlParameters; + getCleanupParameters = X_NXGetCleanupParameters; + getImageParameters = X_NXGetImageParameters; + getUnpackParameters = X_NXGetUnpackParameters; + getShmemParameters = X_NXGetShmemParameters; + getFontParameters = X_NXGetFontParameters; + + startSplit = X_NXStartSplit; + endSplit = X_NXEndSplit; + commitSplit = X_NXCommitSplit; + finishSplit = X_NXFinishSplit; + abortSplit = X_NXAbortSplit; + + splitData = X_NXSplitData; + splitEvent = X_NXSplitEvent; + + setCacheParameters = X_NXSetCacheParameters; + setExposeParameters = X_NXSetExposeParameters; + + setUnpackGeometry = X_NXSetUnpackGeometry; + setUnpackColormap = X_NXSetUnpackColormap; + setUnpackAlpha = X_NXSetUnpackAlpha; + + putPackedImage = X_NXPutPackedImage; + + freeUnpack = X_NXFreeUnpack; + freeSplit = X_NXFreeSplit; + + // + // These values must be fetched + // from the X server. + // + + shapeExtension = 0; + renderExtension = 0; + + // + // Events sent as ClientMessage. + // + + noSplitNotify = NXNoSplitNotify; + startSplitNotify = NXStartSplitNotify; + commitSplitNotify = NXCommitSplitNotify; + endSplitNotify = NXEndSplitNotify; + emptySplitNotify = NXEmptySplitNotify; +} + +OpcodeStore::~OpcodeStore() +{ +} diff --git a/nxcomp/src/OpcodeStore.h b/nxcomp/src/OpcodeStore.h new file mode 100644 index 000000000..d041ed4b8 --- /dev/null +++ b/nxcomp/src/OpcodeStore.h @@ -0,0 +1,91 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef OpcodeStore_H +#define OpcodeStore_H + +#include "NXproto.h" + +class OpcodeStore +{ + public: + + OpcodeStore(); + + ~OpcodeStore(); + + // + // Map NX protocol messages. At the moment mapping is hard- + // coded. Opcodes should be instead agreed with the proxied + // X server (by excluding all opcodes used for extensions) + // and exported by the proxy class to channels. + // + // Some toolkits query the server only once for extensions' + // opcodes and share the same settings across all channels. + // This could be a problem as channels needed to monitor the + // traffic to find out the extensions' opcodes themselves, + // so it is important that proxy passes an instance of this + // class to new channels. + // + + unsigned char getControlParameters; + unsigned char getCleanupParameters; + unsigned char getImageParameters; + unsigned char getUnpackParameters; + unsigned char getShmemParameters; + unsigned char getFontParameters; + + unsigned char startSplit; + unsigned char endSplit; + unsigned char commitSplit; + unsigned char finishSplit; + unsigned char abortSplit; + + unsigned char splitData; + unsigned char splitEvent; + + unsigned char setCacheParameters; + unsigned char setExposeParameters; + + unsigned char setUnpackGeometry; + unsigned char setUnpackColormap; + unsigned char setUnpackAlpha; + + unsigned char putPackedImage; + + unsigned char freeUnpack; + unsigned char freeSplit; + + unsigned char shapeExtension; + unsigned char renderExtension; + + unsigned char noSplitNotify; + unsigned char startSplitNotify; + unsigned char commitSplitNotify; + unsigned char endSplitNotify; + unsigned char emptySplitNotify; +}; + +#endif /* OpcodeStore_H */ diff --git a/nxcomp/src/Pack.c b/nxcomp/src/Pack.c new file mode 100644 index 000000000..97fb93b5f --- /dev/null +++ b/nxcomp/src/Pack.c @@ -0,0 +1,180 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "NXpack.h" + +const ColorMask Mask8TrueColor = { 128, 63, 240, 7 }; +const ColorMask Mask64TrueColor = { 192, 7, 240, 4 }; +const ColorMask Mask256TrueColor = { 255, 0, 255, 0 }; +const ColorMask Mask512TrueColor = { 224, 5, 240, 4 }; +const ColorMask Mask4KTrueColor = { 240, 4, 240, 2 }; +const ColorMask Mask32KTrueColor = { 248, 3, 248, 2 }; +const ColorMask Mask64KTrueColor = { 255, 0, 255, 0 }; +const ColorMask Mask256KTrueColor = { 252, 1, 252, 1 }; +const ColorMask Mask2MTrueColor = { 255, 0, 254, 1 }; +const ColorMask Mask16MTrueColor = { 255, 0, 255, 0 }; + +const ColorMask *MethodColorMask(unsigned int method) +{ + switch (method) + { + case MASK_8_COLORS: + { + return &Mask8TrueColor; + } + case MASK_64_COLORS: + { + return &Mask64TrueColor; + } + case MASK_256_COLORS: + { + return &Mask256TrueColor; + } + case MASK_512_COLORS: + { + return &Mask512TrueColor; + } + case MASK_4K_COLORS: + { + return &Mask4KTrueColor; + } + case MASK_32K_COLORS: + { + return &Mask32KTrueColor; + } + case MASK_64K_COLORS: + { + return &Mask64KTrueColor; + } + case MASK_256K_COLORS: + { + return &Mask256KTrueColor; + } + case MASK_2M_COLORS: + { + return &Mask2MTrueColor; + } + case MASK_16M_COLORS: + { + return &Mask16MTrueColor; + } + default: + { + return NULL; + } + } +} + +int MethodBitsPerPixel(unsigned int method) +{ + switch (method) + { + case PACK_MASKED_8_COLORS: + case PACK_JPEG_8_COLORS: + case PACK_PNG_8_COLORS: + { + return 8; + } + case PACK_MASKED_64_COLORS: + case PACK_JPEG_64_COLORS: + case PACK_PNG_64_COLORS: + { + return 8; + } + case PACK_MASKED_256_COLORS: + case PACK_JPEG_256_COLORS: + case PACK_PNG_256_COLORS: + { + return 8; + } + case PACK_MASKED_512_COLORS: + case PACK_JPEG_512_COLORS: + case PACK_PNG_512_COLORS: + { + return 16; + } + case PACK_MASKED_4K_COLORS: + case PACK_JPEG_4K_COLORS: + case PACK_PNG_4K_COLORS: + { + return 16; + } + case PACK_MASKED_32K_COLORS: + case PACK_JPEG_32K_COLORS: + case PACK_PNG_32K_COLORS: + { + return 16; + } + case PACK_MASKED_64K_COLORS: + case PACK_JPEG_64K_COLORS: + case PACK_PNG_64K_COLORS: + { + return 16; + } + case PACK_MASKED_256K_COLORS: + case PACK_JPEG_256K_COLORS: + case PACK_PNG_256K_COLORS: + { + return 24; + } + case PACK_MASKED_2M_COLORS: + case PACK_JPEG_2M_COLORS: + case PACK_PNG_2M_COLORS: + { + return 24; + } + case PACK_MASKED_16M_COLORS: + case PACK_JPEG_16M_COLORS: + case PACK_PNG_16M_COLORS: + { + return 24; + } + case PACK_BITMAP_16M_COLORS: + case PACK_RGB_16M_COLORS: + case PACK_RLE_16M_COLORS: + { + return 24; + } + default: + { + return 0; + } + } +} + +#ifdef __cplusplus +} +#endif diff --git a/nxcomp/src/Pgn.cpp b/nxcomp/src/Pgn.cpp new file mode 100644 index 000000000..649227f52 --- /dev/null +++ b/nxcomp/src/Pgn.cpp @@ -0,0 +1,809 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// This file obviously supports PNG +// decompression. It was renamed to +// avoid name clashes on Windows. +// + +#include + +#ifdef ANDROID +#include +#endif +#include +#include +#include + +#include "Unpack.h" +#include "Pgn.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#define RGB24_TO_PIXEL(bpp,r,g,b) \ + ((((CARD##bpp)(r) & 0xFF) * srcRedMax2 + 127) / 255 \ + << srcRedShift2 | \ + (((CARD##bpp)(g) & 0xFF) * srcGreenMax2 + 127) / 255 \ + << srcGreenShift2 | \ + (((CARD##bpp)(b) & 0xFF) * srcBlueMax2 + 127) / 255 \ + << srcBlueShift2) + +#define RGB24_TO_PIXEL32(r,g,b) \ + (((CARD32)(r) & 0xFF) << srcRedShift2 | \ + ((CARD32)(g) & 0xFF) << srcGreenShift2 | \ + ((CARD32)(b) & 0xFF) << srcBlueShift2) + +// +// Functions from Unpack.cpp +// + +extern int Unpack32To32(const T_colormask *colormask, const unsigned int *data, + unsigned int *out, unsigned int *end); + +extern int Unpack24To24(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +extern int Unpack16To16(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +// +// Local functions used for the png decompression. +// + +static int DecompressPng16(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, + int byteOrder); + +static int DecompressPng24(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, + int byteOrder); + +static int DecompressPng32(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, + int byteOrder); + +static void PngReadData(png_structp png_ptr, png_bytep data, png_size_t length); + +// +// Colormap stuff. +// + +CARD16 srcRedMax2, srcGreenMax2, srcBlueMax2; +CARD8 srcRedShift2, srcGreenShift2, srcBlueShift2; + +// +// Attributes used for the png decompression. +// + +static char *tmpBuf; +static int tmpBufSize = 0; +static int streamPos; + +int UnpackPng(T_geometry *geometry, unsigned char method, unsigned char *srcData, + int srcSize, int dstBpp, int dstWidth, int dstHeight, + unsigned char *dstData, int dstSize) +{ + int byteOrder = geometry -> image_byte_order; + + // + // Check if data is coming from a failed unsplit. + // + + if (srcSize < 2 || (srcData[0] == SPLIT_PATTERN && + srcData[1] == SPLIT_PATTERN)) + { + #ifdef WARNING + *logofs << "UnpackPng: WARNING! Skipping unpack of dummy data.\n" + << logofs_flush; + #endif + + return -1; + } + + #ifdef DEBUG + *logofs << "UnpackPng: Decompressing image with " + << "srcSize " << srcSize << " and bpp " + << dstBpp << ".\n" << logofs_flush; + #endif + + srcRedShift2 = ffs(geometry -> red_mask) - 1; + srcGreenShift2 = ffs(geometry -> green_mask) - 1; + srcBlueShift2 = ffs(geometry -> blue_mask) - 1; + srcRedMax2 = geometry -> red_mask >> srcRedShift2; + srcGreenMax2 = geometry -> green_mask >> srcGreenShift2; + srcBlueMax2 = geometry -> blue_mask >> srcBlueShift2; + + // + // Make enough space in the temporary + // buffer to have one complete row of + // the image with 3 bytes per pixel. + // + + tmpBufSize = dstWidth * 3; + tmpBuf = new char [tmpBufSize]; + + if (tmpBuf == NULL) + { + #ifdef PANIC + *logofs << "UnpackPng: PANIC! Cannot allocate " + << dstWidth * 3 << " bytes for PNG " + << "decompressed data.\n" << logofs_flush; + #endif + + delete [] tmpBuf; + + return -1; + } + + int result = 1; + + switch (dstBpp) + { + case 8: + { + // + // Simply move the data from srcData to dstData + // taking into consideration the correct padding. + // + + int row; + + unsigned char * dstBuff = dstData; + unsigned char * srcBuff = srcData; + + for (row = 0; row < dstHeight; row++) + { + memcpy(dstBuff, srcBuff, dstWidth ); + + dstBuff += RoundUp4(dstWidth); + srcBuff += dstWidth; + } + } + case 16: + { + result = DecompressPng16(srcData, srcSize, dstWidth, + dstHeight, dstData, byteOrder); + break; + } + case 24: + { + result = DecompressPng24(srcData, srcSize, dstWidth, + dstHeight, dstData, byteOrder); + break; + } + case 32: + { + result = DecompressPng32(srcData, srcSize, dstWidth, + dstHeight, dstData, byteOrder); + break; + } + default: + { + #ifdef PANIC + *logofs << "UnpackPng: PANIC! Error in PNG compression. " + << " Unsupported Bpp value " << dstBpp + << " for the PNG compression" + << ".\n" << logofs_flush; + #endif + + delete [] tmpBuf; + + result = -1; + } + } + + if (result == -1) + { + delete [] tmpBuf; + + return result; + } + + // + // Apply the correction for the brightness + // + + int maskMethod; + + switch (method) + { + case PACK_PNG_8_COLORS: + { + maskMethod = MASK_8_COLORS; + + break; + } + case PACK_PNG_64_COLORS: + { + maskMethod = MASK_64_COLORS; + + break; + } + case PACK_PNG_256_COLORS: + { + maskMethod = MASK_256_COLORS; + + break; + } + case PACK_PNG_512_COLORS: + { + maskMethod = MASK_512_COLORS; + + break; + } + case PACK_PNG_4K_COLORS: + { + maskMethod = MASK_4K_COLORS; + + break; + } + case PACK_PNG_32K_COLORS: + { + maskMethod = MASK_32K_COLORS; + + break; + } + case PACK_PNG_64K_COLORS: + { + maskMethod = MASK_64K_COLORS; + + break; + } + case PACK_PNG_256K_COLORS: + { + maskMethod = MASK_256K_COLORS; + + break; + } + case PACK_PNG_2M_COLORS: + { + maskMethod = MASK_2M_COLORS; + + break; + } + case PACK_PNG_16M_COLORS: + { + maskMethod = MASK_16M_COLORS; + + break; + } + default: + { + #ifdef PANIC + *logofs << "DecompressPng16: PANIC! " + << " No matching decompression method.\n" + << logofs_flush; + #endif + + delete [] tmpBuf; + + return -1; + } + } + + const T_colormask *colorMask = MethodColorMask(maskMethod); + + unsigned char *dstBuff = dstData; + + switch (dstBpp) + { + case 16: + { + Unpack16To16(colorMask, dstBuff, dstBuff, dstBuff + dstSize); + + break; + } + case 24: + { + break; + } + case 32: + { + Unpack32To32(colorMask, (unsigned int *)dstBuff, (unsigned int *)dstBuff, + (unsigned int *)(dstBuff + dstSize)); + break; + } + default: + { + #ifdef PANIC + *logofs << "DecompressPng16: PANIC! " + << " No matching destination bits per plane.\n" + << logofs_flush; + #endif + + delete [] tmpBuf; + + return -1; + } + } + + delete [] tmpBuf; + + return 1; +} + + +// +// Functions that actually do +// the PNG decompression. +// + +int DecompressPng16(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) +{ + unsigned char *data; + unsigned int dx, dy; + + png_structp pngPtr; + png_infop infoPtr; + png_bytep rowPointers; + + + streamPos = 0; + + pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!pngPtr) + { + #ifdef PANIC + *logofs << "DecompressPng16: PANIC! " + << " Failed png_create_read_struct operation" + << ".\n" << logofs_flush; + #endif + + return -1; + } + + infoPtr = png_create_info_struct(pngPtr); + + if (!infoPtr) + { + #ifdef PANIC + *logofs << "DecompressPng16: PANIC! " + << "Failed png_create_info_struct operation" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, NULL, NULL); + + return -1; + } + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng16: PANIC! " + << "Error during IO initialization" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + png_set_read_fn(pngPtr, (void *)compressedData, PngReadData); + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng16: PANIC! " + << "Error during read of PNG header" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + png_read_info(pngPtr, infoPtr); + + if (png_get_color_type(pngPtr, infoPtr) == PNG_COLOR_TYPE_PALETTE) + { + png_set_expand(pngPtr); + } + + // + // data points to dstBuf which is + // already padded correctly for the final + // image to put + // + + data = dstBuf; + rowPointers = (png_byte *) tmpBuf; + + // + // We use setjmp() to save our context. + // The PNG library will call longjmp() + // in case of error. + // + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng16: PANIC! " + << "Error during read of PNG rows" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + unsigned long pixel; + + for (dy = 0; dy < h; dy++) + { + png_read_row(pngPtr, rowPointers, NULL); + + for (dx = 0; dx < w; dx++) + { + pixel = RGB24_TO_PIXEL(16, tmpBuf[dx*3], tmpBuf[dx*3+1], tmpBuf[dx*3+2]); + + // + // Follow the server byte order when arranging data. + // + + if (byteOrder == LSBFirst) + { + data[0] = (unsigned char) (pixel & 0xff); + data[1] = (unsigned char) ((pixel >> 8) & 0xff); + } + else + { + data[1] = (unsigned char) (pixel & 0xff); + data[0] = (unsigned char) ((pixel >> 8) & 0xff); + } + + data += 2; + } + + // + // Move pixelPtr at the beginning of the + // next line. + // + + data = data + (RoundUp4(w * 2) - w * 2); + } + + png_destroy_read_struct(&pngPtr, &infoPtr,NULL); + + #ifdef DEBUG + *logofs << "DecompressPng16: Decompression finished." + << dy << " lines handled.\n" + << logofs_flush; + #endif + + return 1; +} + +int DecompressPng24(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) +{ + static CARD8 *pixelPtr = NULL; + unsigned int dx, dy; + + png_structp pngPtr; + png_infop infoPtr; + png_bytep rowPointers; + + + streamPos = 0; + + pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!pngPtr) + { + #ifdef PANIC + *logofs << "DecompressPng24: PANIC! " + << "Failed png_create_read_struct operation" + << ".\n" << logofs_flush; + #endif + + return -1; + } + + infoPtr = png_create_info_struct(pngPtr); + + if (!infoPtr) + { + #ifdef PANIC + *logofs << "DecompressPng24: PANIC! " + << "Failed png_create_info_struct operation" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, NULL, NULL); + + return -1; + } + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng24: PANIC! " + << "Error during IO initialization" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + png_set_read_fn(pngPtr, (void *)compressedData, PngReadData); + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng24: PANIC! " + << "Error during read of PNG header" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + png_read_info( pngPtr, infoPtr ) ; + + if (png_get_color_type(pngPtr, infoPtr) == PNG_COLOR_TYPE_PALETTE) + { + png_set_expand(pngPtr); + } + + // + // PixelPtr points to dstBuf which is + // already padded correctly for the final + // image to put + // + + pixelPtr = (CARD8 *) dstBuf; + + rowPointers = (png_byte *)tmpBuf; + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng24: PANIC! " + << "Error during read of PNG rows" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + for (dy = 0; dy < h; dy++) + { + png_read_row(pngPtr, rowPointers, NULL); + + for (dx = 0; dx < w; dx++) + { + // + // Follow the server byte order when arranging data. + // + + if (byteOrder == LSBFirst) + { + pixelPtr[0] = tmpBuf[dx * 3]; + pixelPtr[1] = tmpBuf[dx * 3 + 1]; + pixelPtr[2] = tmpBuf[dx * 3 + 2]; + } + else + { + pixelPtr[2] = tmpBuf[dx * 3]; + pixelPtr[1] = tmpBuf[dx * 3 + 1]; + pixelPtr[0] = tmpBuf[dx * 3 + 2]; + } + + pixelPtr += 3; + } + + // + // Go to the next line. + // + + pixelPtr = (CARD8 *) (((char *) pixelPtr) + (RoundUp4(w * 3) - w * 3)); + } + + png_destroy_read_struct(&pngPtr, &infoPtr,NULL); + + #ifdef DEBUG + *logofs << "DecompressPng24: Decompression finished." + << dy << " lines handled.\n" + << logofs_flush; + #endif + + return 1; +} + +int DecompressPng32(unsigned char *compressedData, int compressedLen, + unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder) +{ + unsigned char *data; + + unsigned int dx, dy; + + png_structp pngPtr; + png_infop infoPtr; + png_bytep rowPointers; + + streamPos = 0; + + pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!pngPtr) + { + #ifdef PANIC + *logofs << "DecompressPng32: PANIC! " + << "Failed png_create_read_struct operation" + << ".\n" << logofs_flush; + #endif + + return -1; + } + + infoPtr = png_create_info_struct(pngPtr); + + if (!infoPtr) + { + #ifdef PANIC + *logofs << "DecompressPng32: PANIC! " + << "Failed png_create_info_struct operation." + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, NULL, NULL); + + return -1; + } + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng32: PANIC! " + << "Error during IO initialization" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + png_set_read_fn(pngPtr, (void *)compressedData, PngReadData); + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng32: PANIC! " + << "Error during read of PNG header" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + png_read_info(pngPtr, infoPtr) ; + + + if (png_get_color_type(pngPtr, infoPtr) == PNG_COLOR_TYPE_PALETTE) + { + png_set_expand(pngPtr); + } + + // + // data points to dstBuf which is + // already padded correctly for the final + // image to put + // + + data = dstBuf; + + rowPointers = (png_byte *) tmpBuf; + + if (setjmp(png_jmpbuf(pngPtr))) + { + #ifdef PANIC + *logofs << "DecompressPng32: PANIC! " + << "Error during read of PNG rows" + << ".\n" << logofs_flush; + #endif + + png_destroy_read_struct(&pngPtr, &infoPtr, NULL); + + return -1; + } + + unsigned long pixel; + + int i; + + for (dy = 0; dy < h; dy++) + { + png_read_row(pngPtr, rowPointers, NULL); + + for (dx = 0; dx < w; dx++) + { + pixel = RGB24_TO_PIXEL(32, tmpBuf[dx * 3], tmpBuf[dx * 3 + 1], + tmpBuf[dx * 3 + 2]); + + // + // Follow the server byte order when arranging data. + // + + if (byteOrder == LSBFirst) + { + for (i = 0; i < 4; i++) + { + data[i] = (unsigned char)(pixel & 0xff); + pixel >>= 8; + } + } + else + { + for (i = 3; i >= 0; i--) + { + data[i] = (unsigned char) (pixel & 0xff); + pixel >>= 8; + } + } + + data += 4; + } + } + + png_destroy_read_struct(&pngPtr, &infoPtr,NULL); + + #ifdef DEBUG + *logofs << "DecompressPng32: Decompression finished." + << dy << " lines handled.\n" + << logofs_flush; + #endif + + return 1; +} + +static void PngReadData(png_structp png_ptr, png_bytep data, png_size_t length) +{ + memcpy((char *) data, (char *) png_get_io_ptr(png_ptr) + streamPos, length); + + streamPos += length; +} diff --git a/nxcomp/src/Pgn.h b/nxcomp/src/Pgn.h new file mode 100644 index 000000000..e5ea36715 --- /dev/null +++ b/nxcomp/src/Pgn.h @@ -0,0 +1,42 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Pgn_H +#define Pgn_H + +// +// This file obviously supports PNG +// decompression. It was renamed to +// avoid name clashes on Windows. +// + +#include "Misc.h" +#include "Unpack.h" + +int UnpackPng(T_geometry *geometry, unsigned char method, unsigned char *srcData, + int srcSize, int dstBpp, int dstWidth, int dstHeight, + unsigned char *dstData, int dstSize); + +#endif /* Pgn_H */ diff --git a/nxcomp/src/Pipe.cpp b/nxcomp/src/Pipe.cpp new file mode 100644 index 000000000..4fa149412 --- /dev/null +++ b/nxcomp/src/Pipe.cpp @@ -0,0 +1,433 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "Pipe.h" +#include "Misc.h" +#include "Fork.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +extern void RegisterChild(int child); + +static int Psplit(const char *command, char *parameters[], int limit); + +// +// These are slightly modified versions of popen(3) and pclose(3) +// that don't rely on a shell to be available on the system, so +// that they can also work on Windows. As an additional benefit, +// these functions give up all privileges before running the com- +// mand. Code is taken from the X distribution and, in turn, is +// based on libc from FreeBSD 2.2. +// + +static struct pid +{ + struct pid *next; + FILE *fp; + int self; + +} *pidlist; + +// +// A very unsofisticated attempt to parse the command line and +// split each parameter in distinct strings. This is not going +// to work when dealing with parameters containing spaces, even +// if they are enclosed in quotes. +// + +int Psplit(const char *command, char *parameters[], int limit) +{ + char *line; + char *value; + + int number; + + // + // Preapare the list of parameters. + // + + for (number = 0; number < limit; number++) + { + parameters[number] = NULL; + } + + // + // Copy the command to get rid of the + // const qualifier. + // + + line = new char[strlen(command) + 1]; + + if (line == NULL) + { + goto PsplitError; + } + + strcpy(line, command); + + number = 0; + + value = strtok(line, " "); + + while (value != NULL && number < limit) + { + #ifdef DEBUG + *logofs << "Psplit: Got parameter '" << value + << "'.\n" << logofs_flush; + #endif + + parameters[number] = new char[strlen(value) + 1]; + + if (parameters[number] == NULL) + { + goto PsplitError; + } + + strcpy(parameters[number], value); + + number++; + + // + // If this is the first parameter, then + // copy it in the second position and + // use it as the name of the command. + // + + if (number == 1) + { + parameters[number] = new char[strlen(value) + 1]; + + if (parameters[number] == NULL) + { + goto PsplitError; + } + + strcpy(parameters[number], value); + + number++; + } + + value = strtok(NULL, " "); + } + + // + // Needs at least to have the command itself and + // the first argument, being again the name of + // the command. + // + + if (number < 2) + { + goto PsplitError; + } + + return number; + +PsplitError: + + #ifdef PANIC + *logofs << "Psplit: PANIC! Can't split command line '" + << command << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't split command line '" + << command << "'.\n"; + + delete [] line; + + return -1; +} + +FILE *Popen(char * const parameters[], const char *type) +{ + FILE *iop; + + struct pid *cur; + int pdes[2], pid; + + if (parameters == NULL || type == NULL) + { + return NULL; + } + + if ((*type != 'r' && *type != 'w') || type[1]) + { + return NULL; + } + + if ((cur = (struct pid *) malloc(sizeof(struct pid))) == NULL) + { + return NULL; + } + + if (pipe(pdes) < 0) + { + free(cur); + + return NULL; + } + + // + // Block all signals until command is exited. + // We need to gather information about the + // child in Pclose(). + // + + DisableSignals(); + + switch (pid = Fork()) + { + case -1: + { + // + // Error. + // + + #ifdef PANIC + *logofs << "Popen: PANIC! Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Function fork failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + close(pdes[0]); + close(pdes[1]); + + free(cur); + + return NULL; + } + case 0: + { + // + // Child. + // + + struct passwd *pwent = getpwuid(getuid()); + if (pwent) initgroups(pwent->pw_name,getgid()); + if (setgid(getgid()) == -1) + { + _exit(127); + } + if (setuid(getuid()) == -1) + { + _exit(127); + } + + if (*type == 'r') + { + if (pdes[1] != 1) + { + // + // Set up stdout. + // + + dup2(pdes[1], 1); + close(pdes[1]); + } + + close(pdes[0]); + } + else + { + if (pdes[0] != 0) + { + // + // Set up stdin. + // + + dup2(pdes[0], 0); + close(pdes[0]); + } + + close(pdes[1]); + } + + execvp(parameters[0], parameters + 1); + + exit(127); + } + } + + // + // Parent. Save data about the child. + // + + RegisterChild(pid); + + if (*type == 'r') + { + iop = fdopen(pdes[0], type); + + close(pdes[1]); + } + else + { + iop = fdopen(pdes[1], type); + + close(pdes[0]); + } + + cur -> fp = iop; + cur -> self = pid; + cur -> next = pidlist; + + pidlist = cur; + + #ifdef TEST + *logofs << "Popen: Executing "; + + for (int i = 0; i < 256 && parameters[i] != NULL; i++) + { + *logofs << "[" << parameters[i] << "]"; + } + + *logofs << " with descriptor " << fileno(iop) + << ".\n" << logofs_flush; + #endif + + return iop; +} + +FILE *Popen(const char *command, const char *type) +{ + char *parameters[256]; + + if (Psplit(command, parameters, 256) > 0) + { + FILE *file = Popen(parameters, type); + + for (int i = 0; i < 256; i++) + { + delete [] parameters[i]; + } + + return file; + } + else + { + #ifdef PANIC + *logofs << "Popen: PANIC! Failed to parse command '" + << command << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to parse command '" + << command << "'.\n"; + + return NULL; + } +} + +int Pclose(FILE *iop) +{ + struct pid *cur, *last; + + int pstat; + int pid; + + #ifdef TEST + *logofs << "Pclose: Closing command with output " + << "on descriptor " << fileno(iop) << ".\n" + << logofs_flush; + #endif + + fclose((FILE *) iop); + + for (last = NULL, cur = pidlist; cur; last = cur, cur = cur -> next) + { + if (cur -> fp == iop) + { + break; + } + } + + if (cur == NULL) + { + #ifdef PANIC + *logofs << "Pclose: PANIC! Failed to find the process " + << "for descriptor " << fileno(iop) << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to find the process " + << "for descriptor " << fileno(iop) << ".\n"; + + return -1; + } + + do + { + #ifdef TEST + *logofs << "Pclose: Going to wait for process " + << "with pid '" << cur -> self << "'.\n" + << logofs_flush; + #endif + + pid = waitpid(cur -> self, &pstat, 0); + } + while (pid == -1 && errno == EINTR); + + if (last == NULL) + { + pidlist = cur -> next; + } + else + { + last -> next = cur -> next; + } + + free(cur); + + // + // Child has finished and we called the + // waitpid(). We can enable signals again. + // + + EnableSignals(); + + return (pid == -1 ? -1 : pstat); +} diff --git a/nxcomp/src/Pipe.h b/nxcomp/src/Pipe.h new file mode 100644 index 000000000..fd1061d30 --- /dev/null +++ b/nxcomp/src/Pipe.h @@ -0,0 +1,35 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +// +// These are slightly modified versions of popen(3) and pclose(3) +// that don't rely on a shell to be available on the system, so +// that they can also work on Windows. +// + +extern FILE *Popen(char * const parameters[], const char *type); +extern FILE *Popen(const char *command, const char *type); + +extern int Pclose(FILE *file); diff --git a/nxcomp/src/PolyArc.cpp b/nxcomp/src/PolyArc.cpp new file mode 100644 index 000000000..42dbb265d --- /dev/null +++ b/nxcomp/src/PolyArc.cpp @@ -0,0 +1,162 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PolyArc.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int PolyArcStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyArcMessage *polyArc = (PolyArcMessage *) message; + + // + // Here is the fingerprint. + // + + polyArc -> drawable = GetULONG(buffer + 4, bigEndian); + polyArc -> gcontext = GetULONG(buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PolyArcStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyArcMessage *polyArc = (PolyArcMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(polyArc -> drawable, buffer + 4, bigEndian); + PutULONG(polyArc -> gcontext, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PolyArcStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PolyArcMessage *polyArc = (PolyArcMessage *) message; + + *logofs << name() << ": Identity drawable " << polyArc -> drawable + << ", gcontext " << polyArc -> gcontext + << ", size " << polyArc -> size_ << ".\n" << logofs_flush; + #endif +} + +void PolyArcStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} + +void PolyArcStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + PolyArcMessage *polyArc = (PolyArcMessage *) message; + PolyArcMessage *cachedPolyArc = (PolyArcMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyArc -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyArc -> drawable, clientCache -> drawableCache); + + cachedPolyArc -> drawable = polyArc -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyArc -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyArc -> gcontext, clientCache -> gcCache); + + cachedPolyArc -> gcontext = polyArc -> gcontext; +} + +void PolyArcStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + PolyArcMessage *polyArc = (PolyArcMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + polyArc -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyArc -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + polyArc -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyArc -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/PolyArc.h b/nxcomp/src/PolyArc.h new file mode 100644 index 000000000..d744d6a10 --- /dev/null +++ b/nxcomp/src/PolyArc.h @@ -0,0 +1,185 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PolyArc_H +#define PolyArc_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define POLYARC_ENABLE_CACHE 1 +#define POLYARC_ENABLE_DATA 0 +#define POLYARC_ENABLE_SPLIT 0 +#define POLYARC_ENABLE_COMPRESS 0 + +#define POLYARC_DATA_LIMIT 1980 +#define POLYARC_DATA_OFFSET 12 + +#define POLYARC_CACHE_SLOTS 2000 +#define POLYARC_CACHE_THRESHOLD 2 +#define POLYARC_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class PolyArcMessage : public Message +{ + friend class PolyArcStore; + + public: + + PolyArcMessage() + { + } + + ~PolyArcMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int drawable; + unsigned int gcontext; +}; + +class PolyArcStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PolyArcStore() : MessageStore() + { + enableCache = POLYARC_ENABLE_CACHE; + enableData = POLYARC_ENABLE_DATA; + enableSplit = POLYARC_ENABLE_SPLIT; + enableCompress = POLYARC_ENABLE_COMPRESS; + + dataLimit = POLYARC_DATA_LIMIT; + dataOffset = POLYARC_DATA_OFFSET; + + cacheSlots = POLYARC_CACHE_SLOTS; + cacheThreshold = POLYARC_CACHE_THRESHOLD; + cacheLowerThreshold = POLYARC_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~PolyArcStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "PolyArc"; + } + + virtual unsigned char opcode() const + { + return X_PolyArc; + } + + virtual unsigned int storage() const + { + return sizeof(PolyArcMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new PolyArcMessage(); + } + + virtual Message *create(const Message &message) const + { + return new PolyArcMessage((const PolyArcMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (PolyArcMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PolyArc_H */ diff --git a/nxcomp/src/PolyFillArc.cpp b/nxcomp/src/PolyFillArc.cpp new file mode 100644 index 000000000..35125f0d3 --- /dev/null +++ b/nxcomp/src/PolyFillArc.cpp @@ -0,0 +1,162 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PolyFillArc.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int PolyFillArcStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; + + // + // Here is the fingerprint. + // + + polyFillArc -> drawable = GetULONG(buffer + 4, bigEndian); + polyFillArc -> gcontext = GetULONG(buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PolyFillArcStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(polyFillArc -> drawable, buffer + 4, bigEndian); + PutULONG(polyFillArc -> gcontext, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PolyFillArcStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; + + *logofs << name() << ": Identity drawable " << polyFillArc -> drawable + << ", gcontext " << polyFillArc -> gcontext + << ", size " << polyFillArc -> size_ << ".\n" << logofs_flush; + #endif +} + +void PolyFillArcStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} + +void PolyFillArcStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; + PolyFillArcMessage *cachedPolyFillArc = (PolyFillArcMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyFillArc -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyFillArc -> drawable, clientCache -> drawableCache); + + cachedPolyFillArc -> drawable = polyFillArc -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyFillArc -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyFillArc -> gcontext, clientCache -> gcCache); + + cachedPolyFillArc -> gcontext = polyFillArc -> gcontext; +} + +void PolyFillArcStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + PolyFillArcMessage *polyFillArc = (PolyFillArcMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + polyFillArc -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyFillArc -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + polyFillArc -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyFillArc -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/PolyFillArc.h b/nxcomp/src/PolyFillArc.h new file mode 100644 index 000000000..a4eff5b48 --- /dev/null +++ b/nxcomp/src/PolyFillArc.h @@ -0,0 +1,185 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PolyFillArc_H +#define PolyFillArc_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define POLYFILLARC_ENABLE_CACHE 1 +#define POLYFILLARC_ENABLE_DATA 0 +#define POLYFILLARC_ENABLE_SPLIT 0 +#define POLYFILLARC_ENABLE_COMPRESS 0 + +#define POLYFILLARC_DATA_LIMIT 6144 +#define POLYFILLARC_DATA_OFFSET 12 + +#define POLYFILLARC_CACHE_SLOTS 2000 +#define POLYFILLARC_CACHE_THRESHOLD 2 +#define POLYFILLARC_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class PolyFillArcMessage : public Message +{ + friend class PolyFillArcStore; + + public: + + PolyFillArcMessage() + { + } + + ~PolyFillArcMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int drawable; + unsigned int gcontext; +}; + +class PolyFillArcStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PolyFillArcStore() : MessageStore() + { + enableCache = POLYFILLARC_ENABLE_CACHE; + enableData = POLYFILLARC_ENABLE_DATA; + enableSplit = POLYFILLARC_ENABLE_SPLIT; + enableCompress = POLYFILLARC_ENABLE_COMPRESS; + + dataLimit = POLYFILLARC_DATA_LIMIT; + dataOffset = POLYFILLARC_DATA_OFFSET; + + cacheSlots = POLYFILLARC_CACHE_SLOTS; + cacheThreshold = POLYFILLARC_CACHE_THRESHOLD; + cacheLowerThreshold = POLYFILLARC_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~PolyFillArcStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "PolyFillArc"; + } + + virtual unsigned char opcode() const + { + return X_PolyFillArc; + } + + virtual unsigned int storage() const + { + return sizeof(PolyFillArcMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new PolyFillArcMessage(); + } + + virtual Message *create(const Message &message) const + { + return new PolyFillArcMessage((const PolyFillArcMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (PolyFillArcMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PolyFillArc_H */ diff --git a/nxcomp/src/PolyFillRectangle.cpp b/nxcomp/src/PolyFillRectangle.cpp new file mode 100644 index 000000000..95694e582 --- /dev/null +++ b/nxcomp/src/PolyFillRectangle.cpp @@ -0,0 +1,160 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PolyFillRectangle.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int PolyFillRectangleStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; + + // + // Here is the fingerprint. + // + + polyFillRectangle -> drawable = GetULONG(buffer + 4, bigEndian); + polyFillRectangle -> gcontext = GetULONG(buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PolyFillRectangleStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(polyFillRectangle -> drawable, buffer + 4, bigEndian); + PutULONG(polyFillRectangle -> gcontext, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PolyFillRectangleStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; + + *logofs << name() << ": Identity drawable " << polyFillRectangle -> drawable + << ", gcontext " << polyFillRectangle -> gcontext + << ", size " << polyFillRectangle -> size_ << ".\n" << logofs_flush; + #endif +} + +void PolyFillRectangleStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} + +void PolyFillRectangleStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; + PolyFillRectangleMessage *cachedPolyFillRectangle = (PolyFillRectangleMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding value " << polyFillRectangle -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyFillRectangle -> drawable, clientCache -> drawableCache); + + cachedPolyFillRectangle -> drawable = polyFillRectangle -> drawable; + + #ifdef DEBUG + *logofs << name() << ": Encoding value " << polyFillRectangle -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyFillRectangle -> gcontext, clientCache -> gcCache); + + cachedPolyFillRectangle -> gcontext = polyFillRectangle -> gcontext; +} + +void PolyFillRectangleStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + PolyFillRectangleMessage *polyFillRectangle = (PolyFillRectangleMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + polyFillRectangle -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyFillRectangle -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + polyFillRectangle -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyFillRectangle -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/PolyFillRectangle.h b/nxcomp/src/PolyFillRectangle.h new file mode 100644 index 000000000..7ebb9270d --- /dev/null +++ b/nxcomp/src/PolyFillRectangle.h @@ -0,0 +1,185 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PolyFillRectangle_H +#define PolyFillRectangle_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define POLYFILLRECTANGLE_ENABLE_CACHE 1 +#define POLYFILLRECTANGLE_ENABLE_DATA 0 +#define POLYFILLRECTANGLE_ENABLE_SPLIT 0 +#define POLYFILLRECTANGLE_ENABLE_COMPRESS 0 + +#define POLYFILLRECTANGLE_DATA_LIMIT 2048 +#define POLYFILLRECTANGLE_DATA_OFFSET 12 + +#define POLYFILLRECTANGLE_CACHE_SLOTS 4000 +#define POLYFILLRECTANGLE_CACHE_THRESHOLD 5 +#define POLYFILLRECTANGLE_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class PolyFillRectangleMessage : public Message +{ + friend class PolyFillRectangleStore; + + public: + + PolyFillRectangleMessage() + { + } + + ~PolyFillRectangleMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int drawable; + unsigned int gcontext; +}; + +class PolyFillRectangleStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PolyFillRectangleStore() : MessageStore() + { + enableCache = POLYFILLRECTANGLE_ENABLE_CACHE; + enableData = POLYFILLRECTANGLE_ENABLE_DATA; + enableSplit = POLYFILLRECTANGLE_ENABLE_SPLIT; + enableCompress = POLYFILLRECTANGLE_ENABLE_COMPRESS; + + dataLimit = POLYFILLRECTANGLE_DATA_LIMIT; + dataOffset = POLYFILLRECTANGLE_DATA_OFFSET; + + cacheSlots = POLYFILLRECTANGLE_CACHE_SLOTS; + cacheThreshold = POLYFILLRECTANGLE_CACHE_THRESHOLD; + cacheLowerThreshold = POLYFILLRECTANGLE_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~PolyFillRectangleStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "PolyFillRectangle"; + } + + virtual unsigned char opcode() const + { + return X_PolyFillRectangle; + } + + virtual unsigned int storage() const + { + return sizeof(PolyFillRectangleMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new PolyFillRectangleMessage(); + } + + virtual Message *create(const Message &message) const + { + return new PolyFillRectangleMessage((const PolyFillRectangleMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (PolyFillRectangleMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PolyFillRectangle_H */ diff --git a/nxcomp/src/PolyLine.cpp b/nxcomp/src/PolyLine.cpp new file mode 100644 index 000000000..1b12bbe98 --- /dev/null +++ b/nxcomp/src/PolyLine.cpp @@ -0,0 +1,168 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PolyLine.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int PolyLineStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyLineMessage *polyLine = (PolyLineMessage *) message; + + // + // Here is the fingerprint. + // + + polyLine -> mode = *(buffer + 1); + + polyLine -> drawable = GetULONG(buffer + 4, bigEndian); + polyLine -> gcontext = GetULONG(buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PolyLineStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyLineMessage *polyLine = (PolyLineMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = polyLine -> mode; + + PutULONG(polyLine -> drawable, buffer + 4, bigEndian); + PutULONG(polyLine -> gcontext, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PolyLineStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PolyLineMessage *polyLine = (PolyLineMessage *) message; + + *logofs << name() << ": Identity drawable " << polyLine -> drawable + << ", gcontext " << polyLine -> gcontext + << ", size " << polyLine -> size_ << ".\n" << logofs_flush; + #endif +} + +void PolyLineStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // Since ProtoStep8 (#issue 108) + md5_append(md5_state_, buffer + 1, 1); +} + +void PolyLineStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + PolyLineMessage *polyLine = (PolyLineMessage *) message; + PolyLineMessage *cachedPolyLine = (PolyLineMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyLine -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyLine -> drawable, clientCache -> drawableCache); + + cachedPolyLine -> drawable = polyLine -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyLine -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyLine -> gcontext, clientCache -> gcCache); + + cachedPolyLine -> gcontext = polyLine -> gcontext; +} + +void PolyLineStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + PolyLineMessage *polyLine = (PolyLineMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + polyLine -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyLine -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + polyLine -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyLine -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/PolyLine.h b/nxcomp/src/PolyLine.h new file mode 100644 index 000000000..66fa5df1a --- /dev/null +++ b/nxcomp/src/PolyLine.h @@ -0,0 +1,186 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PolyLine_H +#define PolyLine_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define POLYLINE_ENABLE_CACHE 1 +#define POLYLINE_ENABLE_DATA 0 +#define POLYLINE_ENABLE_SPLIT 0 +#define POLYLINE_ENABLE_COMPRESS 0 + +#define POLYLINE_DATA_LIMIT 144 +#define POLYLINE_DATA_OFFSET 12 + +#define POLYLINE_CACHE_SLOTS 3000 +#define POLYLINE_CACHE_THRESHOLD 3 +#define POLYLINE_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class PolyLineMessage : public Message +{ + friend class PolyLineStore; + + public: + + PolyLineMessage() + { + } + + ~PolyLineMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char mode; + unsigned int drawable; + unsigned int gcontext; +}; + +class PolyLineStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PolyLineStore() : MessageStore() + { + enableCache = POLYLINE_ENABLE_CACHE; + enableData = POLYLINE_ENABLE_DATA; + enableSplit = POLYLINE_ENABLE_SPLIT; + enableCompress = POLYLINE_ENABLE_COMPRESS; + + dataLimit = POLYLINE_DATA_LIMIT; + dataOffset = POLYLINE_DATA_OFFSET; + + cacheSlots = POLYLINE_CACHE_SLOTS; + cacheThreshold = POLYLINE_CACHE_THRESHOLD; + cacheLowerThreshold = POLYLINE_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~PolyLineStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "PolyLine"; + } + + virtual unsigned char opcode() const + { + return X_PolyLine; + } + + virtual unsigned int storage() const + { + return sizeof(PolyLineMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new PolyLineMessage(); + } + + virtual Message *create(const Message &message) const + { + return new PolyLineMessage((const PolyLineMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (PolyLineMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PolyLine_H */ diff --git a/nxcomp/src/PolyPoint.cpp b/nxcomp/src/PolyPoint.cpp new file mode 100644 index 000000000..70151cc0d --- /dev/null +++ b/nxcomp/src/PolyPoint.cpp @@ -0,0 +1,168 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PolyPoint.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int PolyPointStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyPointMessage *polyPoint = (PolyPointMessage *) message; + + // + // Here is the fingerprint. + // + + polyPoint -> mode = *(buffer + 1); + + polyPoint -> drawable = GetULONG(buffer + 4, bigEndian); + polyPoint -> gcontext = GetULONG(buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PolyPointStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyPointMessage *polyPoint = (PolyPointMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = polyPoint -> mode; + + PutULONG(polyPoint -> drawable, buffer + 4, bigEndian); + PutULONG(polyPoint -> gcontext, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PolyPointStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PolyPointMessage *polyPoint = (PolyPointMessage *) message; + + *logofs << name() << ": Identity drawable " << polyPoint -> drawable + << ", gcontext " << polyPoint -> gcontext + << ", size " << polyPoint -> size_ << ".\n" << logofs_flush; + #endif +} + +void PolyPointStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // Since ProtoStep8 (#issue 108) + md5_append(md5_state_, buffer + 1, 1); +} + +void PolyPointStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + PolyPointMessage *polyPoint = (PolyPointMessage *) message; + PolyPointMessage *cachedPolyPoint = (PolyPointMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyPoint -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyPoint -> drawable, clientCache -> drawableCache); + + cachedPolyPoint -> drawable = polyPoint -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyPoint -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyPoint -> gcontext, clientCache -> gcCache); + + cachedPolyPoint -> gcontext = polyPoint -> gcontext; +} + +void PolyPointStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + PolyPointMessage *polyPoint = (PolyPointMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + polyPoint -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyPoint -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + polyPoint -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyPoint -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/PolyPoint.h b/nxcomp/src/PolyPoint.h new file mode 100644 index 000000000..b8ea183bf --- /dev/null +++ b/nxcomp/src/PolyPoint.h @@ -0,0 +1,186 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PolyPoint_H +#define PolyPoint_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define POLYPOINT_ENABLE_CACHE 1 +#define POLYPOINT_ENABLE_DATA 0 +#define POLYPOINT_ENABLE_SPLIT 0 +#define POLYPOINT_ENABLE_COMPRESS 0 + +#define POLYPOINT_DATA_LIMIT 3200 +#define POLYPOINT_DATA_OFFSET 12 + +#define POLYPOINT_CACHE_SLOTS 3000 +#define POLYPOINT_CACHE_THRESHOLD 3 +#define POLYPOINT_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class PolyPointMessage : public Message +{ + friend class PolyPointStore; + + public: + + PolyPointMessage() + { + } + + ~PolyPointMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char mode; + unsigned int drawable; + unsigned int gcontext; +}; + +class PolyPointStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PolyPointStore() : MessageStore() + { + enableCache = POLYPOINT_ENABLE_CACHE; + enableData = POLYPOINT_ENABLE_DATA; + enableSplit = POLYPOINT_ENABLE_SPLIT; + enableCompress = POLYPOINT_ENABLE_COMPRESS; + + dataLimit = POLYPOINT_DATA_LIMIT; + dataOffset = POLYPOINT_DATA_OFFSET; + + cacheSlots = POLYPOINT_CACHE_SLOTS; + cacheThreshold = POLYPOINT_CACHE_THRESHOLD; + cacheLowerThreshold = POLYPOINT_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~PolyPointStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "PolyPoint"; + } + + virtual unsigned char opcode() const + { + return X_PolyPoint; + } + + virtual unsigned int storage() const + { + return sizeof(PolyPointMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new PolyPointMessage(); + } + + virtual Message *create(const Message &message) const + { + return new PolyPointMessage((const PolyPointMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (PolyPointMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PolyPoint_H */ diff --git a/nxcomp/src/PolySegment.cpp b/nxcomp/src/PolySegment.cpp new file mode 100644 index 000000000..aa2d4efe3 --- /dev/null +++ b/nxcomp/src/PolySegment.cpp @@ -0,0 +1,162 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PolySegment.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int PolySegmentStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolySegmentMessage *polySegment = (PolySegmentMessage *) message; + + // + // Here is the fingerprint. + // + + polySegment -> drawable = GetULONG(buffer + 4, bigEndian); + polySegment -> gcontext = GetULONG(buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PolySegmentStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolySegmentMessage *polySegment = (PolySegmentMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(polySegment -> drawable, buffer + 4, bigEndian); + PutULONG(polySegment -> gcontext, buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PolySegmentStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PolySegmentMessage *polySegment = (PolySegmentMessage *) message; + + *logofs << name() << ": Identity drawable " << polySegment -> drawable + << ", gcontext " << polySegment -> gcontext + << ", size " << polySegment -> size_ << ".\n" << logofs_flush; + #endif +} + +void PolySegmentStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} + +void PolySegmentStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + PolySegmentMessage *polySegment = (PolySegmentMessage *) message; + PolySegmentMessage *cachedPolySegment = (PolySegmentMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polySegment -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polySegment -> drawable, clientCache -> drawableCache); + + cachedPolySegment -> drawable = polySegment -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polySegment -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polySegment -> gcontext, clientCache -> gcCache); + + cachedPolySegment -> gcontext = polySegment -> gcontext; +} + +void PolySegmentStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + PolySegmentMessage *polySegment = (PolySegmentMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + polySegment -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polySegment -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + polySegment -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polySegment -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/PolySegment.h b/nxcomp/src/PolySegment.h new file mode 100644 index 000000000..53fd42c60 --- /dev/null +++ b/nxcomp/src/PolySegment.h @@ -0,0 +1,185 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PolySegment_H +#define PolySegment_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define POLYSEGMENT_ENABLE_CACHE 1 +#define POLYSEGMENT_ENABLE_DATA 0 +#define POLYSEGMENT_ENABLE_SPLIT 0 +#define POLYSEGMENT_ENABLE_COMPRESS 0 + +#define POLYSEGMENT_DATA_LIMIT 8192 +#define POLYSEGMENT_DATA_OFFSET 12 + +#define POLYSEGMENT_CACHE_SLOTS 3000 +#define POLYSEGMENT_CACHE_THRESHOLD 5 +#define POLYSEGMENT_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class PolySegmentMessage : public Message +{ + friend class PolySegmentStore; + + public: + + PolySegmentMessage() + { + } + + ~PolySegmentMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int drawable; + unsigned int gcontext; +}; + +class PolySegmentStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PolySegmentStore() : MessageStore() + { + enableCache = POLYSEGMENT_ENABLE_CACHE; + enableData = POLYSEGMENT_ENABLE_DATA; + enableSplit = POLYSEGMENT_ENABLE_SPLIT; + enableCompress = POLYSEGMENT_ENABLE_COMPRESS; + + dataLimit = POLYSEGMENT_DATA_LIMIT; + dataOffset = POLYSEGMENT_DATA_OFFSET; + + cacheSlots = POLYSEGMENT_CACHE_SLOTS; + cacheThreshold = POLYSEGMENT_CACHE_THRESHOLD; + cacheLowerThreshold = POLYSEGMENT_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~PolySegmentStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "PolySegment"; + } + + virtual unsigned char opcode() const + { + return X_PolySegment; + } + + virtual unsigned int storage() const + { + return sizeof(PolySegmentMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new PolySegmentMessage(); + } + + virtual Message *create(const Message &message) const + { + return new PolySegmentMessage((const PolySegmentMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (PolySegmentMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PolySegment_H */ diff --git a/nxcomp/src/PolyText16.cpp b/nxcomp/src/PolyText16.cpp new file mode 100644 index 000000000..32be45482 --- /dev/null +++ b/nxcomp/src/PolyText16.cpp @@ -0,0 +1,312 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PolyText16.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int PolyText16Store::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyText16Message *polyText16 = (PolyText16Message *) message; + + // + // Here is the fingerprint. + // + + polyText16 -> drawable = GetULONG(buffer + 4, bigEndian); + polyText16 -> gcontext = GetULONG(buffer + 8, bigEndian); + + polyText16 -> x = GetUINT(buffer + 12, bigEndian); + polyText16 -> y = GetUINT(buffer + 14, bigEndian); + + // + // Clean up padding bytes. + // + + #ifdef DUMP + + DumpData(buffer, size); + + *logofs << "\n" << logofs_flush; + + #endif + + if ((int) size > dataOffset) + { + int current; + int length; + int delta; + int item; + + unsigned int nitem; + + unsigned char *pad = NULL; + unsigned char *end = NULL; + + delta = 1; + nitem = 0; + + #ifdef DUMP + *logofs << name() << " Size " << size << ".\n" << logofs_flush; + #endif + + // + // Data is a list of TextItem where element + // can be a string or a font shift. + // + + current = POLYTEXT16_DATA_OFFSET; + length = POLYTEXT16_DATA_OFFSET; + + do + { + #ifdef DUMP + *logofs << name() << " Current " << current << ".\n" << logofs_flush; + #endif + + item = GetUINT(buffer + length , bigEndian); + + if (item < 255) + { + // + // Text element. Number represents + // the 'Length of CHAR2B string' + // field. + // + + length += ((item * 2) + delta + 1); + + nitem++; + } + else if (item == 255) + { + // + // Element is a font shift. + // + + length += 5; + + nitem++; + } + + #ifdef DUMP + *logofs << name() << " Item " << item << ".\n" << logofs_flush; + #endif + + current += length; + } + while(current < (int) size && item != 0); + + #ifdef DUMP + *logofs << name() << " Final length " << length << ".\n" << logofs_flush; + #endif + + end = ((unsigned char *) buffer) + size; + + pad = ((unsigned char *) buffer) + length; + + for (; pad < end && nitem >= 1; pad++) + { + #ifdef DUMP + *logofs << name() << " Padding " << " .\n" << logofs_flush; + #endif + + *pad = 0; + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PolyText16Store::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyText16Message *polyText16 = (PolyText16Message *) message; + + // + // Fill all the message's fields. + // + + PutULONG(polyText16 -> drawable, buffer + 4, bigEndian); + PutULONG(polyText16 -> gcontext, buffer + 8, bigEndian); + + PutUINT(polyText16 -> x, buffer + 12, bigEndian); + PutUINT(polyText16 -> y, buffer + 14, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PolyText16Store::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PolyText16Message *polyText16 = (PolyText16Message *) message; + + *logofs << name() << ": Identity drawable " << polyText16 -> drawable + << ", gcontext " << polyText16 -> gcontext << ", x " << polyText16 -> x + << ", y " << polyText16 -> y << ", size " << polyText16 -> size_ + << ".\n"; + + #endif +} + +void PolyText16Store::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} + +void PolyText16Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + PolyText16Message *polyText16 = (PolyText16Message *) message; + PolyText16Message *cachedPolyText16 = (PolyText16Message *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyText16 -> drawable + << " as " << "drawable" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyText16 -> drawable, clientCache -> drawableCache); + + cachedPolyText16 -> drawable = polyText16 -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyText16 -> gcontext + << " as " << "gcontext" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyText16 -> gcontext, clientCache -> gcCache); + + cachedPolyText16 -> gcontext = polyText16 -> gcontext; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyText16 -> x + << " as " << "x" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_x = polyText16 -> x - cachedPolyText16 -> x; + + encodeBuffer.encodeCachedValue(diff_x, 16, + clientCache -> polyTextCacheX); + + cachedPolyText16 -> x = polyText16 -> x; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyText16 -> y + << " as " << "y" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_y = polyText16 -> y - cachedPolyText16 -> y; + + encodeBuffer.encodeCachedValue(diff_y, 16, + clientCache -> polyTextCacheY); + + cachedPolyText16 -> y = polyText16 -> y; +} + +void PolyText16Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + PolyText16Message *polyText16 = (PolyText16Message *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + polyText16 -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyText16 -> drawable + << " as " << "drawable" << " field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + polyText16 -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyText16 -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> polyTextCacheX); + + polyText16 -> x += value; + polyText16 -> x &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyText16 -> x + << " as x field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> polyTextCacheY); + + polyText16 -> y += value; + polyText16 -> y &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyText16 -> y + << " as y field.\n" << logofs_flush; + #endif +} + + diff --git a/nxcomp/src/PolyText16.h b/nxcomp/src/PolyText16.h new file mode 100644 index 000000000..805e1fa04 --- /dev/null +++ b/nxcomp/src/PolyText16.h @@ -0,0 +1,188 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PolyText16_H +#define PolyText16_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define POLYTEXT16_ENABLE_CACHE 1 +#define POLYTEXT16_ENABLE_DATA 0 +#define POLYTEXT16_ENABLE_SPLIT 0 +#define POLYTEXT16_ENABLE_COMPRESS 0 + +#define POLYTEXT16_DATA_LIMIT 420 +#define POLYTEXT16_DATA_OFFSET 16 + +#define POLYTEXT16_CACHE_SLOTS 3000 +#define POLYTEXT16_CACHE_THRESHOLD 4 +#define POLYTEXT16_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class PolyText16Message : public Message +{ + friend class PolyText16Store; + + public: + + PolyText16Message() + { + } + + ~PolyText16Message() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int drawable; + unsigned int gcontext; + + unsigned short x; + unsigned short y; +}; + +class PolyText16Store : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PolyText16Store() : MessageStore() + { + enableCache = POLYTEXT16_ENABLE_CACHE; + enableData = POLYTEXT16_ENABLE_DATA; + enableSplit = POLYTEXT16_ENABLE_SPLIT; + enableCompress = POLYTEXT16_ENABLE_COMPRESS; + + dataLimit = POLYTEXT16_DATA_LIMIT; + dataOffset = POLYTEXT16_DATA_OFFSET; + + cacheSlots = POLYTEXT16_CACHE_SLOTS; + cacheThreshold = POLYTEXT16_CACHE_THRESHOLD; + cacheLowerThreshold = POLYTEXT16_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~PolyText16Store() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "PolyText16"; + } + + virtual unsigned char opcode() const + { + return X_PolyText16; + } + + virtual unsigned int storage() const + { + return sizeof(PolyText16Message); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new PolyText16Message(); + } + + virtual Message *create(const Message &message) const + { + return new PolyText16Message((const PolyText16Message &) message); + } + + virtual void destroy(Message *message) const + { + delete (PolyText16Message *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PolyText16_H */ diff --git a/nxcomp/src/PolyText8.cpp b/nxcomp/src/PolyText8.cpp new file mode 100644 index 000000000..61fef5a4f --- /dev/null +++ b/nxcomp/src/PolyText8.cpp @@ -0,0 +1,310 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PolyText8.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int PolyText8Store::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyText8Message *polyText8 = (PolyText8Message *) message; + + // + // Here is the fingerprint. + // + + polyText8 -> drawable = GetULONG(buffer + 4, bigEndian); + polyText8 -> gcontext = GetULONG(buffer + 8, bigEndian); + + polyText8 -> x = GetUINT(buffer + 12, bigEndian); + polyText8 -> y = GetUINT(buffer + 14, bigEndian); + + // + // Clean up padding bytes. + // + + #ifdef DUMP + + DumpData(buffer, size); + + *logofs << "\n\n" << logofs_flush; + + #endif + + if ((int) size > dataOffset) + { + int length; + int current; + int delta; + int item; + + unsigned int nitem; + + unsigned char *pad = NULL; + unsigned char *end = NULL; + + delta = 1; + nitem = 0; + + #ifdef DUMP + *logofs << name() << " Size " << size << ".\n" << logofs_flush; + #endif + + // + // Data is a list of TextItem where element + // can be a string or a font shift. + // + + current = POLYTEXT8_DATA_OFFSET; + length = POLYTEXT8_DATA_OFFSET; + + do + { + #ifdef DUMP + *logofs << name() << " Current " << current << ".\n" << logofs_flush; + #endif + + item = GetUINT(buffer + length , bigEndian); + + if (item < 255) + { + // + // Text element. Number represents + // the 'Length of string' field. + // + + length += (item + delta + 1); + + nitem++; + } + else if (item == 255) + { + // + // Element is a font shift. + // + + length += 5; + + nitem++; + } + + #ifdef DUMP + *logofs << name() << " Item " << item << ".\n" << logofs_flush; + #endif + + current += length; + } + while(current < (int) size && item != 0); + + + #ifdef DUMP + *logofs << name() << " Final length " << length << ".\n" << logofs_flush; + #endif + + end = ((unsigned char *) buffer) + size; + + pad = ((unsigned char *) buffer) + length; + + for (; pad < end && nitem >= 1; pad++) + { + #ifdef DUMP + *logofs << name() << " Padding " << " .\n" << logofs_flush; + #endif + + *pad = 0; + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PolyText8Store::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PolyText8Message *polyText8 = (PolyText8Message *) message; + + // + // Fill all the message's fields. + // + + PutULONG(polyText8 -> drawable, buffer + 4, bigEndian); + PutULONG(polyText8 -> gcontext, buffer + 8, bigEndian); + + PutUINT(polyText8 -> x, buffer + 12, bigEndian); + PutUINT(polyText8 -> y, buffer + 14, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PolyText8Store::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PolyText8Message *polyText8 = (PolyText8Message *) message; + + *logofs << name() << ": Identity drawable " << polyText8 -> drawable + << ", gcontext " << polyText8 -> gcontext << ", x " << polyText8 -> x + << ", y " << polyText8 -> y << ", size " << polyText8 -> size_ + << ".\n"; + + #endif +} + +void PolyText8Store::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} + +void PolyText8Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + PolyText8Message *polyText8 = (PolyText8Message *) message; + PolyText8Message *cachedPolyText8 = (PolyText8Message *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyText8 -> drawable + << " as " << "drawable" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyText8 -> drawable, clientCache -> drawableCache); + + cachedPolyText8 -> drawable = polyText8 -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyText8 -> gcontext + << " as " << "gcontext" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(polyText8 -> gcontext, clientCache -> gcCache); + + cachedPolyText8 -> gcontext = polyText8 -> gcontext; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyText8 -> x + << " as " << "x" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_x = polyText8 -> x - cachedPolyText8 -> x; + + encodeBuffer.encodeCachedValue(diff_x, 16, + clientCache -> polyTextCacheX); + + cachedPolyText8 -> x = polyText8 -> x; + + #ifdef TEST + *logofs << name() << ": Encoding value " << polyText8 -> y + << " as " << "y" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_y = polyText8 -> y - cachedPolyText8 -> y; + + encodeBuffer.encodeCachedValue(diff_y, 16, + clientCache -> polyTextCacheY); + + cachedPolyText8 -> y = polyText8 -> y; +} + +void PolyText8Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + PolyText8Message *polyText8 = (PolyText8Message *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + polyText8 -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyText8 -> drawable + << " as " << "drawable" << " field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + polyText8 -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyText8 -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> polyTextCacheX); + + polyText8 -> x += value; + polyText8 -> x &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyText8 -> x + << " as x field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> polyTextCacheY); + + polyText8 -> y += value; + polyText8 -> y &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << polyText8 -> y + << " as y field.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/PolyText8.h b/nxcomp/src/PolyText8.h new file mode 100644 index 000000000..3d5ff533a --- /dev/null +++ b/nxcomp/src/PolyText8.h @@ -0,0 +1,188 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PolyText8_H +#define PolyText8_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define POLYTEXT8_ENABLE_CACHE 1 +#define POLYTEXT8_ENABLE_DATA 0 +#define POLYTEXT8_ENABLE_SPLIT 0 +#define POLYTEXT8_ENABLE_COMPRESS 0 + +#define POLYTEXT8_DATA_LIMIT 380 +#define POLYTEXT8_DATA_OFFSET 16 + +#define POLYTEXT8_CACHE_SLOTS 3000 +#define POLYTEXT8_CACHE_THRESHOLD 5 +#define POLYTEXT8_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class PolyText8Message : public Message +{ + friend class PolyText8Store; + + public: + + PolyText8Message() + { + } + + ~PolyText8Message() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int drawable; + unsigned int gcontext; + + unsigned short x; + unsigned short y; +}; + +class PolyText8Store : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PolyText8Store() : MessageStore() + { + enableCache = POLYTEXT8_ENABLE_CACHE; + enableData = POLYTEXT8_ENABLE_DATA; + enableSplit = POLYTEXT8_ENABLE_SPLIT; + enableCompress = POLYTEXT8_ENABLE_COMPRESS; + + dataLimit = POLYTEXT8_DATA_LIMIT; + dataOffset = POLYTEXT8_DATA_OFFSET; + + cacheSlots = POLYTEXT8_CACHE_SLOTS; + cacheThreshold = POLYTEXT8_CACHE_THRESHOLD; + cacheLowerThreshold = POLYTEXT8_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~PolyText8Store() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "PolyText8"; + } + + virtual unsigned char opcode() const + { + return X_PolyText8; + } + + virtual unsigned int storage() const + { + return sizeof(PolyText8Message); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new PolyText8Message(); + } + + virtual Message *create(const Message &message) const + { + return new PolyText8Message((const PolyText8Message &) message); + } + + virtual void destroy(Message *message) const + { + delete (PolyText8Message *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PolyText8_H */ diff --git a/nxcomp/src/Proxy.cpp b/nxcomp/src/Proxy.cpp new file mode 100644 index 000000000..72b2cee21 --- /dev/null +++ b/nxcomp/src/Proxy.cpp @@ -0,0 +1,6529 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef ANDROID +#include +#include +#include +#endif + +#include "Misc.h" + +#if defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun) +#include +#endif + +#ifndef ANDROID +#include +#include +#include +#endif + +#include "NXalert.h" +#include "NXvars.h" + +#include "Proxy.h" + +#include "Socket.h" +#include "Channel.h" +#include "Statistics.h" + +#include "ClientChannel.h" +#include "ServerChannel.h" +#include "GenericChannel.h" +#include "ChannelEndPoint.h" + +// +// We need to adjust some values related +// to these messages at the time the mes- +// sage stores are reconfigured. +// + +#include "PutImage.h" +#include "ChangeGC.h" +#include "PolyFillRectangle.h" +#include "PutPackedImage.h" + +// +// This is from the main loop. +// + +extern void CleanupListeners(); + +extern int HandleChild(int); + +// +// Default size of string buffers. +// + +#define DEFAULT_STRING_LENGTH 512 + +// +// Set the verbosity level. You also need +// to define DUMP in Misc.cpp if DUMP is +// defined here. +// + +#define WARNING +#define PANIC +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Log the important tracepoints related +// to writing packets to the peer proxy. +// + +#undef FLUSH + +// +// Log the operations related to splits. +// + +#undef SPLIT + +// +// Log the operations related to sending +// and receiving the control tokens. +// + +#undef TOKEN + +// +// Log the operations related to setting +// the token limits. +// + +#undef LIMIT + +// +// Log a warning if no data is written by +// the proxy within a timeout. +// + +#undef TIME + +// +// Log the operation related to generating +// the ping message at idle time. +// + +#undef PING + +Proxy::Proxy(int fd) + + : transport_(new ProxyTransport(fd)), fd_(fd), readBuffer_(transport_) +{ + for (int channelId = 0; + channelId < CONNECTIONS_LIMIT; + channelId++) + { + channels_[channelId] = NULL; + transports_[channelId] = NULL; + congestions_[channelId] = 0; + + fdMap_[channelId] = nothing; + channelMap_[channelId] = nothing; + slavePidMap_[channelId] = nothing; + } + + inputChannel_ = nothing; + outputChannel_ = nothing; + + controlLength_ = 0; + + operation_ = operation_in_negotiation; + + draining_ = 0; + priority_ = 0; + finish_ = 0; + shutdown_ = 0; + congestion_ = 0; + + timer_ = 0; + alert_ = 0; + + agent_ = nothing; + + // + // Set null timeouts. This will require + // a new link configuration. + // + + timeouts_.split = 0; + timeouts_.motion = 0; + + timeouts_.readTs = getTimestamp(); + timeouts_.writeTs = getTimestamp(); + + timeouts_.loopTs = getTimestamp(); + timeouts_.pingTs = getTimestamp(); + timeouts_.alertTs = nullTimestamp(); + timeouts_.loadTs = nullTimestamp(); + + timeouts_.splitTs = nullTimestamp(); + timeouts_.motionTs = nullTimestamp(); + + // + // Initialize the token counters. This + // will require a new link configuration. + // + + for (int i = token_control; i <= token_data; i++) + { + tokens_[i].size = 0; + tokens_[i].limit = 0; + + tokens_[i].bytes = 0; + tokens_[i].remaining = 0; + } + + tokens_[token_control].request = code_control_token_request; + tokens_[token_control].reply = code_control_token_reply; + tokens_[token_control].type = token_control; + + tokens_[token_split].request = code_split_token_request; + tokens_[token_split].reply = code_split_token_reply; + tokens_[token_split].type = token_split; + + tokens_[token_data].request = code_data_token_request; + tokens_[token_data].reply = code_data_token_reply; + tokens_[token_data].type = token_data; + + currentStatistics_ = NULL; + + // + // Create compressor and decompressor + // for image and data payload. + // + + compressor_ = new StaticCompressor(control -> LocalDataCompressionLevel, + control -> LocalDataCompressionThreshold); + + // + // Create object storing NX specific + // opcodes. + // + + opcodeStore_ = new OpcodeStore(); + + // + // Create the message stores. + // + + clientStore_ = new ClientStore(compressor_); + serverStore_ = new ServerStore(compressor_); + + clientCache_ = new ClientCache(); + serverCache_ = new ServerCache(); + + if (clientCache_ == NULL || serverCache_ == NULL) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Failed to create the channel cache.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to create the channel cache.\n"; + + HandleCleanup(); + } + + // + // Prepare for image decompression. + // + + UnpackInit(); + + #ifdef DEBUG + *logofs << "Proxy: Created new object at " << this + << ".\n" << logofs_flush; + #endif +} + +Proxy::~Proxy() +{ + for (int channelId = 0; + channelId < CONNECTIONS_LIMIT; + channelId++) + { + if (channels_[channelId] != NULL) + { + deallocateTransport(channelId); + + delete channels_[channelId]; + channels_[channelId] = NULL; + } + } + + // + // Kill all active slave channel children, and + // give them 5 seconds to exit nicely. + + #ifdef DEBUG + *logofs << "Proxy: Killing active slaves" << endl; + #endif + + int slave_count = 999; + int loop_count = 0; + + while(slave_count > 0 && loop_count < 50) + { + slave_count = 0; + + for (int channelId = 0; channelId 1) { + slave_count++; + + #ifdef DEBUG + *logofs << "Proxy: Active slave with pid " << pid << logofs_flush; + #endif + + if ( loop_count == 0 ) + { + #ifdef DEBUG + *logofs << "Proxy: Sending SIGTERM to " << pid << logofs_flush; + #endif + kill(pid, SIGTERM); + } + else if ( loop_count == 25 ) + { + #ifdef DEBUG + *logofs << "Proxy: Sending SIGKILL to " << pid << logofs_flush; + #endif + kill(pid, SIGKILL); + } + + if (HandleChild(pid)) + { + #ifdef DEBUG + *logofs << "Proxy: Slave " << pid << " terminated" << logofs_flush; + #endif + slavePidMap_[channelId] = nothing; + } + } + } + + if ( slave_count > 0 ) + { + cerr << "Proxy: Error: Failed to kill all slave channel processes. " << slave_count << " processes still remaining." << endl; + } + + usleep(200000); + loop_count++; + } + + delete transport_; + delete compressor_; + + // + // Delete storage shared among channels. + // + + delete opcodeStore_; + + delete clientStore_; + delete serverStore_; + + delete clientCache_; + delete serverCache_; + + // + // Get rid of the image decompression + // resources. + // + + UnpackDestroy(); + + #ifdef DEBUG + *logofs << "Proxy: Deleted proxy object at " << this + << ".\n" << logofs_flush; + #endif +} + +int Proxy::setOperational() +{ + #ifdef TEST + *logofs << "Proxy: Entering operational mode.\n" + << logofs_flush; + #endif + + operation_ = operation_in_messages; + + return 1; +} + +int Proxy::setReadDescriptors(fd_set *fdSet, int &fdMax, T_timestamp &tsMax) +{ + // + // Set the initial timeout to the time of + // the next ping. If the congestion count + // is greater than zero, anyway, use a + // shorter timeout to force a congestion + // update. + // + + if (agent_ != nothing && congestions_[agent_] == 0 && + statistics -> getCongestionInFrame() >= 1 && + tokens_[token_control].remaining >= + (tokens_[token_control].limit - 1)) + { + setMinTimestamp(tsMax, control -> IdleTimeout); + + #ifdef TEST + *logofs << "Proxy: Initial timeout is " << tsMax.tv_sec + << " S and " << (double) tsMax.tv_usec / + 1000 << " Ms with congestion " + << statistics -> getCongestionInFrame() + << ".\n" << logofs_flush; + #endif + } + else + { + setMinTimestamp(tsMax, control -> PingTimeout); + + #ifdef TEST + *logofs << "Proxy: Initial timeout is " << tsMax.tv_sec + << " S and " << (double) tsMax.tv_usec / + 1000 << " Ms.\n" << logofs_flush; + #endif + } + + int fd = -1; + + if (isTimeToRead() == 1) + { + // + // If we don't have split tokens available + // don't set the timeout. + // + + if (tokens_[token_split].remaining > 0 && + isTimestamp(timeouts_.splitTs) == 1) + { + int diffTs = getTimeToNextSplit(); + + #if defined(TEST) || defined(INFO) || \ + defined(FLUSH) || defined(SPLIT) + + if (diffTimestamp(timeouts_.splitTs, + getTimestamp()) > timeouts_.split) + { + *logofs << "Proxy: FLUSH! SPLIT! WARNING! Running with " + << diffTimestamp(timeouts_.splitTs, getTimestamp()) + << " Ms elapsed since the last split.\n" + << logofs_flush; + } + + *logofs << "Proxy: FLUSH! SPLIT! Requesting timeout of " + << diffTs << " Ms as there are splits to send.\n" + << logofs_flush; + + #endif + + setMinTimestamp(tsMax, diffTs); + } + #if defined(TEST) || defined(INFO) + else if (isTimestamp(timeouts_.splitTs) == 1) + { + *logofs << "Proxy: WARNING! Not requesting a split " + << "timeout with " << tokens_[token_split].remaining + << " split tokens remaining.\n" << logofs_flush; + } + #endif + + // + // Loop through the valid channels and set + // the descriptors selected for read and + // the timeout. + // + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] == NULL) + { + continue; + } + + fd = getFd(channelId); + + if (channels_[channelId] -> getFinish() == 0 && + (channels_[channelId] -> getType() == channel_x11 || + tokens_[token_data].remaining > 0) && + congestions_[channelId] == 0) + { + FD_SET(fd, fdSet); + + if (fd >= fdMax) + { + fdMax = fd + 1; + } + + #ifdef TEST + *logofs << "Proxy: Descriptor FD#" << fd + << " selected for read with buffer length " + << transports_[channelId] -> length() + << ".\n" << logofs_flush; + #endif + + // + // Wakeup the proxy if there are motion + // events to flush. + // + + if (isTimestamp(timeouts_.motionTs) == 1) + { + int diffTs = getTimeToNextMotion(); + + #if defined(TEST) || defined(INFO) + + if (diffTimestamp(timeouts_.motionTs, + getTimestamp()) > timeouts_.motion) + { + *logofs << "Proxy: FLUSH! WARNING! Running with " + << diffTimestamp(timeouts_.motionTs, getTimestamp()) + << " Ms elapsed since the last motion.\n" + << logofs_flush; + } + + *logofs << "Proxy: FLUSH! Requesting timeout of " + << diffTs << " Ms as FD#" << fd << " has motion " + << "events to send.\n" << logofs_flush; + + #endif + + setMinTimestamp(tsMax, diffTs); + } + } + #if defined(TEST) || defined(INFO) + else + { + if (channels_[channelId] -> getType() != channel_x11 && + tokens_[token_data].remaining <= 0) + { + *logofs << "Proxy: WARNING! Descriptor FD#" << fd + << " not selected for read with " + << tokens_[token_data].remaining << " data " + << "tokens remaining.\n" << logofs_flush; + } + } + #endif + } + } + #if defined(TEST) || defined(INFO) + else + { + *logofs << "Proxy: WARNING! Disabled reading from channels.\n" + << logofs_flush; + + *logofs << "Proxy: WARNING! Congestion is " << congestion_ + << " pending " << transport_ -> pending() << " blocked " + << transport_ -> blocked() << " length " << transport_ -> + length() << ".\n" << logofs_flush; + } + #endif + + // + // Include the proxy descriptor. + // + + FD_SET(fd_, fdSet); + + if (fd_ >= fdMax) + { + fdMax = fd_ + 1; + } + + #ifdef TEST + *logofs << "Proxy: Proxy descriptor FD#" << fd_ + << " selected for read with buffer length " + << transport_ -> length() << ".\n" + << logofs_flush; + #endif + + return 1; +} + +// +// Add to the mask the file descriptors of all +// X connections to write to. +// + +int Proxy::setWriteDescriptors(fd_set *fdSet, int &fdMax, T_timestamp &tsMax) +{ + int fd = -1; + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL) + { + fd = getFd(channelId); + + if (transports_[channelId] -> length() > 0) + { + FD_SET(fd, fdSet); + + #ifdef TEST + *logofs << "Proxy: Descriptor FD#" << fd << " selected " + << "for write with blocked " << transports_[channelId] -> + blocked() << " and length " << transports_[channelId] -> + length() << ".\n" << logofs_flush; + #endif + + if (fd >= fdMax) + { + fdMax = fd + 1; + } + } + #ifdef TEST + else + { + *logofs << "Proxy: Descriptor FD#" << fd << " not selected " + << "for write with blocked " << transports_[channelId] -> + blocked() << " and length " << transports_[channelId] -> + length() << ".\n" << logofs_flush; + } + #endif + + #if defined(TEST) || defined(INFO) + + if (transports_[channelId] -> getType() != + transport_agent && transports_[channelId] -> + length() > 0 && transports_[channelId] -> + blocked() != 1) + { + *logofs << "Proxy: PANIC! Descriptor FD#" << fd + << " has data to write but blocked flag is " + << transports_[channelId] -> blocked() + << ".\n" << logofs_flush; + + cerr << "Error" << ": Descriptor FD#" << fd + << " has data to write but blocked flag is " + << transports_[channelId] -> blocked() + << ".\n"; + + HandleCleanup(); + } + + #endif + } + } + + // + // Check if the proxy transport has data + // from a previous blocking write. + // + + if (transport_ -> blocked() == 1) + { + FD_SET(fd_, fdSet); + + #ifdef TEST + *logofs << "Proxy: Proxy descriptor FD#" + << fd_ << " selected for write. Blocked is " + << transport_ -> blocked() << " length is " + << transport_ -> length() << ".\n" + << logofs_flush; + #endif + + if (fd_ >= fdMax) + { + fdMax = fd_ + 1; + } + } + #ifdef TEST + else + { + *logofs << "Proxy: Proxy descriptor FD#" + << fd_ << " not selected for write. Blocked is " + << transport_ -> blocked() << " length is " + << transport_ -> length() << ".\n" + << logofs_flush; + } + #endif + + // + // We are entering the main select. Save + // the timestamp of the last loop so that + // we can detect the clock drifts. + // + + timeouts_.loopTs = getTimestamp(); + + return 1; +} + +int Proxy::getChannels(T_channel_type type) +{ + int channels = 0; + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL && + (type == channel_none || + type == channels_[channelId] -> + getType())) + { + channels++; + } + } + + return channels; +} + +T_channel_type Proxy::getType(int fd) +{ + int channelId = getChannel(fd); + + if (channelId < 0 || channels_[channelId] == NULL) + { + return channel_none; + } + + return channels_[channelId] -> getType(); +} + +const char *Proxy::getTypeName(T_channel_type type) +{ + switch (type) + { + case channel_x11: + { + return "X"; + } + case channel_cups: + { + return "CUPS"; + } + case channel_smb: + { + return "SMB"; + } + case channel_media: + { + return "media"; + } + case channel_http: + { + return "HTTP"; + } + case channel_font: + { + return "font"; + } + case channel_slave: + { + return "slave"; + } + default: + { + return "unknown"; + } + } +} + +const char *Proxy::getComputerName() +{ + // + // Strangely enough, under some Windows OSes SMB + // service doesn't bind to localhost. Fall back + // to localhost if can't find computer name in + // the environment. In future we should try to + // bind to localhost and then try the other IPs. + // + + const char *hostname = NULL; + + #ifdef __CYGWIN32__ + + hostname = getenv("COMPUTERNAME"); + + #endif + + if (hostname == NULL) + { + hostname = "localhost"; + } + + return hostname; +} + +// +// Handle data from channels selected for read. +// + +int Proxy::handleRead(int &resultFds, fd_set &readSet) +{ + #ifdef DEBUG + *logofs << "Proxy: Checking descriptors selected for read.\n" + << logofs_flush; + #endif + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + #ifdef DEBUG + *logofs << "Proxy: Looping with current channel " + << *j << ".\n" << logofs_flush; + #endif + + int fd = getFd(*j); + + if (fd >= 0 && resultFds > 0 && FD_ISSET(fd, &readSet)) + { + #ifdef DEBUG + *logofs << "Proxy: Going to read messages from FD#" + << fd << ".\n" << logofs_flush; + #endif + + int result = handleRead(fd); + + if (result < 0) + { + #ifdef TEST + *logofs << "Proxy: Failure reading messages from FD#" + << fd << ".\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef DEBUG + *logofs << "Proxy: Clearing the read descriptor " + << "for FD#" << fd << ".\n" << logofs_flush; + #endif + + FD_CLR(fd, &readSet); + + resultFds--; + } + } + + if (resultFds > 0 && FD_ISSET(fd_, &readSet)) + { + #ifdef DEBUG + *logofs << "Proxy: Going to read messages from " + << "proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + if (handleRead() < 0) + { + #ifdef TEST + *logofs << "Proxy: Failure reading from proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef DEBUG + *logofs << "Proxy: Clearing the read descriptor " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + FD_CLR(fd_, &readSet); + + resultFds--; + } + + return 1; +} + +// +// Perform flush on descriptors selected for write. +// + +int Proxy::handleFlush(int &resultFds, fd_set &writeSet) +{ + #ifdef DEBUG + *logofs << "Proxy: Checking descriptors selected for write.\n" + << logofs_flush; + #endif + + if (resultFds > 0 && FD_ISSET(fd_, &writeSet)) + { + #ifdef TEST + *logofs << "Proxy: FLUSH! Proxy descriptor FD#" << fd_ + << " reported to be writable.\n" + << logofs_flush; + #endif + + if (handleFlush() < 0) + { + #ifdef TEST + *logofs << "Proxy: Failure flushing the writable " + << "proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + return -1; + } + + #ifdef DEBUG + *logofs << "Proxy: Clearing the write descriptor " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + FD_CLR(fd_, &writeSet); + + resultFds--; + } + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + resultFds > 0 && j != channelList.end(); j++) + { + #ifdef DEBUG + *logofs << "Proxy: Looping with current channel " + << *j << ".\n" << logofs_flush; + #endif + + int fd = getFd(*j); + + if (fd >= 0 && FD_ISSET(fd, &writeSet)) + { + #ifdef TEST + *logofs << "Proxy: X descriptor FD#" << fd + << " reported to be writable.\n" + << logofs_flush; + #endif + + // + // It can happen that, in handling reads, we + // have destroyed the buffer associated to a + // closed socket, so don't complain about + // the errors. + // + + handleFlush(fd); + + // + // Clear the descriptor from the mask so + // we don't confuse the agent if it's + // not checking only its own descriptors. + // + + #ifdef DEBUG + *logofs << "Proxy: Clearing the write descriptor " + << "for FD#" << fd << ".\n" + << logofs_flush; + #endif + + FD_CLR(fd, &writeSet); + + resultFds--; + } + } + + return 1; +} + +int Proxy::handleRead() +{ + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Decoding data from proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + // + // Decode all the available messages from + // the remote proxy until is not possible + // to read more. + // + + for (;;) + { + int result = readBuffer_.readMessage(); + + #if defined(TEST) || defined(DEBUG) || defined(INFO) + *logofs << "Proxy: Read result on proxy FD#" << fd_ + << " is " << result << ".\n" + << logofs_flush; + #endif + + if (result < 0) + { + if (shutdown_ == 0) + { + if (finish_ == 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Failure reading from the " + << "peer proxy on FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure reading from the " + << "peer proxy.\n"; + } + } + #ifdef TEST + else + { + *logofs << "Proxy: Closure of the proxy link detected " + << "after clean shutdown.\n" << logofs_flush; + } + #endif + + priority_ = 0; + finish_ = 1; + congestion_ = 0; + + return -1; + } + else if (result == 0) + { + #if defined(TEST) || defined(DEBUG) || defined(INFO) + *logofs << "Proxy: No data read from proxy FD#" + << fd_ << "\n" << logofs_flush; + #endif + + return 0; + } + + // + // We read some data from the remote. If we set + // the congestion flag because we couldn't read + // before the timeout and have tokens available, + // then reset the congestion flag. + // + + if (congestion_ == 1 && + tokens_[token_control].remaining > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Exiting congestion due to " + << "proxy data with " << tokens_[token_control].remaining + << " tokens.\n" << logofs_flush; + #endif + + congestion_ = 0; + } + + // + // Set the timestamp of the last read + // operation from the remote proxy and + // enable again showing the 'no data + // received' dialog at the next timeout. + // + + timeouts_.readTs = getTimestamp(); + + if (alert_ != 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Displacing the dialog " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + HandleAlert(DISPLACE_MESSAGE_ALERT, 1); + } + + timeouts_.alertTs = nullTimestamp(); + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Getting messages from proxy FD#" << fd_ + << " with " << readBuffer_.getLength() << " bytes " + << "in the read buffer.\n" << logofs_flush; + #endif + + unsigned int controlLength; + unsigned int dataLength; + + const unsigned char *message; + + while ((message = readBuffer_.getMessage(controlLength, dataLength)) != NULL) + { + statistics -> addFrameIn(); + + if (controlLength == 3 && *message == 0 && + *(message + 1) < code_last_tag) + { + if (handleControlFromProxy(message) < 0) + { + return -1; + } + } + else if (operation_ == operation_in_messages) + { + int channelId = inputChannel_; + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Identified message of " << dataLength + << " bytes for FD#" << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + if (channelId >= 0 && channelId < CONNECTIONS_LIMIT && + channels_[channelId] != NULL) + { + int finish = channels_[channelId] -> getFinish(); + + #ifdef WARNING + + if (finish == 1) + { + *logofs << "Proxy: WARNING! Handling data for finishing " + << "FD#" << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + } + + #endif + + // + // We need to decode all the data to preserve + // the consistency of the cache, so can't re- + // turn as soon as the first error is encount- + // ered. Check if this is the first time that + // the failure is detected. + // + + int result = channels_[channelId] -> handleWrite(message, dataLength); + + if (result < 0 && finish == 0) + { + #ifdef TEST + *logofs << "Proxy: Failed to write proxy data to FD#" + << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + if (handleFinish(channelId) < 0) + { + return -1; + } + } + + // + // Check if we have splits or motion + // events to send. + // + + setSplitTimeout(channelId); + setMotionTimeout(channelId); + } + #ifdef WARNING + else + { + *logofs << "Proxy: WARNING! Received data for " + << "invalid channel ID#" << channelId + << ".\n" << logofs_flush; + } + #endif + } + else if (operation_ == operation_in_statistics) + { + #ifdef TEST + *logofs << "Proxy: Received statistics data from remote proxy.\n" + << logofs_flush; + #endif + + if (handleStatisticsFromProxy(message, dataLength) < 0) + { + return -1; + } + + operation_ = operation_in_messages; + } + else if (operation_ == operation_in_negotiation) + { + #ifdef TEST + *logofs << "Proxy: Received new negotiation data from remote proxy.\n" + << logofs_flush; + #endif + + if (handleNegotiationFromProxy(message, dataLength) < 0) + { + return -1; + } + } + + // + // if (controlLength == 3 && *message == 0 && ...) ... + // else if (operation_ == operation_in_statistics) ... + // else if (operation_ == operation_in_messages) ... + // else if (operation_ == operation_in_negotiation) ... + // else ... + // + + else + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Unrecognized message received on proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unrecognized message received on proxy FD#" + << fd_ << ".\n"; + + return -1; + } + + } // while ((message = readBuffer_.getMessage(controlLength, dataLength)) != NULL) ... + + // + // Reset the read buffer. + // + + readBuffer_.fullReset(); + + // + // Give up if no data is readable. + // + + if (transport_ -> readable() == 0) + { + break; + } + + } // End of for (;;) ... + + return 1; +} + +int Proxy::handleControlFromProxy(const unsigned char *message) +{ + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Received message '" << DumpControl(*(message + 1)) + << "' at " << strMsTimestamp() << " with data ID#" + << (int) *(message + 2) << ".\n" << logofs_flush; + #endif + + T_channel_type channelType = channel_none; + + switch (*(message + 1)) + { + case code_switch_connection: + { + int channelId = *(message + 2); + + // + // If channel is invalid further messages will + // be ignored. The acknowledged shutdown of + // channels should prevent this. + // + + inputChannel_ = channelId; + + break; + } + case code_begin_congestion: + { + // + // Set the congestion state for the + // channel reported by the remote. + // + + int channelId = *(message + 2); + + if (channels_[channelId] != NULL) + { + congestions_[channelId] = 1; + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Received a begin congestion " + << "for channel id ID#" << channelId + << ".\n" << logofs_flush; + #endif + + if (channelId == agent_ && congestions_[agent_] != 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Forcing an update of the congestion " + << "counter with agent congested.\n" + << logofs_flush; + #endif + + statistics -> updateCongestion(-tokens_[token_control].remaining, + tokens_[token_control].limit); + } + } + #ifdef WARNING + else + { + *logofs << "Proxy: WARNING! Received a begin congestion " + << "for invalid channel id ID#" << channelId + << ".\n" << logofs_flush; + } + #endif + + break; + } + case code_end_congestion: + { + // + // Attend again to the channel. + // + + int channelId = *(message + 2); + + if (channels_[channelId] != NULL) + { + congestions_[channelId] = 0; + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Received an end congestion " + << "for channel id ID#" << channelId + << ".\n" << logofs_flush; + #endif + + if (channelId == agent_ && congestions_[agent_] != 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Forcing an update of the congestion " + << "counter with agent decongested.\n" + << logofs_flush; + #endif + + statistics -> updateCongestion(tokens_[token_control].remaining, + tokens_[token_control].limit); + } + } + #ifdef WARNING + else + { + *logofs << "Proxy: WARNING! Received an end congestion " + << "for invalid channel id ID#" << channelId + << ".\n" << logofs_flush; + } + #endif + + break; + } + case code_control_token_request: + { + T_proxy_token &token = tokens_[token_control]; + + if (handleTokenFromProxy(token, *(message + 2)) < 0) + { + return -1; + } + + break; + } + case code_split_token_request: + { + T_proxy_token &token = tokens_[token_split]; + + if (handleTokenFromProxy(token, *(message + 2)) < 0) + { + return -1; + } + + break; + } + case code_data_token_request: + { + T_proxy_token &token = tokens_[token_data]; + + if (handleTokenFromProxy(token, *(message + 2)) < 0) + { + return -1; + } + + break; + } + case code_control_token_reply: + { + T_proxy_token &token = tokens_[token_control]; + + if (handleTokenReplyFromProxy(token, *(message + 2)) < 0) + { + return -1; + } + + break; + } + case code_split_token_reply: + { + T_proxy_token &token = tokens_[token_split]; + + if (handleTokenReplyFromProxy(token, *(message + 2)) < 0) + { + return -1; + } + + break; + } + case code_data_token_reply: + { + T_proxy_token &token = tokens_[token_data]; + + if (handleTokenReplyFromProxy(token, *(message + 2)) < 0) + { + return -1; + } + + break; + } + case code_new_x_connection: + { + // + // Opening the channel is handled later. + // + + channelType = channel_x11; + + break; + } + case code_new_cups_connection: + { + channelType = channel_cups; + + break; + } + case code_new_aux_connection: + { + // + // Starting from version 1.5.0 we create real X + // connections for the keyboard channel. We need + // to refuse old auxiliary X connections because + // they would be unable to leverage the new fake + // authorization cookie. + // + + #ifdef WARNING + *logofs << "Proxy: WARNING! Can't open outdated auxiliary X " + << "channel for code " << *(message + 1) << ".\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Can't open outdated auxiliary X " + << "channel for code " << *(message + 1) << ".\n"; + + if (handleControl(code_drop_connection, *(message + 2)) < 0) + { + return -1; + } + + break; + } + case code_new_smb_connection: + { + channelType = channel_smb; + + break; + } + case code_new_media_connection: + { + channelType = channel_media; + + break; + } + case code_new_http_connection: + { + channelType = channel_http; + + break; + } + case code_new_font_connection: + { + channelType = channel_font; + + break; + } + case code_new_slave_connection: + { + channelType = channel_slave; + + break; + } + case code_drop_connection: + { + int channelId = *(message + 2); + + if (channelId >= 0 && channelId < CONNECTIONS_LIMIT && + channels_[channelId] != NULL) + { + handleDropFromProxy(channelId); + } + #ifdef WARNING + else + { + *logofs << "Proxy: WARNING! Received a drop message " + << "for invalid channel id ID#" << channelId + << ".\n" << logofs_flush; + } + #endif + + break; + } + case code_finish_connection: + { + int channelId = *(message + 2); + + if (channelId >= 0 && channelId < CONNECTIONS_LIMIT && + channels_[channelId] != NULL) + { + // + // Force the finish state on the channel. + // We can receive this message while in + // the read loop, so we only mark the + // channel for deletion. + // + + #ifdef TEST + *logofs << "Proxy: Received a finish message for FD#" + << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + handleFinishFromProxy(channelId); + } + #ifdef WARNING + else + { + *logofs << "Proxy: WARNING! Received a finish message " + << "for invalid channel id ID#" << channelId + << ".\n" << logofs_flush; + } + #endif + + break; + } + case code_finish_listeners: + { + // + // This is from the main loop. + // + + #ifdef TEST + *logofs << "Proxy: Closing down all local listeners.\n" + << logofs_flush; + #endif + + CleanupListeners(); + + finish_ = 1; + + break; + } + case code_reset_request: + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Proxy reset not supported " + << "in this version.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Proxy reset not supported " + << "in this version.\n"; + + HandleCleanup(); + } + case code_shutdown_request: + { + // + // Time to rest in peace. + // + + shutdown_ = 1; + + break; + } + case code_load_request: + { + if (handleLoadFromProxy() < 0) + { + return -1; + } + + break; + } + case code_save_request: + { + // + // Don't abort the connection + // if can't write to disk. + // + + handleSaveFromProxy(); + + break; + } + case code_statistics_request: + { + int type = *(message + 2); + + if (handleStatisticsFromProxy(type) < 0) + { + return -1; + } + + break; + } + case code_statistics_reply: + { + operation_ = operation_in_statistics; + + break; + } + case code_alert_request: + { + HandleAlert(*(message + 2), 1); + + break; + } + case code_sync_request: + { + int channelId = *(message + 2); + + if (handleSyncFromProxy(channelId) < 0) + { + return -1; + } + + break; + } + case code_sync_reply: + { + // + // We are not the one that issued + // the request. + // + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: PANIC! Received an unexpected " + << "synchronization reply.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Received an unexpected " + << "synchronization reply.\n"; + + HandleCleanup(); + } + default: + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Received bad control message number " + << (unsigned int) *(message + 1) << " with attribute " + << (unsigned int) *(message + 2) << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Received bad control message number " + << (unsigned int) *(message + 1) << " with attribute " + << (unsigned int) *(message + 2) << ".\n"; + + HandleCleanup(); + } + + } // End of switch (*(message + 1)) ... + + if (channelType == channel_none) + { + return 1; + } + + // + // Handle the channel allocation that we + // left from the main switch case. + // + + int channelId = *(message + 2); + + // + // Check if the channel has been dropped. + // + + if (channels_[channelId] != NULL && + (channels_[channelId] -> getDrop() == 1 || + channels_[channelId] -> getClosing() == 1)) + { + #ifdef TEST + *logofs << "Proxy: Dropping the descriptor FD#" + << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + handleDrop(channelId); + } + + // + // Check if the channel is in the valid + // range. + // + + int result = checkChannelMap(channelId); + + if (result >= 0) + { + result = handleNewConnectionFromProxy(channelType, channelId); + } + + if (result < 0) + { + // + // Realization of new channel failed. + // Send channel shutdown message to + // the peer proxy. + // + + if (handleControl(code_drop_connection, channelId) < 0) + { + return -1; + } + } + else + { + int fd = getFd(channelId); + + if (getReadable(fd) > 0) + { + #ifdef TEST + *logofs << "Proxy: Trying to read immediately " + << "from descriptor FD#" << fd << ".\n" + << logofs_flush; + #endif + + if (handleRead(fd) < 0) + { + return -1; + } + } + #ifdef TEST + *logofs << "Proxy: Nothing to read immediately " + << "from descriptor FD#" << fd << ".\n" + << logofs_flush; + #endif + } + + return 1; +} + +int Proxy::handleRead(int fd, const char *data, int size) +{ + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Handling data for connection on FD#" + << fd << ".\n" << logofs_flush; + #endif + + if (canRead(fd) == 0) + { + #if defined(TEST) || defined(INFO) + + if (getChannel(fd) < 0) + { + *logofs << "Proxy: PANIC! Can't read from invalid FD#" + << fd << ".\n" << logofs_flush; + + HandleCleanup(); + } + else + { + *logofs << "Proxy: WARNING! Read method called for FD#" + << fd << " but operation is not possible.\n" + << logofs_flush; + } + + #endif + + return 0; + } + + int channelId = getChannel(fd); + + // + // Let the channel object read all the new data from + // its file descriptor, isolate messages, compress + // those messages, and append the compressed form to + // the encode buffer. + // + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Reading messages from FD#" << fd + << " channel ID#" << channelId << ".\n" + << logofs_flush; + #endif + + int result = channels_[channelId] -> handleRead(encodeBuffer_, (const unsigned char *) data, + (unsigned int) size); + + // + // Even in the case of a failure, write the produced + // data to the proxy connection. To keep the stores + // synchronized, the remote side needs to decode any + // message encoded by this side, also if the X socket + // was closed in the meanwhile. If this is the case, + // the decompressed output will be silently discarded. + // + + if (result < 0) + { + #ifdef TEST + *logofs << "Proxy: Failed to read data from connection FD#" + << fd << " channel ID#" << channelId << ".\n" + << logofs_flush; + #endif + + if (handleFinish(channelId) < 0) + { + return -1; + } + } + + // + // Check if there are new splits or + // motion events to send. + // + + setSplitTimeout(channelId); + setMotionTimeout(channelId); + + return 1; +} + +int Proxy::handleEvents() +{ + #ifdef TEST + *logofs << "Proxy: Going to check the events on channels.\n" + << logofs_flush; + #endif + + // + // Check if we can safely write to the + // proxy link. + // + + int read = isTimeToRead(); + + // + // Loop on channels and send the pending + // events. We must copy the list because + // channels can be removed in the middle + // of the loop. + // + + T_list channelList = activeChannels_.copyList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] == NULL) + { + continue; + } + + // + // Check if we need to drop the channel. + // + + if (channels_[channelId] -> getDrop() == 1 || + channels_[channelId] -> getClosing() == 1) + { + #ifdef TEST + *logofs << "Proxy: Dropping the descriptor FD#" + << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + if (handleDrop(channelId) < 0) + { + return -1; + } + + continue; + } + else if (channels_[channelId] -> getFinish() == 1) + { + #ifdef TEST + *logofs << "Proxy: Skipping finishing " + << "descriptor FD#" << getFd(channelId) + << " channel ID#" << channelId << ".\n" + << logofs_flush; + #endif + + continue; + } + + // + // If the proxy link or the channel is + // in congestion state, don't handle + // the further events. + // + + if (read == 0 || congestions_[channelId] == 1) + { + #ifdef TEST + + if (read == 0) + { + *logofs << "Proxy: Can't handle events for FD#" + << getFd(channelId) << " channel ID#" + << channelId << " with proxy not available.\n" + << logofs_flush; + } + else + { + *logofs << "Proxy: Can't handle events for FD#" + << getFd(channelId) << " channel ID#" + << channelId << " with channel congested.\n" + << logofs_flush; + } + + #endif + + continue; + } + + // + // Handle the timeouts on the channel + // operations. + // + + int result = 0; + + // + // Handle the motion events. + // + + if (result >= 0 && channels_[channelId] -> needMotion() == 1) + { + if (isTimeToMotion() == 1) + { + #if defined(TEST) || defined(INFO) || defined(FLUSH) + + *logofs << "Proxy: FLUSH! Motion timeout expired after " + << diffTimestamp(timeouts_.motionTs, getTimestamp()) + << " Ms.\n" << logofs_flush; + + #endif + + result = channels_[channelId] -> handleMotion(encodeBuffer_); + + #ifdef TEST + + if (result < 0) + { + *logofs << "Proxy: Failed to handle motion events for FD#" + << getFd(channelId) << " channel ID#" << channelId + << ".\n" << logofs_flush; + } + + #endif + + timeouts_.motionTs = nullTimestamp(); + + setMotionTimeout(channelId); + } + #if defined(TEST) || defined(INFO) + else if (isTimestamp(timeouts_.motionTs) == 1) + { + *logofs << "Proxy: Running with " + << diffTimestamp(timeouts_.motionTs, getTimestamp()) + << " Ms elapsed since the last motion.\n" + << logofs_flush; + } + #endif + } + + if (result >= 0 && channels_[channelId] -> needSplit() == 1) + { + // + // Check if it is time to send more splits + // and how many bytes are going to be sent. + // + + if (isTimeToSplit() == 1) + { + #if defined(TEST) || defined(INFO) || defined(SPLIT) + *logofs << "Proxy: SPLIT! Split timeout expired after " + << diffTimestamp(timeouts_.splitTs, getTimestamp()) + << " Ms.\n" << logofs_flush; + #endif + + #if defined(TEST) || defined(INFO) || defined(SPLIT) + + *logofs << "Proxy: SPLIT! Encoding splits for FD#" + << getFd(channelId) << " at " << strMsTimestamp() + << " with " << clientStore_ -> getSplitTotalStorageSize() + << " total bytes and " << control -> SplitDataPacketLimit + << " bytes " << "to write.\n" + << logofs_flush; + + #endif + + result = channels_[channelId] -> handleSplit(encodeBuffer_); + + #ifdef TEST + + if (result < 0) + { + *logofs << "Proxy: Failed to handle splits for FD#" + << getFd(channelId) << " channel ID#" << channelId + << ".\n" << logofs_flush; + } + + #endif + + timeouts_.splitTs = nullTimestamp(); + + setSplitTimeout(channelId); + } + #if defined(TEST) || defined(INFO) || defined(SPLIT) + else if (channels_[channelId] -> needSplit() == 1 && + isTimestamp(timeouts_.splitTs) == 0) + { + *logofs << "Proxy: SPLIT! WARNING! Channel for FD#" + << getFd(channelId) << " has split to send but " + << "there is no timeout.\n" << logofs_flush; + } + else if (isTimestamp(timeouts_.splitTs) == 1) + { + *logofs << "Proxy: SPLIT! Running with " + << diffTimestamp(timeouts_.splitTs, getTimestamp()) + << " Ms elapsed since the last split.\n" + << logofs_flush; + } + #endif + } + + if (result < 0) + { + #ifdef TEST + *logofs << "Proxy: Error handling events for FD#" + << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + if (handleFinish(channelId) < 0) + { + return -1; + } + } + } + + return 1; +} + +int Proxy::handleFrame(T_frame_type type) +{ + // + // Write any outstanding control message, followed by the + // content of the encode buffer, to the proxy transport. + // + // This code assumes that the encode buffer data is at an + // offset several bytes from start of the buffer, so that + // the length header and any necessary control bytes can + // be inserted in front of the data already in the buffer. + // This is the easiest way to encapsulate header and data + // together in a single frame. + // + // The way framing is implemented is very efficient but + // inherently limited and does not allow for getting the + // best performance, especially when running over a fast + // link. Framing should be rewritten to include the length + // of the packets in a fixed size header and, possibly, + // to incapsulate the control messages and the channel's + // data in a pseudo X protocol message, so that the proxy + // itself would be treated like any other channel. + // + + #if defined(TEST) || defined(INFO) + + if (congestion_ == 1) + { + // + // This can happen because there may be control + // messages to send, like a proxy shutdown mes- + // sage or a statistics request. All the other + // cases should be considered an error. + // + + #ifdef WARNING + *logofs << "Proxy: WARNING! Data is to be sent while " + << "congestion is " << congestion_ << ".\n" + << logofs_flush; + #endif + } + + #endif + + // + // Check if there is any data available on + // the socket. Recent Linux kernels are very + // picky. They require that we read often or + // they assume that the process is non-inter- + // active. + // + + if (handleAsyncEvents() < 0) + { + return -1; + } + + // + // Check if this is a ping, not a data frame. + // + + if (type == frame_ping) + { + if (handleToken(frame_ping) < 0) + { + return -1; + } + } + + unsigned int dataLength = encodeBuffer_.getLength(); + + #ifdef DEBUG + *logofs << "Proxy: Data length is " << dataLength + << " control length is " << controlLength_ + << ".\n" << logofs_flush; + #endif + + if (dataLength > 0) + { + // + // If this is a generic channel we need + // to add the completion bits. Data can + // also have been encoded because of a + // statistics request, even if no output + // channel was currently selected. + // + + if (outputChannel_ != -1) + { + #if defined(TEST) || defined(INFO) + + if (channels_[outputChannel_] == NULL) + { + *logofs << "Proxy: PANIC! A new frame was requested " + << "but the channel is invalid.\n" + << logofs_flush; + + HandleCleanup(); + } + + #endif + + channels_[outputChannel_] -> handleCompletion(encodeBuffer_); + + dataLength = encodeBuffer_.getLength(); + } + } + else if (controlLength_ == 0) + { + #if defined(TEST) || defined(INFO) + + *logofs << "Proxy: PANIC! A new frame was requested " + << "but there is no data to write.\n" + << logofs_flush; + + HandleCleanup(); + + #endif + + return 0; + } + + #ifdef DEBUG + *logofs << "Proxy: Data length is now " << dataLength + << " control length is " << controlLength_ + << ".\n" << logofs_flush; + #endif + + // + // Check if this frame needs to carry a new + // token request. + // + + if (type == frame_data) + { + if (handleToken(frame_data) < 0) + { + return -1; + } + } + + #ifdef DEBUG + *logofs << "Proxy: Adding a new frame for the remote proxy.\n" + << logofs_flush; + #endif + + unsigned char temp[5]; + + unsigned int lengthLength = 0; + unsigned int shift = dataLength; + + while (shift) + { + temp[lengthLength++] = (unsigned char) (shift & 0x7f); + + shift >>= 7; + } + + unsigned char *data = encodeBuffer_.getData(); + + unsigned char *outputMessage = data - (controlLength_ + lengthLength); + + unsigned char *nextDest = outputMessage; + + for (int i = 0; i < controlLength_; i++) + { + *nextDest++ = controlCodes_[i]; + } + + for (int j = lengthLength - 1; j > 0; j--) + { + *nextDest++ = (temp[j] | 0x80); + } + + if (lengthLength) + { + *nextDest++ = temp[0]; + } + + unsigned int outputLength = dataLength + controlLength_ + lengthLength; + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Produced plain output for " << dataLength << "+" + << controlLength_ << "+" << lengthLength << " out of " + << outputLength << " bytes.\n" << logofs_flush; + #endif + + #if defined(TEST) || defined(INFO) || defined(FLUSH) || defined(TIME) + + T_timestamp nowTs = getTimestamp(); + + *logofs << "Proxy: FLUSH! Immediate with blocked " << transport_ -> + blocked() << " length " << transport_ -> length() + << " new " << outputLength << " flushable " << transport_ -> + flushable() << " tokens " << tokens_[token_control].remaining + << " after " << diffTimestamp(timeouts_.writeTs, nowTs) + << " Ms.\n" << logofs_flush; + + *logofs << "Proxy: FLUSH! Immediate flush to proxy FD#" << fd_ + << " of " << outputLength << " bytes at " << strMsTimestamp() + << " with priority " << priority_ << ".\n" << logofs_flush; + + *logofs << "Proxy: FLUSH! Current bitrate is " + << statistics -> getBitrateInShortFrame() << " with " + << statistics -> getBitrateInLongFrame() << " in the " + << "long frame and top " << statistics -> + getTopBitrate() << ".\n" << logofs_flush; + #endif + + statistics -> addWriteOut(); + + int result = transport_ -> write(write_immediate, outputMessage, outputLength); + + #ifdef TIME + + if (diffTimestamp(timeouts_.writeTs, nowTs) > 50) + { + *logofs << "Proxy: WARNING! TIME! Data written to proxy FD#" + << fd_ << " at " << strMsTimestamp() << " after " + << diffTimestamp(timeouts_.writeTs, nowTs) + << " Ms.\n" << logofs_flush; + } + + #endif + + #ifdef DUMP + *logofs << "Proxy: Sent " << outputLength << " bytes of data " + << "with checksum "; + + DumpChecksum(outputMessage, outputLength); + + *logofs << " on proxy FD#" << fd_ << ".\n" << logofs_flush; + #endif + + #ifdef DUMP + *logofs << "Proxy: Partial checksums are:\n"; + + DumpBlockChecksums(outputMessage, outputLength, 256); + + *logofs << logofs_flush; + #endif + + // + // Clean up the encode buffer and + // bring it to the initial size. + // + + encodeBuffer_.fullReset(); + + // + // Close the connection if we got + // an error. + // + + if (result < 0) + { + #ifdef TEST + *logofs << "Proxy: Failed write to proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + return -1; + } + + // + // Account for the data frame and the + // framing overhead. + // + + if (dataLength > 0) + { + statistics -> addFrameOut(); + } + + statistics -> addFramingBits((controlLength_ + lengthLength) << 3); + + controlLength_ = 0; + + // + // Reset all buffers, counters and the + // priority flag. + // + + handleResetFlush(); + + // + // Check if more data became available + // after writing. + // + + if (handleAsyncEvents() < 0) + { + return -1; + } + + // + // Drain the proxy link if we are in + // congestion state. + // + // if (needDrain() == 1 && draining_ == 0) + // { + // if (handleDrain() < 0) + // { + // return -1; + // } + // } + // + + return result; +} + +int Proxy::handleFlush() +{ + // + // We can have data in the encode buffer or + // control bytes to send. In the case make + // up a new frame. + // + + if (encodeBuffer_.getLength() + controlLength_ > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Flushing data in the encode buffer.\n" + << logofs_flush; + #endif + + priority_ = 1; + + if (handleFrame(frame_data) < 0) + { + return -1; + } + } + + // + // Check if we have something to write. + // + + if (transport_ -> length() + transport_ -> flushable() == 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Nothing else to flush for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + return 0; + } + + #if defined(TEST) || defined(INFO) + + if (transport_ -> blocked() == 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Proxy descriptor FD#" << fd_ + << " has data to flush but the transport " + << "is not blocked.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Proxy descriptor FD#" << fd_ + << " has data to flush but the transport " + << "is not blocked.\n"; + + HandleCleanup(); + } + + #endif + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "Proxy: FLUSH! Deferred with blocked " << transport_ -> + blocked() << " length " << transport_ -> length() + << " flushable " << transport_ -> flushable() << " tokens " + << tokens_[token_control].remaining << ".\n" + << logofs_flush; + + *logofs << "Proxy: FLUSH! Deferred flush to proxy FD#" << fd_ + << " of " << transport_ -> length() + transport_ -> + flushable() << " bytes at " << strMsTimestamp() + << " with priority " << priority_ << ".\n" + << logofs_flush; + + *logofs << "Proxy: FLUSH! Current bitrate is " + << statistics -> getBitrateInShortFrame() << " with " + << statistics -> getBitrateInLongFrame() << " in the " + << "long frame and top " << statistics -> + getTopBitrate() << ".\n" << logofs_flush; + #endif + + statistics -> addWriteOut(); + + int result = transport_ -> flush(); + + if (result < 0) + { + return -1; + } + + // + // Reset the counters and update the + // timestamp of the last write. + // + + handleResetFlush(); + + return result; +} + +int Proxy::handleDrain() +{ + // + // If the proxy is run in the same process + // as SSH, we can't block or the program + // would not have a chance to read or write + // its data. + // + + if (control -> LinkEncrypted == 1) + { + return 0; + } + + if (needDrain() == 0 || draining_ == 1) + { + #if defined(TEST) || defined(INFO) + + if (draining_ == 1) + { + *logofs << "Proxy: WARNING! Already draining proxy FD#" + << fd_ << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + } + else + { + *logofs << "Proxy: WARNING! No need to drain proxy FD#" + << fd_ << " with congestion " << congestion_ + << " length " << transport_ -> length() + << " and blocked " << transport_ -> blocked() + << ".\n" << logofs_flush; + } + + #endif + + return 0; + } + + draining_ = 1; + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Going to drain the proxy FD#" << fd_ + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + int timeout = control -> PingTimeout / 2; + + T_timestamp startTs = getNewTimestamp(); + + T_timestamp nowTs = startTs; + + int remaining; + int result; + + // + // Keep draining the proxy socket while + // reading the incoming messages until + // the timeout is expired. + // + + for (;;) + { + remaining = timeout - diffTimestamp(startTs, nowTs); + + if (remaining <= 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Timeout raised while draining " + << "FD#" << fd_ << " at " << strMsTimestamp() + << " after " << diffTimestamp(startTs, nowTs) + << " Ms.\n" << logofs_flush; + #endif + + result = 0; + + goto ProxyDrainEnd; + } + + if (transport_ -> length() > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Trying to write to FD#" << fd_ + << " at " << strMsTimestamp() << " with length " + << transport_ -> length() << " and " + << remaining << " Ms remaining.\n" + << logofs_flush; + #endif + + result = transport_ -> drain(0, remaining); + + if (result == -1) + { + result = -1; + + goto ProxyDrainEnd; + } + else if (result == 0 && transport_ -> readable() > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Decoding more data from proxy FD#" + << fd_ << " at " << strMsTimestamp() << " with " + << transport_ -> length() << " bytes to write and " + << transport_ -> readable() << " readable.\n" + << logofs_flush; + #endif + + if (handleRead() < 0) + { + result = -1; + + goto ProxyDrainEnd; + } + } + #if defined(TEST) || defined(INFO) + else if (result == 1) + { + *logofs << "Proxy: Transport for proxy FD#" << fd_ + << " drained down to " << transport_ -> length() + << " bytes.\n" << logofs_flush; + } + #endif + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Waiting for more data from proxy " + << "FD#" << fd_ << " at " << strMsTimestamp() + << " with " << remaining << " Ms remaining.\n" + << logofs_flush; + #endif + + + result = transport_ -> wait(remaining); + + if (result == -1) + { + result = -1; + + goto ProxyDrainEnd; + } + else if (result > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Decoding more data from proxy FD#" + << fd_ << " at " << strMsTimestamp() << " with " + << transport_ -> readable() << " bytes readable.\n" + << logofs_flush; + #endif + + if (handleRead() < 0) + { + result = -1; + + goto ProxyDrainEnd; + } + } + } + + // + // Check if we finally got the tokens + // that would allow us to come out of + // the congestion state. + // + + if (needDrain() == 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Got decongestion for proxy FD#" + << fd_ << " at " << strMsTimestamp() << " after " + << diffTimestamp(startTs, getTimestamp()) + << " Ms.\n" << logofs_flush; + #endif + + result = 1; + + goto ProxyDrainEnd; + } + + nowTs = getNewTimestamp(); + } + +ProxyDrainEnd: + + draining_ = 0; + + return result; +} + +int Proxy::handleFlush(int fd) +{ + int channelId = getChannel(fd); + + if (channelId < 0 || channels_[channelId] == NULL) + { + #ifdef TEST + *logofs << "Proxy: WARNING! Skipping flush on invalid " + << "descriptor FD#" << fd << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + return 0; + } + else if (channels_[channelId] -> getFinish() == 1) + { + #ifdef TEST + *logofs << "Proxy: Skipping flush on finishing " + << "descriptor FD#" << fd << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + return 0; + } + + #ifdef TEST + *logofs << "Proxy: Going to flush FD#" << fd + << " with blocked " << transports_[channelId] -> blocked() + << " length " << transports_[channelId] -> length() + << ".\n" << logofs_flush; + #endif + + if (channels_[channelId] -> handleFlush() < 0) + { + #ifdef TEST + *logofs << "Proxy: Failed to flush data to FD#" + << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + handleFinish(channelId); + + return -1; + } + + return 1; +} + +int Proxy::handleStatistics(int type, ostream *stream) +{ + if (stream == NULL || control -> EnableStatistics == 0) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! Cannot produce statistics " + << " for proxy FD#" << fd_ << ". Invalid settings " + << "for statistics or stream.\n" << logofs_flush; + #endif + + return 0; + } + else if (currentStatistics_ != NULL) + { + // + // Need to update the stream pointer as the + // previous one could have been destroyed. + // + + #ifdef WARNING + *logofs << "Proxy: WARNING! Replacing stream while producing " + << "statistics in stream at " << currentStatistics_ + << " for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + } + + currentStatistics_ = stream; + + // + // Get statistics of remote peer. + // + + if (handleControl(code_statistics_request, type) < 0) + { + return -1; + } + + return 1; +} + +int Proxy::handleStatisticsFromProxy(int type) +{ + if (needFlush() == 1) + { + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "Proxy: WARNING! Data for the previous " + << "channel ID#" << outputChannel_ + << " flushed in statistics.\n" + << logofs_flush; + #endif + + if (handleFrame(frame_data) < 0) + { + return -1; + } + } + + if (control -> EnableStatistics == 1) + { + // + // Allocate a buffer for the output. + // + + char *buffer = new char[STATISTICS_LENGTH]; + + *buffer = '\0'; + + if (control -> ProxyMode == proxy_client) + { + #ifdef TEST + *logofs << "Proxy: Producing " + << (type == TOTAL_STATS ? "total" : "partial") + << " client statistics for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + statistics -> getClientProtocolStats(type, buffer); + + statistics -> getClientOverallStats(type, buffer); + } + else + { + #ifdef TEST + *logofs << "Proxy: Producing " + << (type == TOTAL_STATS ? "total" : "partial") + << " server statistics for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + statistics -> getServerProtocolStats(type, buffer); + } + + if (type == PARTIAL_STATS) + { + statistics -> resetPartialStats(); + } + + unsigned int length = strlen((char *) buffer) + 1; + + encodeBuffer_.encodeValue(type, 8); + + encodeBuffer_.encodeValue(length, 32); + + #ifdef TEST + *logofs << "Proxy: Encoding " << length + << " bytes of statistics data for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + encodeBuffer_.encodeMemory((unsigned char *) buffer, length); + + // + // Account statistics data as framing bits. + // + + statistics -> addFramingBits(length << 3); + + delete [] buffer; + } + else + { + #ifdef WARNING + *logofs << "Proxy: WARNING! Got statistics request " + << "but local statistics are disabled.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Got statistics request " + << "but local statistics are disabled.\n"; + + type = NO_STATS; + + encodeBuffer_.encodeValue(type, 8); + + #ifdef TEST + *logofs << "Proxy: Sending error code to remote proxy on FD#" + << fd_ << ".\n" << logofs_flush; + #endif + } + + // + // The next write will flush the statistics + // data and the control message. + // + + if (handleControl(code_statistics_reply, type) < 0) + { + return -1; + } + + return 1; +} + +int Proxy::handleStatisticsFromProxy(const unsigned char *message, unsigned int length) +{ + if (currentStatistics_ == NULL) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! Unexpected statistics data received " + << "from remote proxy on FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Unexpected statistics data received " + << "from remote proxy.\n"; + + return 0; + } + + // + // Allocate the decode buffer and at least + // the 'type' field to see if there was an + // error. + // + + DecodeBuffer decodeBuffer(message, length); + + unsigned int type; + + decodeBuffer.decodeValue(type, 8); + + if (type == NO_STATS) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Couldn't get statistics from remote " + << "proxy on FD#" << fd_ << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Couldn't get statistics from remote proxy.\n"; + } + else if (type != TOTAL_STATS && type != PARTIAL_STATS) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Cannot produce statistics " + << "with qualifier '" << type << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Cannot produce statistics " + << "with qualifier '" << type << "'.\n"; + + return -1; + } + else + { + unsigned int size; + + decodeBuffer.decodeValue(size, 32); + + char *buffer = new char[STATISTICS_LENGTH]; + + *buffer = '\0'; + + if (control -> EnableStatistics == 1) + { + if (control -> ProxyMode == proxy_client) + { + #ifdef TEST + *logofs << "Proxy: Finalizing " + << (type == TOTAL_STATS ? "total" : "partial") + << " client statistics for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + statistics -> getClientCacheStats(type, buffer); + + #ifdef TEST + *logofs << "Proxy: Decoding " << size + << " bytes of statistics data for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + strncat(buffer, (char *) decodeBuffer.decodeMemory(size), size); + + statistics -> getClientProtocolStats(type, buffer); + + statistics -> getClientOverallStats(type, buffer); + } + else + { + #ifdef TEST + *logofs << "Proxy: Finalizing " + << (type == TOTAL_STATS ? "total" : "partial") + << " server statistics for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + statistics -> getServerCacheStats(type, buffer); + + statistics -> getServerProtocolStats(type, buffer); + + #ifdef TEST + *logofs << "Proxy: Decoding " << size + << " bytes of statistics data for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + strncat(buffer, (char *) decodeBuffer.decodeMemory(size), size); + } + + if (type == PARTIAL_STATS) + { + statistics -> resetPartialStats(); + } + + *currentStatistics_ << buffer; + + // + // Mark the end of text to help external parsing. + // + + *currentStatistics_ << '\4'; + + *currentStatistics_ << flush; + } + else + { + // + // It can be that statistics were enabled at the time + // we issued the request (otherwise we could not have + // set the stream), but now they have been disabled + // by user. We must decode statistics data if we want + // to keep the connection. + // + + #ifdef TEST + *logofs << "Proxy: Discarding " << size + << " bytes of statistics data for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + strncat(buffer, (char *) decodeBuffer.decodeMemory(size), size); + } + + delete [] buffer; + } + + currentStatistics_ = NULL; + + return 1; +} + +int Proxy::handleNegotiation(const unsigned char *message, unsigned int length) +{ + #ifdef PANIC + *logofs << "Proxy: PANIC! Writing data during proxy " + << "negotiation is not implemented.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Writing data during proxy " + << "negotiation is not implemented.\n"; + + return -1; +} + +int Proxy::handleNegotiationFromProxy(const unsigned char *message, unsigned int length) +{ + #ifdef PANIC + *logofs << "Proxy: PANIC! Reading data during proxy " + << "negotiation is not implemented.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Reading data during proxy " + << "negotiation is not implemented.\n"; + + return -1; +} + +int Proxy::handleAlert(int alert) +{ + if (handleControl(code_alert_request, alert) < 0) + { + return -1; + } + + return 1; +} + +int Proxy::handleCloseConnection(int clientFd) +{ + int channelId = getChannel(clientFd); + + if (channels_[channelId] != NULL && + channels_[channelId] -> getFinish() == 0) + { + #ifdef TEST + *logofs << "Proxy: Closing down the channel for FD#" + << clientFd << ".\n" << logofs_flush; + #endif + + if (handleFinish(channelId) < 0) + { + return -1; + } + + return 1; + } + + return 0; +} + +int Proxy::handleCloseAllXConnections() +{ + #ifdef TEST + *logofs << "Proxy: Closing down any remaining X channel.\n" + << logofs_flush; + #endif + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL && + channels_[channelId] -> getType() == channel_x11 && + channels_[channelId] -> getFinish() == 0) + { + #ifdef TEST + *logofs << "Proxy: Closing down the channel for FD#" + << getFd(channelId) << ".\n" << logofs_flush; + #endif + + if (handleFinish(channelId) < 0) + { + return -1; + } + } + } + + return 1; +} + +int Proxy::handleCloseAllListeners() +{ + // Since ProtoStep7 (#issue 108) + if (finish_ == 0) + { + #ifdef TEST + *logofs << "Proxy: Closing down all remote listeners.\n" + << logofs_flush; + #endif + + if (handleControl(code_finish_listeners) < 0) + { + return -1; + } + + finish_ = 1; + } + + return 1; +} + +void Proxy::handleResetAlert() +{ + if (alert_ != 0) + { + #ifdef TEST + *logofs << "Proxy: The proxy alert '" << alert_ + << "' was displaced.\n" << logofs_flush; + #endif + + alert_ = 0; + } + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL) + { + channels_[channelId] -> handleResetAlert(); + } + } +} + +int Proxy::handleFinish(int channelId) +{ + // + // Send any outstanding encoded data and + // do any finalization needed on the + // channel. + // + + if (needFlush(channelId) == 1) + { + if (channels_[channelId] -> getFinish() == 1) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! The finishing channel ID#" + << channelId << " has data to flush.\n" + << logofs_flush; + #endif + } + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "Proxy: WARNING! Flushing data for the " + << "finishing channel ID#" << channelId + << ".\n" << logofs_flush; + #endif + + if (handleFrame(frame_data) < 0) + { + return -1; + } + } + + // + // Reset the congestion state and the + // timeouts, if needed. + // + + congestions_[channelId] = 0; + + setSplitTimeout(channelId); + setMotionTimeout(channelId); + + if (channels_[channelId] -> getFinish() == 0) + { + channels_[channelId] -> handleFinish(); + + // + // Force a failure in the case somebody + // would try to read from the channel. + // + + shutdown(getFd(channelId), SHUT_RD); + + // + // If the failure was not originated by + // the remote, send a channel shutdown + // message. + // + + if (channels_[channelId] -> getClosing() == 0) + { + #ifdef TEST + *logofs << "Proxy: Finishing channel for FD#" + << getFd(channelId) << " channel ID#" + << channelId << " because of failure.\n" + << logofs_flush; + #endif + + if (handleControl(code_finish_connection, channelId) < 0) + { + return -1; + } + } + } + + return 1; +} + +int Proxy::handleFinishFromProxy(int channelId) +{ + // + // Check if this channel has pending + // data to send. + // + + if (needFlush(channelId) == 1) + { + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "Proxy: WARNING! Flushing data for the " + << "finishing channel ID#" << channelId + << ".\n" << logofs_flush; + #endif + + if (handleFrame(frame_data) < 0) + { + return -1; + } + } + + // + // Mark the channel. We will free its + // resources at the next loop and will + // send the drop message to the remote. + // + + if (channels_[channelId] -> getClosing() == 0) + { + #ifdef TEST + *logofs << "Proxy: Marking channel for FD#" + << getFd(channelId) << " channel ID#" + << channelId << " as closing.\n" + << logofs_flush; + #endif + + channels_[channelId] -> handleClosing(); + } + + if (channels_[channelId] -> getFinish() == 0) + { + #ifdef TEST + *logofs << "Proxy: Finishing channel for FD#" + << getFd(channelId) << " channel ID#" + << channelId << " because of proxy.\n" + << logofs_flush; + #endif + + channels_[channelId] -> handleFinish(); + } + + if (handleFinish(channelId) < 0) + { + return -1; + } + + return 1; +} + +int Proxy::handleDropFromProxy(int channelId) +{ + // + // Only mark the channel. + // + + #ifdef TEST + *logofs << "Proxy: Marking channel for FD#" + << getFd(channelId) << " channel ID#" + << channelId << " as being dropped.\n" + << logofs_flush; + #endif + + if (channels_[channelId] -> getDrop() == 0) + { + channels_[channelId] -> handleDrop(); + } + + return 1; +} + +// +// Close the channel and deallocate all its +// resources. +// + +int Proxy::handleDrop(int channelId) +{ + // + // Check if this channel has pending + // data to send. + // + + if (needFlush(channelId) == 1) + { + if (channels_[channelId] -> getFinish() == 1) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! The dropping channel ID#" + << channelId << " has data to flush.\n" + << logofs_flush; + #endif + } + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "Proxy: WARNING! Flushing data for the " + << "dropping channel ID#" << channelId + << ".\n" << logofs_flush; + #endif + + if (handleFrame(frame_data) < 0) + { + return -1; + } + } + + #ifdef TEST + *logofs << "Proxy: Dropping channel for FD#" + << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + if (channels_[channelId] -> getFinish() == 0) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! The channel for FD#" + << getFd(channelId) << " channel ID#" + << channelId << " was not marked as " + << "finishing.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": The channel for FD#" + << getFd(channelId) << " channel ID#" + << channelId << " was not marked as " + << "finishing.\n"; + + channels_[channelId] -> handleFinish(); + } + + // + // Send the channel shutdown message + // to the peer proxy. + // + + if (channels_[channelId] -> getClosing() == 1) + { + if (handleControl(code_drop_connection, channelId) < 0) + { + return -1; + } + } + + // + // Get rid of the channel. + // + + if (channels_[channelId] -> getType() != channel_x11) + { + #ifdef TEST + *logofs << "Proxy: Closed connection to " + << getTypeName(channels_[channelId] -> getType()) + << " server.\n" << logofs_flush; + #endif + + cerr << "Info" << ": Closed connection to " + << getTypeName(channels_[channelId] -> getType()) + << " server.\n"; + } + + delete channels_[channelId]; + channels_[channelId] = NULL; + + cleanupChannelMap(channelId); + + // + // Get rid of the transport. + // + + deallocateTransport(channelId); + + congestions_[channelId] = 0; + + decreaseChannels(channelId); + + // + // Check if the channel was the + // one currently selected for + // output. + // + + if (outputChannel_ == channelId) + { + outputChannel_ = -1; + } + + return 1; +} + +// +// Send an empty message to the remote peer +// to verify if the link is alive and let +// the remote proxy detect a congestion. +// + +int Proxy::handlePing() +{ + T_timestamp nowTs = getTimestamp(); + + #if defined(DEBUG) || defined(PING) + + *logofs << "Proxy: Checking ping at " + << strMsTimestamp(nowTs) << logofs_flush; + + *logofs << " with last loop at " + << strMsTimestamp(timeouts_.loopTs) << ".\n" + << logofs_flush; + + *logofs << "Proxy: Last bytes in at " + << strMsTimestamp(timeouts_.readTs) << logofs_flush; + + *logofs << " last bytes out at " + << strMsTimestamp(timeouts_.writeTs) << ".\n" + << logofs_flush; + + *logofs << "Proxy: Last ping at " + << strMsTimestamp(timeouts_.pingTs) << ".\n" + << logofs_flush; + + #endif + + // + // Be sure we take into account any clock drift. This + // can be caused by the user changing the system timer + // or by small adjustments introduced by the operating + // system making the clock go backward. + // + + if (checkDiffTimestamp(timeouts_.loopTs, nowTs) == 0) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! Detected drift in system " + << "timer. Resetting to current time.\n" + << logofs_flush; + #endif + + timeouts_.pingTs = nowTs; + timeouts_.readTs = nowTs; + timeouts_.writeTs = nowTs; + } + + // + // Check timestamp of last read from remote proxy. It can + // happen that we stayed in the main loop long enough to + // have idle timeout expired, for example if the proxy was + // stopped and restarted or because of an extremely high + // load of the system. In this case we don't complain if + // there is something new to read from the remote. + // + + int diffIn = diffTimestamp(timeouts_.readTs, nowTs); + + if (diffIn >= (control -> PingTimeout * 2) - + control -> LatencyTimeout) + { + // + // Force a read to detect whether the remote proxy + // aborted the connection. + // + + int result = handleRead(); + + if (result < 0) + { + #if defined(TEST) || defined(INFO) || defined(PING) + *logofs << "Proxy: WARNING! Detected shutdown waiting " + << "for the ping after " << diffIn / 1000 + << " seconds.\n" << logofs_flush; + #endif + + return -1; + } + else if (result > 0) + { + diffIn = diffTimestamp(timeouts_.readTs, nowTs); + + if (handleFlush() < 0) + { + return -1; + } + } + } + + if (diffIn >= (control -> PingTimeout * 2) - + control -> LatencyTimeout) + { + #if defined(TEST) || defined(INFO) || defined(PING) + *logofs << "Proxy: Detected congestion at " + << strMsTimestamp() << " with " << diffIn / 1000 + << " seconds since the last read.\n" + << logofs_flush; + #endif + + // + // There are two types of proxy congestion. The first, + // affecting the ability of the proxy to write the + // encoded data to the network, is controlled by the + // congestion_ flag. The flag is raised when no data + // is received from the remote proxy within a timeout. + // On the X client side, the flag is also raised when + // the proxy runs out of tokens. + // + + if (control -> ProxyMode == proxy_server) + { + // + // At X server side we must return to read data + // from the channels after a while, because we + // need to give a chance to the channel to read + // the key sequence CTRL+ALT+SHIFT+ESC. + // + + if (congestion_ == 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Forcibly entering congestion due to " + << "timeout with " << tokens_[token_control].remaining + << " tokens.\n" << logofs_flush; + #endif + + congestion_ = 1; + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Forcibly exiting congestion due to " + << "timeout with " << tokens_[token_control].remaining + << " tokens.\n" << logofs_flush; + #endif + + congestion_ = 0; + } + } + else + { + #if defined(TEST) || defined(INFO) + + if (congestion_ == 0) + { + *logofs << "Proxy: Entering congestion due to timeout " + << "with " << tokens_[token_control].remaining + << " tokens.\n" << logofs_flush; + } + + #endif + + congestion_ = 1; + } + + if (control -> ProxyTimeout > 0 && + diffIn >= (control -> ProxyTimeout - + control -> LatencyTimeout)) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! No data received from " + << "remote proxy on FD#" << fd_ << " within " + << (diffIn + control -> LatencyTimeout) / 1000 + << " seconds.\n" << logofs_flush; + #endif + + cerr << "Error" << ": No data received from remote " + << "proxy within " << (diffIn + control -> + LatencyTimeout) / 1000 << " seconds.\n"; + + HandleAbort(); + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: WARNING! No data received from " + << "remote proxy on FD#" << fd_ << " since " + << diffIn << " Ms.\n" << logofs_flush; + #endif + + if (control -> ProxyTimeout > 0 && + isTimestamp(timeouts_.alertTs) == 0 && + diffIn >= (control -> ProxyTimeout - + control -> LatencyTimeout) / 4) + { + // + // If we are in the middle of a shutdown + // procedure but the remote is not resp- + // onding, force the closure of the link. + // + + if (finish_ != 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! No response received from " + << "the remote proxy on FD#" << fd_ << " while " + << "waiting for the shutdown.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": No response received from remote " + << "proxy while waiting for the shutdown.\n"; + + HandleAbort(); + } + else + { + cerr << "Warning" << ": No data received from remote " + << "proxy within " << (diffIn + control -> + LatencyTimeout) / 1000 << " seconds.\n"; + + if (alert_ == 0) + { + if (control -> ProxyMode == proxy_client) + { + alert_ = CLOSE_DEAD_PROXY_CONNECTION_CLIENT_ALERT; + } + else + { + alert_ = CLOSE_DEAD_PROXY_CONNECTION_SERVER_ALERT; + } + + HandleAlert(alert_, 1); + } + + timeouts_.alertTs = nowTs; + } + } + } + } + + // + // Check if we need to update the congestion + // counter. + // + + int diffOut = diffTimestamp(timeouts_.writeTs, nowTs); + + if (agent_ != nothing && congestions_[agent_] == 0 && + statistics -> getCongestionInFrame() >= 1 && + diffOut >= (control -> IdleTimeout - + control -> LatencyTimeout * 5)) + { + #if defined(TEST) || defined(INFO) || defined(PING) + *logofs << "Proxy: Forcing an update of the " + << "congestion counter after timeout.\n" + << logofs_flush; + #endif + + statistics -> updateCongestion(tokens_[token_control].remaining, + tokens_[token_control].limit); + } + + // + // Send a new token if we didn't send any data to + // the remote for longer than the ping timeout. + // The client side sends a token, the server side + // responds with a token reply. + // + // VMWare virtual machines can have the system + // timer deadly broken. Try to send a ping regard- + // less we are the client or the server proxy to + // force a write by the remote. + // + + if (control -> ProxyMode == proxy_client || + diffIn >= (control -> PingTimeout * 4) - + control -> LatencyTimeout) + { + // + // We need to send a new ping even if we didn't + // receive anything from the remote within the + // ping timeout. The server side will respond + // to our ping, so we use the ping to force the + // remote end to send some data. + // + + if (diffIn >= (control -> PingTimeout - + control -> LatencyTimeout * 5) || + diffOut >= (control -> PingTimeout - + control -> LatencyTimeout * 5)) + { + int diffPing = diffTimestamp(timeouts_.pingTs, nowTs); + + if (diffPing < 0 || diffPing >= (control -> PingTimeout - + control -> LatencyTimeout * 5)) + { + #if defined(TEST) || defined(INFO) || defined(PING) + *logofs << "Proxy: Sending a new ping at " << strMsTimestamp() + << " with " << tokens_[token_control].remaining + << " tokens and elapsed in " << diffIn << " out " + << diffOut << " ping " << diffPing + << ".\n" << logofs_flush; + #endif + + if (handleFrame(frame_ping) < 0) + { + return -1; + } + + timeouts_.pingTs = nowTs; + } + #if defined(TEST) || defined(INFO) || defined(PING) + else + { + *logofs << "Proxy: Not sending a new ping with " + << "elapsed in " << diffIn << " out " + << diffOut << " ping " << diffPing + << ".\n" << logofs_flush; + } + #endif + } + } + + return 1; +} + +int Proxy::handleSyncFromProxy(int channelId) +{ + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: WARNING! Received a synchronization " + << "request from the remote proxy.\n" + << logofs_flush; + #endif + + if (handleControl(code_sync_reply, channelId) < 0) + { + return -1; + } + + return 1; +} + +int Proxy::handleResetStores() +{ + // + // Recreate the message stores. + // + + delete clientStore_; + delete serverStore_; + + clientStore_ = new ClientStore(compressor_); + serverStore_ = new ServerStore(compressor_); + + timeouts_.loadTs = nullTimestamp(); + + // + // Replace message stores in channels. + // + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL) + { + if (channels_[channelId] -> setStores(clientStore_, serverStore_) < 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Failed to replace message stores in " + << "channel for FD#" << getFd(channelId) << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to replace message stores in " + << "channel for FD#" << getFd(channelId) << ".\n"; + + return -1; + } + #ifdef TEST + else + { + *logofs << "Proxy: Replaced message stores in channel " + << "for FD#" << getFd(channelId) << ".\n" + << logofs_flush; + } + #endif + } + } + + return 1; +} + +int Proxy::handleResetPersistentCache() +{ + char *fullName = new char[strlen(control -> PersistentCachePath) + + strlen(control -> PersistentCacheName) + 2]; + + strcpy(fullName, control -> PersistentCachePath); + strcat(fullName, "/"); + strcat(fullName, control -> PersistentCacheName); + + #ifdef TEST + *logofs << "Proxy: Going to remove persistent cache file '" + << fullName << "'\n" << logofs_flush; + #endif + + unlink(fullName); + + delete [] fullName; + + delete [] control -> PersistentCacheName; + + control -> PersistentCacheName = NULL; + + return 1; +} + +void Proxy::handleResetFlush() +{ + #ifdef TEST + *logofs << "Proxy: Going to reset flush counters " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + // + // Reset the proxy priority flag. + // + + priority_ = 0; + + // + // Restore buffers to their initial + // size. + // + + transport_ -> partialReset(); + + // + // Update the timestamp of the last + // write operation performed on the + // socket. + // + + timeouts_.writeTs = getTimestamp(); +} + +int Proxy::handleFinish() +{ + // + // Reset the timestamps to give the proxy + // another chance to show the 'no response' + // dialog if the shutdown message doesn't + // come in time. + // + + timeouts_.readTs = getTimestamp(); + + timeouts_.alertTs = nullTimestamp(); + + finish_ = 1; + + return 1; +} + +int Proxy::handleShutdown() +{ + // + // Send shutdown message to remote proxy. + // + + shutdown_ = 1; + + handleControl(code_shutdown_request); + + #ifdef TEST + *logofs << "Proxy: Starting shutdown procedure " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + // + // Ensure that all the data accumulated + // in the transport buffer is flushed + // to the network layer. + // + + for (int i = 0; i < 100; i++) + { + if (canFlush() == 1) + { + handleFlush(); + } + else + { + break; + } + + usleep(100000); + } + + // + // Now wait for the network layers to + // consume all the data. + // + + for (int i = 0; i < 100; i++) + { + if (transport_ -> queued() <= 0) + { + break; + } + + usleep(100000); + } + + // + // Give time to the remote end to read + // the shutdown message and close the + // connection. + // + + transport_ -> wait(10000); + + #ifdef TEST + *logofs << "Proxy: Ending shutdown procedure " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + return 1; +} + +int Proxy::handleChannelConfiguration() +{ + if (activeChannels_.getSize() == 0) + { + #ifdef TEST + *logofs << "Proxy: Going to initialize the static " + << "members in channels for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + Channel::setReferences(); + + ClientChannel::setReferences(); + ServerChannel::setReferences(); + + GenericChannel::setReferences(); + } + + return 1; +} + +int Proxy::handleSocketConfiguration() +{ + // + // Set linger mode on proxy to correctly + // get shutdown notification. + // + + SetLingerTimeout(fd_, 30); + + // + // Set keep-alive on socket so that if remote link + // terminates abnormally (as killed hard or because + // of a power-off) process will get a SIGPIPE. In + // practice this is useless as proxies already ping + // each other every few seconds. + // + + if (control -> OptionProxyKeepAlive == 1) + { + SetKeepAlive(fd_); + } + + // + // Set 'priority' flag at TCP layer for path + // proxy-to-proxy. Look at IPTOS_LOWDELAY in + // man 7 ip. + // + + if (control -> OptionProxyLowDelay == 1) + { + SetLowDelay(fd_); + } + + // + // Update size of TCP send and receive buffers. + // + + if (control -> OptionProxySendBuffer != -1) + { + SetSendBuffer(fd_, control -> OptionProxySendBuffer); + } + + if (control -> OptionProxyReceiveBuffer != -1) + { + SetReceiveBuffer(fd_, control -> OptionProxyReceiveBuffer); + } + + // + // Update TCP_NODELAY settings. Note that on old Linux + // kernels turning off the Nagle algorithm didn't work + // when proxy was run through a PPP link. Trying to do + // so caused the kernel to stop delivering data to us + // if a serious network congestion was encountered. + // + + if (control -> ProxyMode == proxy_client) + { + if (control -> OptionProxyClientNoDelay != -1) + { + SetNoDelay(fd_, control -> OptionProxyClientNoDelay); + } + } + else + { + if (control -> OptionProxyServerNoDelay != -1) + { + SetNoDelay(fd_, control -> OptionProxyServerNoDelay); + } + } + + return 1; +} + +int Proxy::handleLinkConfiguration() +{ + #ifdef TEST + *logofs << "Proxy: Propagating parameters to " + << "channels' read buffers.\n" + << logofs_flush; + #endif + + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL) + { + channels_[channelId] -> handleConfiguration(); + } + } + + #ifdef TEST + *logofs << "Proxy: Propagating parameters to " + << "proxy buffers.\n" + << logofs_flush; + #endif + + readBuffer_.setSize(control -> ProxyInitialReadSize, + control -> ProxyMaximumBufferSize); + + encodeBuffer_.setSize(control -> TransportProxyBufferSize, + control -> TransportProxyBufferThreshold, + control -> TransportMaximumBufferSize); + + transport_ -> setSize(control -> TransportProxyBufferSize, + control -> TransportProxyBufferThreshold, + control -> TransportMaximumBufferSize); + + #ifdef TEST + *logofs << "Proxy: Configuring the proxy timeouts.\n" + << logofs_flush; + #endif + + timeouts_.split = control -> SplitTimeout; + timeouts_.motion = control -> MotionTimeout; + + #ifdef TEST + *logofs << "Proxy: Configuring the proxy tokens.\n" + << logofs_flush; + #endif + + tokens_[token_control].size = control -> TokenSize; + tokens_[token_control].limit = control -> TokenLimit; + + if (tokens_[token_control].limit < 1) + { + tokens_[token_control].limit = 1; + } + + #if defined(TEST) || defined(INFO) || defined(LIMIT) + *logofs << "Proxy: TOKEN! LIMIT! Setting token [" + << DumpToken(token_control) << "] size to " + << tokens_[token_control].size << " and limit to " + << tokens_[token_control].limit << ".\n" + << logofs_flush; + #endif + + tokens_[token_split].size = control -> TokenSize; + tokens_[token_split].limit = control -> TokenLimit / 2; + + if (tokens_[token_split].limit < 1) + { + tokens_[token_split].limit = 1; + } + + #if defined(TEST) || defined(INFO) || defined(LIMIT) + *logofs << "Proxy: TOKEN! LIMIT! Setting token [" + << DumpToken(token_split) << "] size to " + << tokens_[token_split].size << " and limit to " + << tokens_[token_split].limit << ".\n" + << logofs_flush; + #endif + + tokens_[token_data].size = control -> TokenSize; + tokens_[token_data].limit = control -> TokenLimit / 4; + + if (tokens_[token_data].limit < 1) + { + tokens_[token_data].limit = 1; + } + + #if defined(TEST) || defined(INFO) || defined(LIMIT) + *logofs << "Proxy: TOKEN! LIMIT! Setting token [" + << DumpToken(token_data) << "] size to " + << tokens_[token_data].size << " and limit to " + << tokens_[token_data].limit << ".\n" + << logofs_flush; + #endif + + for (int i = token_control; i <= token_data; i++) + { + tokens_[i].remaining = tokens_[i].limit; + } + + #if defined(TEST) || defined(INFO) || defined(LIMIT) + *logofs << "Proxy: LIMIT! Using client bitrate " + << "limit " << control -> ClientBitrateLimit + << " server bitrate limit " << control -> + ServerBitrateLimit << " with local limit " + << control -> LocalBitrateLimit << ".\n" + << logofs_flush; + #endif + + // + // Set the other parameters based on + // the token size. + // + + int base = control -> TokenSize; + + control -> SplitDataThreshold = base * 4; + control -> SplitDataPacketLimit = base / 2; + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: LIMIT! Setting split data threshold " + << "to " << control -> SplitDataThreshold + << " split packet limit to " << control -> + SplitDataPacketLimit << " with base " + << base << ".\n" << logofs_flush; + #endif + + // + // Set the number of bytes read from the + // data channels at each loop. This will + // basically determine the maximum band- + // width available for the generic chan- + // nels. + // + + control -> GenericInitialReadSize = base / 2; + control -> GenericMaximumBufferSize = base / 2; + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: LIMIT! Setting generic channel " + << "initial read size to " << control -> + GenericInitialReadSize << " maximum read " + << "size to " << control -> GenericMaximumBufferSize + << " with base " << base << ".\n" + << logofs_flush; + #endif + + return 1; +} + +int Proxy::handleCacheConfiguration() +{ + #ifdef TEST + *logofs << "Proxy: Configuring cache according to pack parameters.\n" + << logofs_flush; + #endif + + // + // Further adjust the cache parameters. If + // packing of the images is enabled, reduce + // the size available for plain images. + // + + if (control -> SessionMode == session_agent) + { + if (control -> PackMethod != NO_PACK) + { + clientStore_ -> getRequestStore(X_PutImage) -> + cacheThreshold = PUTIMAGE_CACHE_THRESHOLD_IF_PACKED; + + clientStore_ -> getRequestStore(X_PutImage) -> + cacheLowerThreshold = PUTIMAGE_CACHE_LOWER_THRESHOLD_IF_PACKED; + } + } + + // + // If this is a shadow session increase the + // size of the image cache. + // + + if (control -> SessionMode == session_shadow) + { + if (control -> PackMethod != NO_PACK) + { + clientStore_ -> getRequestStore(X_NXPutPackedImage) -> + cacheThreshold = PUTPACKEDIMAGE_CACHE_THRESHOLD_IF_PACKED_SHADOW; + + clientStore_ -> getRequestStore(X_NXPutPackedImage) -> + cacheLowerThreshold = PUTPACKEDIMAGE_CACHE_LOWER_THRESHOLD_IF_PACKED_SHADOW; + } + else + { + clientStore_ -> getRequestStore(X_PutImage) -> + cacheThreshold = PUTIMAGE_CACHE_THRESHOLD_IF_SHADOW; + + clientStore_ -> getRequestStore(X_PutImage) -> + cacheLowerThreshold = PUTIMAGE_CACHE_LOWER_THRESHOLD_IF_SHADOW; + } + } + + return 1; +} + +int Proxy::handleSaveStores() +{ + // + // Save content of stores on disk. + // + + char *cacheToAdopt = NULL; + + // + // Set to false the indicator for cumulative store + // size too small + // + bool isTooSmall = false; + + if (control -> PersistentCacheEnableSave) + { + #ifdef TEST + *logofs << "Proxy: Going to save content of client store.\n" + << logofs_flush; + #endif + + cacheToAdopt = handleSaveAllStores(control -> PersistentCachePath, isTooSmall); + } + #ifdef TEST + else + { + if (control -> ProxyMode == proxy_client) + { + *logofs << "Proxy: Saving persistent cache to disk disabled.\n" + << logofs_flush; + } + else + { + *logofs << "Proxy: PANIC! Protocol violation in command save.\n" + << logofs_flush; + + cerr << "Error" << ": Protocol violation in command save.\n"; + + HandleCleanup(); + } + } + #endif + + if (cacheToAdopt != NULL) + { + // + // Do we have a cache already? + // + + if (control -> PersistentCacheName != NULL) + { + // + // Check if old and new cache are the same. + // In this case don't remove the old cache. + // + + if (strcasecmp(control -> PersistentCacheName, cacheToAdopt) != 0) + { + handleResetPersistentCache(); + } + + delete [] control -> PersistentCacheName; + } + + #ifdef TEST + *logofs << "Proxy: Setting current persistent cache file to '" + << cacheToAdopt << "'\n" << logofs_flush; + #endif + + control -> PersistentCacheName = cacheToAdopt; + + return 1; + } + else + { + #ifdef TEST + *logofs << "Proxy: No cache file produced from message stores.\n" + << logofs_flush; + #endif + + // + // It can be that we didn't generate a new cache + // because store was too small or persistent cache + // was disabled. This is not an error. + // + + if (control -> PersistentCacheEnableSave && !isTooSmall) + { + return -1; + } + else + { + return 0; + } + } +} + +int Proxy::handleLoadStores() +{ + // + // Restore the content of the client store + // from disk if a valid cache was negotiated + // at session startup. + // + + if (control -> PersistentCacheEnableLoad == 1 && + control -> PersistentCachePath != NULL && + control -> PersistentCacheName != NULL) + { + #ifdef TEST + *logofs << "Proxy: Going to load content of client store.\n" + << logofs_flush; + #endif + + // + // Returns the same string passed as name of + // the cache, or NULL if it was not possible + // to load the cache from disk. + // + + if (handleLoadAllStores(control -> PersistentCachePath, + control -> PersistentCacheName) == NULL) + { + // + // The corrupted cache should have been + // removed from disk. Get rid of the + // reference so we don't try to delete + // it once again. + // + + if (control -> PersistentCacheName != NULL) + { + delete [] control -> PersistentCacheName; + } + + control -> PersistentCacheName = NULL; + + return -1; + } + + // + // Set timestamp of last time cache + // was loaded from data on disk. + // + + timeouts_.loadTs = getTimestamp(); + + return 1; + } + #ifdef TEST + else + { + if (control -> ProxyMode == proxy_client) + { + *logofs << "Proxy: Loading of cache disabled or no cache file selected.\n" + << logofs_flush; + } + else + { + *logofs << "Proxy: PANIC! Protocol violation in command load.\n" + << logofs_flush; + + cerr << "Error" << ": Protocol violation in command load.\n"; + + HandleCleanup(); + } + } + #endif + + return 0; +} + +int Proxy::handleControl(T_proxy_code code, int data) +{ + // + // Send the given control messages + // to the remote proxy. + // + + #if defined(TEST) || defined(INFO) + + if (data != -1) + { + if (code == code_control_token_reply || + code == code_split_token_reply || + code == code_data_token_reply) + { + *logofs << "Proxy: TOKEN! Sending message '" << DumpControl(code) + << "' at " << strMsTimestamp() << " with count " + << data << ".\n" << logofs_flush; + } + else + { + *logofs << "Proxy: Sending message '" << DumpControl(code) + << "' at " << strMsTimestamp() << " with data ID#" + << data << ".\n" << logofs_flush; + } + } + else + { + *logofs << "Proxy: Sending message '" << DumpControl(code) + << "' at " << strMsTimestamp() << ".\n" + << logofs_flush; + } + + #endif + + // + // Add the control message and see if the + // data has to be flushed immediately. + // + + if (addControlCodes(code, data) < 0) + { + return -1; + } + + switch (code) + { + // + // Append the first data read from the opened + // channel to the control code. + // + + case code_new_x_connection: + case code_new_cups_connection: + case code_new_aux_connection: + case code_new_smb_connection: + case code_new_media_connection: + case code_new_http_connection: + case code_new_font_connection: + case code_new_slave_connection: + + // + // Do we send the token reply immediately? + // The control messages are put at the begin- + // ning of the of the encode buffer, so we may + // reply to multiple tokens before having the + // chance of handling the actual frame data. + // On the other hand, the sooner we reply, the + // sooner the remote proxy is restarted. + // + + case code_control_token_reply: + case code_split_token_reply: + case code_data_token_reply: + { + break; + } + + // + // Also send the congestion control codes + // immediately. + // + // case code_begin_congestion: + // case code_end_congestion: + // + + default: + { + priority_ = 1; + + break; + } + } + + if (priority_ == 1) + { + if (handleFrame(frame_data) < 0) + { + return -1; + } + } + + return 1; +} + +int Proxy::handleSwitch(int channelId) +{ + // + // If data is for a different channel than last + // selected for output, prepend to the data the + // new channel id. + // + + #ifdef DEBUG + *logofs << "Proxy: Requested a switch with " + << "current channel ID#" << outputChannel_ + << " new channel ID#" << channelId << ".\n" + << logofs_flush; + #endif + + if (channelId != outputChannel_) + { + if (needFlush() == 1) + { + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "Proxy: WARNING! Flushing data for the " + << "previous channel ID#" << outputChannel_ + << ".\n" << logofs_flush; + #endif + + if (handleFrame(frame_data) < 0) + { + return -1; + } + } + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Sending message '" + << DumpControl(code_switch_connection) << "' at " + << strMsTimestamp() << " with FD#" << getFd(channelId) + << " channel ID#" << channelId << ".\n" + << logofs_flush; + #endif + + if (addControlCodes(code_switch_connection, channelId) < 0) + { + return -1; + } + + outputChannel_ = channelId; + } + + return 1; +} + +int Proxy::addTokenCodes(T_proxy_token &token) +{ + #if defined(TEST) || defined(INFO) || defined(TOKEN) + *logofs << "Proxy: TOKEN! Sending token [" + << DumpToken(token.type) << "] with " + << token.bytes << " bytes accumulated size " + << token.size << " and " << token.remaining + << " available.\n" << logofs_flush; + #endif + + // + // Give a 'weight' to the token. The tokens + // remaining can become negative if we sent + // a packet that was exceptionally big. + // + + int count = 0; + + // Since ProtoStep7 (#issue 108) + count = token.bytes / token.size; + + // + // Force a count of 1, for example + // if this is a ping. + // + + if (count < 1) + { + count = 1; + + token.bytes = 0; + } + else + { + // Since ProtoStep7 (#issue 108) + if (count > 255) + { + count = 255; + } + + // + // Let the next token account for the + // remaining bytes. + // + + token.bytes %= token.size; + } + + #if defined(TEST) || defined(INFO) || defined(TOKEN) + *logofs << "Proxy: Sending message '" + << DumpControl(token.request) << "' at " + << strMsTimestamp() << " with count " << count + << ".\n" << logofs_flush; + #endif + + controlCodes_[controlLength_++] = 0; + controlCodes_[controlLength_++] = (unsigned char) token.request; + controlCodes_[controlLength_++] = (unsigned char) count; + + statistics -> addFrameOut(); + + token.remaining -= count; + + return 1; +} + +int Proxy::handleToken(T_frame_type type) +{ + #if defined(TEST) || defined(INFO) || defined(TOKEN) + *logofs << "Proxy: TOKEN! Checking tokens with " + << "frame type ["; + + *logofs << (type == frame_ping ? "frame_ping" : "frame_data"); + + *logofs << "] with stream ratio " << statistics -> + getStreamRatio() << ".\n" << logofs_flush; + #endif + + if (type == frame_data) + { + // + // Since ProtoStep7 (#issue 108) + // + + // Send a distinct token for each data type. + // We don't want to slow down the sending of + // the X events, X replies and split confir- + // mation events on the X server side, so + // take care only of the generic data token. + // + + if (control -> ProxyMode == proxy_client) + { + statistics -> updateControlToken(tokens_[token_control].bytes); + + if (tokens_[token_control].bytes > tokens_[token_control].size) + { + if (addTokenCodes(tokens_[token_control]) < 0) + { + return -1; + } + + #if defined(TEST) || defined(INFO) || defined(TOKEN) + + T_proxy_token &token = tokens_[token_control]; + + *logofs << "Proxy: TOKEN! Token class [" + << DumpToken(token.type) << "] has now " + << token.bytes << " bytes accumulated and " + << token.remaining << " tokens remaining.\n" + << logofs_flush; + #endif + } + + statistics -> updateSplitToken(tokens_[token_split].bytes); + + if (tokens_[token_split].bytes > tokens_[token_split].size) + { + if (addTokenCodes(tokens_[token_split]) < 0) + { + return -1; + } + + #if defined(TEST) || defined(INFO) || defined(TOKEN) + + T_proxy_token &token = tokens_[token_split]; + + *logofs << "Proxy: TOKEN! Token class [" + << DumpToken(token.type) << "] has now " + << token.bytes << " bytes accumulated and " + << token.remaining << " tokens remaining.\n" + << logofs_flush; + #endif + } + } + + statistics -> updateDataToken(tokens_[token_data].bytes); + + if (tokens_[token_data].bytes > tokens_[token_data].size) + { + if (addTokenCodes(tokens_[token_data]) < 0) + { + return -1; + } + + #if defined(TEST) || defined(INFO) || defined(TOKEN) + + T_proxy_token &token = tokens_[token_data]; + + *logofs << "Proxy: TOKEN! Token class [" + << DumpToken(token.type) << "] has now " + << token.bytes << " bytes accumulated and " + << token.remaining << " tokens remaining.\n" + << logofs_flush; + #endif + } + } + else + { + if (addTokenCodes(tokens_[token_control]) < 0) + { + return -1; + } + + // + // Reset all counters on a ping. + // + + tokens_[token_control].bytes = 0; + tokens_[token_split].bytes = 0; + tokens_[token_data].bytes = 0; + + #if defined(TEST) || defined(INFO) || defined(TOKEN) + + T_proxy_token &token = tokens_[token_control]; + + *logofs << "Proxy: TOKEN! Token class [" + << DumpToken(token.type) << "] has now " + << token.bytes << " bytes accumulated and " + << token.remaining << " tokens remaining.\n" + << logofs_flush; + #endif + } + + // + // Check if we have entered in + // congestion state. + // + + if (congestion_ == 0 && + tokens_[token_control].remaining <= 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Entering congestion with " + << tokens_[token_control].remaining + << " tokens remaining.\n" << logofs_flush; + #endif + + congestion_ = 1; + } + + statistics -> updateCongestion(tokens_[token_control].remaining, + tokens_[token_control].limit); + + return 1; +} + +int Proxy::handleTokenFromProxy(T_proxy_token &token, int count) +{ + #if defined(TEST) || defined(INFO) || defined(TOKEN) + *logofs << "Proxy: TOKEN! Received token [" + << DumpToken(token.type) << "] request at " + << strMsTimestamp() << " with count " + << count << ".\n" << logofs_flush; + #endif + + // + // Since ProtoStep7 (#issue 108) with no limitations + // concerning invalid token requests at this point + // + + // + // Add our token reply. + // + + if (handleControl(token.reply, count) < 0) + { + return -1; + } + + return 1; +} + +int Proxy::handleTokenReplyFromProxy(T_proxy_token &token, int count) +{ + #if defined(TEST) || defined(INFO) || defined(TOKEN) + *logofs << "Proxy: TOKEN! Received token [" + << DumpToken(token.type) << "] reply at " + << strMsTimestamp() << " with count " << count + << ".\n" << logofs_flush; + #endif + + // + // Since ProtoStep7 (#issue 108) with no limitations + // concerning invalid token requests at this point + // + + // + // Increment the available tokens. + // + + token.remaining += count; + + if (token.remaining > token.limit) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Token overflow handling messages.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Token overflow handling messages.\n"; + + HandleCleanup(); + } + + #if defined(TEST) || defined(INFO) || defined(TOKEN) + *logofs << "Proxy: TOKEN! Token class [" + << DumpToken(token.type) << "] has now " << token.bytes + << " bytes accumulated and " << token.remaining + << " tokens remaining.\n" << logofs_flush; + #endif + + // + // Check if we can jump out of the + // congestion state. + // + + if (congestion_ == 1 && + tokens_[token_control].remaining > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Exiting congestion with " + << tokens_[token_control].remaining + << " tokens remaining.\n" << logofs_flush; + #endif + + congestion_ = 0; + } + + statistics -> updateCongestion(tokens_[token_control].remaining, + tokens_[token_control].limit); + + return 1; +} + +void Proxy::handleFailOnSave(const char *fullName, const char *failContext) const +{ + #ifdef WARNING + *logofs << "Proxy: WARNING! Error saving stores to cache file " + << "in context [" << failContext << "].\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Error saving stores to cache file " + << "in context [" << failContext << "].\n"; + + #ifdef WARNING + *logofs << "Proxy: WARNING! Removing invalid cache '" + << fullName << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Removing invalid cache '" + << fullName << "'.\n"; + + unlink(fullName); +} + +void Proxy::handleFailOnLoad(const char *fullName, const char *failContext) const +{ + #ifdef WARNING + *logofs << "Proxy: WARNING! Error loading stores from cache file " + << "in context [" << failContext << "].\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Error loading stores from cache file " + << "in context [" << failContext << "].\n"; + + #ifdef WARNING + *logofs << "Proxy: WARNING! Removing invalid cache '" + << fullName << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Removing invalid cache '" + << fullName << "'.\n"; + + unlink(fullName); +} + +int Proxy::handleSaveVersion(unsigned char *buffer, int &major, + int &minor, int &patch) const +{ + // Since ProtoStep8 (#issue 108) + major = 3; + minor = 0; + patch = 0; + + *(buffer + 0) = major; + *(buffer + 1) = minor; + + PutUINT(patch, buffer + 2, storeBigEndian()); + + return 1; +} + +int Proxy::handleLoadVersion(const unsigned char *buffer, int &major, + int &minor, int &patch) const +{ + major = *(buffer + 0); + minor = *(buffer + 1); + + patch = GetUINT(buffer + 2, storeBigEndian()); + + // + // Force the proxy to discard the + // incompatible caches. + // + + // Since ProtoStep8 (#issue 108) + if (major < 3) + { + return -1; + } + + return 1; +} + +char *Proxy::handleSaveAllStores(const char *savePath, bool & isTooSmall) const +{ + isTooSmall = false; + + int cumulativeSize = MessageStore::getCumulativeTotalStorageSize(); + + if (cumulativeSize < control -> PersistentCacheThreshold) + { + #ifdef TEST + *logofs << "Proxy: Cache not saved as size is " + << cumulativeSize << " with threshold set to " + << control -> PersistentCacheThreshold + << ".\n" << logofs_flush; + #endif + + // + // Cumulative store size is smaller than threshold + // so the indicator is set to true + // + + isTooSmall = true; + + return NULL; + } + else if (savePath == NULL) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! No name provided for save path.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": No name provided for save path.\n"; + + return NULL; + } + + #ifdef TEST + *logofs << "Proxy: Going to save content of message stores.\n" + << logofs_flush; + #endif + + // + // Our parent process is likely going to terminate. + // Until we finish saving cache we must ignore its + // SIGIPE. + // + + DisableSignals(); + + ofstream *cachefs = NULL; + + md5_state_t *md5StateStream = NULL; + md5_byte_t *md5DigestStream = NULL; + + md5_state_t *md5StateClient = NULL; + md5_byte_t *md5DigestClient = NULL; + + char md5String[MD5_LENGTH * 2 + 2]; + + char fullName[strlen(savePath) + MD5_LENGTH * 2 + 4]; + + // + // Prepare the template for the temporary file + // + + const char* const uniqueTemplate = "XXXXXX"; + char tempName[strlen(savePath) + strlen("/") + 4 + strlen(uniqueTemplate) + 1]; + + snprintf(tempName, sizeof tempName, "%s/%s%s", + savePath, + control -> ProxyMode == proxy_client ? + "Z-C-" : + "Z-S-", + uniqueTemplate); + + #ifdef TEST + *logofs << "Proxy: Generating temporary file with template '" + << tempName << "'.\n" << logofs_flush; + #endif + + // + // Change the mask to make the file only + // readable by the user, then restore the + // old mask. + // + + mode_t fileMode = umask(0077); + + // + // Generate a unique temporary filename from tempName + // and then create and open the file + // + + int fdTemp = mkstemp(tempName); + if (fdTemp == -1) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Can't create temporary file in '" + << savePath << "'. Cause = " << strerror(errno) << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't create temporary file in '" + << savePath << "'. Cause = " << strerror(errno) << ".\n"; + + umask(fileMode); + + EnableSignals(); + + return NULL; + } + + #ifdef TEST + *logofs << "Proxy: Saving cache to file '" + << tempName << "'.\n" << logofs_flush; + #endif + + // + // Create and open the output stream for the new temporary + // file + // + + cachefs = new (std::nothrow) ofstream(tempName, ios::out | ios::binary); + if ((cachefs == NULL) || cachefs->fail()) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Can't create stream for temporary file '" + << tempName << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't create stream for temporary file '" + << tempName << "'.\n"; + + close(fdTemp); + unlink(tempName); + + umask(fileMode); + + EnableSignals(); + + return NULL; + } + + // + // Close the file descriptor returned by mkstemp + // and restore the old mask + // + + close(fdTemp); + umask(fileMode); + + md5StateStream = new md5_state_t(); + md5DigestStream = new md5_byte_t[MD5_LENGTH]; + + md5_init(md5StateStream); + + // + // First write the proxy version. + // + + unsigned char version[4]; + + int major; + int minor; + int patch; + + handleSaveVersion(version, major, minor, patch); + + #ifdef TEST + *logofs << "Proxy: Saving cache using version '" + << major << "." << minor << "." << patch + << "'.\n" << logofs_flush; + #endif + + if (PutData(cachefs, version, 4) < 0) + { + handleFailOnSave(tempName, "A"); + + delete cachefs; + + delete md5StateStream; + delete [] md5DigestStream; + + EnableSignals(); + + return NULL; + } + + // + // Make space for the calculated MD5 so we + // can later rewind the file and write it + // at this position. + // + + if (PutData(cachefs, md5DigestStream, MD5_LENGTH) < 0) + { + handleFailOnSave(tempName, "B"); + + delete cachefs; + + delete md5StateStream; + delete [] md5DigestStream; + + EnableSignals(); + + return NULL; + } + + md5StateClient = new md5_state_t(); + md5DigestClient = new md5_byte_t[MD5_LENGTH]; + + md5_init(md5StateClient); + + #ifdef DUMP + + ofstream *cacheDump = NULL; + + ofstream *tempfs = (ofstream*) logofs; + + char cacheDumpName[DEFAULT_STRING_LENGTH]; + + if (control -> ProxyMode == proxy_client) + { + snprintf(cacheDumpName, DEFAULT_STRING_LENGTH - 1, + "%s/client-cache-dump", control -> TempPath); + } + else + { + snprintf(cacheDumpName, DEFAULT_STRING_LENGTH - 1, + "%s/server-cache-dump", control -> TempPath); + } + + *(cacheDumpName + DEFAULT_STRING_LENGTH - 1) = '\0'; + + fileMode = umask(0077); + + cacheDump = new ofstream(cacheDumpName, ios::out); + + umask(fileMode); + + logofs = cacheDump; + + #endif + + // + // Use the virtual method of the concrete proxy class. + // + + int allSaved = handleSaveAllStores(cachefs, md5StateStream, md5StateClient); + + #ifdef DUMP + + logofs = tempfs; + + delete cacheDump; + + #endif + + if (allSaved == -1) + { + handleFailOnSave(tempName, "C"); + + delete cachefs; + + delete md5StateStream; + delete [] md5DigestStream; + + delete md5StateClient; + delete [] md5DigestClient; + + EnableSignals(); + + return NULL; + } + + md5_finish(md5StateClient, md5DigestClient); + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + sprintf(md5String + (i * 2), "%02X", md5DigestClient[i]); + } + + strcpy(fullName, (control -> ProxyMode == proxy_client) ? "C-" : "S-"); + + strcat(fullName, md5String); + + md5_append(md5StateStream, (const md5_byte_t *) fullName, strlen(fullName)); + md5_finish(md5StateStream, md5DigestStream); + + // + // Go to the beginning of file plus + // the integer where we wrote our + // proxy version. + // + + cachefs -> seekp(4); + + if (PutData(cachefs, md5DigestStream, MD5_LENGTH) < 0) + { + handleFailOnSave(tempName, "D"); + + delete cachefs; + + delete md5StateStream; + delete [] md5DigestStream; + + delete md5StateClient; + delete [] md5DigestClient; + + EnableSignals(); + + return NULL; + } + + delete cachefs; + + // + // Copy the resulting cache name without + // the path so that we can return it to + // the caller. + // + + char *cacheName = new char[MD5_LENGTH * 2 + 4]; + + strcpy(cacheName, fullName); + + // + // Add the path to the full name and move + // the cache into the path. + // + + strcpy(fullName, savePath); + strcat(fullName, (control -> ProxyMode == proxy_client) ? "/C-" : "/S-"); + strcat(fullName, md5String); + + #ifdef TEST + *logofs << "Proxy: Renaming cache file from '" + << tempName << "' to '" << fullName + << "'.\n" << logofs_flush; + #endif + + rename(tempName, fullName); + + delete md5StateStream; + delete [] md5DigestStream; + + delete md5StateClient; + delete [] md5DigestClient; + + // + // Restore the original handlers. + // + + EnableSignals(); + + #ifdef TEST + *logofs << "Proxy: Successfully saved cache file '" + << cacheName << "'.\n" << logofs_flush; + #endif + + // + // This must be enabled only for test + // because it requires that client and + // server reside on the same machine. + // + + if (control -> PersistentCacheCheckOnShutdown == 1 && + control -> ProxyMode == proxy_server) + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: MATCH! Checking if the file '" + << fullName << "' matches a client cache.\n" + << logofs_flush; + #endif + + strcpy(fullName, savePath); + strcat(fullName, "/C-"); + strcat(fullName, md5String); + + struct stat fileStat; + + if (stat(fullName, &fileStat) != 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Can't find a client cache " + << "with name '" << fullName << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't find a client cache " + << "with name '" << fullName << "'.\n"; + + HandleShutdown(); + } + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: MATCH! Client cache '" << fullName + << "' matches the local cache.\n" + << logofs_flush; + #endif + } + + return cacheName; +} + +const char *Proxy::handleLoadAllStores(const char *loadPath, const char *loadName) const +{ + #ifdef TEST + *logofs << "Proxy: Going to load content of message stores.\n" + << logofs_flush; + #endif + + // + // Until we finish loading cache we + // must at least ignore any SIGIPE. + // + + DisableSignals(); + + if (loadPath == NULL || loadName == NULL) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! No path or no file name provided for cache to restore.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": No path or no file name provided for cache to restore.\n"; + + EnableSignals(); + + return NULL; + } + else if (strlen(loadName) != MD5_LENGTH * 2 + 2) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Bad file name provided for cache to restore.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Bad file name provided for cache to restore.\n"; + + EnableSignals(); + + return NULL; + } + + istream *cachefs = NULL; + char md5String[(MD5_LENGTH * 2) + 2]; + md5_byte_t md5FromFile[MD5_LENGTH]; + + char *cacheName = new char[strlen(loadPath) + strlen(loadName) + 3]; + + strcpy(cacheName, loadPath); + strcat(cacheName, "/"); + strcat(cacheName, loadName); + + #ifdef TEST + *logofs << "Proxy: Name of cache file is '" + << cacheName << "'.\n" << logofs_flush; + #endif + + cachefs = new ifstream(cacheName, ios::in | ios::binary); + + unsigned char version[4]; + + if (cachefs == NULL || GetData(cachefs, version, 4) < 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Can't read cache file '" + << cacheName << "'.\n" << logofs_flush;; + #endif + + handleFailOnLoad(cacheName, "A"); + + delete cachefs; + + delete [] cacheName; + + EnableSignals(); + + return NULL; + } + + int major; + int minor; + int patch; + + if (handleLoadVersion(version, major, minor, patch) < 0) + { + #ifdef PANIC + *logofs << "Proxy: WARNING! Incompatible version '" + << major << "." << minor << "." << patch + << "' in cache file '" << cacheName + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Incompatible version '" + << major << "." << minor << "." << patch + << "' in cache file '" << cacheName + << "'.\n" << logofs_flush; + + if (control -> ProxyMode == proxy_server) + { + handleFailOnLoad(cacheName, "B"); + } + else + { + // + // Simply remove the cache file. + // + + unlink(cacheName); + } + + delete cachefs; + + delete [] cacheName; + + EnableSignals(); + + return NULL; + } + + #ifdef TEST + *logofs << "Proxy: Reading from cache file version '" + << major << "." << minor << "." << patch + << "'.\n" << logofs_flush; + #endif + + if (GetData(cachefs, md5FromFile, MD5_LENGTH) < 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! No checksum in cache file '" + << loadName << "'.\n" << logofs_flush; + #endif + + handleFailOnLoad(cacheName, "C"); + + delete cachefs; + + delete [] cacheName; + + EnableSignals(); + + return NULL; + } + + md5_state_t *md5StateStream = NULL; + md5_byte_t *md5DigestStream = NULL; + + md5StateStream = new md5_state_t(); + md5DigestStream = new md5_byte_t[MD5_LENGTH]; + + md5_init(md5StateStream); + + // + // Use the virtual method of the proxy class. + // + + if (handleLoadAllStores(cachefs, md5StateStream) < 0) + { + handleFailOnLoad(cacheName, "D"); + + delete cachefs; + + delete md5StateStream; + delete [] md5DigestStream; + + delete [] cacheName; + + EnableSignals(); + + return NULL; + } + + md5_append(md5StateStream, (const md5_byte_t *) loadName, strlen(loadName)); + md5_finish(md5StateStream, md5DigestStream); + + for (int i = 0; i < MD5_LENGTH; i++) + { + if (md5DigestStream[i] != md5FromFile[i]) + { + #ifdef PANIC + + *logofs << "Proxy: PANIC! Bad checksum for cache file '" + << cacheName << "'.\n" << logofs_flush; + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + sprintf(md5String + (i * 2), "%02X", md5FromFile[i]); + } + + *logofs << "Proxy: PANIC! Saved checksum is '" + << md5String << "'.\n" << logofs_flush; + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + sprintf(md5String + (i * 2),"%02X", md5DigestStream[i]); + } + + *logofs << "Proxy: PANIC! Calculated checksum is '" + << md5String << "'.\n" << logofs_flush; + + #endif + + handleFailOnLoad(cacheName, "E"); + + delete cachefs; + + delete md5StateStream; + delete [] md5DigestStream; + + delete [] cacheName; + + EnableSignals(); + + return NULL; + } + } + + delete cachefs; + + delete md5StateStream; + delete [] md5DigestStream; + + delete [] cacheName; + + // + // Restore the original handlers. + // + + EnableSignals(); + + #ifdef TEST + *logofs << "Proxy: Successfully loaded cache file '" + << loadName << "'.\n" << logofs_flush; + #endif + + // + // Return the string provided by caller. + // + + return loadName; +} + +int Proxy::allocateChannelMap(int fd) +{ + // + // We assume that the fd is lower than + // the maximum allowed number. This is + // checked at the time the connection + // is accepted. + // + + if (fd < 0 || fd >= CONNECTIONS_LIMIT) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Internal error allocating " + << "new channel with FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Internal error allocating " + << "new channel with FD#" << fd_ << ".\n"; + + HandleCleanup(); + } + + for (int channelId = 0; + channelId < CONNECTIONS_LIMIT; + channelId++) + { + if (checkLocalChannelMap(channelId) == 1 && + fdMap_[channelId] == -1) + { + fdMap_[channelId] = fd; + channelMap_[fd] = channelId; + + #ifdef TEST + *logofs << "Proxy: Allocated new channel ID#" + << channelId << " with FD#" << fd << ".\n" + << logofs_flush; + #endif + + return channelId; + } + } + + // + // No available channel is remaining. + // + + #ifdef TEST + *logofs << "Proxy: WARNING! Can't allocate a new channel " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + return -1; +} + +int Proxy::checkChannelMap(int channelId) +{ + // + // To be acceptable, the channel id must + // be an id that is not possible to use + // to allocate channels at this side. + // + + if (checkLocalChannelMap(channelId) == 1) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Can't open a new channel " + << "with invalid ID#" << channelId << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't open a new channel " + << "with invalid ID#" << channelId << ".\n"; + + return -1; + } + else if (channels_[channelId] != NULL) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Can't open a new channel " + << "over an existing ID#" << channelId + << " with FD#" << getFd(channelId) + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't open a new channel " + << "over an existing ID#" << channelId + << " with FD#" << getFd(channelId) + << ".\n"; + + return -1; + } + + return 1; +} + +int Proxy::assignChannelMap(int channelId, int fd) +{ + // + // We assume that the fd is lower than + // the maximum allowed number. This is + // checked at the time the connection + // is accepted. + // + + if (channelId < 0 || channelId >= CONNECTIONS_LIMIT || + fd < 0 || fd >= CONNECTIONS_LIMIT) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Internal error assigning " + << "new channel with FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Internal error assigning " + << "new channel with FD#" << fd_ << ".\n"; + + HandleCleanup(); + } + + fdMap_[channelId] = fd; + channelMap_[fd] = channelId; + + return 1; +} + +void Proxy::cleanupChannelMap(int channelId) +{ + int fd = fdMap_[channelId]; + + if (fd != -1) + { + fdMap_[channelId] = -1; + channelMap_[fd] = -1; + } +} + +int Proxy::addControlCodes(T_proxy_code code, int data) +{ + // + // Flush the encode buffer plus all the outstanding + // control codes if there is not enough space for + // the new control message. We need to ensure that + // there are further bytes available, in the case + // we will need to add more token control messages. + // + + if (controlLength_ + 3 > CONTROL_CODES_THRESHOLD) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! Flushing control messages " + << "while sending code '" << DumpControl(code) + << "'.\n" << logofs_flush; + #endif + + if (handleFlush() < 0) + { + return -1; + } + } + + controlCodes_[controlLength_++] = 0; + controlCodes_[controlLength_++] = (unsigned char) code; + controlCodes_[controlLength_++] = (unsigned char) (data == -1 ? 0 : data); + + // + // Account for the control frame. + // + + statistics -> addFrameOut(); + + return 1; +} + +void Proxy::setSplitTimeout(int channelId) +{ + int needed = channels_[channelId] -> needSplit(); + + if (needed != isTimestamp(timeouts_.splitTs)) + { + if (needed == 1) + { + #if defined(TEST) || defined(INFO) || defined(SPLIT) + *logofs << "Proxy: SPLIT! Allocating split timestamp at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + timeouts_.splitTs = getTimestamp(); + } + else + { + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL && + channels_[channelId] -> needSplit() == 1) + { + #ifdef TEST + *logofs << "Proxy: SPLIT! Channel for FD#" + << getFd(channelId) << " still needs splits.\n" + << logofs_flush; + #endif + + return; + } + } + + #if defined(TEST) || defined(INFO) || defined(SPLIT) + *logofs << "Proxy: SPLIT! Resetting split timestamp at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + timeouts_.splitTs = nullTimestamp(); + } + } +} + +void Proxy::setMotionTimeout(int channelId) +{ + int needed = channels_[channelId] -> needMotion(); + + if (needed != isTimestamp(timeouts_.motionTs)) + { + if (channels_[channelId] -> needMotion() == 1) + { + #if defined(TEST) || defined(INFO) || defined(SPLIT) + *logofs << "Proxy: Allocating motion timestamp at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + timeouts_.motionTs = getTimestamp(); + } + else + { + T_list &channelList = activeChannels_.getList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL && + channels_[channelId] -> needMotion() == 1) + { + #ifdef TEST + *logofs << "Proxy: SPLIT! Channel for FD#" + << getFd(channelId) << " still needs motions.\n" + << logofs_flush; + #endif + + return; + } + } + + #if defined(TEST) || defined(INFO) || defined(SPLIT) + *logofs << "Proxy: Resetting motion timestamp at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + timeouts_.motionTs = nullTimestamp(); + } + } +} + +void Proxy::increaseChannels(int channelId) +{ + #ifdef TEST + *logofs << "Proxy: Adding channel " << channelId + << " to the list of active channels.\n" + << logofs_flush; + #endif + + activeChannels_.add(channelId); + + #ifdef TEST + *logofs << "Proxy: There are " << activeChannels_.getSize() + << " allocated channels for proxy FD#" << fd_ + << ".\n" << logofs_flush; + #endif +} + +void Proxy::decreaseChannels(int channelId) +{ + #ifdef TEST + *logofs << "Proxy: Removing channel " << channelId + << " from the list of active channels.\n" + << logofs_flush; + #endif + + activeChannels_.remove(channelId); + + #ifdef TEST + *logofs << "Proxy: There are " << activeChannels_.getSize() + << " allocated channels for proxy FD#" << fd_ + << ".\n" << logofs_flush; + #endif +} + +int Proxy::allocateTransport(int channelFd, int channelId) +{ + if (transports_[channelId] == NULL) + { + transports_[channelId] = new Transport(channelFd); + + if (transports_[channelId] == NULL) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Can't allocate transport for " + << "channel id " << channelId << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate transport for " + << "channel id " << channelId << ".\n"; + + return -1; + } + } + else if (transports_[channelId] -> + getType() != transport_agent) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Transport for channel id " + << channelId << " should be null.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Transport for channel id " + << channelId << " should be null.\n"; + + return -1; + } + + return 1; +} + +int Proxy::deallocateTransport(int channelId) +{ + // + // Transport for the agent connection + // is passed from the outside when + // creating the channel. + // + + if (transports_[channelId] -> + getType() != transport_agent) + { + delete transports_[channelId]; + } + + transports_[channelId] = NULL; + + return 1; +} + +int Proxy::handleNewGenericConnection(int clientFd, T_channel_type type, const char *label) +{ + int channelId = allocateChannelMap(clientFd); + + if (channelId == -1) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Maximum number of available " + << "channels exceeded.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Maximum number of available " + << "channels exceeded.\n"; + + return -1; + } + + #ifdef TEST + *logofs << "Proxy: Channel for " << label << " descriptor " + << "FD#" << clientFd << " mapped to ID#" + << channelId << ".\n" + << logofs_flush; + #endif + + // + // Turn queuing off for path server-to-proxy. + // + + SetNoDelay(clientFd, 1); + + if (allocateTransport(clientFd, channelId) < 0) + { + return -1; + } + + switch (type) + { + case channel_cups: + { + channels_[channelId] = new CupsChannel(transports_[channelId], compressor_); + + break; + } + case channel_smb: + { + channels_[channelId] = new SmbChannel(transports_[channelId], compressor_); + + break; + } + case channel_media: + { + channels_[channelId] = new MediaChannel(transports_[channelId], compressor_); + + break; + } + case channel_http: + { + channels_[channelId] = new HttpChannel(transports_[channelId], compressor_); + + break; + } + case channel_font: + { + channels_[channelId] = new FontChannel(transports_[channelId], compressor_); + + break; + } + default: + { + channels_[channelId] = new SlaveChannel(transports_[channelId], compressor_); + + break; + } + } + + if (channels_[channelId] == NULL) + { + deallocateTransport(channelId); + + return -1; + } + + #ifdef TEST + *logofs << "Proxy: Accepted new connection to " + << label << " server.\n" << logofs_flush; + #endif + + cerr << "Info" << ": Accepted new connection to " + << label << " server.\n"; + + increaseChannels(channelId); + + switch (type) + { + case channel_cups: + { + if (handleControl(code_new_cups_connection, channelId) < 0) + { + return -1; + } + + break; + } + case channel_smb: + { + if (handleControl(code_new_smb_connection, channelId) < 0) + { + return -1; + } + + break; + } + case channel_media: + { + if (handleControl(code_new_media_connection, channelId) < 0) + { + return -1; + } + + break; + } + case channel_http: + { + if (handleControl(code_new_http_connection, channelId) < 0) + { + return -1; + } + + break; + } + case channel_font: + { + if (handleControl(code_new_font_connection, channelId) < 0) + { + return -1; + } + + break; + } + default: + { + if (handleControl(code_new_slave_connection, channelId) < 0) + { + return -1; + } + + break; + } + } + + channels_[channelId] -> handleConfiguration(); + + return 1; +} + +int Proxy::handleNewSlaveConnection(int clientFd) +{ + // Since ProtoStep7 (#issue 108) + return handleNewGenericConnection(clientFd, channel_slave, "slave"); +} + + + +int Proxy::handleNewGenericConnectionFromProxy(int channelId, T_channel_type type, + ChannelEndPoint &endPoint, const char *label) +{ + char *unixPath, *host; + long port; + + if (endPoint.getUnixPath(&unixPath)) { + return handleNewGenericConnectionFromProxyUnix(channelId, type, unixPath, label); + } + + if (endPoint.getTCPHostAndPort(&host, &port)) { + return handleNewGenericConnectionFromProxyTCP(channelId, type, host, port, label); + } + + #ifdef WARNING + *logofs << "Proxy: WARNING! Refusing attempted connection " + << "to " << label << " server.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Refusing attempted connection " + << "to " << label << " server.\n"; + + return -1; +} + +int Proxy::handleNewGenericConnectionFromProxyTCP(int channelId, T_channel_type type, + const char *hostname, long port, const char *label) + +{ + if (port <= 0) + { + // + // This happens when user has disabled + // forwarding of the specific service. + // + + #ifdef WARNING + *logofs << "Proxy: WARNING! Refusing attempted connection " + << "to " << label << " server.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Refusing attempted connection " + << "to " << label << " server.\n"; + + return -1; + } + + const char *serverHost = hostname; + int serverAddrFamily = AF_INET; + sockaddr *serverAddr = NULL; + unsigned int serverAddrLength = 0; + + #ifdef TEST + *logofs << "Proxy: Connecting to " << label + << " server '" << serverHost << "' on TCP port '" + << port << "'.\n" << logofs_flush; + #endif + + int serverIPAddr = GetHostAddress(serverHost); + + if (serverIPAddr == 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Unknown " << label + << " server host '" << serverHost << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Unknown " << label + << " server host '" << serverHost + << "'.\n"; + + return -1; + } + + sockaddr_in *serverAddrTCP = new sockaddr_in; + + serverAddrTCP -> sin_family = AF_INET; + serverAddrTCP -> sin_port = htons(port); + serverAddrTCP -> sin_addr.s_addr = serverIPAddr; + + serverAddr = (sockaddr *) serverAddrTCP; + serverAddrLength = sizeof(sockaddr_in); + + // + // Connect to the requested server. + // + + int serverFd = socket(serverAddrFamily, SOCK_STREAM, PF_UNSPEC); + + if (serverFd < 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Call to socket failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to socket failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + delete serverAddrTCP; + + return -1; + } + else if (connect(serverFd, serverAddr, serverAddrLength) < 0) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! Connection to " << label + << " server '" << serverHost << ":" << port + << "' failed with error '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Connection to " << label + << " server '" << serverHost << ":" << port + << "' failed with error '" << ESTR() << "'.\n"; + + close(serverFd); + + delete serverAddrTCP; + + return -1; + } + + delete serverAddrTCP; + + if (handlePostConnectionFromProxy(channelId, serverFd, type, label) < 0) + { + return -1; + } + + #ifdef TEST + *logofs << "Proxy: Forwarded new connection to " + << label << " server on port '" << port + << "'.\n" << logofs_flush; + #endif + + cerr << "Info" << ": Forwarded new connection to " + << label << " server on port '" << port + << "'.\n"; + + return 1; +} + +int Proxy::handleNewGenericConnectionFromProxyUnix(int channelId, T_channel_type type, + const char *path, const char *label) +{ + if (path == NULL || *path == '\0' ) + { + // + // This happens when user has disabled + // forwarding of the specific service. + // + + #ifdef WARNING + *logofs << "Proxy: WARNING! Refusing attempted connection " + << "to " << label << " server.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Refusing attempted connection " + << "to " << label << " server.\n"; + + return -1; + } + + sockaddr_un serverAddrUnix; + + unsigned int serverAddrLength = sizeof(sockaddr_un); + + int serverAddrFamily = AF_UNIX; + + serverAddrUnix.sun_family = AF_UNIX; + + const int serverAddrNameLength = 108; + + strncpy(serverAddrUnix.sun_path, path, serverAddrNameLength); + + *(serverAddrUnix.sun_path + serverAddrNameLength - 1) = '\0'; + + #ifdef TEST + *logofs << "Proxy: Connecting to " << label << " server " + << "on Unix port '" << path << "'.\n" << logofs_flush; + #endif + + // + // Connect to the requested server. + // + + int serverFd = socket(serverAddrFamily, SOCK_STREAM, PF_UNSPEC); + + if (serverFd < 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! Call to socket failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to socket failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + return -1; + } + else if (connect(serverFd, (sockaddr *) &serverAddrUnix, serverAddrLength) < 0) + { + #ifdef WARNING + *logofs << "Proxy: WARNING! Connection to " << label + << " server on Unix port '" << path << "' failed " + << "with error " << EGET() << ", '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Connection to " << label + << " server on Unix port '" << path << "' failed " + << "with error " << EGET() << ", '" << ESTR() << "'.\n"; + + close(serverFd); + + return -1; + } + + if (handlePostConnectionFromProxy(channelId, serverFd, type, label) < 0) + { + return -1; + } + + #ifdef TEST + *logofs << "Proxy: Forwarded new connection to " + << label << " server on Unix port '" << path + << "'.\n" << logofs_flush; + #endif + + cerr << "Info" << ": Forwarded new connection to " + << label << " server on Unix port '" << path + << "'.\n"; + + return 1; +} + +int Proxy::handleNewSlaveConnectionFromProxy(int channelId) +{ + + cerr << "Info" << ": New slave connection on " + << "channel ID#" << channelId << "\n"; + + char *nx_slave_cmd = getenv("NX_SLAVE_CMD"); + if (nx_slave_cmd == NULL) { + return -1; + } + + int spair[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, spair) == -1) { + perror("socketpair"); + return -1; + } + + int serverFd = spair[0]; + int clientFd = spair[1]; + + if (handlePostConnectionFromProxy(channelId, serverFd, channel_slave, "slave") < 0) + { + close(serverFd); + close(clientFd); + return -1; + } + + + int pid = fork(); + if (pid == 0) + { + + if (dup2(clientFd, 0) == -1) + { + perror("dup2"); + exit(1); + } + + if (dup2(clientFd, 1) == -1) + { + perror("dup2"); + exit(1); + } + + close(serverFd); + close(clientFd); + + /* Close FDs used by NX, QVD #1208 */ + for (int fd = 3; fd < 256; fd++) { + close(fd); + } + + char *const argv[2] = {nx_slave_cmd, NULL}; + + if (execv(nx_slave_cmd, argv) == -1) + { + perror("execv"); + } + exit(1); + + } + else if (pid == -1) + { + // TODO Test this! + perror("fork"); + close(serverFd); + close(clientFd); + return -1; + } + + close(clientFd); + slavePidMap_[channelId] = pid; + + cerr << "Info" << ": slave channel ID#" << channelId << " handler has PID " << pid << endl; + + return 1; +} + +void Proxy::checkSlaves() +{ + for (int channelId = 0; channelId 1 && HandleChild(pid)) + { + slavePidMap_[channelId] = nothing; + cerr << "Info:" << " Handled death of slave with pid " << pid << endl; + } + } +} + +int Proxy::handlePostConnectionFromProxy(int channelId, int serverFd, + T_channel_type type, const char *label) +{ + // + // Turn queuing off for path proxy-to-server. + // + + SetNoDelay(serverFd, 1); + + assignChannelMap(channelId, serverFd); + + #ifdef TEST + *logofs << "Proxy: Descriptor FD#" << serverFd + << " mapped to channel ID#" << channelId << ".\n" + << logofs_flush; + #endif + + if (allocateTransport(serverFd, channelId) < 0) + { + return -1; + } + + switch (type) + { + case channel_cups: + { + channels_[channelId] = new CupsChannel(transports_[channelId], compressor_); + break; + } + case channel_smb: + { + channels_[channelId] = new SmbChannel(transports_[channelId], compressor_); + + break; + } + case channel_media: + { + channels_[channelId] = new MediaChannel(transports_[channelId], compressor_); + + break; + } + case channel_http: + { + channels_[channelId] = new HttpChannel(transports_[channelId], compressor_); + + break; + } + case channel_font: + { + channels_[channelId] = new FontChannel(transports_[channelId], compressor_); + + break; + } + default: + { + channels_[channelId] = new SlaveChannel(transports_[channelId], compressor_); + + break; + } + } + + if (channels_[channelId] == NULL) + { + deallocateTransport(channelId); + + return -1; + } + + increaseChannels(channelId); + + channels_[channelId] -> handleConfiguration(); + + return 1; +} diff --git a/nxcomp/src/Proxy.h b/nxcomp/src/Proxy.h new file mode 100644 index 000000000..ea60c827a --- /dev/null +++ b/nxcomp/src/Proxy.h @@ -0,0 +1,1276 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Proxy_H +#define Proxy_H + +#include + +#ifdef _AIX +#include +#endif + +#include "Misc.h" +#include "Timestamp.h" + +#include "List.h" +#include "Channel.h" +#include "Transport.h" +#include "EncodeBuffer.h" +#include "ProxyReadBuffer.h" +#include "ChannelEndPoint.h" + +// +// Forward declaration as we +// need a pointer. +// + +class Agent; + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Log the important tracepoints related +// to writing packets to the peer proxy. +// + +#undef FLUSH + +// +// Codes used for control messages in +// proxy-to-proxy protocol. +// +// The following codes are currently +// unused. +// +// code_alert_reply, +// code_reset_request, +// code_reset_reply, +// code_load_reply, +// code_save_reply, +// code_shutdown_reply, +// code_configuration_request, +// code_configuration_reply. +// +// These are for compatibility with +// old versions. +// +// code_sync_request, +// code_sync_reply, +// +// The code_new_aux_connection should not +// be used anymore. Auxiliary X connections +// are treated as normal X channels since +// version 1.5.0. +// + +typedef enum +{ + code_new_x_connection, + code_new_cups_connection, + code_new_aux_connection, + code_new_smb_connection, + code_new_media_connection, + code_switch_connection, + code_drop_connection, + code_finish_connection, + code_begin_congestion, + code_end_congestion, + code_alert_request, + code_alert_reply, + code_reset_request, + code_reset_reply, + code_load_request, + code_load_reply, + code_save_request, + code_save_reply, + code_shutdown_request, + code_shutdown_reply, + code_control_token_request, + code_control_token_reply, + code_configuration_request, + code_configuration_reply, + code_statistics_request, + code_statistics_reply, + code_new_http_connection, + code_sync_request, + code_sync_reply, + code_new_font_connection, + code_new_slave_connection, + code_finish_listeners, + code_split_token_request, + code_split_token_reply, + code_data_token_request, + code_data_token_reply, + code_last_tag + +} T_proxy_code; + +typedef enum +{ + operation_in_negotiation, + operation_in_messages, + operation_in_configuration, + operation_in_statistics, + operation_last_tag + +} T_proxy_operation; + +typedef enum +{ + frame_ping, + frame_data, + +} T_frame_type; + +typedef enum +{ + token_control, + token_split, + token_data + +} T_token_type; + +typedef enum +{ + load_if_any, + load_if_first + +} T_load_type; + +class Proxy +{ + public: + + // + // Maximum number of supported channels. + // + + static const int CONNECTIONS_LIMIT = 256; + + // + // Numboer of token types. + // + + static const int TOKEN_TYPES = 3; + + // + // Lenght of buffer we use to add our + // control messages plus the length of + // the data frame. + // + + static const int CONTROL_CODES_LENGTH = ENCODE_BUFFER_PREFIX_SIZE - 5; + + static const int CONTROL_CODES_THRESHOLD = CONTROL_CODES_LENGTH - 9; + + Proxy(int fd); + + virtual ~Proxy(); + + // + // Inform the proxy that the negotiation phase is + // completed and that it can start handling binary + // messages. + // + + int setOperational(); + + int getOperational() + { + return (operation_ != operation_in_negotiation); + } + + int setReadDescriptors(fd_set *fdSet, int &fdMax, T_timestamp &tsMax); + + int setWriteDescriptors(fd_set *fdSet, int &fdMax, T_timestamp &tsMax); + + // + // Perform the operation on the proxy + // link or its own channels. + // + + int handleRead(int &resultFds, fd_set &fdSet); + + int handleFlush(int &resultFds, fd_set &fdSet); + + int handleRead(); + + int handleRead(int fd, const char *data = NULL, int size = 0); + + int handleEvents(); + + int handleFlush(); + + int handleFlush(int fd); + + int handlePing(); + + int handleFinish(); + + int handleShutdown(); + + int handleStatistics(int type, ostream *statofs); + + int handleAlert(int alert); + + int handleRotate() + { + activeChannels_.rotate(); + + return 1; + } + + int handleChannelConfiguration(); + + int handleSocketConfiguration(); + + int handleLinkConfiguration(); + + int handleCacheConfiguration(); + + // + // These must be called just after initialization to + // tell to the proxy where the network connections + // have to be forwarded. + // + + virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, + sockaddr * xServerAddr, unsigned int xServerAddrLength) = 0; + + virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort, + ChannelEndPoint &smbServerPort, + ChannelEndPoint &mediaServerPort, + ChannelEndPoint &httpServerPort, + const char *fontServerPort) = 0; + + // + // Create new tunneled channels. + // + + virtual int handleNewConnection(T_channel_type type, int clientFd) = 0; + + virtual int handleNewConnectionFromProxy(T_channel_type type, int channelId) = 0; + + virtual int handleNewAgentConnection(Agent *agent) = 0; + + virtual int handleNewXConnection(int clientFd) = 0; + + virtual int handleNewXConnectionFromProxy(int channelId) = 0; + + int handleNewGenericConnection(int clientFd, T_channel_type type, const char *label); + + int handleNewGenericConnectionFromProxy(int channelId, T_channel_type type, + ChannelEndPoint &endpoint, const char *label); + + int handleNewGenericConnectionFromProxyUnix(int channelId, T_channel_type type, + const char *path, const char *label); + + int handleNewGenericConnectionFromProxyTCP(int channelId, T_channel_type type, + const char *hostname, long port, const char *label); + + int handleNewSlaveConnection(int clientFd); + + int handleNewSlaveConnectionFromProxy(int channelId); + + void checkSlaves(); + + // + // Force closure of channels. + // + + int handleCloseConnection(int clientFd); + + int handleCloseAllXConnections(); + + int handleCloseAllListeners(); + + // + // Called when the loop has replaced + // or closed a previous alert. + // + + void handleResetAlert(); + + // + // Handle the persistent cache. + // + + virtual int handleLoad(T_load_type type) = 0; + + virtual int handleSave() = 0; + + protected: + + // + // Timeout related data: + // + // flush + // split + // motion + // + // Timeouts in milliseconds after which the + // proxy will have to perform the operation. + // + // readTs, writeTs + // + // Timestamp of last packet received or sent + // to remote proxy. Used to detect lost con- + // nection. + // + // loopTs + // + // Timestamp of last loop completed by the + // proxy + // + // pingTs + // + // Timestamp of last ping request sent to the + // remote peer. + // + // alertTs + // + // Timestamp of last 'no data received' alert + // dialog shown to the user. + // + // loadTs + // + // Were message stores populated from data on + // disk. + // + // splitTs + // motionTs + // + // Timestamps of the last operation of this + // kind handled by the proxy. + // + + typedef struct + { + int split; + int motion; + + T_timestamp readTs; + T_timestamp writeTs; + + T_timestamp loopTs; + T_timestamp pingTs; + T_timestamp alertTs; + T_timestamp loadTs; + + T_timestamp splitTs; + T_timestamp motionTs; + + } T_proxy_timeouts; + + // + // Bytes accumulated so far while waiting + // to send the next token, number of tokens + // remaining for each token type and other + // token related information. + // + + typedef struct + { + int size; + int limit; + + int bytes; + int remaining; + + T_proxy_code request; + T_proxy_code reply; + + T_token_type type; + + } T_proxy_token; + + int handlePostConnectionFromProxy(int channelId, int serverFd, + T_channel_type type, const char *label); + + int handleDrain(); + + int handleFrame(T_frame_type type); + + int handleFinish(int channelId); + + int handleDrop(int channelId); + + int handleFinishFromProxy(int channelId); + + int handleDropFromProxy(int channelId); + + int handleStatisticsFromProxy(int type); + + int handleStatisticsFromProxy(const unsigned char *message, unsigned int length); + + int handleNegotiation(const unsigned char *message, unsigned int length); + + int handleNegotiationFromProxy(const unsigned char *message, unsigned int length); + + int handleToken(T_frame_type type); + + int handleTokenFromProxy(T_proxy_token &token, int count); + + int handleTokenReplyFromProxy(T_proxy_token &token, int count); + + int handleSyncFromProxy(int channelId); + + int handleSwitch(int channelId); + + int handleControl(T_proxy_code code, int data = -1); + + int handleControlFromProxy(const unsigned char *message); + + // + // Interleave reads of the X server + // events while writing data to the + // remote proxy. + // + + virtual int handleAsyncEvents() = 0; + + // + // Timer related functions. + // + + protected: + + void setTimer(int value) + { + SetTimer(value); + } + + void resetTimer() + { + ResetTimer(); + + timer_ = 0; + } + + public: + + void handleTimer() + { + timer_ = 1; + } + + int getTimer() + { + return timer_; + } + + // + // Can the channel consume data and the + // proxy produce more output? + // + + int canRead(int fd) const + { + return (isTimeToRead() == 1 && + isTimeToRead(getChannel(fd)) == 1); + } + + // + // Can the proxy read more data from its + // peer? + // + + int canRead() const + { + return (transport_ -> readable() != 0); + } + + int canFlush() const + { + return (encodeBuffer_.getLength() + + controlLength_ + transport_ -> length() + + transport_ -> flushable() > 0); + } + + int needFlush(int channelId) const + { + return (outputChannel_ == channelId && + encodeBuffer_.getLength() > 0); + } + + int needFlush() const + { + return (encodeBuffer_.getLength() > 0); + } + + int shouldFlush() const + { + if ((int) ((encodeBuffer_.getLength() + + controlLength_) / statistics -> + getStreamRatio()) >= control -> TokenSize) + { + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "Proxy: FLUSH! Requesting a flush with " + << (encodeBuffer_.getLength() + controlLength_) + << " bytes and stream ratio " << (double) statistics -> + getStreamRatio() << ".\n" << logofs_flush; + #endif + + return 1; + } + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "Proxy: Not requesting a flush with " + << (encodeBuffer_.getLength() + controlLength_) + << " bytes and stream ratio " << (double) statistics -> + getStreamRatio() << ".\n" << logofs_flush; + #endif + + return 0; + } + + int needDrain() const + { + return (congestion_ == 1 || transport_ -> length() > + control -> TransportProxyBufferThreshold); + } + + int getFd() const + { + return fd_; + } + + int getFlushable(int fd) const + { + if (fd == fd_) + { + return (encodeBuffer_.getLength() + controlLength_ + + transport_ -> flushable()); + } + + return 0; + } + + int getSplitSize() + { + return (clientStore_ != NULL ? clientStore_ -> + getSplitTotalSize() : 0); + } + + int getSplitStorageSize() + { + return (clientStore_ != NULL ? clientStore_ -> + getSplitTotalStorageSize() : 0); + } + + // + // Returns the number of active channels + // that currently managed by this proxy. + // + + int getChannels(T_channel_type type = channel_none); + + // + // If descriptor corresponds to a valid + // channel, returns the type of traffic + // carried by it. + // + + T_channel_type getType(int fd); + + // + // Given a channel type, returns the + // literal name. + // + + const char *getTypeName(T_channel_type type); + + // + // Get a convenient name for 'localhost'. + // + + const char *getComputerName(); + + // + // Set if we have initiated the shutdown + // procedure and if the shutdown request + // has been received from the remote. + // + + int getFinish() const + { + return finish_; + } + + int getShutdown() const + { + return shutdown_; + } + + // + // Interfaces to the transport buffers. + // + + int getLength(int fd) const + { + if (fd == fd_) + { + return transport_ -> length(); + } + + int channelId = getChannel(fd); + + if (channelId < 0 || channels_[channelId] == NULL) + { + return 0; + } + + return transports_[channelId] -> length(); + } + + int getPending(int fd) const + { + if (fd == fd_) + { + return transport_ -> pending(); + } + + int channelId = getChannel(fd); + + if (channelId < 0 || channels_[channelId] == NULL) + { + return 0; + } + + return transports_[channelId] -> pending(); + } + + // + // Check if the proxy or the given channel + // has data in the buffer because of a + // blocking write. + // + + int getBlocked(int fd) const + { + if (fd == fd_) + { + return transport_ -> blocked(); + } + + int channelId = getChannel(fd); + + if (channelId < 0 || channels_[channelId] == NULL) + { + return 0; + } + + return transports_[channelId] -> blocked(); + } + + // + // Check if the proxy or the given channel has + // data to read. + // + + int getReadable(int fd) const + { + if (fd == fd_) + { + return transport_ -> readable(); + } + + int channelId = getChannel(fd); + + if (channelId < 0 || channels_[channelId] == NULL) + { + return 0; + } + + return transports_[channelId] -> readable(); + } + + // + // Return a vale between 0 and 9 in the case + // of the proxy descriptor. + // + + int getCongestion(int fd) const + { + if (fd == fd_) + { + return (agent_ != nothing && congestions_[agent_] == 1 ? 9 : + (int) statistics -> getCongestionInFrame()); + } + + int channelId = getChannel(fd); + + if (channelId < 0 || channels_[channelId] == NULL) + { + return 0; + } + + return channels_[channelId] -> getCongestion(); + } + + // + // Let the statistics class get info + // from the message stores. + // + + const ClientStore * const getClientStore() const + { + return clientStore_; + } + + const ServerStore * const getServerStore() const + { + return serverStore_; + } + + // + // These can be called asynchronously by + // channels during their read or write + // loop. + // + + int handleAsyncRead(int fd) + { + return handleRead(fd); + } + + int handleAsyncCongestion(int fd) + { + int channelId = getChannel(fd); + + return handleControl(code_begin_congestion, channelId); + } + + int handleAsyncDecongestion(int fd) + { + int channelId = getChannel(fd); + + return handleControl(code_end_congestion, channelId); + } + + int handleAsyncSplit(int fd, Split *split) + { + return channels_[getChannel(fd)] -> + handleSplitEvent(encodeBuffer_, split); + } + + int handleAsyncPriority() + { + if (control -> FlushPriority == 1) + { + return handleFlush(); + } + + return 0; + } + + int canAsyncFlush() const + { + return shouldFlush(); + } + + int handleAsyncFlush() + { + return handleFlush(); + } + + int handleAsyncSwitch(int fd) + { + return handleSwitch(getChannel(fd)); + } + + int handleAsyncKeeperCallback() + { + KeeperCallback(); + + return 1; + } + + // + // Internal interfaces used to verify the + // availability of channels and the proxy + // link. + // + + protected: + + int isTimeToRead() const + { + if (congestion_ == 0 && transport_ -> + blocked() == 0) + { + return 1; + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Can't read from channels " + << "with congestion " << congestion_ + << " and blocked " << transport_ -> + blocked() << ".\n" << logofs_flush; + #endif + + return 0; + } + } + + int isTimeToRead(int channelId) const + { + if (channelId >= 0 && channelId < CONNECTIONS_LIMIT && + channels_[channelId] != NULL && + congestions_[channelId] == 0) + { + if (channels_[channelId] -> getType() == channel_x11 || + tokens_[token_data].remaining > 0 || + channels_[channelId] -> + getFinish() == 1) + { + return 1; + } + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: Can't read from generic " + << "descriptor FD#" << getFd(channelId) + << " channel ID#" << channelId << " with " + << tokens_[token_data].remaining + << " data tokens remaining.\n" + << logofs_flush; + #endif + + return 0; + } + + #if defined(TEST) || defined(INFO) + + if (channelId < 0 || channelId >= CONNECTIONS_LIMIT || + channels_[channelId] == NULL) + { + *logofs << "Proxy: WARNING! No valid channel for ID#" + << channelId << ".\n" << logofs_flush; + } + else if (channels_[channelId] -> getFinish()) + { + *logofs << "Proxy: Can't read from finishing " + << "descriptor FD#" << getFd(channelId) + << " channel ID#" << channelId << ".\n" + << logofs_flush; + } + else if (congestions_[channelId] == 1) + { + *logofs << "Proxy: Can't read from congested " + << "descriptor FD#" << getFd(channelId) + << " channel ID#" << channelId << ".\n" + << logofs_flush; + } + + #endif + + return 0; + } + + // + // Handle the flush and split timeouts. + // All these functions should round up + // to the value of the latency timeout + // to save a further loop. + // + + protected: + + int isTimeToSplit() const + { + if (isTimestamp(timeouts_.splitTs) && + getTimeToNextSplit() <= control -> + LatencyTimeout) + { + if (tokens_[token_split].remaining > 0) + { + return 1; + } + + #if defined(TEST) || defined(INFO) + *logofs << "Proxy: WARNING! Can't encode splits " + << "with " << tokens_[token_split].remaining + << " split tokens remaining.\n" + << logofs_flush; + #endif + } + + return 0; + } + + int isTimeToMotion() const + { + return (isTimestamp(timeouts_.motionTs) && + getTimeToNextMotion() <= control -> + LatencyTimeout); + } + + int getTimeToNextSplit() const + { + #if defined(TEST) || defined(INFO) || defined(FLUSH) + + if (isTimestamp(timeouts_.splitTs) == 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! No split timeout was set " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": No split timeout was set " + << "for proxy FD#" << fd_ << ".\n"; + + HandleCleanup(); + } + + #endif + + int diffTs = timeouts_.split - + diffTimestamp(timeouts_.splitTs, + getTimestamp()); + + return (diffTs > 0 ? diffTs : 0); + } + + int getTimeToNextMotion() const + { + #if defined(TEST) || defined(INFO) || defined(FLUSH) + + if (isTimestamp(timeouts_.motionTs) == 0) + { + #ifdef PANIC + *logofs << "Proxy: PANIC! No motion timeout was set " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": No motion timeout was set " + << "for proxy FD#" << fd_ << ".\n"; + + HandleCleanup(); + } + + #endif + + int diffTs = timeouts_.motion - + diffTimestamp(timeouts_.motionTs, + getTimestamp()); + + return (diffTs > 0 ? diffTs : 0); + } + + protected: + + // + // Implement persistence of cache on disk. + // + + virtual int handleLoadFromProxy() = 0; + virtual int handleSaveFromProxy() = 0; + + int handleLoadStores(); + int handleSaveStores(); + + char *handleSaveAllStores(const char *savePath, bool & isTooSmall) const; + + virtual int handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient) const = 0; + + int handleSaveVersion(unsigned char *buffer, int &major, int &minor, int &patch) const; + + void handleFailOnSave(const char *fullName, const char *failContext) const; + + const char *handleLoadAllStores(const char *loadPath, const char *loadName) const; + + virtual int handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const = 0; + + int handleLoadVersion(const unsigned char *buffer, int &major, int &minor, int &patch) const; + + void handleFailOnLoad(const char *fullName, const char *failContext) const; + + // + // Prepare for a new persistent cache. + // + + int handleResetPersistentCache(); + + // + // Reset the stores in the case of a + // failure loading the cache. + // + + int handleResetStores(); + + // + // Reset the transport buffer and the + // other counters. + // + + void handleResetFlush(); + + // + // Utility functions used to map file + // descriptors to channel ids. + // + + protected: + + int allocateChannelMap(int fd); + int checkChannelMap(int channelId); + int assignChannelMap(int channelId, int fd); + + void cleanupChannelMap(int channelId); + + virtual int checkLocalChannelMap(int channelId) = 0; + + int addControlCodes(T_proxy_code code, int data); + int addTokenCodes(T_proxy_token &token); + + int getFd(int channelId) const + { + if (channelId >= 0 && channelId < CONNECTIONS_LIMIT) + { + return fdMap_[channelId]; + } + + return -1; + } + + int getChannel(int fd) const + { + if (fd >= 0 && fd < CONNECTIONS_LIMIT) + { + return channelMap_[fd]; + } + + return -1; + } + + protected: + + void setSplitTimeout(int channelId); + void setMotionTimeout(int channelId); + + void increaseChannels(int channelId); + void decreaseChannels(int channelId); + + int allocateTransport(int channelFd, int channelId); + int deallocateTransport(int channelId); + + // + // The proxy has its own transport. + // + + ProxyTransport *transport_; + + // + // The static compressor is shared among + // channels and all the message stores. + // + + StaticCompressor *compressor_; + + // + // Map NX specific opcodes. + // + + OpcodeStore *opcodeStore_; + + // + // Stores are shared between channels. + // + + ClientStore *clientStore_; + ServerStore *serverStore_; + + // + // Client and server caches are shared + // between channels. + // + + ClientCache *clientCache_; + ServerCache *serverCache_; + + // + // The proxy's file descriptor. + // + + int fd_; + + // + // Channels currently selected for I/O + // operations. + // + + int inputChannel_; + int outputChannel_; + + // + // List of active channels. + // + + List activeChannels_; + + // + // Used to read data sent from peer proxy. + // + + ProxyReadBuffer readBuffer_; + + // + // Used to send data to peer proxy. + // + + EncodeBuffer encodeBuffer_; + + // + // Control messages' array. + // + + int controlLength_; + + unsigned char controlCodes_[CONTROL_CODES_LENGTH]; + + // + // Table of channel classes taking + // care of open X connections. + // + + Channel *channels_[CONNECTIONS_LIMIT]; + + // + // Table of open sockets. + // + + Transport *transports_[CONNECTIONS_LIMIT]; + + // + // Timeout related data. + // + + T_proxy_timeouts timeouts_; + + // + // Proxy can be decoding messages, + // handling a link reconfiguration, + // or decoding statistics. + // + + int operation_; + + // + // True if we are currently draining + // the proxy link. + // + + int draining_; + + // + // Force flush because of prioritized + // control messages to send. + // + + int priority_; + + // + // Set if we have initiated the close + // down procedure. + // + + int finish_; + + // + // Remote peer requested the shutdown. + // + + int shutdown_; + + // + // We are in the middle of a network + // congestion in the path to remote + // proxy. + // + + int congestion_; + + // + // Channels at the remote end that + // are not consuming their data. + // + + int congestions_[CONNECTIONS_LIMIT]; + + // + // Is the timer expired? + // + + int timer_; + + // + // Did the proxy request an alert? + // + + int alert_; + + // + // The channel id of the agent. + // + + int agent_; + + // + // Token related data. + // + + T_proxy_token tokens_[TOKEN_TYPES]; + + // + // Pointer to stream descriptor where + // proxy is producing statistics. + // + + ostream *currentStatistics_; + + private: + + // + // Map channel ids to file descriptors. + // + + int channelMap_[CONNECTIONS_LIMIT]; + int fdMap_[CONNECTIONS_LIMIT]; + int slavePidMap_[CONNECTIONS_LIMIT]; +}; + +#endif /* Proxy_H */ diff --git a/nxcomp/src/ProxyReadBuffer.cpp b/nxcomp/src/ProxyReadBuffer.cpp new file mode 100644 index 000000000..77f12771b --- /dev/null +++ b/nxcomp/src/ProxyReadBuffer.cpp @@ -0,0 +1,211 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ProxyReadBuffer.h" + +#include "Transport.h" + +// +// Set the verbosity level. You also +// need to define DUMP in Misc.cpp +// if DUMP is defined here. +// + +#define WARNING +#define PANIC +#undef TEST +#undef DEBUG +#undef DUMP + +unsigned int ProxyReadBuffer::suggestedLength(unsigned int pendingLength) +{ + // + // Always read all the data that + // is available. + // + + int readable = transport_ -> readable(); + + unsigned int readLength = (readable == -1 ? 0 : (unsigned int) readable); + + if (readLength < pendingLength) + { + readLength = pendingLength; + } + + // + // Even if the readable data is not + // enough to make a complete message, + // resize the buffer to accommodate + // it all. + // + + if (pendingLength < remaining_) + { + readLength = remaining_; + } + + return readLength; +} + +int ProxyReadBuffer::locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength) +{ + unsigned int lengthLength = 0; + const unsigned char *nextSrc = start; + unsigned char next; + + dataLength = 0; + + #ifdef TEST + *logofs << "ProxyReadBuffer: Locating message for FD#" + << transport_ -> fd() << " with " << end - start + << " bytes.\n" << logofs_flush; + #endif + + // + // Use something like the following if + // you are looking for errors. + // + + #ifdef DUMP + if (control -> ProxyMode == proxy_server && start < end && + transport_ -> fd() == 6 || transport_ -> fd() == 11) + { + *logofs << "ProxyReadBuffer: Partial checksums are:\n"; + + DumpBlockChecksums(start, end - start, 256); + + *logofs << logofs_flush; + } + #endif + + do + { + if (nextSrc >= end) + { + remaining_ = 1; + + #ifdef TEST + *logofs << "ProxyReadBuffer: No message was located " + << "with remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + next = *nextSrc++; + + dataLength <<= 7; + dataLength |= (unsigned int) (next & 0x7f); + + lengthLength++; + } + while (next & 0x80); + + unsigned int totalLength; + + if (dataLength == 0) + { + trailerLength = 0; + controlLength = 3; + totalLength = controlLength; + } + else + { + trailerLength = lengthLength; + controlLength = 0; + totalLength = dataLength + trailerLength; + } + + if (start + totalLength > end) + { + // + // When having to decompress a ZLIB stream, + // a single byte can be enough to complete + // the frame. + // + + if (control -> RemoteStreamCompression == 0) + { + remaining_ = totalLength - (end - start); + } + else + { + remaining_ = 1; + } + + #ifdef TEST + *logofs << "ProxyReadBuffer: No message was located " + << "with remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + else + { + #ifdef DUMP + *logofs << "ProxyReadBuffer: Received " << totalLength << " bytes of data " + << "with checksum "; + + DumpChecksum(start, totalLength); + + *logofs << " on proxy FD#" << transport_ -> fd() << ".\n" << logofs_flush; + #endif + + #if defined(TEST) || defined(INFO) + *logofs << "ProxyReadBuffer: Produced plain input for " << dataLength + << "+" << trailerLength << "+" << controlLength << " bytes out of " + << totalLength << " bytes.\n" << logofs_flush; + #endif + + #ifdef DUMP + *logofs << "ProxyReadBuffer: Partial checksums are:\n"; + + DumpBlockChecksums(start, totalLength, 256); + + *logofs << logofs_flush; + #endif + + remaining_ = 0; + + #ifdef TEST + *logofs << "ProxyReadBuffer: Located message with " + << "remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 1; + } +} diff --git a/nxcomp/src/ProxyReadBuffer.h b/nxcomp/src/ProxyReadBuffer.h new file mode 100644 index 000000000..68e9e95fa --- /dev/null +++ b/nxcomp/src/ProxyReadBuffer.h @@ -0,0 +1,57 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ProxyReadBuffer_H +#define ProxyReadBuffer_H + +#include "ReadBuffer.h" +#include "Control.h" + +class ProxyReadBuffer : public ReadBuffer +{ + public: + + ProxyReadBuffer(Transport *transport) + + : ReadBuffer(transport) + { + } + + virtual ~ProxyReadBuffer() + { + } + + protected: + + virtual unsigned int suggestedLength(unsigned int pendingLength); + + virtual int locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength); +}; + +#endif /* ProxyReadBuffer_H */ diff --git a/nxcomp/src/PutImage.cpp b/nxcomp/src/PutImage.cpp new file mode 100644 index 000000000..d14f922c3 --- /dev/null +++ b/nxcomp/src/PutImage.cpp @@ -0,0 +1,411 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PutImage.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +PutImageStore::PutImageStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = PUTIMAGE_ENABLE_CACHE; + enableData = PUTIMAGE_ENABLE_DATA; + + // Since ProtoStep7 (#issue 108) + enableCompress = PUTIMAGE_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = PUTIMAGE_DATA_LIMIT; + dataOffset = PUTIMAGE_DATA_OFFSET; + + cacheSlots = PUTIMAGE_CACHE_SLOTS; + cacheThreshold = PUTIMAGE_CACHE_THRESHOLD; + cacheLowerThreshold = PUTIMAGE_CACHE_LOWER_THRESHOLD; + + // Since ProtoStep8 (#issue 108) + enableSplit = PUTIMAGE_ENABLE_SPLIT_IF_PROTO_STEP_8; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +PutImageStore::~PutImageStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int PutImageStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; + #endif + + encodeBuffer.encodeValue(GetUINT(buffer + 2, bigEndian), 16, 8); + + encodeBuffer.encodeValue((unsigned int) buffer[1], 2); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> drawableCache); + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> gcCache); + + unsigned int width = GetUINT(buffer + 12, bigEndian); + encodeBuffer.encodeCachedValue(width, 16, + clientCache -> putImageWidthCache, 8); + + unsigned int height = GetUINT(buffer + 14, bigEndian); + encodeBuffer.encodeCachedValue(height, 16, + clientCache -> putImageHeightCache, 8); + + unsigned int x = GetUINT(buffer + 16, bigEndian); + int xDiff = x - clientCache -> putImageLastX; + clientCache -> putImageLastX = x; + encodeBuffer.encodeCachedValue(xDiff, 16, + clientCache -> putImageXCache, 8); + + unsigned int y = GetUINT(buffer + 18, bigEndian); + int yDiff = y - clientCache -> putImageLastY; + clientCache -> putImageLastY = y; + encodeBuffer.encodeCachedValue(yDiff, 16, + clientCache -> putImageYCache, 8); + + encodeBuffer.encodeCachedValue(buffer[20], 8, + clientCache -> putImageLeftPadCache); + + encodeBuffer.encodeCachedValue(buffer[21], 8, + clientCache -> depthCache); + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int PutImageStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; + #endif + + unsigned int value; + unsigned char cValue; + + decodeBuffer.decodeValue(value, 16, 8); + + size = (value << 2); + + buffer = writeBuffer -> addMessage(size); + + decodeBuffer.decodeValue(value, 2); + buffer[1] = (unsigned char) value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + PutULONG(value, buffer + 4, bigEndian); + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + PutULONG(value, buffer + 8, bigEndian); + + unsigned int width; + decodeBuffer.decodeCachedValue(width, 16, + clientCache -> putImageWidthCache, 8); + PutUINT(width, buffer + 12, bigEndian); + + unsigned int height; + decodeBuffer.decodeCachedValue(height, 16, + clientCache -> putImageHeightCache, 8); + PutUINT(height, buffer + 14, bigEndian); + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageXCache, 8); + clientCache -> putImageLastX += value; + clientCache -> putImageLastX &= 0xffff; + PutUINT(clientCache -> putImageLastX, buffer + 16, bigEndian); + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageYCache, 8); + clientCache -> putImageLastY += value; + clientCache -> putImageLastY &= 0xffff; + PutUINT(clientCache -> putImageLastY, buffer + 18, bigEndian); + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> putImageLeftPadCache); + buffer[20] = cValue; + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + buffer[21] = cValue; + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int PutImageStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PutImageMessage *putImage = (PutImageMessage *) message; + + // + // Here is the fingerprint. + // + + putImage -> format = *(buffer + 1); + putImage -> depth = *(buffer + 21); + putImage -> left_pad = *(buffer + 20); + + putImage -> width = GetUINT(buffer + 12, bigEndian); + putImage -> height = GetUINT(buffer + 14, bigEndian); + putImage -> pos_x = GetUINT(buffer + 16, bigEndian); + putImage -> pos_y = GetUINT(buffer + 18, bigEndian); + + putImage -> drawable = GetULONG(buffer + 4, bigEndian); + putImage -> gcontext = GetULONG(buffer + 8, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PutImageStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PutImageMessage *putImage = (PutImageMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = putImage -> format; + + PutULONG(putImage -> drawable, buffer + 4, bigEndian); + PutULONG(putImage -> gcontext, buffer + 8, bigEndian); + + PutUINT(putImage -> width, buffer + 12, bigEndian); + PutUINT(putImage -> height, buffer + 14, bigEndian); + PutUINT(putImage -> pos_x, buffer + 16, bigEndian); + PutUINT(putImage -> pos_y, buffer + 18, bigEndian); + + *(buffer + 20) = (unsigned char) putImage -> left_pad; + *(buffer + 21) = (unsigned char) putImage -> depth; + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PutImageStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PutImageMessage *putImage = (PutImageMessage *) message; + + *logofs << name() << ": Identity format " << (unsigned) putImage -> format + << ", depth " << (unsigned) putImage -> depth << ", left_pad " + << (unsigned) putImage -> left_pad << ", width " << putImage -> width + << ", height " << putImage -> height << ", pos_x " << putImage -> pos_x + << ", pos_y " << putImage -> pos_y << ", drawable " << putImage -> drawable + << ", gcontext " << putImage -> gcontext << ", size " << putImage -> size_ + << ".\n" << logofs_flush; + + #endif +} + +void PutImageStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Fields format, width, height, left_pad, depth. + // + + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 12, 4); + md5_append(md5_state_, buffer + 20, 2); +} + +void PutImageStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + // + // Encode the variant part. + // + + PutImageMessage *putImage = (PutImageMessage *) message; + PutImageMessage *cachedPutImage = (PutImageMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putImage -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(putImage -> drawable, clientCache -> drawableCache); + + cachedPutImage -> drawable = putImage -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putImage -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(putImage -> gcontext, clientCache -> gcCache); + + cachedPutImage -> gcontext = putImage -> gcontext; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putImage -> pos_x + << " as " << "pos_x" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_x = putImage -> pos_x - cachedPutImage -> pos_x; + + encodeBuffer.encodeCachedValue(diff_x, 16, + clientCache -> putImageXCache, 8); + + cachedPutImage -> pos_x = putImage -> pos_x; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putImage -> pos_y + << " as " << "pos_y" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_y = putImage -> pos_y - cachedPutImage -> pos_y; + + encodeBuffer.encodeCachedValue(diff_y, 16, + clientCache -> putImageYCache, 8); + + cachedPutImage -> pos_y = putImage -> pos_y; +} + +void PutImageStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + // + // Decode the variant part. + // + + PutImageMessage *putImage = (PutImageMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + putImage -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putImage -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + putImage -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putImage -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageXCache, 8); + + putImage -> pos_x += value; + putImage -> pos_x &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putImage -> pos_x + << " as pos_x field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageYCache, 8); + + putImage -> pos_y += value; + putImage -> pos_y &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putImage -> pos_y + << " as pos_y field.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/PutImage.h b/nxcomp/src/PutImage.h new file mode 100644 index 000000000..93dde9dfb --- /dev/null +++ b/nxcomp/src/PutImage.h @@ -0,0 +1,172 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PutImage_H +#define PutImage_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define PUTIMAGE_ENABLE_CACHE 1 +#define PUTIMAGE_ENABLE_DATA 1 + +#define PUTIMAGE_DATA_LIMIT 262144 - 24 +#define PUTIMAGE_DATA_OFFSET 24 + +#define PUTIMAGE_CACHE_SLOTS 6000 +#define PUTIMAGE_CACHE_THRESHOLD 70 +#define PUTIMAGE_CACHE_LOWER_THRESHOLD 50 + +#define PUTIMAGE_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +#define PUTIMAGE_CACHE_THRESHOLD_IF_PACKED 10 +#define PUTIMAGE_CACHE_LOWER_THRESHOLD_IF_PACKED 5 + +#define PUTIMAGE_CACHE_THRESHOLD_IF_SHADOW 97 +#define PUTIMAGE_CACHE_LOWER_THRESHOLD_IF_SHADOW 90 + +#define PUTIMAGE_ENABLE_SPLIT_IF_PROTO_STEP_8 0 + +// +// The message class. +// + +class PutImageMessage : public Message +{ + friend class PutImageStore; + + public: + + PutImageMessage() + { + } + + ~PutImageMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char format; + unsigned char depth; + unsigned char left_pad; + unsigned short width; + unsigned short height; + unsigned int drawable; + unsigned int gcontext; + unsigned short pos_x; + unsigned short pos_y; +}; + +class PutImageStore : public MessageStore +{ + public: + + PutImageStore(StaticCompressor *compressor); + + virtual ~PutImageStore(); + + virtual const char *name() const + { + return "PutImage"; + } + + virtual unsigned char opcode() const + { + return X_PutImage; + } + + virtual unsigned int storage() const + { + return sizeof(PutImageMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new PutImageMessage(); + } + + virtual Message *create(const Message &message) const + { + return new PutImageMessage((const PutImageMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (PutImageMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PutImage_H */ diff --git a/nxcomp/src/PutPackedImage.cpp b/nxcomp/src/PutPackedImage.cpp new file mode 100644 index 000000000..0bae2c0d4 --- /dev/null +++ b/nxcomp/src/PutPackedImage.cpp @@ -0,0 +1,604 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "PutPackedImage.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +PutPackedImageStore::PutPackedImageStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = PUTPACKEDIMAGE_ENABLE_CACHE; + enableData = PUTPACKEDIMAGE_ENABLE_DATA; + enableCompress = PUTPACKEDIMAGE_ENABLE_COMPRESS; + + dataLimit = PUTPACKEDIMAGE_DATA_LIMIT; + dataOffset = PUTPACKEDIMAGE_DATA_OFFSET; + + cacheSlots = PUTPACKEDIMAGE_CACHE_SLOTS; + cacheThreshold = PUTPACKEDIMAGE_CACHE_THRESHOLD; + cacheLowerThreshold = PUTPACKEDIMAGE_CACHE_LOWER_THRESHOLD; + + // Since ProtoStep8 (#issue 108) + enableSplit = PUTPACKEDIMAGE_ENABLE_SPLIT_IF_PROTO_STEP_8; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +PutPackedImageStore::~PutPackedImageStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int PutPackedImageStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; + #endif + + // Client. + encodeBuffer.encodeCachedValue(*(buffer + 1), 8, + clientCache -> resourceCache); + + // Size. + encodeBuffer.encodeValue(GetUINT(buffer + 2, bigEndian), 16, 10); + + // Drawable. + encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> drawableCache); + // GC. + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> gcCache); + // Method. + encodeBuffer.encodeCachedValue(*(buffer + 12), 8, + clientCache -> methodCache); + // Format. + encodeBuffer.encodeValue(*(buffer + 13), 2); + + // SrcDepth. + encodeBuffer.encodeCachedValue(*(buffer + 14), 8, + clientCache -> depthCache); + // DstDepth. + encodeBuffer.encodeCachedValue(*(buffer + 15), 8, + clientCache -> depthCache); + // SrcLength. + encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 24, + clientCache -> putPackedImageSrcLengthCache); + // DstLength. + encodeBuffer.encodeCachedValue(GetULONG(buffer + 20, bigEndian), 24, + clientCache -> putPackedImageDstLengthCache); + // SrcX. + unsigned int x = GetUINT(buffer + 24, bigEndian); + int xDiff = x - clientCache -> putImageLastX; + clientCache -> putImageLastX = x; + encodeBuffer.encodeCachedValue(xDiff, 16, + clientCache -> putImageXCache, 8); + // SrcY. + unsigned int y = GetUINT(buffer + 26, bigEndian); + int yDiff = y - clientCache -> putImageLastY; + clientCache -> putImageLastY = y; + encodeBuffer.encodeCachedValue(yDiff, 16, + clientCache -> putImageYCache, 8); + // SrcWidth. + encodeBuffer.encodeCachedValue(GetUINT(buffer + 28, bigEndian), 16, + clientCache -> putImageWidthCache, 8); + // SrcHeight. + encodeBuffer.encodeCachedValue(GetUINT(buffer + 30, bigEndian), 16, + clientCache -> putImageHeightCache, 8); + // DstX. + x = GetUINT(buffer + 32, bigEndian); + xDiff = x - clientCache -> putImageLastX; + clientCache -> putImageLastX = x; + encodeBuffer.encodeCachedValue(xDiff, 16, + clientCache -> putImageXCache, 8); + // DstY. + y = GetUINT(buffer + 34, bigEndian); + yDiff = y - clientCache -> putImageLastY; + clientCache -> putImageLastY = y; + encodeBuffer.encodeCachedValue(yDiff, 16, + clientCache -> putImageYCache, 8); + // DstWidth. + encodeBuffer.encodeCachedValue(GetUINT(buffer + 36, bigEndian), 16, + clientCache -> putImageWidthCache, 8); + // DstHeight. + encodeBuffer.encodeCachedValue(GetUINT(buffer + 38, bigEndian), 16, + clientCache -> putImageHeightCache, 8); + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int PutPackedImageStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; + #endif + + unsigned int value; + unsigned char cValue; + + // Client. + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> resourceCache); + + // Size. + decodeBuffer.decodeValue(size, 16, 10); + + size <<= 2; + + buffer = writeBuffer -> addMessage(size); + + *(buffer + 1) = cValue; + + // Drawable. + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + PutULONG(value, buffer + 4, bigEndian); + + // GC. + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + PutULONG(value, buffer + 8, bigEndian); + + // Method. + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> methodCache); + *(buffer + 12) = cValue; + + // Format. + decodeBuffer.decodeValue(value, 2); + *(buffer + 13) = value; + + // SrcDepth. + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + *(buffer + 14) = cValue; + + // DstDepth. + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + *(buffer + 15) = cValue; + + // SrcLength. + decodeBuffer.decodeCachedValue(value, 24, + clientCache -> putPackedImageSrcLengthCache); + PutULONG(value, buffer + 16, bigEndian); + + // DstLength. + decodeBuffer.decodeCachedValue(value, 24, + clientCache -> putPackedImageDstLengthCache); + PutULONG(value, buffer + 20, bigEndian); + + // SrcX. + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageXCache, 8); + clientCache -> putImageLastX += value; + clientCache -> putImageLastX &= 0xffff; + PutUINT(clientCache -> putImageLastX, buffer + 24, bigEndian); + + // SrcY. + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageYCache, 8); + clientCache -> putImageLastY += value; + clientCache -> putImageLastY &= 0xffff; + PutUINT(clientCache -> putImageLastY, buffer + 26, bigEndian); + + // SrcWidth. + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageWidthCache, 8); + PutUINT(value, buffer + 28, bigEndian); + + // SrcHeight. + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageHeightCache, 8); + PutUINT(value, buffer + 30, bigEndian); + + // DstX. + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageXCache, 8); + clientCache -> putImageLastX += value; + clientCache -> putImageLastX &= 0xffff; + PutUINT(clientCache -> putImageLastX, buffer + 32, bigEndian); + + // DstY. + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageYCache, 8); + clientCache -> putImageLastY += value; + clientCache -> putImageLastY &= 0xffff; + PutUINT(clientCache -> putImageLastY, buffer + 34, bigEndian); + + // DstWidth. + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageWidthCache, 8); + PutUINT(value, buffer + 36, bigEndian); + + // DstHeight. + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageHeightCache, 8); + PutUINT(value, buffer + 38, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int PutPackedImageStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; + + // + // Here is the fingerprint. + // + + putPackedImage -> client = *(buffer + 1); + + putPackedImage -> drawable = GetULONG(buffer + 4, bigEndian); + putPackedImage -> gcontext = GetULONG(buffer + 8, bigEndian); + + putPackedImage -> method = *(buffer + 12); + + putPackedImage -> format = *(buffer + 13); + putPackedImage -> src_depth = *(buffer + 14); + putPackedImage -> dst_depth = *(buffer + 15); + + putPackedImage -> src_length = GetULONG(buffer + 16, bigEndian); + putPackedImage -> dst_length = GetULONG(buffer + 20, bigEndian); + + putPackedImage -> src_x = GetUINT(buffer + 24, bigEndian); + putPackedImage -> src_y = GetUINT(buffer + 26, bigEndian); + putPackedImage -> src_width = GetUINT(buffer + 28, bigEndian); + putPackedImage -> src_height = GetUINT(buffer + 30, bigEndian); + + putPackedImage -> dst_x = GetUINT(buffer + 32, bigEndian); + putPackedImage -> dst_y = GetUINT(buffer + 34, bigEndian); + putPackedImage -> dst_width = GetUINT(buffer + 36, bigEndian); + putPackedImage -> dst_height = GetUINT(buffer + 38, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int PutPackedImageStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = putPackedImage -> client; + + PutULONG(putPackedImage -> drawable, buffer + 4, bigEndian); + PutULONG(putPackedImage -> gcontext, buffer + 8, bigEndian); + + *(buffer + 12) = putPackedImage -> method; + + *(buffer + 13) = putPackedImage -> format; + *(buffer + 14) = putPackedImage -> src_depth; + *(buffer + 15) = putPackedImage -> dst_depth; + + PutULONG(putPackedImage -> src_length, buffer + 16, bigEndian); + PutULONG(putPackedImage -> dst_length, buffer + 20, bigEndian); + + PutUINT(putPackedImage -> src_x, buffer + 24, bigEndian); + PutUINT(putPackedImage -> src_y, buffer + 26, bigEndian); + PutUINT(putPackedImage -> src_width, buffer + 28, bigEndian); + PutUINT(putPackedImage -> src_height, buffer + 30, bigEndian); + + PutUINT(putPackedImage -> dst_x, buffer + 32, bigEndian); + PutUINT(putPackedImage -> dst_y, buffer + 34, bigEndian); + PutUINT(putPackedImage -> dst_width, buffer + 36, bigEndian); + PutUINT(putPackedImage -> dst_height, buffer + 38, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void PutPackedImageStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; + + *logofs << name() << ": Identity format " + + << "drawable " << putPackedImage -> drawable << ", " + << "gcontext " << putPackedImage -> gcontext << ", " + + << "format " << (unsigned int) putPackedImage -> format << ", " + << "method " << (unsigned int) putPackedImage -> method << ", " + + << "src_depth " << (unsigned int) putPackedImage -> src_depth << ", " + << "dst_depth " << (unsigned int) putPackedImage -> dst_depth << ", " + + << "src_length " << putPackedImage -> src_length << ", " + << "dst_length " << putPackedImage -> dst_length << ", " + + << "src_x " << putPackedImage -> src_x << ", " + << "src_y " << putPackedImage -> src_y << ", " + << "src_width " << putPackedImage -> src_width << ", " + << "src_height " << putPackedImage -> src_height << ", " + + << "dst_x " << putPackedImage -> dst_x << ", " + << "dst_y " << putPackedImage -> dst_y << ", " + << "dst_width " << putPackedImage -> dst_width << ", " + << "dst_height " << putPackedImage -> dst_height << ", " + + << "size " << putPackedImage -> size_ << ".\n" + << logofs_flush; + + #endif +} + +void PutPackedImageStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Fields method, format, src_depth, dst_depth, + // src_length, dst_length, src_x, src_y, src_width, + // src_height. + // + // + // TODO: We should better investigate the effect of + // having fields src_x and src_y in identity instead + // of keeping them in differences. + // + + md5_append(md5_state_, buffer + 12, 20); +} + +void PutPackedImageStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + // + // Encode the variant part. + // + + PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; + PutPackedImageMessage *cachedPutPackedImage = (PutPackedImageMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " + << (unsigned int) putPackedImage -> client + << " as client field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(putPackedImage -> client, 8, + clientCache -> resourceCache); + + cachedPutPackedImage -> client = putPackedImage -> client; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putPackedImage -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(putPackedImage -> drawable, clientCache -> drawableCache); + + cachedPutPackedImage -> drawable = putPackedImage -> drawable; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putPackedImage -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(putPackedImage -> gcontext, clientCache -> gcCache); + + cachedPutPackedImage -> gcontext = putPackedImage -> gcontext; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putPackedImage -> dst_x + << " as " << "dst_x" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_x = putPackedImage -> dst_x - cachedPutPackedImage -> dst_x; + + encodeBuffer.encodeCachedValue(diff_x, 16, + clientCache -> putImageXCache, 8); + + cachedPutPackedImage -> dst_x = putPackedImage -> dst_x; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putPackedImage -> dst_y + << " as " << "dst_y" << " field.\n" << logofs_flush; + #endif + + unsigned short int diff_y = putPackedImage -> dst_y - cachedPutPackedImage -> dst_y; + + encodeBuffer.encodeCachedValue(diff_y, 16, + clientCache -> putImageYCache, 8); + + cachedPutPackedImage -> dst_y = putPackedImage -> dst_y; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putPackedImage -> dst_width + << " as " << "dst_width" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(putPackedImage -> dst_width, 16, + clientCache -> putImageWidthCache, 8); + + cachedPutPackedImage -> dst_width = putPackedImage -> dst_width; + + #ifdef TEST + *logofs << name() << ": Encoding value " << putPackedImage -> dst_height + << " as " << "dst_height" << " field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(putPackedImage -> dst_height, 16, + clientCache -> putImageHeightCache, 8); + + cachedPutPackedImage -> dst_height = putPackedImage -> dst_height; +} + +void PutPackedImageStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + // + // Decode the variant part. + // + + PutPackedImageMessage *putPackedImage = (PutPackedImageMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeCachedValue(putPackedImage -> client, 8, + clientCache -> resourceCache); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " + << (unsigned int) putPackedImage -> client + << " as client field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> drawableCache); + + putPackedImage -> drawable = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putPackedImage -> drawable + << " as drawable field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + putPackedImage -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putPackedImage -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageXCache, 8); + + putPackedImage -> dst_x += value; + putPackedImage -> dst_x &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putPackedImage -> dst_x + << " as dst_x field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageYCache, 8); + + putPackedImage -> dst_y += value; + putPackedImage -> dst_y &= 0xffff; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putPackedImage -> dst_y + << " as dst_y field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageWidthCache, 8); + + putPackedImage -> dst_width = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putPackedImage -> dst_width + << " as dst_width field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> putImageHeightCache, 8); + + putPackedImage -> dst_height = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << putPackedImage -> dst_height + << " as dst_height field.\n" << logofs_flush; + #endif +} + diff --git a/nxcomp/src/PutPackedImage.h b/nxcomp/src/PutPackedImage.h new file mode 100644 index 000000000..d28ad39eb --- /dev/null +++ b/nxcomp/src/PutPackedImage.h @@ -0,0 +1,218 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef PutPackedImage_H +#define PutPackedImage_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define PUTPACKEDIMAGE_ENABLE_CACHE 1 +#define PUTPACKEDIMAGE_ENABLE_DATA 1 +#define PUTPACKEDIMAGE_ENABLE_COMPRESS 0 + +// +// We can't exceed lenght of 262144 bytes. +// + +#define PUTPACKEDIMAGE_DATA_LIMIT 262144 - 40 +#define PUTPACKEDIMAGE_DATA_OFFSET 40 + +#define PUTPACKEDIMAGE_CACHE_SLOTS 6000 +#define PUTPACKEDIMAGE_CACHE_THRESHOLD 70 +#define PUTPACKEDIMAGE_CACHE_LOWER_THRESHOLD 50 + +#define PUTPACKEDIMAGE_CACHE_THRESHOLD_IF_PACKED_SHADOW 97 +#define PUTPACKEDIMAGE_CACHE_LOWER_THRESHOLD_IF_PACKED_SHADOW 90 + +#define PUTPACKEDIMAGE_ENABLE_SPLIT_IF_PROTO_STEP_8 0 + +// +// The message class. +// + +class PutPackedImageMessage : public Message +{ + friend class PutPackedImageStore; + + public: + + PutPackedImageMessage() + { + } + + ~PutPackedImageMessage() + { + } + + // + // Here are the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char client; + + unsigned int drawable; + unsigned int gcontext; + + unsigned char format; + unsigned char method; + + unsigned char src_depth; + unsigned char dst_depth; + + unsigned int src_length; + unsigned int dst_length; + + short int src_x; + short int src_y; + unsigned short src_width; + unsigned short src_height; + + short int dst_x; + short int dst_y; + unsigned short dst_width; + unsigned short dst_height; +}; + +class PutPackedImageStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + PutPackedImageStore(StaticCompressor *compressor); + + virtual ~PutPackedImageStore(); + + virtual const char *name() const + { + return "PutPackedImage"; + } + + virtual unsigned char opcode() const + { + return X_NXPutPackedImage; + } + + virtual unsigned int storage() const + { + return sizeof(PutPackedImageMessage); + } + + // + // Very special of this class. + // + + int getPackedSize(const int position) const + { + PutPackedImageMessage *message = (PutPackedImageMessage *) (*messages_)[position]; + + if (message == NULL) + { + return 0; + } + + return dataOffset + message -> src_length; + } + + int getUnpackedSize(const int position) const + { + PutPackedImageMessage *message = (PutPackedImageMessage *) (*messages_)[position]; + + if (message == NULL) + { + return 0; + } + + return dataOffset + message -> dst_length; + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new PutPackedImageMessage(); + } + + virtual Message *create(const Message &message) const + { + return new PutPackedImageMessage((const PutPackedImageMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (PutPackedImageMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* PutPackedImage_H */ diff --git a/nxcomp/src/QueryFontReply.cpp b/nxcomp/src/QueryFontReply.cpp new file mode 100644 index 000000000..fde873140 --- /dev/null +++ b/nxcomp/src/QueryFontReply.cpp @@ -0,0 +1,154 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "QueryFontReply.h" + +#include "ServerCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +QueryFontReplyStore::QueryFontReplyStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = QUERYFONTREPLY_ENABLE_CACHE; + enableData = QUERYFONTREPLY_ENABLE_DATA; + enableSplit = QUERYFONTREPLY_ENABLE_SPLIT; + + // Since ProtoStep7 (#issue 108) + enableCompress = QUERYFONTREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = QUERYFONTREPLY_DATA_LIMIT; + dataOffset = QUERYFONTREPLY_DATA_OFFSET; + + cacheSlots = QUERYFONTREPLY_CACHE_SLOTS; + cacheThreshold = QUERYFONTREPLY_CACHE_THRESHOLD; + cacheLowerThreshold = QUERYFONTREPLY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +QueryFontReplyStore::~QueryFontReplyStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int QueryFontReplyStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Clear the padding bytes. + // + + unsigned char *pad = (unsigned char *) buffer; + + if (size >= 24) + { + PutULONG(0, pad + 20, bigEndian); + } + + if (size >= 40) + { + PutULONG(0, pad + 36, bigEndian); + } + + // + // TODO: This doesn't work. Probably these + // padding bytes are not padding anymore. + // This is to be investigated. + // + // pad += 60; + // + // while (pad + 16 <= (buffer + size)) + // { + // PutULONG(0, pad + 12, bigEndian); + // + // pad += 16; + // } + // + + #ifdef DEBUG + *logofs << name() << ": Cleaned padding bytes of " + << "message at " << message << ".\n" + << logofs_flush; + #endif + + return 1; +} + +int QueryFontReplyStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + return 1; +} + +void QueryFontReplyStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + QueryFontReplyMessage *queryFontReply = (QueryFontReplyMessage *) message; + + *logofs << name() << ": Identity size " << queryFontReply -> size_ << ".\n"; + + #endif +} + +void QueryFontReplyStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} diff --git a/nxcomp/src/QueryFontReply.h b/nxcomp/src/QueryFontReply.h new file mode 100644 index 000000000..e12fe4e4b --- /dev/null +++ b/nxcomp/src/QueryFontReply.h @@ -0,0 +1,136 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef QueryFontReply_H +#define QueryFontReply_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// +#define QUERYFONTREPLY_ENABLE_CACHE 1 +#define QUERYFONTREPLY_ENABLE_DATA 1 +#define QUERYFONTREPLY_ENABLE_SPLIT 0 + +#define QUERYFONTREPLY_DATA_LIMIT 1048576 - 32 +#define QUERYFONTREPLY_DATA_OFFSET 8 + +#define QUERYFONTREPLY_CACHE_SLOTS 200 +#define QUERYFONTREPLY_CACHE_THRESHOLD 20 +#define QUERYFONTREPLY_CACHE_LOWER_THRESHOLD 5 + +#define QUERYFONTREPLY_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +// +// The message class. +// + +class QueryFontReplyMessage : public Message +{ + friend class QueryFontReplyStore; + + public: + + QueryFontReplyMessage() + { + } + + ~QueryFontReplyMessage() + { + } +}; + +class QueryFontReplyStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + QueryFontReplyStore(StaticCompressor *compressor); + + virtual ~QueryFontReplyStore(); + + virtual const char *name() const + { + return "QueryFontReply"; + } + + virtual unsigned char opcode() const + { + return X_QueryFont; + } + + virtual unsigned int storage() const + { + return sizeof(QueryFontReplyMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new QueryFontReplyMessage(); + } + + virtual Message *create(const Message &message) const + { + return new QueryFontReplyMessage((const QueryFontReplyMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (QueryFontReplyMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* QueryFontReply_H */ diff --git a/nxcomp/src/ReadBuffer.cpp b/nxcomp/src/ReadBuffer.cpp new file mode 100644 index 000000000..154225e75 --- /dev/null +++ b/nxcomp/src/ReadBuffer.cpp @@ -0,0 +1,639 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ReadBuffer.h" + +#include "Transport.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +ReadBuffer::ReadBuffer(Transport *transport) + + : transport_(transport) +{ + // + // The read buffer will grow until + // reaching the maximum buffer size + // and then will remain stable at + // that size. + // + + initialReadSize_ = READ_BUFFER_DEFAULT_SIZE; + maximumBufferSize_ = READ_BUFFER_DEFAULT_SIZE; + + size_ = 0; + buffer_ = NULL; + + owner_ = 1; + length_ = 0; + start_ = 0; + + remaining_ = 0; +} + +ReadBuffer::~ReadBuffer() +{ + if (owner_ == 1) + { + delete [] buffer_; + } +} + +void ReadBuffer::readMessage(const unsigned char *message, unsigned int length) +{ + // + // To be here we must be the real owner + // of the buffer and there must not be + // pending bytes in the transport. + // + + #ifdef TEST + + if (owner_ == 0) + { + *logofs << "ReadBuffer: PANIC! Class for FD#" + << transport_ -> fd() << " doesn't " + << "appear to be the owner of the buffer " + << "while borrowing from the caller.\n" + << logofs_flush; + + HandleCleanup(); + } + + #endif + + // + // Be sure that any outstanding data from + // the transport is appended to our own + // byffer. + // + + if (transport_ -> pending() != 0) + { + #ifdef WARNING + *logofs << "ReadBuffer: WARNING! Class for FD#" + << transport_ -> fd() << " has pending " + << "data in the transport while " + << "borrowing from the caller.\n" + << logofs_flush; + #endif + + readMessage(); + + if (owner_ == 0) + { + convertBuffer(); + } + } + + // + // Can't borrow the buffer if there is data + // from a partial message. In this case add + // the new data to the end of our buffer. + // + + if (length_ == 0) + { + #ifdef TEST + *logofs << "ReadBuffer: Borrowing " << length + << " bytes from the caller for FD#" + << transport_ -> fd() << " with " + << length_ << " bytes in the buffer.\n" + << logofs_flush; + #endif + + delete [] buffer_; + + buffer_ = (unsigned char *) message; + size_ = length; + + length_ = length; + + owner_ = 0; + start_ = 0; + } + else + { + #ifdef TEST + *logofs << "ReadBuffer: Appending " << length + << " bytes from the caller for FD#" + << transport_ -> fd() << " with " + << length_ << " bytes in the buffer.\n" + << logofs_flush; + #endif + + appendBuffer(message, length); + } +} + +int ReadBuffer::readMessage() +{ + int pendingLength = transport_ -> pending(); + + if (pendingLength > 0) + { + // + // Can't move the data in the borrowed buffer, + // so use the tansport buffer only if we don't + // have any partial message. This can happen + // with the proxy where we need to deflate the + // stream. + // + + if (length_ == 0) + { + unsigned char *newBuffer; + + length_ = transport_ -> getPending(newBuffer); + + if (newBuffer == NULL) + { + #ifdef PANIC + *logofs << "ReadBuffer: PANIC! Failed to borrow " + << length_ << " bytes of memory for buffer " + << "in context [A].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to borrow memory for " + << "read buffer in context [A].\n"; + + HandleCleanup(); + } + + delete [] buffer_; + + buffer_ = newBuffer; + size_ = length_; + + owner_ = 0; + start_ = 0; + + #ifdef TEST + *logofs << "ReadBuffer: Borrowed " << length_ + << " pending bytes for FD#" << transport_ -> + fd() << ".\n" << logofs_flush; + #endif + + return length_; + } + #ifdef TEST + else + { + *logofs << "ReadBuffer: WARNING! Cannot borrow " + << pendingLength << " bytes for FD#" + << transport_ -> fd() << " with " + << length_ << " bytes in the buffer.\n" + << logofs_flush; + } + #endif + } + + unsigned int readLength = suggestedLength(pendingLength); + + #ifdef DEBUG + *logofs << "ReadBuffer: Requested " << readLength + << " bytes for FD#" << transport_ -> fd() + << " with readable " << transport_ -> readable() + << " remaining " << remaining_ << " pending " + << transport_ -> pending() << ".\n" + << logofs_flush; + #endif + + if (readLength < initialReadSize_) + { + readLength = initialReadSize_; + } + + #ifdef DEBUG + *logofs << "ReadBuffer: Buffer size is " << size_ + << " length " << length_ << " and start " + << start_ << ".\n" << logofs_flush; + #endif + + // + // We can't use the transport buffer + // to read our own data in it. + // + + #ifdef TEST + + if (owner_ == 0) + { + *logofs << "ReadBuffer: PANIC! Class for FD#" + << transport_ -> fd() << " doesn't " + << "appear to be the owner of the buffer " + << "while reading.\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + // + // Be sure that we have enough space + // to store all the requested data. + // + + if (buffer_ == NULL || length_ + readLength > size_) + { + unsigned int newSize = length_ + readLength; + + #ifdef TEST + *logofs << "ReadBuffer: Resizing buffer for FD#" + << transport_ -> fd() << " in read from " + << size_ << " to " << newSize << " bytes.\n" + << logofs_flush; + #endif + + unsigned char *newBuffer = allocateBuffer(newSize); + + memcpy(newBuffer, buffer_ + start_, length_); + + delete [] buffer_; + + buffer_ = newBuffer; + size_ = newSize; + + transport_ -> pendingReset(); + + owner_ = 1; + } + else if (start_ != 0 && length_ != 0) + { + // + // If any bytes are left due to a partial + // message, shift them to the beginning + // of the buffer. + // + + #ifdef TEST + *logofs << "ReadBuffer: Moving " << length_ + << " bytes of data " << "at beginning of " + << "the buffer for FD#" << transport_ -> fd() + << ".\n" << logofs_flush; + #endif + + memmove(buffer_, buffer_ + start_, length_); + } + + start_ = 0; + + #ifdef DEBUG + *logofs << "ReadBuffer: Buffer size is now " << size_ + << " length is " << length_ << " and start is " + << start_ << ".\n" << logofs_flush; + #endif + + unsigned char *readData = buffer_ + length_; + + #ifdef DEBUG + *logofs << "ReadBuffer: Going to read " << readLength + << " bytes from FD#" << transport_ -> fd() << ".\n" + << logofs_flush; + #endif + + int bytesRead = transport_ -> read(readData, readLength); + + if (bytesRead > 0) + { + #ifdef TEST + *logofs << "ReadBuffer: Read " << bytesRead + << " bytes from FD#" << transport_ -> fd() + << ".\n" << logofs_flush; + #endif + + length_ += bytesRead; + } + else if (bytesRead < 0) + { + // + // Check if there is more data pending than the + // size of the provided buffer. After reading + // the requested amount, in fact, the transport + // may have decompressed the data and produced + // more input. This trick allows us to always + // borrow the buffer from the transport, even + // when the partial read would have prevented + // that. + // + + if (transport_ -> pending() > 0) + { + #ifdef TEST + *logofs << "ReadBuffer: WARNING! Trying to read some " + << "more with " << transport_ -> pending() + << " bytes pending for FD#" << transport_ -> + fd() << ".\n" << logofs_flush; + #endif + + return readMessage(); + } + + #ifdef TEST + *logofs << "ReadBuffer: Error detected reading " + << "from FD#" << transport_ -> fd() + << ".\n" << logofs_flush; + #endif + + return -1; + } + #ifdef TEST + else + { + *logofs << "ReadBuffer: No data read from FD#" + << transport_ -> fd() << " with remaining " + << remaining_ << ".\n" << logofs_flush; + } + #endif + + return bytesRead; +} + +const unsigned char *ReadBuffer::getMessage(unsigned int &controlLength, + unsigned int &dataLength) +{ + #ifdef TEST + + if (transport_ -> pending() > 0) + { + *logofs << "ReadBuffer: PANIC! The transport " + << "appears to have data pending.\n" + << logofs_flush; + + HandleCleanup(); + } + + #endif + + if (length_ == 0) + { + #ifdef DEBUG + *logofs << "ReadBuffer: No message can be located " + << "for FD#" << transport_ -> fd() << ".\n" + << logofs_flush; + #endif + + if (owner_ == 0) + { + buffer_ = NULL; + size_ = 0; + + transport_ -> pendingReset(); + + owner_ = 1; + start_ = 0; + } + + return NULL; + } + + unsigned int trailerLength; + + #ifdef DEBUG + *logofs << "ReadBuffer: Going to locate message with " + << "start at " << start_ << " and length " + << length_ << " for FD#" << transport_ -> fd() + << ".\n" << logofs_flush; + #endif + + int located = locateMessage(buffer_ + start_, buffer_ + start_ + length_, + controlLength, dataLength, trailerLength); + + if (located == 0) + { + // + // No more complete messages are in + // the buffer. + // + + #ifdef DEBUG + *logofs << "ReadBuffer: No message was located " + << "for FD#" << transport_ -> fd() + << ".\n" << logofs_flush; + #endif + + if (owner_ == 0) + { + // + // Must move the remaining bytes in + // our own buffer. + // + + convertBuffer(); + } + + return NULL; + } + else + { + const unsigned char *result = buffer_ + start_; + + if (dataLength > 0) + { + // + // Message contains data, so go to the + // first byte of payload. + // + + result += trailerLength; + + start_ += (dataLength + trailerLength); + length_ -= (dataLength + trailerLength); + } + else + { + // + // It is a control message. + // + + start_ += (controlLength + trailerLength); + length_ -= (controlLength + trailerLength); + } + + #ifdef DEBUG + *logofs << "ReadBuffer: Located message for FD#" + << transport_ -> fd() << " with control length " + << controlLength << " and data length " + << dataLength << ".\n" << logofs_flush; + #endif + + remaining_ = 0; + + return result; + } +} + +int ReadBuffer::setSize(int initialReadSize, int maximumBufferSize) +{ + initialReadSize_ = initialReadSize; + maximumBufferSize_ = maximumBufferSize; + + #ifdef TEST + *logofs << "ReadBuffer: WARNING! Set buffer parameters to " + << initialReadSize_ << "/" << maximumBufferSize_ + << " for object at "<< this << ".\n" + << logofs_flush; + #endif + + return 1; +} + +void ReadBuffer::fullReset() +{ + #ifdef TEST + + if (owner_ == 0) + { + *logofs << "ReadBuffer: PANIC! Class for FD#" + << transport_ -> fd() << " doesn't " + << "appear to be the owner of the buffer " + << "in reset.\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + if (length_ == 0 && size_ > maximumBufferSize_) + { + #ifdef TEST + *logofs << "ReadBuffer: Resizing buffer for FD#" + << transport_ -> fd() << " in reset from " + << size_ << " to " << maximumBufferSize_ + << " bytes.\n" << logofs_flush; + #endif + + delete [] buffer_; + + int newSize = maximumBufferSize_; + + unsigned char *newBuffer = allocateBuffer(newSize); + + buffer_ = newBuffer; + size_ = newSize; + + transport_ -> pendingReset(); + + owner_ = 1; + start_ = 0; + } +} + +unsigned char *ReadBuffer::allocateBuffer(unsigned int newSize) +{ + unsigned char *newBuffer = new unsigned char[newSize]; + + if (newBuffer == NULL) + { + #ifdef PANIC + *logofs << "ReadBuffer: PANIC! Can't allocate " + << newSize << " bytes of memory for buffer " + << "in context [B].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "read buffer in context [B].\n"; + + HandleCleanup(); + } + + #ifdef VALGRIND + + memset(newBuffer, '\0', newSize); + + #endif + + return newBuffer; +} + +void ReadBuffer::appendBuffer(const unsigned char *message, unsigned int length) +{ + if (start_ + length_ + length > size_) + { + unsigned int newSize = length_ + length + initialReadSize_; + + #ifdef TEST + *logofs << "ReadBuffer: WARNING! Resizing buffer " + << "for FD#" << transport_ -> fd() + << " from " << size_ << " to " << newSize + << " bytes.\n" << logofs_flush; + #endif + + unsigned char *newBuffer = allocateBuffer(newSize); + + memcpy(newBuffer, buffer_ + start_, length_); + + delete [] buffer_; + + buffer_ = newBuffer; + size_ = newSize; + + start_ = 0; + } + + memcpy(buffer_ + start_ + length_, message, length); + + length_ += length; + + transport_ -> pendingReset(); + + owner_ = 1; +} + +void ReadBuffer::convertBuffer() +{ + unsigned int newSize = length_ + initialReadSize_; + + #ifdef TEST + *logofs << "ReadBuffer: WARNING! Converting " + << length_ << " bytes to own buffer " + << "for FD#" << transport_ -> fd() + << " with new size " << newSize + << " bytes.\n" << logofs_flush; + #endif + + unsigned char *newBuffer = allocateBuffer(newSize); + + memcpy(newBuffer, buffer_ + start_, length_); + + buffer_ = newBuffer; + size_ = newSize; + + transport_ -> pendingReset(); + + owner_ = 1; + start_ = 0; +} diff --git a/nxcomp/src/ReadBuffer.h b/nxcomp/src/ReadBuffer.h new file mode 100644 index 000000000..a12bcc9b3 --- /dev/null +++ b/nxcomp/src/ReadBuffer.h @@ -0,0 +1,128 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ReadBuffer_H +#define ReadBuffer_H + +#include "Misc.h" +#include "Timestamp.h" +#include "Transport.h" + +#define READ_BUFFER_DEFAULT_SIZE 8192 + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +class ReadBuffer +{ + public: + + ReadBuffer(Transport *transport); + + virtual ~ReadBuffer(); + + int readMessage(); + + void readMessage(const unsigned char *message, unsigned int length); + + const unsigned char *getMessage(unsigned int &dataLength) + { + unsigned int controlLength; + + return getMessage(controlLength, dataLength); + } + + const unsigned char *getMessage(unsigned int &controlLength, unsigned int &dataLength); + + unsigned int getLength() const + { + return length_; + } + + unsigned int getRemaining() const + { + return remaining_; + } + + int setSize(int initialReadSize, int initialbufferSize); + + void fullReset(); + + // + // Check if there is a complete + // message in the buffer. + // + + int checkMessage() + { + if (length_ == 0) + { + return 0; + } + else + { + unsigned int controlLength; + unsigned int dataLength; + unsigned int trailerLength; + + return (locateMessage(buffer_ + start_, buffer_ + start_ + length_, + controlLength, dataLength, trailerLength)); + } + } + + protected: + + virtual unsigned int suggestedLength(unsigned int pendingLength) = 0; + + virtual int locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength) = 0; + + unsigned char *allocateBuffer(unsigned int newSize); + + void appendBuffer(const unsigned char *message, unsigned int length); + + void convertBuffer(); + + Transport *transport_; + + unsigned char *buffer_; + + unsigned int length_; + unsigned int size_; + unsigned int start_; + unsigned int remaining_; + + int owner_; + + unsigned int initialReadSize_; + unsigned int maximumBufferSize_; +}; + +#endif /* ReadBuffer_H */ diff --git a/nxcomp/src/RenderAddGlyphs.cpp b/nxcomp/src/RenderAddGlyphs.cpp new file mode 100644 index 000000000..ef13d6890 --- /dev/null +++ b/nxcomp/src/RenderAddGlyphs.cpp @@ -0,0 +1,233 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +// +// Include the template for +// this message class. +// + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "RenderAddGlyphs.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 4, bigEndian), 29, + clientCache -> renderGlyphSetCache); + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 8, bigEndian), 32, + clientCache -> renderNumGlyphsCache, 8); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeCachedValue(value, 29, + clientCache -> renderGlyphSetCache); + + PutULONG(value, buffer + 4, bigEndian); + + decodeBuffer.decodeCachedValue(value, 32, + clientCache -> renderNumGlyphsCache, 8); + + PutULONG(value, buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + encodeCharData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + decodeCharData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.add_glyphs.type = *(buffer + 1); + + renderExtension -> data.add_glyphs.set_id = GetULONG(buffer + 4, bigEndian); + renderExtension -> data.add_glyphs.num_elm = GetULONG(buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.add_glyphs.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.add_glyphs.type; + + PutULONG(renderExtension -> data.add_glyphs.set_id, buffer + 4, bigEndian); + PutULONG(renderExtension -> data.add_glyphs.num_elm, buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.add_glyphs.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + md5_append(md5_state, buffer + 1, 3); + md5_append(md5_state, buffer + 8, 4); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(renderExtension -> data.add_glyphs.set_id, 29, + clientCache -> renderGlyphSetCache); + + cachedRenderExtension -> data.add_glyphs.set_id = + renderExtension -> data.add_glyphs.set_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.add_glyphs.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(renderExtension -> data.add_glyphs.set_id, 29, + clientCache -> renderGlyphSetCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.add_glyphs.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderAddGlyphs.h b/nxcomp/src/RenderAddGlyphs.h new file mode 100644 index 000000000..d3c8cd158 --- /dev/null +++ b/nxcomp/src/RenderAddGlyphs.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderAddGlyphs_H +#define RenderAddGlyphs_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderAddGlyphs" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderAddGlyphsStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 12 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderAddGlyphs_H */ diff --git a/nxcomp/src/RenderChangePicture.cpp b/nxcomp/src/RenderChangePicture.cpp new file mode 100644 index 000000000..d202b92ad --- /dev/null +++ b/nxcomp/src/RenderChangePicture.cpp @@ -0,0 +1,238 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +// +// Include the template for +// this message class. +// + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "RenderChangePicture.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> renderSrcPictureCache); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeXidValue(value, clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + #ifdef DEBUG + + if (size == MESSAGE_OFFSET + 4) + { + *logofs << name() << ": Mask is " << GetULONG(buffer + 8, bigEndian) + << " value is " << GetULONG(buffer + 12, bigEndian) + << ".\n" << logofs_flush; + } + else + { + *logofs << name() << ": WARNING! Unexpected size. Mask is " + << GetULONG(buffer + 8, bigEndian) << ".\n" + << logofs_flush; + } + + #endif + + encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.change_picture.type = *(buffer + 1); + + renderExtension -> data.change_picture.src_id = GetULONG(buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.change_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.change_picture.type; + + PutULONG(renderExtension -> data.change_picture.src_id, buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.change_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + md5_append(md5_state, buffer + 1, 3); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(renderExtension -> data.change_picture.src_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.change_picture.src_id = + renderExtension -> data.change_picture.src_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.change_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.change_picture.src_id, + clientCache -> renderSrcPictureCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.change_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderChangePicture.h b/nxcomp/src/RenderChangePicture.h new file mode 100644 index 000000000..4bab1ef98 --- /dev/null +++ b/nxcomp/src/RenderChangePicture.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderChangePicture_H +#define RenderChangePicture_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderChangePicture" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderChangePictureStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 8 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderChangePicture_H */ diff --git a/nxcomp/src/RenderComposite.cpp b/nxcomp/src/RenderComposite.cpp new file mode 100644 index 000000000..f82f80f06 --- /dev/null +++ b/nxcomp/src/RenderComposite.cpp @@ -0,0 +1,400 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +// +// Include the template for +// this message class. +// + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "RenderComposite.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> renderSrcPictureCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), + clientCache -> renderMaskPictureCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 16, bigEndian), + clientCache -> renderDstPictureCache); + + // + // Src X and Y. + // + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 20, bigEndian), + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 22, bigEndian), + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + // + // Mask X and Y. + // + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 24, bigEndian), + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 26, bigEndian), + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + // + // Dst X and Y. + // + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 28, bigEndian), + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 30, bigEndian), + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + // + // Width and height. + // + + encodeBuffer.encodeCachedValue(GetUINT(buffer + 32, bigEndian), 16, + clientCache -> renderWidthCache, 11); + + encodeBuffer.encodeCachedValue(GetUINT(buffer + 34, bigEndian), 16, + clientCache -> renderHeightCache, 11); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + decodeBuffer.decodeXidValue(value, clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 8, bigEndian); + + decodeBuffer.decodeXidValue(value, clientCache -> renderMaskPictureCache); + + PutULONG(value, buffer + 12, bigEndian); + + decodeBuffer.decodeXidValue(value, clientCache -> renderDstPictureCache); + + PutULONG(value, buffer + 16, bigEndian); + + // + // Src X and Y. + // + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + PutUINT(clientCache -> renderLastX, buffer + 20, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + PutUINT(clientCache -> renderLastY, buffer + 22, bigEndian); + + // + // Mask X and Y. + // + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + PutUINT(clientCache -> renderLastX, buffer + 24, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + PutUINT(clientCache -> renderLastY, buffer + 26, bigEndian); + + // + // Dst X and Y. + // + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + PutUINT(clientCache -> renderLastX, buffer + 28, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + PutUINT(clientCache -> renderLastY, buffer + 30, bigEndian); + + // + // Width and height. + // + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> renderWidthCache, 11); + + PutUINT(value, buffer + 32, bigEndian); + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> renderHeightCache, 11); + + PutUINT(value, buffer + 34, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.composite.type = *(buffer + 1); + renderExtension -> data.composite.op = *(buffer + 4); + + renderExtension -> data.composite.src_id = GetULONG(buffer + 8, bigEndian); + renderExtension -> data.composite.msk_id = GetULONG(buffer + 12, bigEndian); + renderExtension -> data.composite.dst_id = GetULONG(buffer + 16, bigEndian); + + renderExtension -> data.composite.src_x = GetUINT(buffer + 20, bigEndian); + renderExtension -> data.composite.src_y = GetUINT(buffer + 22, bigEndian); + + renderExtension -> data.composite.msk_x = GetUINT(buffer + 24, bigEndian); + renderExtension -> data.composite.msk_y = GetUINT(buffer + 26, bigEndian); + + renderExtension -> data.composite.dst_x = GetUINT(buffer + 28, bigEndian); + renderExtension -> data.composite.dst_y = GetUINT(buffer + 30, bigEndian); + + renderExtension -> data.composite.width = GetUINT(buffer + 32, bigEndian); + renderExtension -> data.composite.height = GetUINT(buffer + 34, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.composite.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.composite.type; + *(buffer + 4) = renderExtension -> data.composite.op; + + PutULONG(renderExtension -> data.composite.src_id, buffer + 8, bigEndian); + PutULONG(renderExtension -> data.composite.msk_id, buffer + 12, bigEndian); + PutULONG(renderExtension -> data.composite.dst_id, buffer + 16, bigEndian); + + PutUINT(renderExtension -> data.composite.src_x, buffer + 20, bigEndian); + PutUINT(renderExtension -> data.composite.src_y, buffer + 22, bigEndian); + + PutUINT(renderExtension -> data.composite.msk_x, buffer + 24, bigEndian); + PutUINT(renderExtension -> data.composite.msk_y, buffer + 26, bigEndian); + + PutUINT(renderExtension -> data.composite.dst_x, buffer + 28, bigEndian); + PutUINT(renderExtension -> data.composite.dst_y, buffer + 30, bigEndian); + + PutUINT(renderExtension -> data.composite.width, buffer + 32, bigEndian); + PutUINT(renderExtension -> data.composite.height, buffer + 34, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.composite.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + // + // Include the minor opcode and size in the + // identity, plus the operator, the x and y + // of the source and mask and the width and + // height of the destination. + // + + md5_append(md5_state, buffer + 1, 4); + md5_append(md5_state, buffer + 20, 8); + md5_append(md5_state, buffer + 32, 4); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Source " << renderExtension -> data.composite.src_id + << " mask " << renderExtension -> data.composite.msk_id + << " destination " << renderExtension -> data.composite.msk_id + << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(renderExtension -> data.composite.src_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.composite.src_id = + renderExtension -> data.composite.src_id; + + encodeBuffer.encodeXidValue(renderExtension -> data.composite.msk_id, + clientCache -> renderMaskPictureCache); + + cachedRenderExtension -> data.composite.msk_id = + renderExtension -> data.composite.msk_id; + + encodeBuffer.encodeXidValue(renderExtension -> data.composite.dst_id, + clientCache -> renderDstPictureCache); + + cachedRenderExtension -> data.composite.dst_id = + renderExtension -> data.composite.dst_id; + + // + // Dst X and Y. + // + + unsigned int value; + unsigned int previous; + + value = renderExtension -> data.composite.dst_x; + previous = cachedRenderExtension -> data.composite.dst_x; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderXCache, 11); + + cachedRenderExtension -> data.composite.dst_x = value; + + value = renderExtension -> data.composite.dst_y; + previous = cachedRenderExtension -> data.composite.dst_y; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderYCache, 11); + + cachedRenderExtension -> data.composite.dst_y = value; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.composite.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.composite.src_id, + clientCache -> renderSrcPictureCache); + + decodeBuffer.decodeXidValue(renderExtension -> data.composite.msk_id, + clientCache -> renderMaskPictureCache); + + decodeBuffer.decodeXidValue(renderExtension -> data.composite.dst_id, + clientCache -> renderDstPictureCache); + + // + // Dst X and Y. + // + + unsigned int value; + unsigned int previous; + + previous = renderExtension -> data.composite.dst_x; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderXCache, 11); + + renderExtension -> data.composite.dst_x = value; + + previous = renderExtension -> data.composite.dst_y; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderYCache, 11); + + renderExtension -> data.composite.dst_y = value; + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.composite.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderComposite.h b/nxcomp/src/RenderComposite.h new file mode 100644 index 000000000..aafa1e776 --- /dev/null +++ b/nxcomp/src/RenderComposite.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderComposite_H +#define RenderComposite_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderComposite" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderCompositeStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 36 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 0 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 0 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderComposite_H */ diff --git a/nxcomp/src/RenderCompositeGlyphs.cpp b/nxcomp/src/RenderCompositeGlyphs.cpp new file mode 100644 index 000000000..0949d3e2c --- /dev/null +++ b/nxcomp/src/RenderCompositeGlyphs.cpp @@ -0,0 +1,629 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderCompositeGlyphs.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding value " + << ((size - MESSAGE_OFFSET) >> 2) << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << size + << ".\n" << logofs_flush; + #endif + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> renderSrcPictureCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), + clientCache -> renderDstPictureCache); + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 32, + clientCache -> renderFormatCache); + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 20, bigEndian), 29, + clientCache -> renderGlyphSetCache); + + unsigned int src_x = GetUINT(buffer + 24, bigEndian); + unsigned int src_y = GetUINT(buffer + 26, bigEndian); + + // Since ProtoStep8 (#issue 108) + encodeBuffer.encodeDiffCachedValue(src_x, + clientCache -> renderGlyphX, 16, + clientCache -> renderGlyphXCache, 11); + + encodeBuffer.encodeDiffCachedValue(src_y, + clientCache -> renderGlyphY, 16, + clientCache -> renderGlyphYCache, 11); + + #ifdef TEST + *logofs << name() << ": Encoded source X " + << GetUINT(buffer + 24, bigEndian) << " source Y " + << GetUINT(buffer + 26, bigEndian) << ".\n" + << logofs_flush; + #endif + + // + // Bytes from 28 to 36 contain in the order: + // + // 1 byte for the length of the first string. + // 3 bytes of padding. + // 2 bytes for the X offset. + // 2 bytes for the Y offset. + // + // Encode these bytes differentially to match + // all the strings that have equal glyphs. + // + // Only manage the first string of glyphs. The + // others strings should match, if they contain + // the same glyphs, since the offset are rela- + // tive to the first offset coordinates. + // + + // Since ProtoStep8 (#issue 108) + if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + unsigned int numGlyphs = *(buffer + 28); + + encodeBuffer.encodeCachedValue(numGlyphs, 8, + clientCache -> renderNumGlyphsCache); + + unsigned int offset_x = GetUINT(buffer + 32, bigEndian); + unsigned int offset_y = GetUINT(buffer + 34, bigEndian); + + if (offset_x == src_x && offset_y == src_y) + { + encodeBuffer.encodeBoolValue(0); + + #ifdef TEST + *logofs << name() << ": Matched offset X " + << GetUINT(buffer + 32, bigEndian) << " offset Y " + << GetUINT(buffer + 34, bigEndian) << ".\n" + << logofs_flush; + #endif + } + else + { + encodeBuffer.encodeBoolValue(1); + + encodeBuffer.encodeDiffCachedValue(offset_x, + clientCache -> renderGlyphX, 16, + clientCache -> renderGlyphXCache, 11); + + encodeBuffer.encodeDiffCachedValue(offset_y, + clientCache -> renderGlyphY, 16, + clientCache -> renderGlyphYCache, 11); + + #ifdef TEST + *logofs << name() << ": Missed offset X " + << GetUINT(buffer + 32, bigEndian) << " offset Y " + << GetUINT(buffer + 34, bigEndian) << ".\n" + << logofs_flush; + #endif + } + } + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + decodeBuffer.decodeXidValue(value, + clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 8, bigEndian); + + decodeBuffer.decodeXidValue(value, + clientCache -> renderDstPictureCache); + + PutULONG(value, buffer + 12, bigEndian); + + decodeBuffer.decodeCachedValue(value, 32, + clientCache -> renderFormatCache); + + PutULONG(value, buffer + 16, bigEndian); + + decodeBuffer.decodeCachedValue(value, 29, + clientCache -> renderGlyphSetCache); + + PutULONG(value, buffer + 20, bigEndian); + + unsigned int src_x; + unsigned int src_y; + + // Since ProtoStep8 (#issue 108) + decodeBuffer.decodeDiffCachedValue(src_x, + clientCache -> renderGlyphX, 16, + clientCache -> renderGlyphXCache, 11); + + decodeBuffer.decodeDiffCachedValue(src_y, + clientCache -> renderGlyphY, 16, + clientCache -> renderGlyphYCache, 11); + + PutUINT(src_x, buffer + 24, bigEndian); + PutUINT(src_y, buffer + 26, bigEndian); + + // Since ProtoStep8 (#issue 108) + if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + decodeBuffer.decodeCachedValue(value, 8, + clientCache -> renderNumGlyphsCache); + + *(buffer + 28) = value; + + decodeBuffer.decodeBoolValue(value); + + if (value == 0) + { + PutUINT(src_x, buffer + 32, bigEndian); + PutUINT(src_y, buffer + 34, bigEndian); + } + else + { + decodeBuffer.decodeDiffCachedValue(src_x, + clientCache -> renderGlyphX, 16, + clientCache -> renderGlyphXCache, 11); + + PutUINT(src_x, buffer + 32, bigEndian); + + decodeBuffer.decodeDiffCachedValue(src_y, + clientCache -> renderGlyphY, 16, + clientCache -> renderGlyphYCache, 11); + + PutUINT(src_y, buffer + 34, bigEndian); + } + } + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + // Since ProtoStep8 (#issue 108) + if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + encodeCharData(encodeBuffer, buffer, MESSAGE_OFFSET_IF_PROTO_STEP_8, + size, bigEndian, channelCache); + } + else if (size > MESSAGE_OFFSET) + { + encodeCharData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + } + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of text data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + // Since ProtoStep8 (#issue 108) + if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + decodeCharData(decodeBuffer, buffer, MESSAGE_OFFSET_IF_PROTO_STEP_8, + size, bigEndian, channelCache); + } + else if (size > MESSAGE_OFFSET) + { + decodeCharData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + } + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.composite_glyphs.type = *(buffer + 1); + renderExtension -> data.composite_glyphs.op = *(buffer + 4); + + renderExtension -> data.composite_glyphs.src_id = GetULONG(buffer + 8, bigEndian); + renderExtension -> data.composite_glyphs.dst_id = GetULONG(buffer + 12, bigEndian); + + renderExtension -> data.composite_glyphs.format = GetULONG(buffer + 16, bigEndian); + renderExtension -> data.composite_glyphs.set_id = GetULONG(buffer + 20, bigEndian); + + renderExtension -> data.composite_glyphs.src_x = GetUINT(buffer + 24, bigEndian); + renderExtension -> data.composite_glyphs.src_y = GetUINT(buffer + 26, bigEndian); + + // Since ProtoStep8 (#issue 108) + if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + renderExtension -> data.composite_glyphs.num_elm = *(buffer + 28); + + renderExtension -> data.composite_glyphs.offset_x = GetUINT(buffer + 32, bigEndian); + renderExtension -> data.composite_glyphs.offset_y = GetUINT(buffer + 34, bigEndian); + } + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.composite_glyphs.type + << " size is " << renderExtension -> size_ << " identity size " + << renderExtension -> i_size_ << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.composite_glyphs.type; + *(buffer + 4) = renderExtension -> data.composite_glyphs.op; + + PutULONG(renderExtension -> data.composite_glyphs.src_id, buffer + 8, bigEndian); + PutULONG(renderExtension -> data.composite_glyphs.dst_id, buffer + 12, bigEndian); + + PutULONG(renderExtension -> data.composite_glyphs.format, buffer + 16, bigEndian); + PutULONG(renderExtension -> data.composite_glyphs.set_id, buffer + 20, bigEndian); + + PutUINT(renderExtension -> data.composite_glyphs.src_x, buffer + 24, bigEndian); + PutUINT(renderExtension -> data.composite_glyphs.src_y, buffer + 26, bigEndian); + + // Since ProtoStep8 (#issue 108) + if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + *(buffer + 28) = renderExtension -> data.composite_glyphs.num_elm; + + PutUINT(renderExtension -> data.composite_glyphs.offset_x, buffer + 32, bigEndian); + PutUINT(renderExtension -> data.composite_glyphs.offset_y, buffer + 34, bigEndian); + } + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.composite_glyphs.type + << " size is " << renderExtension -> size_ << " identity size " + << renderExtension -> i_size_ << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + // + // Include minor opcode, size and + // the composite operator in the + // identity. + // + + md5_append(md5_state, buffer + 1, 4); + + // + // Include the format. + // + + md5_append(md5_state, buffer + 16, 4); + + // + // Also include the length of the + // first string. + // + + // Since ProtoStep8 (#issue 108) + if (size >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + md5_append(md5_state, buffer + 28, 1); + } +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(renderExtension -> data.composite_glyphs.src_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.composite_glyphs.src_id = + renderExtension -> data.composite_glyphs.src_id; + + encodeBuffer.encodeXidValue(renderExtension -> data.composite_glyphs.dst_id, + clientCache -> renderDstPictureCache); + + cachedRenderExtension -> data.composite_glyphs.dst_id = + renderExtension -> data.composite_glyphs.dst_id; + + encodeBuffer.encodeCachedValue(renderExtension -> data.composite_glyphs.set_id, 29, + clientCache -> renderGlyphSetCache); + + cachedRenderExtension -> data.composite_glyphs.set_id = + renderExtension -> data.composite_glyphs.set_id; + + // + // Src X and Y. + // + // The source X and Y coordinates are + // encoded as differerences in respect + // to the cached message. + // + + unsigned int value; + unsigned int previous; + + // Since ProtoStep8 (#issue 108) + value = renderExtension -> data.composite_glyphs.src_x; + previous = cachedRenderExtension -> data.composite_glyphs.src_x; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderGlyphXCache, 11); + + cachedRenderExtension -> data.composite_glyphs.src_x = value; + + value = renderExtension -> data.composite_glyphs.src_y; + previous = cachedRenderExtension -> data.composite_glyphs.src_y; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderGlyphYCache, 11); + + cachedRenderExtension -> data.composite_glyphs.src_y = value; + + #ifdef TEST + *logofs << name() << ": Encoded source X " + << renderExtension -> data.composite_glyphs.src_x << " source Y " + << renderExtension -> data.composite_glyphs.src_y << ".\n" + << logofs_flush; + #endif + + // Since ProtoStep8 (#issue 108) + if (renderExtension -> size_ >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + // + // Offset X and Y. + // + + if (renderExtension -> data.composite_glyphs.offset_x == + renderExtension -> data.composite_glyphs.src_x && + renderExtension -> data.composite_glyphs.offset_y == + renderExtension -> data.composite_glyphs.src_y) + { + encodeBuffer.encodeBoolValue(0); + + cachedRenderExtension -> data.composite_glyphs.offset_x = + renderExtension -> data.composite_glyphs.offset_x; + + cachedRenderExtension -> data.composite_glyphs.offset_y = + renderExtension -> data.composite_glyphs.offset_y; + + #ifdef TEST + *logofs << name() << ": Matched offset X " + << renderExtension -> data.composite_glyphs.offset_x << " offset Y " + << renderExtension -> data.composite_glyphs.offset_y << ".\n" + << logofs_flush; + #endif + } + else + { + encodeBuffer.encodeBoolValue(1); + + value = renderExtension -> data.composite_glyphs.offset_x; + previous = cachedRenderExtension -> data.composite_glyphs.offset_x; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderGlyphXCache, 11); + + cachedRenderExtension -> data.composite_glyphs.offset_x = value; + + value = renderExtension -> data.composite_glyphs.offset_y; + previous = cachedRenderExtension -> data.composite_glyphs.offset_y; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderGlyphYCache, 11); + + cachedRenderExtension -> data.composite_glyphs.offset_y = value; + + #ifdef TEST + *logofs << name() << ": Missed offset X " + << renderExtension -> data.composite_glyphs.offset_x << " offset Y " + << renderExtension -> data.composite_glyphs.offset_y << ".\n" + << logofs_flush; + #endif + } + } + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.composite_glyphs.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.composite_glyphs.src_id, + clientCache -> renderSrcPictureCache); + + decodeBuffer.decodeXidValue(renderExtension -> data.composite_glyphs.dst_id, + clientCache -> renderDstPictureCache); + + decodeBuffer.decodeCachedValue(renderExtension -> data.composite_glyphs.set_id, 29, + clientCache -> renderGlyphSetCache); + + // + // Src X and Y. + // + + unsigned int value; + unsigned int previous; + + // Since ProtoStep8 (#issue 108) + previous = renderExtension -> data.composite_glyphs.src_x; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderGlyphXCache, 11); + + renderExtension -> data.composite_glyphs.src_x = value; + + previous = renderExtension -> data.composite_glyphs.src_y; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderGlyphYCache, 11); + + renderExtension -> data.composite_glyphs.src_y = value; + + // Since ProtoStep8 (#issue 108) + if (renderExtension -> size_ >= MESSAGE_OFFSET_IF_PROTO_STEP_8) + { + // + // Offset X and Y. + // + + decodeBuffer.decodeBoolValue(value); + + if (value == 0) + { + renderExtension -> data.composite_glyphs.offset_x = + renderExtension -> data.composite_glyphs.src_x; + + renderExtension -> data.composite_glyphs.offset_y = + renderExtension -> data.composite_glyphs.src_y; + } + else + { + previous = renderExtension -> data.composite_glyphs.offset_x; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderGlyphXCache, 11); + + renderExtension -> data.composite_glyphs.offset_x = value; + + previous = renderExtension -> data.composite_glyphs.offset_y; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderGlyphYCache, 11); + + renderExtension -> data.composite_glyphs.offset_y = value; + } + } + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.composite_glyphs.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderCompositeGlyphs.h b/nxcomp/src/RenderCompositeGlyphs.h new file mode 100644 index 000000000..1062ee781 --- /dev/null +++ b/nxcomp/src/RenderCompositeGlyphs.h @@ -0,0 +1,100 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderCompositeGlyphs_H +#define RenderCompositeGlyphs_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderCompositeGlyphs" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderCompositeGlyphsStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 28 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Encode the first 8 bytes of the +// data differentially in newer +// protocol versions. +// + +#undef MESSAGE_OFFSET_IF_PROTO_STEP_8 +#define MESSAGE_OFFSET_IF_PROTO_STEP_8 36 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + // Since ProtoStep8 (#issue 108) + unsigned int offset = MESSAGE_OFFSET_IF_PROTO_STEP_8; + + return (size >= offset ? offset : size); + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderCompositeGlyphs_H */ diff --git a/nxcomp/src/RenderCreateGlyphSet.cpp b/nxcomp/src/RenderCreateGlyphSet.cpp new file mode 100644 index 000000000..e3a842de9 --- /dev/null +++ b/nxcomp/src/RenderCreateGlyphSet.cpp @@ -0,0 +1,185 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderCreateGlyphSet.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeNewXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> renderGlyphSetCache, + clientCache -> renderFreeGlyphSetCache); + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 8, bigEndian), 32, + clientCache -> renderFormatCache); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeNewXidValue(value, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> renderGlyphSetCache, + clientCache -> renderFreeGlyphSetCache); + + PutULONG(value, buffer + 4, bigEndian); + + decodeBuffer.decodeCachedValue(value, 32, + clientCache -> renderFormatCache); + + PutULONG(value, buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.create_set.type = *(buffer + 1); + + renderExtension -> data.create_set.set_id = GetULONG(buffer + 4, bigEndian); + renderExtension -> data.create_set.format = GetULONG(buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.create_set.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.create_set.type; + + PutULONG(renderExtension -> data.create_set.set_id, buffer + 4, bigEndian); + PutULONG(renderExtension -> data.create_set.format, buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.create_set.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + md5_append(md5_state, buffer + 1, 3); + md5_append(md5_state, buffer + 8, 4); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeNewXidValue(renderExtension -> data.create_set.set_id, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> renderGlyphSetCache, + clientCache -> renderFreeGlyphSetCache); + + cachedRenderExtension -> data.create_set.set_id = + renderExtension -> data.create_set.set_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.create_set.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeNewXidValue(renderExtension -> data.create_set.set_id, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> renderGlyphSetCache, + clientCache -> renderFreeGlyphSetCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.create_set.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderCreateGlyphSet.h b/nxcomp/src/RenderCreateGlyphSet.h new file mode 100644 index 000000000..10f5d6699 --- /dev/null +++ b/nxcomp/src/RenderCreateGlyphSet.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderCreateGlyphSet_H +#define RenderCreateGlyphSet_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderCreateGlyphSet" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderCreateGlyphSetStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 12 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 0 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 0 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderCreateGlyphSet_H */ diff --git a/nxcomp/src/RenderCreatePicture.cpp b/nxcomp/src/RenderCreatePicture.cpp new file mode 100644 index 000000000..f3f9f8b8a --- /dev/null +++ b/nxcomp/src/RenderCreatePicture.cpp @@ -0,0 +1,278 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderCreatePicture.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeNewXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> renderSrcPictureCache, + clientCache -> renderFreePictureCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> drawableCache); + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 12, bigEndian), 32, + clientCache -> renderFormatCache); + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 32, + clientCache -> renderValueMaskCache); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeNewXidValue(value, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> renderSrcPictureCache, + clientCache -> renderFreePictureCache); + + PutULONG(value, buffer + 4, bigEndian); + + decodeBuffer.decodeXidValue(value, + clientCache -> drawableCache); + + PutULONG(value, buffer + 8, bigEndian); + + decodeBuffer.decodeCachedValue(value, 32, + clientCache -> renderFormatCache); + + PutULONG(value, buffer + 12, bigEndian); + + decodeBuffer.decodeCachedValue(value, 32, + clientCache -> renderValueMaskCache); + + PutULONG(value, buffer + 16, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.create_picture.type = *(buffer + 1); + + renderExtension -> data.create_picture.src_id = GetULONG(buffer + 4, bigEndian); + renderExtension -> data.create_picture.dst_id = GetULONG(buffer + 8, bigEndian); + + renderExtension -> data.create_picture.format = GetULONG(buffer + 12, bigEndian); + renderExtension -> data.create_picture.mask = GetULONG(buffer + 16, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.create_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.create_picture.type; + + PutULONG(renderExtension -> data.create_picture.src_id, buffer + 4, bigEndian); + PutULONG(renderExtension -> data.create_picture.dst_id, buffer + 8, bigEndian); + + PutULONG(renderExtension -> data.create_picture.format, buffer + 12, bigEndian); + PutULONG(renderExtension -> data.create_picture.mask, buffer + 16, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.create_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + md5_append(md5_state, buffer + 1, 3); + md5_append(md5_state, buffer + 12, 8); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding new id value " + << renderExtension -> data.create_picture.src_id + << ".\n"; + #endif + + encodeBuffer.encodeNewXidValue(renderExtension -> data.create_picture.src_id, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> renderSrcPictureCache, + clientCache -> renderFreePictureCache); + + cachedRenderExtension -> data.create_picture.src_id = + renderExtension -> data.create_picture.src_id; + + encodeBuffer.encodeXidValue(renderExtension -> data.create_picture.dst_id, + clientCache -> drawableCache); + + cachedRenderExtension -> data.create_picture.dst_id = + renderExtension -> data.create_picture.dst_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.create_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeNewXidValue(renderExtension -> data.create_picture.src_id, + clientCache -> lastId, clientCache -> lastIdCache, + clientCache -> renderSrcPictureCache, + clientCache -> renderFreePictureCache); + + decodeBuffer.decodeXidValue(renderExtension -> data.create_picture.dst_id, + clientCache -> drawableCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.create_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderCreatePicture.h b/nxcomp/src/RenderCreatePicture.h new file mode 100644 index 000000000..ae2f583a0 --- /dev/null +++ b/nxcomp/src/RenderCreatePicture.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderCreatePicture_H +#define RenderCreatePicture_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderCreatePicture" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderCreatePictureStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 20 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderCreatePicture_H */ diff --git a/nxcomp/src/RenderExtension.cpp b/nxcomp/src/RenderExtension.cpp new file mode 100644 index 000000000..64761bc05 --- /dev/null +++ b/nxcomp/src/RenderExtension.cpp @@ -0,0 +1,427 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "NXrender.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +#include "RenderExtension.h" + +#include "RenderGenericRequest.h" +#include "RenderCreatePicture.h" +#include "RenderChangePicture.h" +#include "RenderFreePicture.h" +#include "RenderPictureClip.h" +#include "RenderPictureTransform.h" +#include "RenderPictureFilter.h" +#include "RenderCreateGlyphSet.h" +#include "RenderFreeGlyphSet.h" +#include "RenderAddGlyphs.h" +#include "RenderComposite.h" +#include "RenderCompositeGlyphs.h" +#include "RenderFillRectangles.h" +#include "RenderTrapezoids.h" +#include "RenderTriangles.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Constructor and destructor. +// + +RenderExtensionStore::RenderExtensionStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = RENDEREXTENSION_ENABLE_CACHE; + enableData = RENDEREXTENSION_ENABLE_DATA; + enableSplit = RENDEREXTENSION_ENABLE_SPLIT; + enableCompress = RENDEREXTENSION_ENABLE_COMPRESS; + + generic_ = new RenderGenericRequestStore(); + + for (int i = 0; i < RENDEREXTENSION_MINOR_OPCODE_LIMIT; i++) + { + minors_[i] = generic_; + } + + minors_[X_RenderChangePicture] = new RenderChangePictureStore(); + minors_[X_RenderFillRectangles] = new RenderFillRectanglesStore(); + minors_[X_RenderAddGlyphs] = new RenderAddGlyphsStore(); + + // Since ProtoStep7 (#issue 108) + minors_[X_RenderCreatePicture] = new RenderCreatePictureStore(); + minors_[X_RenderFreePicture] = new RenderFreePictureStore(); + minors_[X_RenderSetPictureClipRectangles] = new RenderPictureClipStore(); + minors_[X_RenderCreateGlyphSet] = new RenderCreateGlyphSetStore(); + minors_[X_RenderComposite] = new RenderCompositeStore(); + minors_[X_RenderCompositeGlyphs8] = new RenderCompositeGlyphsStore(); + minors_[X_RenderCompositeGlyphs16] = new RenderCompositeGlyphsStore(); + minors_[X_RenderCompositeGlyphs32] = new RenderCompositeGlyphsStore(); + + minors_[X_RenderSetPictureTransform] = new RenderPictureTransformStore(); + minors_[X_RenderSetPictureFilter] = new RenderPictureFilterStore(); + minors_[X_RenderFreeGlyphSet] = new RenderFreeGlyphSetStore(); + minors_[X_RenderTrapezoids] = new RenderTrapezoidsStore(); + minors_[X_RenderTriangles] = new RenderTrianglesStore(); + + dataLimit = RENDEREXTENSION_DATA_LIMIT; + dataOffset = RENDEREXTENSION_DATA_OFFSET; + + // Since ProtoStep7 (#issue 108) + cacheSlots = RENDEREXTENSION_CACHE_SLOTS_IF_PROTO_STEP_7; + + cacheThreshold = RENDEREXTENSION_CACHE_THRESHOLD; + cacheLowerThreshold = RENDEREXTENSION_CACHE_LOWER_THRESHOLD; + + opcode_ = X_NXInternalRenderExtension; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +RenderExtensionStore::~RenderExtensionStore() +{ + for (int i = 0; i < RENDEREXTENSION_MINOR_OPCODE_LIMIT; i++) + { + if (minors_[i] != generic_) + { + delete minors_[i]; + } + } + + delete generic_; + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +int RenderExtensionStore::validateMessage(const unsigned char *buffer, int size) +{ + #ifdef TEST + *logofs << name() << ": Encoding message OPCODE#" + << (unsigned) *buffer << " MINOR#" << (unsigned) + *(buffer + 1) << " with size " << size + << ".\n" << logofs_flush; + #endif + + return (size >= control -> MinimumMessageSize && + size <= control -> MaximumMessageSize); +} + +// +// Here are the methods to handle the messages' content. +// + +int RenderExtensionStore::identitySize(const unsigned char *buffer, unsigned int size) +{ + return minors_[*(buffer + 1)] -> identitySize(buffer, size); +} + +int RenderExtensionStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + encodeBuffer.encodeOpcodeValue(*(buffer + 1), + ((ClientCache *) channelCache) -> renderOpcodeCache); + + minors_[*(buffer + 1)] -> encodeMessage(encodeBuffer, buffer, size, + bigEndian, channelCache); + + return 1; +} + +int RenderExtensionStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + unsigned char type; + + decodeBuffer.decodeOpcodeValue(type, + ((ClientCache *) channelCache) -> renderOpcodeCache); + + minors_[type] -> decodeMessage(decodeBuffer, buffer, size, type, + bigEndian, writeBuffer, channelCache); + + return 1; +} + +int RenderExtensionStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + return minors_[*(buffer + 1)] -> parseIdentity(message, buffer, size, bigEndian); +} + +int RenderExtensionStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + return minors_[((RenderExtensionMessage *) message) -> data.any.type] -> + unparseIdentity(message, buffer, size, bigEndian); +} + +void RenderExtensionStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + minors_[*(buffer + 1)] -> identityChecksum(message, buffer, size, md5_state_, bigEndian); +} + +void RenderExtensionStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + minors_[((RenderExtensionMessage *) message) -> data.any.type] -> + updateIdentity(encodeBuffer, message, cachedMessage, channelCache); +} + +void RenderExtensionStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + minors_[((RenderExtensionMessage *) message) -> data.any.type] -> + updateIdentity(decodeBuffer, message, channelCache); +} + +void RenderExtensionStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + #ifdef WARNING + *logofs << name() << ": WARNING! Dump of identity not implemented.\n" + << logofs_flush; + #endif + + #endif +} + +// +// TODO: The following encoding and decoding functions +// could be generalized further, for example by passing +// the pointer to the data cache, the number of caches +// made available by the caller and the first cache to +// iterate through. +// + +void RenderMinorExtensionStore::encodeLongData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeLongData(buffer + offset, size - offset); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - offset + << " bytes of long data.\n" << logofs_flush; + #endif +} + +void RenderMinorExtensionStore::encodeIntData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeIntData(buffer + offset, size - offset); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - offset + << " bytes of int data.\n" << logofs_flush; + #endif +} + +void RenderMinorExtensionStore::encodeCharData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(buffer + offset, size - offset); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - offset + << " bytes of text data.\n" << logofs_flush; + #endif +} + +void RenderMinorExtensionStore::decodeLongData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeLongData(buffer + offset, size - offset); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - offset + << " bytes of long data.\n" << logofs_flush; + #endif +} + +void RenderMinorExtensionStore::decodeIntData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeIntData(buffer + offset, size - offset); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - offset + << " bytes of int data.\n" << logofs_flush; + #endif +} + +void RenderMinorExtensionStore::decodeCharData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(buffer + offset, size - offset); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - offset + << " bytes of text data.\n" << logofs_flush; + #endif +} + +void RenderMinorExtensionStore::parseIntData(const Message *message, const unsigned char *buffer, + unsigned int offset, unsigned int size, + int bigEndian) const +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_); + + for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2) + { + #ifdef DEBUG + *logofs << name() << ": Parsing int with i = " << i << " c = " + << c << ".\n" << logofs_flush; + #endif + + renderExtension -> data.any.short_data[c] = GetUINT(buffer + i, bigEndian); + + if (++c == 16) c = 0; + } +} + +void RenderMinorExtensionStore::unparseIntData(const Message *message, unsigned char *buffer, + unsigned int offset, unsigned int size, + int bigEndian) const +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_); + + for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2) + { + #ifdef DEBUG + *logofs << name() << ": Unparsing int with i = " << i << " c = " + << c << ".\n" << logofs_flush; + #endif + + PutUINT(renderExtension -> data.any.short_data[c], buffer + i, bigEndian); + + if (++c == 16) c = 0; + } +} + +void RenderMinorExtensionStore::updateIntData(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, unsigned int offset, + unsigned int size, ChannelCache *channelCache) const +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_); + + for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2) + { + #ifdef DEBUG + *logofs << name() << ": Encoding int update with i = " << i + << " c = " << c << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(renderExtension -> data.any.short_data[c], 16, + *clientCache -> renderDataCache[c]); + + cachedRenderExtension -> data.any.short_data[c] = + renderExtension -> data.any.short_data[c]; + + if (++c == 16) c = 0; + } +} + +void RenderMinorExtensionStore::updateIntData(DecodeBuffer &decodeBuffer, const Message *message, + unsigned int offset, unsigned int size, + ChannelCache *channelCache) const +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_); + + unsigned int value; + + for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2) + { + #ifdef DEBUG + *logofs << name() << ": Decoding int update with i = " << i + << " c = " << c << ".\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache -> renderDataCache[c]); + + renderExtension -> data.any.short_data[c] = value; + + if (++c == 16) c = 0; + } +} diff --git a/nxcomp/src/RenderExtension.h b/nxcomp/src/RenderExtension.h new file mode 100644 index 000000000..aa9db1b55 --- /dev/null +++ b/nxcomp/src/RenderExtension.h @@ -0,0 +1,504 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderExtension_H +#define RenderExtension_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Compression of data part is not enabled as +// most messages of this type are smaller than +// the current data size compression threshold. +// + +#define RENDEREXTENSION_ENABLE_CACHE 1 +#define RENDEREXTENSION_ENABLE_DATA 0 +#define RENDEREXTENSION_ENABLE_SPLIT 0 +#define RENDEREXTENSION_ENABLE_COMPRESS 0 + +#define RENDEREXTENSION_DATA_LIMIT 6144 +#define RENDEREXTENSION_DATA_OFFSET 36 + +#define RENDEREXTENSION_CACHE_THRESHOLD 20 +#define RENDEREXTENSION_CACHE_LOWER_THRESHOLD 10 + +#define RENDEREXTENSION_CACHE_SLOTS_IF_PROTO_STEP_7 8000 + +// +// Used to build the table of minor opcodes. +// + +#define RENDEREXTENSION_MINOR_OPCODE_LIMIT 256 + +// +// The message class. +// + +class RenderMinorExtensionStore; + +class RenderExtensionMessage : public Message +{ + friend class RenderExtensionStore; + friend class RenderMinorExtensionStore; + + friend class RenderGenericRequestStore; + friend class RenderCreatePictureStore; + friend class RenderChangePictureStore; + friend class RenderFreePictureStore; + friend class RenderPictureClipStore; + friend class RenderPictureTransformStore; + friend class RenderPictureFilterStore; + friend class RenderCreateGlyphSetStore; + friend class RenderFreeGlyphSetStore; + friend class RenderAddGlyphsStore; + friend class RenderCompositeStore; + friend class RenderCompositeGlyphsStore; + friend class RenderFillRectanglesStore; + friend class RenderTrapezoidsStore; + friend class RenderTrianglesStore; + + public: + + RenderExtensionMessage() + { + } + + ~RenderExtensionMessage() + { + } + + // + // We consider for this message a data offset of 36, + // that is size of the biggest among all requests of + // this extension. The most common requests have a + // specific differential encoding, others are simply + // encoded through an array of int or char caches. + // + + private: + + union + { + struct + { + unsigned char type; + + unsigned char char_data[32]; + unsigned short short_data[16]; + unsigned short long_data[8]; + } + any; + + struct + { + unsigned char type; + + unsigned int src_id; + unsigned int dst_id; + + unsigned int format; + unsigned int mask; + } + create_picture; + + struct + { + unsigned char type; + + unsigned int src_id; + } + change_picture; + + struct + { + unsigned char type; + + unsigned int src_id; + } + free_picture; + + struct + { + unsigned char type; + + unsigned int src_id; + + unsigned short src_x; + unsigned short src_y; + } + picture_clip; + + struct + { + unsigned char type; + + unsigned int src_id; + } + picture_transform; + + struct + { + unsigned char type; + + unsigned int src_id; + unsigned int num_elm; + } + picture_filter; + + struct + { + unsigned char type; + + unsigned int set_id; + unsigned int format; + } + create_set; + + struct + { + unsigned char type; + + unsigned int set_id; + } + free_set; + + struct + { + unsigned char type; + + unsigned int set_id; + unsigned int num_elm; + } + add_glyphs; + + struct + { + unsigned char type; + + unsigned char op; + + unsigned int src_id; + unsigned int msk_id; + unsigned int dst_id; + + unsigned short src_x; + unsigned short src_y; + + unsigned short msk_x; + unsigned short msk_y; + + unsigned short dst_x; + unsigned short dst_y; + + unsigned short width; + unsigned short height; + } + composite; + + struct + { + unsigned char type; + + unsigned char op; + + unsigned char num_elm; + + unsigned int src_id; + unsigned int dst_id; + + unsigned int format; + unsigned int set_id; + + unsigned short src_x; + unsigned short src_y; + + unsigned short offset_x; + unsigned short offset_y; + } + composite_glyphs; + + struct + { + unsigned char type; + + unsigned char op; + + unsigned int dst_id; + } + fill_rectangles; + + struct + { + unsigned char type; + + unsigned char op; + + unsigned int src_id; + unsigned int dst_id; + + unsigned int format; + + unsigned short src_x; + unsigned short src_y; + } + trapezoids; + + struct + { + unsigned char type; + + unsigned char op; + + unsigned int src_id; + unsigned int dst_id; + + unsigned int format; + + unsigned short src_x; + unsigned short src_y; + } + triangles; + + struct + { + unsigned char type; + + unsigned char op; + + unsigned char num_elm; + + unsigned int src_id; + unsigned int dst_id; + + unsigned int format; + unsigned int set_id; + + unsigned short src_x; + unsigned short src_y; + + unsigned short delta_x; + unsigned short delta_y; + } + composite_glyphs_compat; + + } + data; +}; + +class RenderExtensionStore : public MessageStore +{ + public: + + RenderExtensionStore(StaticCompressor *compressor); + + virtual ~RenderExtensionStore(); + + virtual const char *name() const + { + return "RenderExtension"; + } + + virtual unsigned char opcode() const + { + return opcode_; + } + + virtual unsigned int storage() const + { + return sizeof(RenderExtensionMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new RenderExtensionMessage(); + } + + virtual Message *create(const Message &message) const + { + return new RenderExtensionMessage((const RenderExtensionMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (RenderExtensionMessage *) message; + } + + // + // Determine if the message must be stored + // in the cache. + // + + virtual int validateMessage(const unsigned char *buffer, int size); + + // + // Since protocol step 5 these methods are + // specialized in their minor opcode stores. + // + + virtual int identitySize(const unsigned char *buffer, unsigned int size); + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; + + private: + + unsigned char opcode_; + + // + // Keep pointers to specialized classes. + // + + RenderMinorExtensionStore *minors_[RENDEREXTENSION_MINOR_OPCODE_LIMIT]; + + RenderMinorExtensionStore *generic_; +}; + +class RenderMinorExtensionStore : public MinorMessageStore +{ + public: + + virtual const char *name() const = 0; + + virtual int identitySize(const unsigned char *buffer, unsigned int size) = 0; + + virtual int encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const = 0; + + virtual int decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, unsigned char type, int bigEndian, + WriteBuffer *writeBuffer, ChannelCache *channelCache) const = 0; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const = 0; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const = 0; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const = 0; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const = 0; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, md5_state_t *md5_state, + int bigEndian) const = 0; + + // + // Internal encode and decode utilities. + // + + protected: + + void encodeLongData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + void encodeIntData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + void encodeCharData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + void decodeLongData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + void decodeIntData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + void decodeCharData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int offset, unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + /* + * The following methods are only used in the + * encoding of the generic render request. To + * be removed in future. + */ + + void parseIntData(const Message *message, const unsigned char *buffer, + unsigned int offset, unsigned int size, + int bigEndian) const; + + void unparseIntData(const Message *message, unsigned char *buffer, + unsigned int offset, unsigned int size, + int bigEndian) const; + + void updateIntData(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, unsigned int offset, + unsigned int size, ChannelCache *channelCache) const; + + void updateIntData(DecodeBuffer &decodeBuffer, const Message *message, + unsigned int offset, unsigned int size, + ChannelCache *channelCache) const; +}; + +#endif /* RenderExtension_H */ diff --git a/nxcomp/src/RenderFillRectangles.cpp b/nxcomp/src/RenderFillRectangles.cpp new file mode 100644 index 000000000..db05887ab --- /dev/null +++ b/nxcomp/src/RenderFillRectangles.cpp @@ -0,0 +1,237 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderFillRectangles.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + // + // The color structure (4 components, 2 bytes + // each) is included in the data part, so that + // it gets into the checksum. The rectangles + // are in the format x, y, width, height with + // 2 bytes per each field, so each request is + // at least 12 + 8 + 8 = 28 bytes long. + // + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> renderSrcPictureCache); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + decodeBuffer.decodeXidValue(value, clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + encodeIntData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + decodeIntData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.fill_rectangles.type = *(buffer + 1); + renderExtension -> data.fill_rectangles.op = *(buffer + 4); + + renderExtension -> data.fill_rectangles.dst_id = GetULONG(buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.fill_rectangles.type << " size is " + << renderExtension -> size_ << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.fill_rectangles.type; + *(buffer + 4) = renderExtension -> data.fill_rectangles.op; + + PutULONG(renderExtension -> data.fill_rectangles.dst_id, buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.fill_rectangles.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + md5_append(md5_state, buffer + 1, 4); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(renderExtension -> data.fill_rectangles.dst_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.fill_rectangles.dst_id = + renderExtension -> data.fill_rectangles.dst_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.fill_rectangles.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.fill_rectangles.dst_id, + clientCache -> renderSrcPictureCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.fill_rectangles.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderFillRectangles.h b/nxcomp/src/RenderFillRectangles.h new file mode 100644 index 000000000..9efaeffa8 --- /dev/null +++ b/nxcomp/src/RenderFillRectangles.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderFillRectangles_H +#define RenderFillRectangles_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderFillRectangles" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderFillRectanglesStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 12 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderFillRectangles_H */ diff --git a/nxcomp/src/RenderFreeGlyphSet.cpp b/nxcomp/src/RenderFreeGlyphSet.cpp new file mode 100644 index 000000000..88dfb791a --- /dev/null +++ b/nxcomp/src/RenderFreeGlyphSet.cpp @@ -0,0 +1,166 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderFreeGlyphSet.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeFreeXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> renderFreeGlyphSetCache); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + unsigned int value; + + ClientCache *clientCache = (ClientCache *) channelCache; + + *(buffer + 1) = type; + + decodeBuffer.decodeFreeXidValue(value, + clientCache -> renderFreeGlyphSetCache); + + PutULONG(value, buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.free_set.type = *(buffer + 1); + + renderExtension -> data.free_set.set_id = GetULONG(buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.free_set.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.free_set.type; + + PutULONG(renderExtension -> data.free_set.set_id, buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.free_set.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + md5_append(md5_state, buffer + 1, 3); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeFreeXidValue(renderExtension -> data.free_set.set_id, + clientCache -> renderFreeGlyphSetCache); + + cachedRenderExtension -> data.free_set.set_id = + renderExtension -> data.free_set.set_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.free_set.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeFreeXidValue(renderExtension -> data.free_set.set_id, + clientCache -> renderFreeGlyphSetCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.free_set.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderFreeGlyphSet.h b/nxcomp/src/RenderFreeGlyphSet.h new file mode 100644 index 000000000..8817e8d99 --- /dev/null +++ b/nxcomp/src/RenderFreeGlyphSet.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderFreeGlyphSet_H +#define RenderFreeGlyphSet_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderFreeGlyphSet" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderFreeGlyphSetStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 8 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 0 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 0 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderFreeGlyphSet_H */ diff --git a/nxcomp/src/RenderFreePicture.cpp b/nxcomp/src/RenderFreePicture.cpp new file mode 100644 index 000000000..31662a7e2 --- /dev/null +++ b/nxcomp/src/RenderFreePicture.cpp @@ -0,0 +1,166 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderFreePicture.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeFreeXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> renderFreePictureCache); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + unsigned int value; + + ClientCache *clientCache = (ClientCache *) channelCache; + + *(buffer + 1) = type; + + decodeBuffer.decodeFreeXidValue(value, + clientCache -> renderFreePictureCache); + + PutULONG(value, buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.free_picture.type = *(buffer + 1); + + renderExtension -> data.free_picture.src_id = GetULONG(buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.free_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.free_picture.type; + + PutULONG(renderExtension -> data.free_picture.src_id, buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.free_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + md5_append(md5_state, buffer + 1, 3); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeFreeXidValue(renderExtension -> data.free_picture.src_id, + clientCache -> renderFreePictureCache); + + cachedRenderExtension -> data.free_picture.src_id = + renderExtension -> data.free_picture.src_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.free_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeFreeXidValue(renderExtension -> data.free_picture.src_id, + clientCache -> renderFreePictureCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.free_picture.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderFreePicture.h b/nxcomp/src/RenderFreePicture.h new file mode 100644 index 000000000..b50191a72 --- /dev/null +++ b/nxcomp/src/RenderFreePicture.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderFreePicture_H +#define RenderFreePicture_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderFreePicture" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderFreePictureStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 8 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 0 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 0 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderFreePicture_H */ diff --git a/nxcomp/src/RenderGenericRequest.cpp b/nxcomp/src/RenderGenericRequest.cpp new file mode 100644 index 000000000..cff34e61e --- /dev/null +++ b/nxcomp/src/RenderGenericRequest.cpp @@ -0,0 +1,270 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "NXrender.h" + +#include "RenderExtension.h" +#include "RenderGenericRequest.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Here are the methods to handle the messages' content. +// + +int RenderGenericRequestStore::encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message.\n" + << logofs_flush; + + unsigned char type = *(buffer + 1); + + #endif + + encodeBuffer.encodeCachedValue(size >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef DEBUG + *logofs << name() << ": Encoding full unhandled message. " + << "Type is " << (unsigned int) type << " size is " + << size << ".\n" << logofs_flush; + #endif + + encodeIntData(encodeBuffer, buffer, 4, size, + bigEndian, clientCache); + + #ifdef DEBUG + *logofs << name() << ": Encoded full message.\n" + << logofs_flush; + #endif + + return 1; +} + +int RenderGenericRequestStore::decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, unsigned char type, int bigEndian, + WriteBuffer *writeBuffer, ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message.\n" + << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + size <<= 2; + + buffer = writeBuffer -> addMessage(size); + + *(buffer + 1) = type; + + #ifdef DEBUG + *logofs << name() << ": Decoding full unhandled message. " + << "Type is " << (unsigned int) type << " size is " + << size << ".\n" << logofs_flush; + #endif + + decodeIntData(decodeBuffer, buffer, 4, size, + bigEndian, clientCache); + + #ifdef DEBUG + *logofs << name() << ": Decoded full message.\n" + << logofs_flush; + #endif + + return 1; +} + +void RenderGenericRequestStore::encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ +} + +void RenderGenericRequestStore::decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ +} + +int RenderGenericRequestStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + #ifdef DEBUG + *logofs << name() << ": Parsing identity for message at " + << this << ".\n" << logofs_flush; + #endif + + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + unsigned char type = *(buffer + 1); + + renderExtension -> data.any.type = type; + + #ifdef DEBUG + *logofs << name() << ": Parsing unhandled identity. " + << "Type is " << (unsigned int) renderExtension -> data.any.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif + + parseIntData(message, buffer, 4, size, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int RenderGenericRequestStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + #ifdef DEBUG + *logofs << name() << ": Unparsing identity for message at " + << this << ".\n" << logofs_flush; + #endif + + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + unsigned char type = renderExtension -> data.any.type; + + *(buffer + 1) = type; + + #ifdef DEBUG + *logofs << name() << ": Unparsing unhandled identity. " + << "Type is " << (unsigned int) renderExtension -> data.any.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif + + unparseIntData(message, buffer, 4, size, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void RenderGenericRequestStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, md5_state_t *md5_state, + int bigEndian) const +{ + // + // Include the minor opcode in the checksum. + // Because the data offset can be beyond the + // real end of the message, we need to include + // the size or we will match any message whose + // size is less or equal to the data offset. + // + + md5_append(md5_state, buffer + 1, 3); +} + +void RenderGenericRequestStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + // + // Encode the variant part. + // + + #ifdef DEBUG + *logofs << name() << ": Updating identity for message at " + << this << ".\n" << logofs_flush; + #endif + + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + #ifdef DEBUG + *logofs << name() << ": Encoding unhandled update. " + << "Type is " << (unsigned int) renderExtension -> data.any.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif + + updateIntData(encodeBuffer, message, cachedMessage, 4, + renderExtension -> size_, channelCache); + + #ifdef DEBUG + *logofs << name() << ": Updated identity for message at " + << this << ".\n" << logofs_flush; + #endif +} + +void RenderGenericRequestStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + #ifdef DEBUG + *logofs << name() << ": Updating identity for message at " + << this << ".\n" << logofs_flush; + #endif + + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + #ifdef DEBUG + *logofs << name() << ": Decoding unhandled update. " + << "Type is " << (unsigned int) renderExtension -> data.any.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif + + updateIntData(decodeBuffer, message, 4, + renderExtension -> size_, channelCache); + + #ifdef DEBUG + *logofs << name() << ": Updated identity for message at " + << this << ".\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/RenderGenericRequest.h b/nxcomp/src/RenderGenericRequest.h new file mode 100644 index 000000000..fdf5ca876 --- /dev/null +++ b/nxcomp/src/RenderGenericRequest.h @@ -0,0 +1,89 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderGenericRequest_H +#define RenderGenericRequest_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +class RenderGenericRequestStore : public RenderMinorExtensionStore +{ + public: + + virtual const char *name() const + { + return "RenderGenericRequest"; + } + + virtual int identitySize(const unsigned char *buffer, unsigned int size) + { + return RENDEREXTENSION_DATA_OFFSET; + } + + virtual int encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, unsigned char type, int bigEndian, + WriteBuffer *writeBuffer, ChannelCache *channelCache) const; + + virtual void encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual void decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, md5_state_t *md5_state, + int bigEndian) const; +}; + +#endif /* RenderGenericRequest_H */ diff --git a/nxcomp/src/RenderMinorExtensionHeaders.h b/nxcomp/src/RenderMinorExtensionHeaders.h new file mode 100644 index 000000000..b7f6efc5a --- /dev/null +++ b/nxcomp/src/RenderMinorExtensionHeaders.h @@ -0,0 +1,42 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderMinorExtensionHeaders_H +#define RenderMinorExtensionHeaders_H + +#include "NXrender.h" + +#include "Message.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +#include "RenderExtension.h" + +#endif /* RenderMinorExtensionHeaders_H */ diff --git a/nxcomp/src/RenderMinorExtensionMethods.h b/nxcomp/src/RenderMinorExtensionMethods.h new file mode 100644 index 000000000..d272337e0 --- /dev/null +++ b/nxcomp/src/RenderMinorExtensionMethods.h @@ -0,0 +1,81 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +// +// This file is included multiple times, +// one for each message inheriting the +// parent class. +// + +public: + +#if MESSAGE_HAS_SIZE + +virtual void encodeSize(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + +virtual void decodeSize(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, unsigned char type, int bigEndian, + WriteBuffer *writeBuffer, ChannelCache *channelCache) const; + +#endif + +#if MESSAGE_HAS_DATA + +virtual void encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + +virtual void decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, + unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + +#endif + +virtual int encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + +virtual int decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, unsigned char type, int bigEndian, + WriteBuffer *writeBuffer, ChannelCache *channelCache) const; + +virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + +virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + +virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + +virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + +virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, md5_state_t *md5_state, + int bigEndian) const; diff --git a/nxcomp/src/RenderMinorExtensionTags.h b/nxcomp/src/RenderMinorExtensionTags.h new file mode 100644 index 000000000..c24a99638 --- /dev/null +++ b/nxcomp/src/RenderMinorExtensionTags.h @@ -0,0 +1,194 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderMinorExtensionTags_H +#define RenderMinorExtensionTags_H + +// +// Set in the message header file. +// + +#if MESSAGE_HAS_SIZE + +#define MESSAGE_ENCODE_SIZE encodeSize(encodeBuffer, buffer, size, bigEndian, channelCache) +#define MESSAGE_DECODE_SIZE decodeSize(decodeBuffer, buffer, size, type, bigEndian, writeBuffer, channelCache) + +#else + +#define MESSAGE_ENCODE_SIZE +#define MESSAGE_DECODE_SIZE size = MESSAGE_OFFSET; buffer = writeBuffer -> addMessage(size); + +#endif + +#if MESSAGE_HAS_DATA + +#define MESSAGE_ENCODE_DATA encodeData(encodeBuffer, buffer, size, bigEndian, channelCache) +#define MESSAGE_DECODE_DATA decodeData(decodeBuffer, buffer, size, bigEndian, channelCache) + +#else + +#define MESSAGE_ENCODE_DATA +#define MESSAGE_DECODE_DATA + +#endif + +// +// Prologue an epilogue of the message +// handling functions. +// + +#define MESSAGE_BEGIN_ENCODE_SIZE \ +\ +void MESSAGE_STORE::encodeSize(EncodeBuffer &encodeBuffer, const unsigned char *buffer, \ + const unsigned int size, int bigEndian, \ + ChannelCache *channelCache) const \ +{ + +#define MESSAGE_END_ENCODE_SIZE \ +\ +} + +#define MESSAGE_BEGIN_DECODE_SIZE \ +\ +void MESSAGE_STORE::decodeSize(DecodeBuffer &decodeBuffer, unsigned char *&buffer, \ + unsigned int &size, unsigned char type, int bigEndian, \ + WriteBuffer *writeBuffer, ChannelCache *channelCache) const \ +{ + +#define MESSAGE_END_DECODE_SIZE \ +\ +} + +#define MESSAGE_BEGIN_ENCODE_MESSAGE \ +\ +int MESSAGE_STORE::encodeMessage(EncodeBuffer &encodeBuffer, const unsigned char *buffer, \ + const unsigned int size, int bigEndian, \ + ChannelCache *channelCache) const \ +{ \ + MESSAGE_ENCODE_SIZE; + + +#define MESSAGE_END_ENCODE_MESSAGE \ +\ + MESSAGE_ENCODE_DATA; \ +\ + return 1; \ +} + +#define MESSAGE_BEGIN_DECODE_MESSAGE \ +\ +int MESSAGE_STORE::decodeMessage(DecodeBuffer &decodeBuffer, unsigned char *&buffer, \ + unsigned int &size, unsigned char type, int bigEndian, \ + WriteBuffer *writeBuffer, ChannelCache *channelCache) const \ +{ \ + MESSAGE_DECODE_SIZE; + + +#define MESSAGE_END_DECODE_MESSAGE \ +\ + MESSAGE_DECODE_DATA; \ +\ + return 1; \ +} + +#define MESSAGE_BEGIN_ENCODE_DATA \ +\ +void MESSAGE_STORE::encodeData(EncodeBuffer &encodeBuffer, const unsigned char *buffer, \ + unsigned int size, int bigEndian, \ + ChannelCache *channelCache) const \ +{ + +#define MESSAGE_END_ENCODE_DATA \ +\ +} + +#define MESSAGE_BEGIN_DECODE_DATA \ +\ +void MESSAGE_STORE::decodeData(DecodeBuffer &decodeBuffer, unsigned char *buffer, \ + unsigned int size, int bigEndian, \ + ChannelCache *channelCache) const \ +{ + +#define MESSAGE_END_DECODE_DATA \ +\ +} + +#define MESSAGE_BEGIN_PARSE_IDENTITY \ +\ +int MESSAGE_STORE::parseIdentity(Message *message, const unsigned char *buffer, \ + unsigned int size, int bigEndian) const \ +{ + +#define MESSAGE_END_PARSE_IDENTITY \ +\ + return 1; \ +\ +} + +#define MESSAGE_BEGIN_UNPARSE_IDENTITY \ +\ +int MESSAGE_STORE::unparseIdentity(const Message *message, unsigned char *buffer, \ + unsigned int size, int bigEndian) const \ +{ + +#define MESSAGE_END_UNPARSE_IDENTITY \ +\ + return 1; \ +\ +} + +#define MESSAGE_BEGIN_IDENTITY_CHECKSUM \ +\ +void MESSAGE_STORE::identityChecksum(const Message *message, const unsigned char *buffer, \ + unsigned int size, md5_state_t *md5_state, \ + int bigEndian) const \ +{ + +#define MESSAGE_END_IDENTITY_CHECKSUM \ +\ +} + +#define MESSAGE_BEGIN_ENCODE_UPDATE \ +\ +void MESSAGE_STORE::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, \ + const Message *cachedMessage, \ + ChannelCache *channelCache) const \ +{ + +#define MESSAGE_END_ENCODE_UPDATE \ +\ +} + +#define MESSAGE_BEGIN_DECODE_UPDATE \ +\ +void MESSAGE_STORE::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, \ + ChannelCache *channelCache) const \ +{ + +#define MESSAGE_END_DECODE_UPDATE \ +\ +} + +#endif /* RenderMinorExtensionTags_H */ diff --git a/nxcomp/src/RenderPictureClip.cpp b/nxcomp/src/RenderPictureClip.cpp new file mode 100644 index 000000000..0d6b505eb --- /dev/null +++ b/nxcomp/src/RenderPictureClip.cpp @@ -0,0 +1,303 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderPictureClip.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + // + // The data is constituted by a number of + // rectangles. Each rectangle is in the + // format x, y, width, height with 2 bytes + // per each field, so each request is at + // least 12 + 8 = 20 bytes long. + // + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> renderSrcPictureCache); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 8, bigEndian), + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 10, bigEndian), + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeXidValue(value, + clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 4, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + PutUINT(clientCache -> renderLastX, buffer + 8, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + PutUINT(clientCache -> renderLastY, buffer + 10, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + encodeIntData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + decodeIntData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.picture_clip.type = *(buffer + 1); + + renderExtension -> data.picture_clip.src_id = GetULONG(buffer + 4, bigEndian); + + renderExtension -> data.picture_clip.src_x = GetUINT(buffer + 8, bigEndian); + renderExtension -> data.picture_clip.src_y = GetUINT(buffer + 10, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.picture_clip.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.picture_clip.type; + + PutULONG(renderExtension -> data.picture_clip.src_id, buffer + 4, bigEndian); + + PutUINT(renderExtension -> data.picture_clip.src_x, buffer + 8, bigEndian); + PutUINT(renderExtension -> data.picture_clip.src_y, buffer + 10, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.picture_clip.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + // + // Encode the picture id and the + // source x and y differentially. + // + + md5_append(md5_state, buffer + 1, 3); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(renderExtension -> data.picture_clip.src_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.picture_clip.src_id = + renderExtension -> data.picture_clip.src_id; + + // + // The source x and y coordinates are + // encoded as differerences in respect + // to the previous cached value. + // + + unsigned int value; + unsigned int previous; + + value = renderExtension -> data.picture_clip.src_x; + previous = cachedRenderExtension -> data.picture_clip.src_x; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderXCache, 11); + + cachedRenderExtension -> data.picture_clip.src_x = value; + + value = renderExtension -> data.picture_clip.src_y; + previous = cachedRenderExtension -> data.picture_clip.src_y; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderYCache, 11); + + cachedRenderExtension -> data.picture_clip.src_y = value; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.picture_clip.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.picture_clip.src_id, + clientCache -> renderSrcPictureCache); + + unsigned int value; + unsigned int previous; + + previous = renderExtension -> data.picture_clip.src_x; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderXCache, 11); + + renderExtension -> data.picture_clip.src_x = value; + + previous = renderExtension -> data.picture_clip.src_y; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderYCache, 11); + + renderExtension -> data.picture_clip.src_y = value; + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.picture_clip.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderPictureClip.h b/nxcomp/src/RenderPictureClip.h new file mode 100644 index 000000000..bd811dfcd --- /dev/null +++ b/nxcomp/src/RenderPictureClip.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderPictureClip_H +#define RenderPictureClip_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderPictureClip" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderPictureClipStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 12 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderPictureClip_H */ diff --git a/nxcomp/src/RenderPictureFilter.cpp b/nxcomp/src/RenderPictureFilter.cpp new file mode 100644 index 000000000..ce40e051a --- /dev/null +++ b/nxcomp/src/RenderPictureFilter.cpp @@ -0,0 +1,278 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderPictureFilter.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding value " + << ((size - MESSAGE_OFFSET) >> 2) << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << size + << ".\n" << logofs_flush; + #endif + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> renderSrcPictureCache); + + encodeBuffer.encodeCachedValue(GetUINT(buffer + 8, bigEndian), 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeXidValue(value, + clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 4, bigEndian); + + decodeBuffer.decodeCachedValue(value, 16, + clientCache -> renderLengthCache, 5); + + PutUINT(value, buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + encodeCharData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + decodeCharData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.picture_filter.type = *(buffer + 1); + + renderExtension -> data.picture_filter.src_id = GetULONG(buffer + 4, bigEndian); + renderExtension -> data.picture_filter.num_elm = GetUINT(buffer + 8, bigEndian); + + // + // Clean the padding bytes. This + // should be the purpose of the + // filter. + // + + #ifdef TEST + *logofs << name() << ": Cleaning " + << RoundUp4(renderExtension -> data.picture_filter.num_elm) - + renderExtension -> data.picture_filter.num_elm << " bytes " + << "at offset " << MESSAGE_OFFSET + renderExtension -> + data.picture_filter.num_elm << " with " << renderExtension -> + data.picture_filter.num_elm << " elements and size " + << renderExtension -> size_ << ".\n" << logofs_flush; + #endif + + if (size >= MESSAGE_OFFSET + renderExtension -> + data.picture_filter.num_elm) + { + unsigned char *next = (unsigned char *) buffer + + MESSAGE_OFFSET + renderExtension -> + data.picture_filter.num_elm; + + while (next < buffer + size) + { + *next++ = '\0'; + } + } + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.picture_filter.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.picture_filter.type; + + PutULONG(renderExtension -> data.picture_filter.src_id, buffer + 4, bigEndian); + PutUINT(renderExtension -> data.picture_filter.num_elm, buffer + 8, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.picture_filter.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + // + // Include the length of the filter name + // in the checksum. + // + + md5_append(md5_state, buffer + 1, 3); + md5_append(md5_state, buffer + 8, 2); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(renderExtension -> data.picture_filter.src_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.picture_filter.src_id = + renderExtension -> data.picture_filter.src_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.picture_filter.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.picture_filter.src_id, + clientCache -> renderSrcPictureCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.picture_filter.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderPictureFilter.h b/nxcomp/src/RenderPictureFilter.h new file mode 100644 index 000000000..a3e37538b --- /dev/null +++ b/nxcomp/src/RenderPictureFilter.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderPictureFilter_H +#define RenderPictureFilter_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderPictureFilter" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderPictureFilterStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 12 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderPictureFilter_H */ diff --git a/nxcomp/src/RenderPictureTransform.cpp b/nxcomp/src/RenderPictureTransform.cpp new file mode 100644 index 000000000..0048e61f4 --- /dev/null +++ b/nxcomp/src/RenderPictureTransform.cpp @@ -0,0 +1,214 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderPictureTransform.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + // + // Size is always 44. The identity size + // is set to 8, so we encode the 36 bytes + // of the transformation matrix as our + // data. + // +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + size = MESSAGE_OFFSET + 36; + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(GetULONG(buffer + 4, bigEndian), + clientCache -> renderSrcPictureCache); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeXidValue(value, + clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.picture_transform.type = *(buffer + 1); + + renderExtension -> data.picture_transform.src_id = GetULONG(buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.picture_transform.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.picture_transform.type; + + PutULONG(renderExtension -> data.picture_transform.src_id, buffer + 4, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.picture_transform.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + md5_append(md5_state, buffer + 1, 3); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(renderExtension -> data.picture_transform.src_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.picture_transform.src_id = + renderExtension -> data.picture_transform.src_id; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.picture_transform.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.picture_transform.src_id, + clientCache -> renderSrcPictureCache); + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.picture_transform.type + << " size is " << renderExtension -> size_ << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderPictureTransform.h b/nxcomp/src/RenderPictureTransform.h new file mode 100644 index 000000000..649cd05d3 --- /dev/null +++ b/nxcomp/src/RenderPictureTransform.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderPictureTransform_H +#define RenderPictureTransform_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderPictureTransform" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderPictureTransformStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 8 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return MESSAGE_OFFSET; + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderPictureTransform_H */ diff --git a/nxcomp/src/RenderTrapezoids.cpp b/nxcomp/src/RenderTrapezoids.cpp new file mode 100644 index 000000000..bf84509dc --- /dev/null +++ b/nxcomp/src/RenderTrapezoids.cpp @@ -0,0 +1,372 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderTrapezoids.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + // + // The trapezoid data is made up of a structure + // containing a top and bottom coordinate in 4 + // bytes format, plus two lines, each represent- + // ed as four points in 4 bytes format. Thus + // each trapezoid is 4 * 2 + (4 * 4) * 2 = 40 + // bytes. Bytes are all padded to an long int, + // so we don't need to clean the message. + // + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding value " + << ((size - MESSAGE_OFFSET) >> 2) << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << size + << ".\n" << logofs_flush; + #endif + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> renderSrcPictureCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), + clientCache -> renderDstPictureCache); + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 32, + clientCache -> renderFormatCache); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 20, bigEndian), + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 22, bigEndian), + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + decodeBuffer.decodeXidValue(value, + clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 8, bigEndian); + + decodeBuffer.decodeXidValue(value, + clientCache -> renderDstPictureCache); + + PutULONG(value, buffer + 12, bigEndian); + + decodeBuffer.decodeCachedValue(value, 32, + clientCache -> renderFormatCache); + + PutULONG(value, buffer + 16, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + PutUINT(clientCache -> renderLastX, buffer + 20, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + PutUINT(clientCache -> renderLastY, buffer + 22, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + if (size > MESSAGE_OFFSET) + { + encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + } + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of text data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + if (size > MESSAGE_OFFSET) + { + decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + } + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.trapezoids.type = *(buffer + 1); + renderExtension -> data.trapezoids.op = *(buffer + 4); + + renderExtension -> data.trapezoids.src_id = GetULONG(buffer + 8, bigEndian); + renderExtension -> data.trapezoids.dst_id = GetULONG(buffer + 12, bigEndian); + + renderExtension -> data.trapezoids.format = GetULONG(buffer + 16, bigEndian); + + renderExtension -> data.trapezoids.src_x = GetUINT(buffer + 20, bigEndian); + renderExtension -> data.trapezoids.src_y = GetUINT(buffer + 22, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.trapezoids.type + << " size is " << renderExtension -> size_ << " identity size " + << renderExtension -> i_size_ << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.trapezoids.type; + *(buffer + 4) = renderExtension -> data.trapezoids.op; + + PutULONG(renderExtension -> data.trapezoids.src_id, buffer + 8, bigEndian); + PutULONG(renderExtension -> data.trapezoids.dst_id, buffer + 12, bigEndian); + + PutULONG(renderExtension -> data.trapezoids.format, buffer + 16, bigEndian); + + PutUINT(renderExtension -> data.trapezoids.src_x, buffer + 20, bigEndian); + PutUINT(renderExtension -> data.trapezoids.src_y, buffer + 22, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.trapezoids.type + << " size is " << renderExtension -> size_ << " identity size " + << renderExtension -> i_size_ << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + // + // Include minor opcode, size and the + // operator in the identity. + // + + md5_append(md5_state, buffer + 1, 4); + + // + // Also include the format but not the + // x and y source. + // + + md5_append(md5_state, buffer + 16, 4); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(renderExtension -> data.trapezoids.src_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.trapezoids.src_id = + renderExtension -> data.trapezoids.src_id; + + encodeBuffer.encodeXidValue(renderExtension -> data.trapezoids.dst_id, + clientCache -> renderDstPictureCache); + + cachedRenderExtension -> data.trapezoids.dst_id = + renderExtension -> data.trapezoids.dst_id; + + // + // The source x and y coordinates are + // encoded as differerences in respect + // to the previous cached value. + // + + unsigned int value; + unsigned int previous; + + value = renderExtension -> data.trapezoids.src_x; + previous = cachedRenderExtension -> data.trapezoids.src_x; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderXCache, 11); + + cachedRenderExtension -> data.trapezoids.src_x = value; + + value = renderExtension -> data.trapezoids.src_y; + previous = cachedRenderExtension -> data.trapezoids.src_y; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderYCache, 11); + + cachedRenderExtension -> data.trapezoids.src_y = value; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.trapezoids.type + << " size is " << renderExtension -> size_ << " source x " + << renderExtension -> data.trapezoids.src_x << " y " + << renderExtension -> data.trapezoids.src_y << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.trapezoids.src_id, + clientCache -> renderSrcPictureCache); + + decodeBuffer.decodeXidValue(renderExtension -> data.trapezoids.dst_id, + clientCache -> renderDstPictureCache); + + unsigned int value; + unsigned int previous; + + previous = renderExtension -> data.trapezoids.src_x; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderXCache, 11); + + renderExtension -> data.trapezoids.src_x = value; + + previous = renderExtension -> data.trapezoids.src_y; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderYCache, 11); + + renderExtension -> data.trapezoids.src_y = value; + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.trapezoids.type + << " size is " << renderExtension -> size_ << " source x " + << renderExtension -> data.trapezoids.src_x << " y " + << renderExtension -> data.trapezoids.src_y << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderTrapezoids.h b/nxcomp/src/RenderTrapezoids.h new file mode 100644 index 000000000..faf524c76 --- /dev/null +++ b/nxcomp/src/RenderTrapezoids.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderTrapezoids_H +#define RenderTrapezoids_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderTrapezoids" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderTrapezoidsStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 24 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return (size >= MESSAGE_OFFSET ? MESSAGE_OFFSET : size); + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderTrapezoids_H */ diff --git a/nxcomp/src/RenderTriangles.cpp b/nxcomp/src/RenderTriangles.cpp new file mode 100644 index 000000000..a5eb4d83d --- /dev/null +++ b/nxcomp/src/RenderTriangles.cpp @@ -0,0 +1,362 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// +// Include the template for +// this message class. +// + +#include "RenderTriangles.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#include MESSAGE_TAGS + +// +// Message handling methods. +// + +MESSAGE_BEGIN_ENCODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding value " + << ((size - MESSAGE_OFFSET) >> 2) << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue((size - MESSAGE_OFFSET) >> 2, 16, + clientCache -> renderLengthCache, 5); + + #ifdef TEST + *logofs << name() << ": Encoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_SIZE + +MESSAGE_BEGIN_DECODE_SIZE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(size, 16, + clientCache -> renderLengthCache, 5); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << size + << ".\n" << logofs_flush; + #endif + + size = MESSAGE_OFFSET + (size << 2); + + buffer = writeBuffer -> addMessage(size); + + #ifdef TEST + *logofs << name() << ": Decoded size with value " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_SIZE + +MESSAGE_BEGIN_ENCODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), + clientCache -> renderSrcPictureCache); + + encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), + clientCache -> renderDstPictureCache); + + encodeBuffer.encodeCachedValue(GetULONG(buffer + 16, bigEndian), 32, + clientCache -> renderFormatCache); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 20, bigEndian), + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 22, bigEndian), + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + #ifdef TEST + *logofs << name() << ": Encoded message. Type is " + << (unsigned int) *(buffer + 1) << " size is " + << size << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_MESSAGE + +MESSAGE_BEGIN_DECODE_MESSAGE +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + *(buffer + 1) = type; + + decodeBuffer.decodeCachedValue(*(buffer + 4), 8, + clientCache -> renderOpCache); + + decodeBuffer.decodeXidValue(value, + clientCache -> renderSrcPictureCache); + + PutULONG(value, buffer + 8, bigEndian); + + decodeBuffer.decodeXidValue(value, + clientCache -> renderDstPictureCache); + + PutULONG(value, buffer + 12, bigEndian); + + decodeBuffer.decodeCachedValue(value, 32, + clientCache -> renderFormatCache); + + PutULONG(value, buffer + 16, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastX, 16, + clientCache -> renderXCache, 11); + + PutUINT(clientCache -> renderLastX, buffer + 20, bigEndian); + + decodeBuffer.decodeDiffCachedValue(value, + clientCache -> renderLastY, 16, + clientCache -> renderYCache, 11); + + PutUINT(clientCache -> renderLastY, buffer + 22, bigEndian); + + #ifdef TEST + *logofs << name() << ": Decoded message. Type is " + << (unsigned int) type << " size is " << size + << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_MESSAGE + +MESSAGE_BEGIN_ENCODE_DATA +{ + if (size > MESSAGE_OFFSET) + { + encodeLongData(encodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + } + + #ifdef TEST + *logofs << name() << ": Encoded " << size - MESSAGE_OFFSET + << " bytes of text data.\n" << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_DATA + +MESSAGE_BEGIN_DECODE_DATA +{ + if (size > MESSAGE_OFFSET) + { + decodeLongData(decodeBuffer, buffer, MESSAGE_OFFSET, + size, bigEndian, channelCache); + } + + #ifdef TEST + *logofs << name() << ": Decoded " << size - MESSAGE_OFFSET + << " bytes of data.\n" << logofs_flush; + #endif +} +MESSAGE_END_DECODE_DATA + +MESSAGE_BEGIN_PARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + renderExtension -> data.triangles.type = *(buffer + 1); + renderExtension -> data.triangles.op = *(buffer + 4); + + renderExtension -> data.triangles.src_id = GetULONG(buffer + 8, bigEndian); + renderExtension -> data.triangles.dst_id = GetULONG(buffer + 12, bigEndian); + + renderExtension -> data.triangles.format = GetULONG(buffer + 16, bigEndian); + + renderExtension -> data.triangles.src_x = GetUINT(buffer + 20, bigEndian); + renderExtension -> data.triangles.src_y = GetUINT(buffer + 22, bigEndian); + + #ifdef TEST + *logofs << name() << ": Parsed identity. Type is " + << (unsigned int) renderExtension -> data.triangles.type + << " size is " << renderExtension -> size_ << " identity size " + << renderExtension -> i_size_ << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_PARSE_IDENTITY + +MESSAGE_BEGIN_UNPARSE_IDENTITY +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + *(buffer + 1) = renderExtension -> data.triangles.type; + *(buffer + 4) = renderExtension -> data.triangles.op; + + PutULONG(renderExtension -> data.triangles.src_id, buffer + 8, bigEndian); + PutULONG(renderExtension -> data.triangles.dst_id, buffer + 12, bigEndian); + + PutULONG(renderExtension -> data.triangles.format, buffer + 16, bigEndian); + + PutUINT(renderExtension -> data.triangles.src_x, buffer + 20, bigEndian); + PutUINT(renderExtension -> data.triangles.src_y, buffer + 22, bigEndian); + + #ifdef TEST + *logofs << name() << ": Unparsed identity. Type is " + << (unsigned int) renderExtension -> data.triangles.type + << " size is " << renderExtension -> size_ << " identity size " + << renderExtension -> i_size_ << ".\n" << logofs_flush; + #endif +} +MESSAGE_END_UNPARSE_IDENTITY + +MESSAGE_BEGIN_IDENTITY_CHECKSUM +{ + // + // Include minor opcode, size and the + // operator in the identity. + // + + md5_append(md5_state, buffer + 1, 4); + + // + // Also include the format but not the + // x and y source. + // + + md5_append(md5_state, buffer + 16, 4); +} +MESSAGE_END_IDENTITY_CHECKSUM + +MESSAGE_BEGIN_ENCODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeXidValue(renderExtension -> data.triangles.src_id, + clientCache -> renderSrcPictureCache); + + cachedRenderExtension -> data.triangles.src_id = + renderExtension -> data.triangles.src_id; + + encodeBuffer.encodeXidValue(renderExtension -> data.triangles.dst_id, + clientCache -> renderDstPictureCache); + + cachedRenderExtension -> data.triangles.dst_id = + renderExtension -> data.triangles.dst_id; + + // + // The source x and y coordinates are + // encoded as differerences in respect + // to the previous cached value. + // + + unsigned int value; + unsigned int previous; + + value = renderExtension -> data.triangles.src_x; + previous = cachedRenderExtension -> data.triangles.src_x; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderXCache, 11); + + cachedRenderExtension -> data.triangles.src_x = value; + + value = renderExtension -> data.triangles.src_y; + previous = cachedRenderExtension -> data.triangles.src_y; + + encodeBuffer.encodeDiffCachedValue(value, previous, 16, + clientCache -> renderYCache, 11); + + cachedRenderExtension -> data.triangles.src_y = value; + + #ifdef TEST + *logofs << name() << ": Encoded update. Type is " + << (unsigned int) renderExtension -> data.triangles.type + << " size is " << renderExtension -> size_ << " source x " + << renderExtension -> data.triangles.src_x << " y " + << renderExtension -> data.triangles.src_y << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_ENCODE_UPDATE + +MESSAGE_BEGIN_DECODE_UPDATE +{ + RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeXidValue(renderExtension -> data.triangles.src_id, + clientCache -> renderSrcPictureCache); + + decodeBuffer.decodeXidValue(renderExtension -> data.triangles.dst_id, + clientCache -> renderDstPictureCache); + + unsigned int value; + unsigned int previous; + + previous = renderExtension -> data.triangles.src_x; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderXCache, 11); + + renderExtension -> data.triangles.src_x = value; + + previous = renderExtension -> data.triangles.src_y; + + decodeBuffer.decodeDiffCachedValue(value, previous, 16, + clientCache -> renderYCache, 11); + + renderExtension -> data.triangles.src_y = value; + + #ifdef TEST + *logofs << name() << ": Decoded update. Type is " + << (unsigned int) renderExtension -> data.triangles.type + << " size is " << renderExtension -> size_ << " source x " + << renderExtension -> data.triangles.src_x << " y " + << renderExtension -> data.triangles.src_y << ".\n" + << logofs_flush; + #endif +} +MESSAGE_END_DECODE_UPDATE diff --git a/nxcomp/src/RenderTriangles.h b/nxcomp/src/RenderTriangles.h new file mode 100644 index 000000000..d73efb7b8 --- /dev/null +++ b/nxcomp/src/RenderTriangles.h @@ -0,0 +1,88 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef RenderTriangles_H +#define RenderTriangles_H + +// +// Define the characteristics +// of this message class here. +// + +#undef MESSAGE_NAME +#define MESSAGE_NAME "RenderTriangles" + +#undef MESSAGE_STORE +#define MESSAGE_STORE RenderTrianglesStore + +#undef MESSAGE_CLASS +#define MESSAGE_CLASS RenderMinorExtensionStore + +#undef MESSAGE_METHODS +#define MESSAGE_METHODS "RenderMinorExtensionMethods.h" + +#undef MESSAGE_HEADERS +#define MESSAGE_HEADERS "RenderMinorExtensionHeaders.h" + +#undef MESSAGE_TAGS +#define MESSAGE_TAGS "RenderMinorExtensionTags.h" + +#undef MESSAGE_OFFSET +#define MESSAGE_OFFSET 24 + +#undef MESSAGE_HAS_SIZE +#define MESSAGE_HAS_SIZE 1 + +#undef MESSAGE_HAS_DATA +#define MESSAGE_HAS_DATA 1 + +#undef MESSAGE_HAS_FILTER +#define MESSAGE_HAS_FILTER 0 + +// +// Declare the message class. +// + +#include MESSAGE_HEADERS + +class MESSAGE_STORE : public MESSAGE_CLASS +{ + public: + + virtual const char *name() const + { + return MESSAGE_NAME; + } + + virtual int identitySize(const unsigned char *buffer, + unsigned int size) + { + return (size >= MESSAGE_OFFSET ? MESSAGE_OFFSET : size); + } + + #include MESSAGE_METHODS +}; + +#endif /* RenderTriangles_H */ diff --git a/nxcomp/src/Rgb.cpp b/nxcomp/src/Rgb.cpp new file mode 100644 index 000000000..c98fa5147 --- /dev/null +++ b/nxcomp/src/Rgb.cpp @@ -0,0 +1,106 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Rgb.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +int UnpackRgb(T_geometry *geometry, unsigned char method, unsigned char *src_data, + int src_size, int dst_bpp, int dst_width, int dst_height, + unsigned char *dst_data, int dst_size) +{ + if (*src_data == 0) + { + if (dst_size != src_size - 1) + { + #ifdef TEST + *logofs << "UnpackRgb: PANIC! Invalid destination size " + << dst_size << " with source " << src_size + << ".\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef TEST + *logofs << "UnpackRgb: Expanding " << src_size - 1 + << " bytes of plain RGB data.\n" << logofs_flush; + #endif + + memcpy(dst_data, src_data + 1, src_size - 1); + + return 1; + } + + unsigned int check_size = dst_size; + + int result = ZDecompress(&unpackStream, dst_data, &check_size, + src_data + 1, src_size - 1); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "UnpackRgb: PANIC! Failure decompressing RGB data. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decompressing RGB data. " + << "Error is '" << zError(result) << "'.\n"; + + return -1; + } + else if (check_size != (unsigned int) dst_size) + { + #ifdef PANIC + *logofs << "UnpackRgb: PANIC! Size mismatch in RGB data. " + << "Resulting size is " << check_size << " with " + << "expected size " << dst_size << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Size mismatch in RGB data. " + << "Resulting size is " << check_size << " with " + << "expected size " << dst_size << ".\n"; + + return -1; + } + + #ifdef TEST + *logofs << "UnpackRgb: Decompressed " << src_size - 1 + << " bytes to " << dst_size << " bytes of RGB data.\n" + << logofs_flush; + #endif + + return 1; +} diff --git a/nxcomp/src/Rgb.h b/nxcomp/src/Rgb.h new file mode 100644 index 000000000..ec088dd1b --- /dev/null +++ b/nxcomp/src/Rgb.h @@ -0,0 +1,36 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Rgb_H +#define Rgb_H + +#include "Unpack.h" + +int UnpackRgb(T_geometry *geometry, unsigned char method, + unsigned char *src_data, int src_size, int dst_bpp, + int dst_width, int dst_height, unsigned char *dst_data, + int dst_size); + +#endif /* Rgb_H */ diff --git a/nxcomp/src/Rle.cpp b/nxcomp/src/Rle.cpp new file mode 100644 index 000000000..2a145aa0c --- /dev/null +++ b/nxcomp/src/Rle.cpp @@ -0,0 +1,106 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Rle.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +int UnpackRle(T_geometry *geometry, unsigned char method, unsigned char *src_data, + int src_size, int dst_bpp, int dst_width, int dst_height, + unsigned char *dst_data, int dst_size) +{ + if (*src_data == 0) + { + if (dst_size != src_size - 1) + { + #ifdef TEST + *logofs << "UnpackRle: PANIC! Invalid destination size " + << dst_size << " with source " << src_size + << ".\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef TEST + *logofs << "UnpackRle: Expanding " << src_size - 1 + << " bytes of plain RLE data.\n" << logofs_flush; + #endif + + memcpy(dst_data, src_data + 1, src_size - 1); + + return 1; + } + + unsigned int check_size = dst_size; + + int result = ZDecompress(&unpackStream, dst_data, &check_size, + src_data + 1, src_size - 1); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "UnpackRle: PANIC! Failure decompressing RLE data. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decompressing RLE data. " + << "Error is '" << zError(result) << "'.\n"; + + return -1; + } + else if (check_size != (unsigned int) dst_size) + { + #ifdef PANIC + *logofs << "UnpackRle: PANIC! Size mismatch in RLE data. " + << "Resulting size is " << check_size << " with " + << "expected size " << dst_size << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Size mismatch in RLE data. " + << "Resulting size is " << check_size << " with " + << "expected size " << dst_size << ".\n"; + + return -1; + } + + #ifdef TEST + *logofs << "UnpackRle: Decompressed " << src_size - 1 + << " bytes to " << dst_size << " bytes of RLE data.\n" + << logofs_flush; + #endif + + return 1; +} diff --git a/nxcomp/src/Rle.h b/nxcomp/src/Rle.h new file mode 100644 index 000000000..cc5dab0e8 --- /dev/null +++ b/nxcomp/src/Rle.h @@ -0,0 +1,36 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Rle_H +#define Rle_H + +#include "Unpack.h" + +int UnpackRle(T_geometry *geometry, unsigned char method, + unsigned char *src_data, int src_size, int dst_bpp, + int dst_width, int dst_height, unsigned char *dst_data, + int dst_size); + +#endif /* Rle_H */ diff --git a/nxcomp/src/SendEvent.cpp b/nxcomp/src/SendEvent.cpp new file mode 100644 index 000000000..8867d0a9e --- /dev/null +++ b/nxcomp/src/SendEvent.cpp @@ -0,0 +1,304 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SendEvent.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "IntCache.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int SendEventStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SendEventMessage *sendEvent = (SendEventMessage *) message; + + // + // Here is the fingerprint. + // + + sendEvent -> propagate = *(buffer + 1); + + sendEvent -> window = GetULONG(buffer + 4, bigEndian); + sendEvent -> mask = GetULONG(buffer + 8, bigEndian); + + sendEvent -> code = *(buffer + 12); + sendEvent -> byte_data = *(buffer + 13); + + sendEvent -> sequence = GetUINT(buffer + 14, bigEndian); + + sendEvent -> int_data = GetULONG(buffer + 16, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int SendEventStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SendEventMessage *sendEvent = (SendEventMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = sendEvent -> propagate; + + PutULONG(sendEvent -> window, buffer + 4, bigEndian); + PutULONG(sendEvent -> mask, buffer + 8, bigEndian); + + *(buffer + 12) = sendEvent -> code; + *(buffer + 13) = sendEvent -> byte_data; + + PutUINT(sendEvent -> sequence, buffer + 14, bigEndian); + + PutULONG(sendEvent -> int_data, buffer + 16, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void SendEventStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + SendEventMessage *sendEvent = (SendEventMessage *) message; + + *logofs << name() << ": Identity propagate " << (unsigned int) sendEvent -> propagate + << ", window " << sendEvent -> window << ", mask " << sendEvent -> mask + << ", code " << (unsigned int) sendEvent -> code << ", byte_data " + << (unsigned int) sendEvent -> byte_data << ", sequence " + << sendEvent -> sequence << ", int_data " << sendEvent -> int_data + << ", size " << sendEvent -> size_ << ".\n" << logofs_flush; + + #endif +} + +void SendEventStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ +} + +void SendEventStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + SendEventMessage *sendEvent = (SendEventMessage *) message; + SendEventMessage *cachedSendEvent = (SendEventMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << (unsigned int) sendEvent -> propagate + << " as propagate field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeBoolValue(sendEvent -> propagate); + + cachedSendEvent -> propagate = sendEvent -> propagate; + + #ifdef TEST + *logofs << name() << ": Encoding value " << sendEvent -> window + << " as window field.\n" << logofs_flush; + #endif + + if (sendEvent -> window == 0 || sendEvent -> window == 1) + { + encodeBuffer.encodeBoolValue(1); + + encodeBuffer.encodeBoolValue(sendEvent -> window); + } + else + { + encodeBuffer.encodeBoolValue(0); + + encodeBuffer.encodeXidValue(sendEvent -> window, clientCache -> windowCache); + } + + cachedSendEvent -> window = sendEvent -> window; + + #ifdef TEST + *logofs << name() << ": Encoding value " << sendEvent -> mask + << " as mask field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(sendEvent -> mask, 32, + clientCache -> sendEventMaskCache); + + cachedSendEvent -> mask = sendEvent -> mask; + + #ifdef TEST + *logofs << name() << ": Encoding value " << sendEvent -> code + << " as code field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(sendEvent -> code, 8, + clientCache -> sendEventCodeCache); + + cachedSendEvent -> code = sendEvent -> code; + + #ifdef TEST + *logofs << name() << ": Encoding value " << sendEvent -> byte_data + << " as byte_data field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(sendEvent -> byte_data, 8, + clientCache -> sendEventByteDataCache); + + cachedSendEvent -> byte_data = sendEvent -> byte_data; + + #ifdef TEST + *logofs << name() << ": Encoding value " << sendEvent -> sequence + << " as sequence field.\n" << logofs_flush; + #endif + + unsigned int diffSeq = sendEvent -> sequence - + clientCache -> sendEventLastSequence; + + clientCache -> sendEventLastSequence = sendEvent -> sequence; + + encodeBuffer.encodeValue(diffSeq, 16, 4); + + cachedSendEvent -> sequence = sendEvent -> sequence; + + #ifdef TEST + *logofs << name() << ": Encoding value " << sendEvent -> int_data + << " as int_data field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(sendEvent -> int_data, 32, + clientCache -> sendEventIntDataCache); + + cachedSendEvent -> int_data = sendEvent -> int_data; +} + +void SendEventStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + SendEventMessage *sendEvent = (SendEventMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeBoolValue(value); + + sendEvent -> propagate = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << (unsigned int) sendEvent -> propagate + << " as propagate field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeBoolValue(value); + + if (value) + { + decodeBuffer.decodeBoolValue(value); + } + else + { + decodeBuffer.decodeXidValue(value, clientCache -> windowCache); + } + + sendEvent -> window = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << sendEvent -> window + << " as window field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(sendEvent -> mask, 32, + clientCache -> sendEventMaskCache); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << sendEvent -> mask + << " as mask field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(sendEvent -> code, 8, + clientCache -> sendEventCodeCache); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << sendEvent -> code + << " as code field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(sendEvent -> byte_data, 8, + clientCache -> sendEventByteDataCache); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << sendEvent -> byte_data + << " as byte_data field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeValue(value, 16, 4); + + clientCache -> sendEventLastSequence += value; + clientCache -> sendEventLastSequence &= 0xffff; + + sendEvent -> sequence = clientCache -> sendEventLastSequence; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << sendEvent -> sequence + << " as sequence field.\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(sendEvent -> int_data, 32, + clientCache -> sendEventIntDataCache); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << sendEvent -> int_data + << " as int_data field.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/SendEvent.h b/nxcomp/src/SendEvent.h new file mode 100644 index 000000000..a8841a706 --- /dev/null +++ b/nxcomp/src/SendEvent.h @@ -0,0 +1,195 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef SendEvent_H +#define SendEvent_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define SENDEVENT_ENABLE_CACHE 1 +#define SENDEVENT_ENABLE_DATA 0 +#define SENDEVENT_ENABLE_SPLIT 0 +#define SENDEVENT_ENABLE_COMPRESS 0 + +#define SENDEVENT_DATA_LIMIT 24 +#define SENDEVENT_DATA_OFFSET 20 + +#define SENDEVENT_CACHE_SLOTS 2000 +#define SENDEVENT_CACHE_THRESHOLD 2 +#define SENDEVENT_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class SendEventMessage : public Message +{ + friend class SendEventStore; + + public: + + SendEventMessage() + { + } + + ~SendEventMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char propagate; + unsigned int window; + unsigned int mask; + + // + // These are part of the event data. + // + + unsigned char code; + unsigned char byte_data; + unsigned short sequence; + unsigned int int_data; +}; + +class SendEventStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + SendEventStore() : MessageStore() + { + enableCache = SENDEVENT_ENABLE_CACHE; + enableData = SENDEVENT_ENABLE_DATA; + enableSplit = SENDEVENT_ENABLE_SPLIT; + enableCompress = SENDEVENT_ENABLE_COMPRESS; + + dataLimit = SENDEVENT_DATA_LIMIT; + dataOffset = SENDEVENT_DATA_OFFSET; + + cacheSlots = SENDEVENT_CACHE_SLOTS; + cacheThreshold = SENDEVENT_CACHE_THRESHOLD; + cacheLowerThreshold = SENDEVENT_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~SendEventStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "SendEvent"; + } + + virtual unsigned char opcode() const + { + return X_SendEvent; + } + + virtual unsigned int storage() const + { + return sizeof(SendEventMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new SendEventMessage(); + } + + virtual Message *create(const Message &message) const + { + return new SendEventMessage((const SendEventMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (SendEventMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* SendEvent_H */ diff --git a/nxcomp/src/SequenceQueue.cpp b/nxcomp/src/SequenceQueue.cpp new file mode 100644 index 000000000..a045875d7 --- /dev/null +++ b/nxcomp/src/SequenceQueue.cpp @@ -0,0 +1,174 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SequenceQueue.h" + +static const unsigned int INITIAL_SIZE_ = 16; +static const unsigned int GROWTH_INCREMENT = 16; + +SequenceQueue::SequenceQueue() + + : queue_(new RequestSequence[INITIAL_SIZE_]), size_(INITIAL_SIZE_), + length_(0), start_(0), end_(0) +{ +} + +SequenceQueue::~SequenceQueue() +{ + delete [] queue_; +} + +void SequenceQueue::push(unsigned short int sequence, unsigned char opcode, + unsigned int data1, unsigned int data2, + unsigned int data3) +{ + if (length_ == 0) + { + start_ = end_ = 0; + + queue_[0].opcode = opcode; + queue_[0].sequence = sequence; + + queue_[0].data1 = data1; + queue_[0].data2 = data2; + queue_[0].data3 = data3; + + length_ = 1; + + return; + } + + if (length_ == size_) + { + size_ += GROWTH_INCREMENT; + + RequestSequence *newQueue = new RequestSequence[size_]; + + for (int i = start_; (unsigned int) i < length_; i++) + { + newQueue[i - start_] = queue_[i]; + } + + for (int i1 = 0; (unsigned int) i1 < start_; i1++) + { + newQueue[i1 + length_ - start_] = queue_[i1]; + } + + delete [] queue_; + + queue_ = newQueue; + + start_ = 0; + + end_ = length_ - 1; + } + + end_++; + + if (end_ == size_) + { + end_ = 0; + } + + queue_[end_].opcode = opcode; + queue_[end_].sequence = sequence; + + queue_[end_].data1 = data1; + queue_[end_].data2 = data2; + queue_[end_].data3 = data3; + + length_++; +} + +int SequenceQueue::peek(unsigned short int &sequence, + unsigned char &opcode) +{ + if (length_ == 0) + { + return 0; + } + else + { + opcode = queue_[start_].opcode; + sequence = queue_[start_].sequence; + + return 1; + } +} + +int SequenceQueue::peek(unsigned short int &sequence, unsigned char &opcode, + unsigned int &data1, unsigned int &data2, + unsigned int &data3) +{ + if (length_ == 0) + { + return 0; + } + else + { + opcode = queue_[start_].opcode; + sequence = queue_[start_].sequence; + + data1 = queue_[start_].data1; + data2 = queue_[start_].data2; + data3 = queue_[start_].data3; + + return 1; + } +} + +int SequenceQueue::pop(unsigned short int &sequence, unsigned char &opcode, + unsigned int &data1, unsigned int &data2, + unsigned int &data3) +{ + if (length_ == 0) + { + return 0; + } + else + { + opcode = queue_[start_].opcode; + sequence = queue_[start_].sequence; + + data1 = queue_[start_].data1; + data2 = queue_[start_].data2; + data3 = queue_[start_].data3; + + start_++; + + if (start_ == size_) + { + start_ = 0; + } + + length_--; + + return 1; + } +} diff --git a/nxcomp/src/SequenceQueue.h b/nxcomp/src/SequenceQueue.h new file mode 100644 index 000000000..2a72bc3fe --- /dev/null +++ b/nxcomp/src/SequenceQueue.h @@ -0,0 +1,91 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef SequenceQueue_H +#define SequenceQueue_H + +// +// List of outstanding request messages which +// are waiting for a reply. This class is used +// in X client and server channels to correlate +// the replies sequence numbers to the original +// request type. +// + +class SequenceQueue +{ + public: + + SequenceQueue(); + + virtual ~SequenceQueue(); + + void push(unsigned short int sequence, unsigned char opcode, + unsigned int data1 = 0, unsigned int data2 = 0, + unsigned int data3 = 0); + + int peek(unsigned short int &sequence, unsigned char &opcode); + + int peek(unsigned short int &sequence, unsigned char &opcode, + unsigned int &data1, unsigned int &data2, + unsigned int &data3); + + int pop(unsigned short int &sequence, unsigned char &opcode, + unsigned int &data1, unsigned int &data2, + unsigned int &data3); + + int pop(unsigned short int &sequence, unsigned char &opcode) + { + unsigned int data1, data2, data3; + + return pop(sequence, opcode, data1, data2, data3); + } + + int length() + { + return length_; + } + + private: + + struct RequestSequence + { + unsigned short int sequence; + unsigned char opcode; + unsigned int data1; + unsigned int data2; + unsigned int data3; + }; + + RequestSequence *queue_; + + unsigned int size_; + unsigned int length_; + + unsigned int start_; + unsigned int end_; +}; + +#endif /* SequenceQueue_H */ diff --git a/nxcomp/src/ServerCache.cpp b/nxcomp/src/ServerCache.cpp new file mode 100644 index 000000000..c4c088dca --- /dev/null +++ b/nxcomp/src/ServerCache.cpp @@ -0,0 +1,195 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ServerCache.h" + +// +// Some global caches used to store information +// common to all X connections. +// + +BlockCache ServerCache::lastInitReply; +BlockCache ServerCache::lastKeymap; +unsigned char ServerCache::getKeyboardMappingLastKeysymsPerKeycode = 0; +BlockCache ServerCache::getKeyboardMappingLastMap; +BlockCache ServerCache::getModifierMappingLastMap; +BlockCache ServerCache::xResources; +BlockCacheSet ServerCache::queryFontFontCache(16); + +ServerCache::ServerCache() : + + replySequenceCache(6), eventSequenceCache(6), + lastTimestamp(0), visualCache(8), colormapCache(8), + + errorMinorCache(8), + + colormapNotifyWindowCache(8), colormapNotifyColormapCache(8), + + createNotifyWindowCache(8), createNotifyLastWindow(0), + + exposeWindowCache(12), + + focusInWindowCache(8), + + keyPressLastKey(0), + + mapNotifyEventCache(8), mapNotifyWindowCache(8), + + motionNotifyTimestampCache(8), motionNotifyLastRootX(0), + motionNotifyLastRootY(0), motionNotifyRootXCache(8), + motionNotifyRootYCache(8), motionNotifyEventXCache(8), + motionNotifyEventYCache(8), motionNotifyStateCache(8), + + noExposeDrawableCache(8), noExposeMinorCache(8), + + propertyNotifyWindowCache(8), propertyNotifyAtomCache(8), + + reparentNotifyWindowCache(8), + + selectionClearWindowCache(8), selectionClearAtomCache(8), + + visibilityNotifyWindowCache(8), + + getGeometryRootCache(8), + + getInputFocusWindowCache(8), + + getKeyboardMappingKeysymCache(8), + + getPropertyTypeCache(8), + + getSelectionOwnerCache(8), + + getWindowAttributesClassCache(8), getWindowAttributesPlanesCache(8), + getWindowAttributesPixelCache(8), getWindowAttributesAllEventsCache(8), + getWindowAttributesYourEventsCache(8), + getWindowAttributesDontPropagateCache(8), + + queryPointerRootCache(8), queryPointerChildCache(8), + + translateCoordsChildCache(8), translateCoordsXCache(8), + translateCoordsYCache(8), + + queryTreeWindowCache(8) + +{ + unsigned int i; + + for (i = 0; i < 3; i++) + { + configureNotifyWindowCache[i] = new IntCache(8); + } + + for (i = 0; i < 5; i++) + { + configureNotifyGeomCache[i] = new IntCache(8); + } + + for (i = 0; i < 5; i++) + { + exposeGeomCache[i] = new IntCache(8); + } + + for (i = 0; i < 3; i++) + { + motionNotifyWindowCache[i] = new IntCache(8); + } + + for (i = 0; i < 5; i++) + { + getGeometryGeomCache[i] = new IntCache(8); + } + + for (i = 0; i < 23; i++) + { + keyPressCache[i] = 0; + } + + for (i = 0; i < 6; i++) + { + queryFontCharInfoCache[i] = new IntCache(8); + queryFontLastCharInfo[i] = 0; + } + + for (i = 0; i < 12; i++) + { + genericReplyIntCache[i] = new IntCache(8); + } + + for (i = 0; i < 14; i++) + { + genericEventIntCache[i] = new IntCache(8); + } +} + + +ServerCache::~ServerCache() +{ + unsigned int i; + + for (i = 0; i < 3; i++) + { + delete configureNotifyWindowCache[i]; + } + + for (i = 0; i < 5; i++) + { + delete configureNotifyGeomCache[i]; + } + + for (i = 0; i < 5; i++) + { + delete exposeGeomCache[i]; + } + + for (i = 0; i < 3; i++) + { + delete motionNotifyWindowCache[i]; + } + + for (i = 0; i < 5; i++) + { + delete getGeometryGeomCache[i]; + } + + for (i = 0; i < 6; i++) + { + delete queryFontCharInfoCache[i]; + } + + for (i = 0; i < 12; i++) + { + delete genericReplyIntCache[i]; + } + + for (i = 0; i < 14; i++) + { + delete genericEventIntCache[i]; + } +} diff --git a/nxcomp/src/ServerCache.h b/nxcomp/src/ServerCache.h new file mode 100644 index 000000000..c6e2b81b6 --- /dev/null +++ b/nxcomp/src/ServerCache.h @@ -0,0 +1,303 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ServerCache_H +#define ServerCache_H + +#include "Misc.h" + +#include "IntCache.h" +#include "CharCache.h" +#include "OpcodeCache.h" +#include "BlockCache.h" +#include "BlockCacheSet.h" + +#include "ChannelCache.h" + +class ServerCache : public ChannelCache +{ + public: + + ServerCache(); + + ~ServerCache(); + + // + // Opcode prediction caches. + // + + OpcodeCache opcodeCache; + + // + // General-purpose caches. + // + + IntCache replySequenceCache; + IntCache eventSequenceCache; + unsigned int lastTimestamp; + CharCache depthCache; + IntCache visualCache; + IntCache colormapCache; + CharCache resourceCache; + + // + // X connection startup. + // + + static BlockCache lastInitReply; + + // + // X errors. + // + + CharCache errorCodeCache; + IntCache errorMinorCache; + CharCache errorMajorCache; + + // + // ButtonPress and ButtonRelease events. + // + + CharCache buttonCache; + + // + // ColormapNotify event. + // + + IntCache colormapNotifyWindowCache; + IntCache colormapNotifyColormapCache; + + // + // ConfigureNotify event. + // + + IntCache *configureNotifyWindowCache[3]; + IntCache *configureNotifyGeomCache[5]; + + // + // CreateNotify event. + // + + IntCache createNotifyWindowCache; + unsigned int createNotifyLastWindow; + + // + // Expose event. + // + + IntCache exposeWindowCache; + IntCache *exposeGeomCache[5]; + + // + // FocusIn event (also used for FocusOut). + // + + IntCache focusInWindowCache; + + // + // KeymapNotify event. + // + + static BlockCache lastKeymap; + + // + // KeyPress event. + // + + unsigned char keyPressLastKey; + unsigned char keyPressCache[23]; + + // + // MapNotify event (also used for UnmapNotify). + // + + IntCache mapNotifyEventCache; + IntCache mapNotifyWindowCache; + + // + // MotionNotify event (also used for KeyPress, + // KeyRelease, ButtonPress, ButtonRelease, + // EnterNotify, and LeaveNotify events and + // QueryPointer reply). + // + + IntCache motionNotifyTimestampCache; + unsigned int motionNotifyLastRootX; + unsigned int motionNotifyLastRootY; + IntCache motionNotifyRootXCache; + IntCache motionNotifyRootYCache; + IntCache motionNotifyEventXCache; + IntCache motionNotifyEventYCache; + IntCache motionNotifyStateCache; + IntCache *motionNotifyWindowCache[3]; + + // + // NoExpose event. + // + + IntCache noExposeDrawableCache; + IntCache noExposeMinorCache; + CharCache noExposeMajorCache; + + // + // PropertyNotify event. + // + + IntCache propertyNotifyWindowCache; + IntCache propertyNotifyAtomCache; + + // + // ReparentNotify event. + // + + IntCache reparentNotifyWindowCache; + + // + // SelectionClear event. + // + + IntCache selectionClearWindowCache; + IntCache selectionClearAtomCache; + + // + // VisibilityNotify event. + // + + IntCache visibilityNotifyWindowCache; + + // + // GetGeometry reply. + // + + IntCache getGeometryRootCache; + IntCache *getGeometryGeomCache[5]; + + // + // GetInputFocus reply. + // + + IntCache getInputFocusWindowCache; + + // + // GetKeyboardMapping reply. + // + + static unsigned char getKeyboardMappingLastKeysymsPerKeycode; + static BlockCache getKeyboardMappingLastMap; + IntCache getKeyboardMappingKeysymCache; + CharCache getKeyboardMappingLastByteCache; + + // + // GetModifierMapping reply. + // + + static BlockCache getModifierMappingLastMap; + + // + // GetProperty reply. + // + + CharCache getPropertyFormatCache; + IntCache getPropertyTypeCache; + static BlockCache xResources; + + // + // GetSelection reply. + // + + IntCache getSelectionOwnerCache; + + // + // GetWindowAttributes reply. + // + + IntCache getWindowAttributesClassCache; + CharCache getWindowAttributesBitGravityCache; + CharCache getWindowAttributesWinGravityCache; + IntCache getWindowAttributesPlanesCache; + IntCache getWindowAttributesPixelCache; + IntCache getWindowAttributesAllEventsCache; + IntCache getWindowAttributesYourEventsCache; + IntCache getWindowAttributesDontPropagateCache; + + // + // QueryColors reply. + // + + BlockCache queryColorsLastReply; + + // + // QueryFont reply. + // + + static BlockCacheSet queryFontFontCache; + IntCache *queryFontCharInfoCache[6]; + unsigned int queryFontLastCharInfo[6]; + + // + // QueryPointer reply. + // + + IntCache queryPointerRootCache; + IntCache queryPointerChildCache; + + // + // TranslateCoords reply. + // + + IntCache translateCoordsChildCache; + IntCache translateCoordsXCache; + IntCache translateCoordsYCache; + + // + // QueryTree reply. + // + + IntCache queryTreeWindowCache; + + // + // Generic reply. Use short data + // in protocol versions >= 3. + // + + CharCache genericReplyCharCache; + IntCache *genericReplyIntCache[12]; + + // + // Generic event. Only in protocol + // versions >= 3. + // + + CharCache genericEventCharCache; + IntCache *genericEventIntCache[14]; + + // + // Used in the abort split events. + // + + OpcodeCache abortOpcodeCache; +}; + +#endif /* ServerCache_H */ diff --git a/nxcomp/src/ServerChannel.cpp b/nxcomp/src/ServerChannel.cpp new file mode 100644 index 000000000..a560eca6d --- /dev/null +++ b/nxcomp/src/ServerChannel.cpp @@ -0,0 +1,7946 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#ifndef ANDROID +#include +#endif + +#include +#include + +#include "NXproto.h" +#include "NXalert.h" +#include "NXpack.h" +#include "NXmitshm.h" + +#include "ServerChannel.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "StaticCompressor.h" + +#include "Statistics.h" +#include "Proxy.h" + +#include "Auth.h" +#include "Unpack.h" + +// +// Available unpack methods. +// + +#include "Alpha.h" +#include "Colormap.h" +#include "Bitmap.h" +#include "Jpeg.h" +#include "Pgn.h" +#include "Rgb.h" +#include "Rle.h" + +extern Proxy *proxy; + +// +// Set the verbosity level. You also +// need to define OPCODES in Misc.cpp +// if you want literals instead of +// opcodes' numbers. +// + +#define PANIC +#define WARNING +#undef OPCODES +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Log the important tracepoints related +// to writing packets to the peer proxy. +// + +#undef FLUSH + +// +// Log the operations related to splits. +// + +#undef SPLIT + +// +// Define this to log when a channel +// is created or destroyed. +// + +#undef REFERENCES + +// +// Define this to exit and suspend the +// session after a given number of X +// messages decoded by the proxy. +// + +#undef SUSPEND + +// +// Define these to hide the server extensions. +// + +#define HIDE_MIT_SHM_EXTENSION +#define HIDE_BIG_REQUESTS_EXTENSION +#define HIDE_XFree86_Bigfont_EXTENSION +#undef HIDE_SHAPE_EXTENSION +#undef HIDE_XKEYBOARD_EXTENSION + +// +// Known reasons of connection failures. +// + +#define INVALID_COOKIE_DATA "Invalid MIT-MAGIC-COOKIE-1 key" +#define INVALID_COOKIE_SIZE ((int) sizeof(INVALID_COOKIE_DATA) - 1) + +#define NO_AUTH_PROTO_DATA "No protocol specified" +#define NO_AUTH_PROTO_SIZE ((int) sizeof(NO_AUTH_PROTO_DATA) - 1) + +// +// Here are the static members. +// + +#ifdef REFERENCES + +int ServerChannel::references_ = 0; + +#endif + +ServerChannel::ServerChannel(Transport *transport, StaticCompressor *compressor) + + : Channel(transport, compressor), readBuffer_(transport_, this) +{ + // + // Sequence number of the next message + // being encoded or decoded. + // + + clientSequence_ = 0; + serverSequence_ = 0; + + // + // Save the last motion event and flush + // it only when the timeout expires. + // + + lastMotion_[0] = '\0'; + + // + // Clear the queue of sequence numbers + // of split commits. Used to mask the + // errors. + // + + initCommitQueue(); + + // + // Do we enable or not sending of expose + // events to the X client. + // + + enableExpose_ = 1; + enableGraphicsExpose_ = 1; + enableNoExpose_ = 1; + + // + // Track data of image currently being + // decompressed. + // + + imageState_ = NULL; + + // + // Track MIT-SHM resources. + // + + shmemState_ = NULL; + + // + // Store the unpack state for each agent + // resource. + // + + for (int i = 0; i < CONNECTIONS_LIMIT; i++) + { + unpackState_[i] = NULL; + } + + // + // Data about the split parameters requested + // by the encoding side. + // + + splitState_.resource = nothing; + splitState_.current = 0; + splitState_.save = 1; + splitState_.load = 1; + splitState_.commit = 0; + + // + // It will be eventually set by + // the server proxy. + // + + fontPort_ = -1; + + #ifdef REFERENCES + *logofs << "ServerChannel: Created new object at " + << this << " for FD#" << fd_ << " out of " + << ++references_ << " allocated channels.\n" + << logofs_flush; + #endif +} + +ServerChannel::~ServerChannel() +{ + #ifdef TEST + *logofs << "ServerChannel: Freeing image state information.\n" + << logofs_flush; + #endif + + handleImageStateRemove(); + + #ifdef TEST + *logofs << "ServerChannel: Freeing shared memory information.\n" + << logofs_flush; + #endif + + handleShmemStateRemove(); + + #ifdef TEST + *logofs << "ServerChannel: Freeing unpack state information.\n" + << logofs_flush; + #endif + + for (int i = 0; i < CONNECTIONS_LIMIT; i++) + { + handleUnpackStateRemove(i); + } + + #ifdef TEST + *logofs << "ServerChannel: Freeing channel caches.\n" + << logofs_flush; + #endif + + #ifdef REFERENCES + *logofs << "ServerChannel: Deleted object at " + << this << " for FD#" << fd_ << " out of " + << --references_ << " allocated channels.\n" + << logofs_flush; + #endif +} + +// +// Beginning of handleRead(). +// + +int ServerChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, + unsigned int length) +{ + #ifdef DEBUG + *logofs << "handleRead: Called for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + // + // Pointer to located message and + // its size in bytes. + // + + const unsigned char *inputMessage; + unsigned int inputLength; + + // + // Set when message is found in + // cache. + // + + int hit; + + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: Trying to read from FD#" + << fd_ << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + int result = readBuffer_.readMessage(); + + #if defined(DEBUG) || defined(INFO) + *logofs << "handleRead: Read result on FD#" << fd_ + << " is " << result << ".\n" + << logofs_flush; + #endif + + if (result < 0) + { + // + // Let the proxy close the channel. + // + + return -1; + } + else if (result == 0) + { + #if defined(TEST) || defined(INFO) + + // + // This can happen because we have the descriptor + // selected in the read set but we already read + // the data asynchronously, while decoding data + // read from the proxy. + // + + *logofs << "handleRead: WARNING! No data read from FD#" + << fd_ << " while encoding messages.\n" + << logofs_flush; + + #endif + + return 0; + } + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "handleRead: Encoding messages for FD#" << fd_ + << " with " << readBuffer_.getLength() << " bytes " + << "in the buffer.\n" << logofs_flush; + #endif + + // + // Extract any complete message which + // is available in the buffer. + // + + if (proxy -> handleAsyncSwitch(fd_) < 0) + { + return -1; + } + + while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) + { + hit = 0; + + if (firstReply_) + { + // + // Handle the X server's authorization reply. + // + + if (handleAuthorization(inputMessage, inputLength) < 0) + { + return -1; + } + + imageByteOrder_ = inputMessage[30]; + bitmapBitOrder_ = inputMessage[31]; + scanlineUnit_ = inputMessage[32]; + scanlinePad_ = inputMessage[33]; + + encodeBuffer.encodeValue((unsigned int) inputMessage[0], 8); + encodeBuffer.encodeValue((unsigned int) inputMessage[1], 8); + encodeBuffer.encodeValue(GetUINT(inputMessage + 2, bigEndian_), 16); + encodeBuffer.encodeValue(GetUINT(inputMessage + 4, bigEndian_), 16); + encodeBuffer.encodeValue(GetUINT(inputMessage + 6, bigEndian_), 16); + + if (ServerCache::lastInitReply.compare(inputLength - 8, inputMessage + 8)) + { + encodeBuffer.encodeBoolValue(1); + } + else + { + encodeBuffer.encodeBoolValue(0); + + for (unsigned int i = 8; i < inputLength; i++) + { + encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8); + } + } + + firstReply_ = 0; + + #if defined(TEST) || defined(OPCODES) + + int bits = encodeBuffer.diffBits(); + + *logofs << "handleRead: Handled first reply. " << inputLength + << " bytes in, " << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + + #endif + + priority_++; + + } + else + { + // + // NX client needs this line to consider + // the initialization phase successfully + // completed. + // + + if (firstClient_ == -1) + { + cerr << "Info" << ": Established X server connection.\n" ; + + firstClient_ = fd_; + } + + // + // Check if this is a reply. + // + + if (*inputMessage == X_Reply) + { + int bits = 0; + + unsigned char inputOpcode = *inputMessage; + + unsigned short int requestSequenceNum; + unsigned char requestOpcode; + unsigned int requestData[3]; + + unsigned int sequenceNum = GetUINT(inputMessage + 2, bigEndian_); + + #ifdef SUSPEND + + if (sequenceNum >= 1000) + { + cerr << "Warning" << ": Exiting to test the resilience of the agent.\n"; + + sleep(2); + + HandleAbort(); + } + + #endif + + // + // We managed all the events and errors caused + // by the previous requests. We can now reset + // the queue of split commits. + // + + clearCommitQueue(); + + // + // Encode opcode and difference between + // current sequence and the last one. + // + + encodeBuffer.encodeOpcodeValue(inputOpcode, serverCache_ -> opcodeCache); + + unsigned int sequenceDiff = sequenceNum - serverSequence_; + + serverSequence_ = sequenceNum; + + #ifdef DEBUG + *logofs << "handleRead: Last server sequence number for FD#" + << fd_ << " is " << serverSequence_ << " with " + << "difference " << sequenceDiff << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(sequenceDiff, 16, + serverCache_ -> replySequenceCache, 7); + + // + // Now handle the data part. + // + + if (sequenceQueue_.peek(requestSequenceNum, requestOpcode) && + requestSequenceNum == sequenceNum) + { + // + // We've found the request that generated this reply. + // It is possible to compress the reply based on the + // specific request type. + // + + sequenceQueue_.pop(requestSequenceNum, requestOpcode, + requestData[0], requestData[1], requestData[2]); + + // + // If differential compression is disabled + // then use the most simple encoding. + // + + if (control -> LocalDeltaCompression == 0) + { + int result = handleFastReadReply(encodeBuffer, requestOpcode, + inputMessage, inputLength); + if (result < 0) + { + return -1; + } + else if (result > 0) + { + continue; + } + } + + switch (requestOpcode) + { + case X_AllocColor: + { + const unsigned char *nextSrc = inputMessage + 8; + for (unsigned int i = 0; i < 3; i++) + { + unsigned int colorValue = GetUINT(nextSrc, bigEndian_); + nextSrc += 2; + if (colorValue == requestData[i]) + encodeBuffer.encodeBoolValue(1); + else + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeValue(colorValue - colorValue, 16, 6); + } + } + unsigned int pixel = GetULONG(inputMessage + 16, bigEndian_); + encodeBuffer.encodeValue(pixel, 32, 9); + + priority_++; + } + break; + case X_GetAtomName: + { + unsigned int nameLength = GetUINT(inputMessage + 8, bigEndian_); + encodeBuffer.encodeValue(nameLength, 16, 6); + const unsigned char *nextSrc = inputMessage + 32; + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, nameLength); + + priority_++; + } + break; + case X_GetGeometry: + { + // + // TODO: This obtains a satisfactory 10:1, but + // could be cached to leverage the big amount + // of such requests issued by QT clients. + // + + encodeBuffer.encodeCachedValue(inputMessage[1], 8, + serverCache_ -> depthCache); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> getGeometryRootCache, 9); + const unsigned char *nextSrc = inputMessage + 12; + for (unsigned int i = 0; i < 5; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *serverCache_ -> getGeometryGeomCache[i], 8); + nextSrc += 2; + } + + priority_++; + } + break; + case X_GetInputFocus: + { + // + // Is it a real X_GetInputFocus or a + // masqueraded reply? + // + + if (requestData[0] == X_GetInputFocus) + { + encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> getInputFocusWindowCache); + + priority_++; + } + else + { + // + // TODO: We are not setting priority in case + // of replies other than real X_GetInputFocus + // or X_NXGetUnpackParameters. We should check + // once again that this is OK. + // + + #ifdef TEST + *logofs << "handleRead: Received tainted X_GetInputFocus reply " + << "for request OPCODE#" << requestData[0] << " with " + << "sequence " << sequenceNum << ".\n" + << logofs_flush; + #endif + + // + // Don't encode any data in case of sync + // messages or any other reply for which + // opcode is enough. + // + + if (requestData[0] == opcodeStore_ -> getUnpackParameters) + { + for (int i = 0; i < PACK_METHOD_LIMIT; i++) + { + encodeBuffer.encodeBoolValue(control -> LocalUnpackMethods[i]); + } + + priority_++; + } + else if (requestData[0] == opcodeStore_ -> getShmemParameters) + { + if (handleShmemReply(encodeBuffer, requestOpcode, requestData[1], + inputMessage, inputLength) < 0) + { + return -1; + } + + priority_++; + } + else if (requestData[0] == opcodeStore_ -> getFontParameters) + { + if (handleFontReply(encodeBuffer, requestOpcode, + inputMessage, inputLength) < 0) + { + return -1; + } + } + + // + // Account this data to the original opcode. + // + + requestOpcode = requestData[0]; + } + } + break; + case X_GetKeyboardMapping: + { + unsigned int keysymsPerKeycode = (unsigned int) inputMessage[1]; + if (ServerCache::getKeyboardMappingLastMap.compare(inputLength - 32, + inputMessage + 32) && (keysymsPerKeycode == + ServerCache::getKeyboardMappingLastKeysymsPerKeycode)) + { + encodeBuffer.encodeBoolValue(1); + + priority_++; + + break; + } + ServerCache::getKeyboardMappingLastKeysymsPerKeycode = keysymsPerKeycode; + encodeBuffer.encodeBoolValue(0); + unsigned int numKeycodes = + (((inputLength - 32) / keysymsPerKeycode) >> 2); + encodeBuffer.encodeValue(numKeycodes, 8); + encodeBuffer.encodeValue(keysymsPerKeycode, 8, 4); + const unsigned char *nextSrc = inputMessage + 32; + unsigned char previous = 0; + for (unsigned int count = numKeycodes * keysymsPerKeycode; + count; --count) + { + unsigned int keysym = GetULONG(nextSrc, bigEndian_); + nextSrc += 4; + if (keysym == NoSymbol) + encodeBuffer.encodeBoolValue(1); + else + { + encodeBuffer.encodeBoolValue(0); + unsigned int first3Bytes = (keysym >> 8); + encodeBuffer.encodeCachedValue(first3Bytes, 24, + serverCache_ -> getKeyboardMappingKeysymCache, 9); + unsigned char lastByte = (unsigned char) (keysym & 0xff); + encodeBuffer.encodeCachedValue(lastByte - previous, 8, + serverCache_ -> getKeyboardMappingLastByteCache, 5); + previous = lastByte; + } + } + + priority_++; + } + break; + case X_GetModifierMapping: + { + encodeBuffer.encodeValue((unsigned int) inputMessage[1], 8); + const unsigned char *nextDest = inputMessage + 32; + if (ServerCache::getModifierMappingLastMap.compare(inputLength - 32, + nextDest)) + { + encodeBuffer.encodeBoolValue(1); + + priority_++; + + break; + } + encodeBuffer.encodeBoolValue(0); + for (unsigned int count = inputLength - 32; count; count--) + { + unsigned char next = *nextDest++; + if (next == 0) + encodeBuffer.encodeBoolValue(1); + else + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeValue(next, 8); + } + } + + priority_++; + } + break; + case X_GetProperty: + { + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_GetProperty); + + hit = handleEncode(encodeBuffer, serverCache_, messageStore, + requestOpcode, inputMessage, inputLength); + + priority_++; + } + break; + case X_GetSelectionOwner: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> getSelectionOwnerCache, 9); + priority_++; + } + break; + case X_GetWindowAttributes: + { + encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> visualCache); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 12, bigEndian_), + 16, serverCache_ -> getWindowAttributesClassCache, 3); + encodeBuffer.encodeCachedValue(inputMessage[14], 8, + serverCache_ -> getWindowAttributesBitGravityCache); + encodeBuffer.encodeCachedValue(inputMessage[15], 8, + serverCache_ -> getWindowAttributesWinGravityCache); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), + 32, serverCache_ -> getWindowAttributesPlanesCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 20, bigEndian_), + 32, serverCache_ -> getWindowAttributesPixelCache, 9); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[24]); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[25]); + encodeBuffer.encodeValue((unsigned int) inputMessage[26], 2); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[27]); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 28, bigEndian_), + 29, serverCache_ -> colormapCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 32, bigEndian_), + 32, serverCache_ -> getWindowAttributesAllEventsCache); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 36, bigEndian_), + 32, serverCache_ -> getWindowAttributesYourEventsCache); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 40, bigEndian_), + 16, serverCache_ -> getWindowAttributesDontPropagateCache); + + priority_++; + } + break; + case X_GrabKeyboard: + case X_GrabPointer: + { + encodeBuffer.encodeValue((unsigned int) inputMessage[1], 3); + + priority_++; + } + break; + case X_InternAtom: + { + encodeBuffer.encodeValue(GetULONG(inputMessage + 8, bigEndian_), 29, 9); + + priority_++; + } + break; + case X_ListExtensions: + { + encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8); + unsigned int numExtensions = (unsigned int) inputMessage[1]; + encodeBuffer.encodeValue(numExtensions, 8); + const unsigned char *nextSrc = inputMessage + 32; + + for (; numExtensions; numExtensions--) + { + unsigned int length = (unsigned int) (*nextSrc++); + + encodeBuffer.encodeValue(length, 8); + + #ifdef HIDE_MIT_SHM_EXTENSION + + if (!strncmp((char *) nextSrc, "MIT-SHM", 7)) + { + #ifdef TEST + *logofs << "handleRead: Hiding MIT-SHM extension in reply.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) nextSrc, "NO-MIT-", 7); + } + + #endif + + #ifdef HIDE_BIG_REQUESTS_EXTENSION + + if (!strncmp((char *) nextSrc, "BIG-REQUESTS", 12)) + { + #ifdef TEST + *logofs << "handleRead: Hiding BIG-REQUESTS extension in reply.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) nextSrc, "NO-BIG-REQUE", 12); + } + + #endif + + #ifdef HIDE_XKEYBOARD_EXTENSION + + if (!strncmp((char *) nextSrc, "XKEYBOARD", 9)) + { + #ifdef TEST + *logofs << "handleRead: Hiding XKEYBOARD extension in reply.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) nextSrc, "NO-XKEYBO", 9); + } + + #endif + + #ifdef HIDE_XFree86_Bigfont_EXTENSION + + if (!strncmp((char *) nextSrc, "XFree86-Bigfont", 15)) + { + #ifdef TEST + *logofs << "handleRead: Hiding XFree86-Bigfont extension in reply.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) nextSrc, "NO-XFree86-Bigf", 15); + } + + #endif + + #ifdef HIDE_SHAPE_EXTENSION + + if (!strncmp((char *) nextSrc, "SHAPE", 5)) + { + #ifdef TEST + *logofs << "handleRead: Hiding SHAPE extension in reply.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) nextSrc, "NO-SH", 5); + } + + #endif + + // + // Check if user disabled RENDER extension. + // + + if (control -> HideRender == 1 && + !strncmp((char *) nextSrc, "RENDER", 6)) + { + #ifdef TEST + *logofs << "handleRead: Hiding RENDER extension in reply.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) nextSrc, "NO-REN", 6); + } + + for (; length; length--) + { + encodeBuffer.encodeValue((unsigned int) (*nextSrc++), 8); + } + } + + priority_++; + } + break; + case X_ListFonts: + { + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_ListFonts); + + if (handleEncodeCached(encodeBuffer, serverCache_, messageStore, + inputMessage, inputLength)) + { + priority_++; + + hit = 1; + + break; + } + + encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8); + unsigned int numFonts = GetUINT(inputMessage + 8, bigEndian_); + encodeBuffer.encodeValue(numFonts, 16, 6); + + // Differential encoding. + encodeBuffer.encodeBoolValue(1); + + const unsigned char* nextSrc = inputMessage + 32; + for (; numFonts; numFonts--) + { + unsigned int length = (unsigned int) (*nextSrc++); + encodeBuffer.encodeValue(length, 8); + + // Since ProtoStep7 (#issue 108) + encodeBuffer.encodeTextData(nextSrc, length); + + nextSrc += length; + } + + priority_++; + } + break; + case X_LookupColor: + case X_AllocNamedColor: + { + const unsigned char *nextSrc = inputMessage + 8; + if (requestOpcode == X_AllocNamedColor) + { + encodeBuffer.encodeValue(GetULONG(nextSrc, bigEndian_), 32, 9); + nextSrc += 4; + } + unsigned int count = 3; + do + { + unsigned int exactColor = GetUINT(nextSrc, bigEndian_); + encodeBuffer.encodeValue(exactColor, 16, 9); + unsigned int visualColor = GetUINT(nextSrc + 6, bigEndian_) - + exactColor; + encodeBuffer.encodeValue(visualColor, 16, 5); + nextSrc += 2; + } + while (--count); + + priority_++; + } + break; + case X_QueryBestSize: + { + encodeBuffer.encodeValue(GetUINT(inputMessage + 8, bigEndian_), 16, 8); + encodeBuffer.encodeValue(GetUINT(inputMessage + 10, bigEndian_), 16, 8); + + priority_++; + } + break; + case X_QueryColors: + { + // Differential encoding. + encodeBuffer.encodeBoolValue(1); + + unsigned int numColors = ((inputLength - 32) >> 3); + const unsigned char *nextSrc = inputMessage + 40; + unsigned char *nextDest = (unsigned char *) inputMessage + 38; + for (unsigned int c = 1; c < numColors; c++) + { + for (unsigned int i = 0; i < 6; i++) + *nextDest++ = *nextSrc++; + nextSrc += 2; + } + unsigned int colorsLength = numColors * 6; + if (serverCache_ -> queryColorsLastReply.compare(colorsLength, + inputMessage + 32)) + encodeBuffer.encodeBoolValue(1); + else + { + const unsigned char *nextSrc = inputMessage + 32; + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeValue(numColors, 16, 5); + for (numColors *= 3; numColors; numColors--) + { + encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16); + nextSrc += 2; + } + } + + priority_++; + } + break; + case X_QueryExtension: + { + if (requestData[0] == X_QueryExtension) + { + // + // Value in requestData[0] will be nonzero + // if the request is for an extension that + // we should hide to the X client. + // + + if (requestData[1]) + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeValue(0, 8); + } + else + { + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[8]); + encodeBuffer.encodeValue((unsigned int) inputMessage[9], 8); + } + + encodeBuffer.encodeValue((unsigned int) inputMessage[10], 8); + encodeBuffer.encodeValue((unsigned int) inputMessage[11], 8); + + if (requestData[2] == X_NXInternalShapeExtension) + { + opcodeStore_ -> shapeExtension = inputMessage[9]; + + #ifdef TEST + *logofs << "handleRead: Shape extension opcode for FD#" << fd_ + << " is " << (unsigned int) opcodeStore_ -> shapeExtension + << ".\n" << logofs_flush; + #endif + } + else if (requestData[2] == X_NXInternalRenderExtension) + { + opcodeStore_ -> renderExtension = inputMessage[9]; + + #ifdef TEST + *logofs << "handleRead: Render extension opcode for FD#" << fd_ + << " is " << (unsigned int) opcodeStore_ -> renderExtension + << ".\n" << logofs_flush; + #endif + } + + priority_++; + } + else + { + #ifdef TEST + *logofs << "handleRead: Received tainted X_QueryExtension reply " + << "for request OPCODE#" << requestData[0] << " with " + << "sequence " << sequenceNum << ".\n" + << logofs_flush; + #endif + + if (requestData[0] == opcodeStore_ -> getShmemParameters) + { + if (handleShmemReply(encodeBuffer, requestOpcode, requestData[1], + inputMessage, inputLength) < 0) + { + return -1; + } + + priority_++; + } + // + // Account this data to the original opcode. + // + + requestOpcode = requestData[0]; + } + } + break; + case X_QueryFont: + { + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_QueryFont); + + if (handleEncodeCached(encodeBuffer, serverCache_, messageStore, + inputMessage, inputLength)) + { + priority_++; + + hit = 1; + + break; + } + + // Differential encoding. + encodeBuffer.encodeBoolValue(1); + + unsigned int numProperties = GetUINT(inputMessage + 46, bigEndian_); + unsigned int numCharInfos = GetULONG(inputMessage + 56, bigEndian_); + encodeBuffer.encodeValue(numProperties, 16, 8); + encodeBuffer.encodeValue(numCharInfos, 32, 10); + handleEncodeCharInfo(inputMessage + 8, encodeBuffer); + handleEncodeCharInfo(inputMessage + 24, encodeBuffer); + encodeBuffer.encodeValue(GetUINT(inputMessage + 40, bigEndian_), 16, 9); + encodeBuffer.encodeValue(GetUINT(inputMessage + 42, bigEndian_), 16, 9); + encodeBuffer.encodeValue(GetUINT(inputMessage + 44, bigEndian_), 16, 9); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[48]); + encodeBuffer.encodeValue((unsigned int) inputMessage[49], 8); + encodeBuffer.encodeValue((unsigned int) inputMessage[50], 8); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[51]); + encodeBuffer.encodeValue(GetUINT(inputMessage + 52, bigEndian_), 16, 9); + encodeBuffer.encodeValue(GetUINT(inputMessage + 54, bigEndian_), 16, 9); + const unsigned char *nextSrc = inputMessage + 60; + unsigned int index; + + int end = 0; + + if (ServerCache::queryFontFontCache.lookup(numProperties * 8 + + numCharInfos * 12, nextSrc, index)) + { + encodeBuffer.encodeBoolValue(1); + encodeBuffer.encodeValue(index, 4); + + end = 1; + } + + if (end == 0) + { + encodeBuffer.encodeBoolValue(0); + for (; numProperties; numProperties--) + { + encodeBuffer.encodeValue(GetULONG(nextSrc, bigEndian_), 32, 9); + encodeBuffer.encodeValue(GetULONG(nextSrc + 4, bigEndian_), 32, 9); + nextSrc += 8; + } + for (; numCharInfos; numCharInfos--) + { + handleEncodeCharInfo(nextSrc, encodeBuffer); + + nextSrc += 12; + } + } + + priority_++; + } + break; + case X_QueryPointer: + { + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> queryPointerRootCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), + 29, serverCache_ -> queryPointerChildCache, 9); + unsigned int rootX = GetUINT(inputMessage + 16, bigEndian_); + unsigned int rootY = GetUINT(inputMessage + 18, bigEndian_); + unsigned int eventX = GetUINT(inputMessage + 20, bigEndian_); + unsigned int eventY = GetUINT(inputMessage + 22, bigEndian_); + eventX -= rootX; + eventY -= rootY; + encodeBuffer.encodeCachedValue( + rootX - serverCache_ -> motionNotifyLastRootX, 16, + serverCache_ -> motionNotifyRootXCache, 8); + serverCache_ -> motionNotifyLastRootX = rootX; + encodeBuffer.encodeCachedValue( + rootY - serverCache_ -> motionNotifyLastRootY, 16, + serverCache_ -> motionNotifyRootYCache, 8); + serverCache_ -> motionNotifyLastRootY = rootY; + encodeBuffer.encodeCachedValue(eventX, 16, + serverCache_ -> motionNotifyEventXCache, 8); + encodeBuffer.encodeCachedValue(eventY, 16, + serverCache_ -> motionNotifyEventYCache, 8); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 24, bigEndian_), + 16, serverCache_ -> motionNotifyStateCache); + priority_++; + } + break; + case X_QueryTree: + { + // + // This was very inefficient. In practice + // it just copied data on the output. Now + // it obtains an average 7:1 compression + // and could optionally be cached. + // + + unsigned int children = GetUINT(inputMessage + 16, bigEndian_); + + encodeBuffer.encodeValue(children, 16, 8); + + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, + serverCache_ -> queryTreeWindowCache); + + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 29, + serverCache_ -> queryTreeWindowCache); + + const unsigned char *next = inputMessage + 32; + + for (unsigned int i = 0; i < children; i++) + { + encodeBuffer.encodeCachedValue(GetULONG(next + (i * 4), bigEndian_), 29, + serverCache_ -> queryTreeWindowCache); + } + + priority_++; + } + break; + case X_TranslateCoords: + { + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> translateCoordsChildCache, 9); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 12, bigEndian_), + 16, serverCache_ -> translateCoordsXCache, 8); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 14, bigEndian_), + 16, serverCache_ -> translateCoordsYCache, 8); + priority_++; + } + break; + case X_GetImage: + { + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_GetImage); + + if (handleEncodeCached(encodeBuffer, serverCache_, messageStore, + inputMessage, inputLength)) + { + priority_++; + + hit = 1; + + break; + } + + // Depth. + encodeBuffer.encodeCachedValue(inputMessage[1], 8, + serverCache_ -> depthCache); + // Reply length. + encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 9); + + // Visual. + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29, + serverCache_ -> visualCache); + + // Since ProtoStep8 (#issue 108) + handleCopy(encodeBuffer, requestOpcode, messageStore -> + dataOffset, inputMessage, inputLength); + + priority_++; + } + break; + case X_GetPointerMapping: + { + encodeBuffer.encodeValue(inputMessage[1], 8, 4); + encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 4); + for (unsigned int i = 32; i < inputLength; i++) + encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8, 4); + + priority_++; + } + break; + case X_GetKeyboardControl: + { + encodeBuffer.encodeValue(inputMessage[1], 8, 2); + encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8); + for (unsigned int i = 8; i < inputLength; i++) + encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8, 4); + + priority_++; + } + break; + default: + { + #ifdef PANIC + *logofs << "ServerChannel: PANIC! No matching request with " + << "OPCODE#" << (unsigned int) requestOpcode + << " for reply with sequence number " + << requestSequenceNum << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": No matching request with OPCODE#" + << (unsigned int) requestOpcode << " for reply with " + << "sequence number " << requestSequenceNum << ".\n"; + + return -1; + } + } + + bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + + const char *cacheString = (hit ? "cached " : ""); + + *logofs << "handleRead: Handled " << cacheString << "reply to OPCODE#" + << (unsigned int) requestOpcode << " (" << DumpOpcode(requestOpcode) + << ") for FD#" << fd_ << " sequence " << serverSequence_ + << ". " << inputLength << " bytes in, " << bits << " bits (" + << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; + + #endif + + } // End of if (sequenceQueue_.peek(requestSequenceNum, requestOpcode) && ... + else + { + // + // We didn't push the request opcode. + // Check if fast encoding is required. + // + + requestOpcode = X_Reply; + + if (control -> LocalDeltaCompression == 0) + { + int result = handleFastReadReply(encodeBuffer, requestOpcode, + inputMessage, inputLength); + if (result < 0) + { + return -1; + } + else if (result > 0) + { + continue; + } + } + + // + // Group all replies whose opcode was not + // pushed in sequence number queue under + // the category 'generic reply'. + // + + #ifdef DEBUG + *logofs << "handleRead: Identified generic reply.\n" + << logofs_flush; + #endif + + MessageStore *messageStore = serverStore_ -> + getReplyStore(X_NXInternalGenericReply); + + hit = handleEncode(encodeBuffer, serverCache_, messageStore, + requestOpcode, inputMessage, inputLength); + + priority_++; + + bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + + const char *cacheString = (hit ? "cached " : ""); + + *logofs << "handleRead: Handled " << cacheString << "generic reply " + << "OPCODE#" << X_NXInternalGenericReply << " for FD#" << fd_ + << " sequence " << serverSequence_ << ". " << inputLength + << " bytes in, " << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + + #endif + } + + if (hit) + { + statistics -> addCachedReply(requestOpcode); + } + + statistics -> addReplyBits(requestOpcode, inputLength << 3, bits); + + } // End of if (inputMessage[0] == 1) ... + else + { + // + // Event or error. + // + + unsigned char inputOpcode = *inputMessage; + + unsigned int inputSequence = GetUINT(inputMessage + 2, bigEndian_); + + // + // Check if this is an event which we can discard. + // + + if ((inputOpcode == Expose && enableExpose_ == 0) || + (inputOpcode == GraphicsExpose && enableGraphicsExpose_ == 0) || + (inputOpcode == NoExpose && enableNoExpose_ == 0)) + { + continue; + } + else if (shmemState_ != NULL && shmemState_ -> enabled == 1 && + inputOpcode == shmemState_ -> event && + checkShmemEvent(inputOpcode, inputSequence, + inputMessage) > 0) + { + continue; + } + else if (inputOpcode == MotionNotify) + { + // + // Save the motion event and send when another + // event or error is received or the motion ti- + // meout is elapsed. If a previous motion event + // was already saved, we replace it with the + // new one and don't reset the timeout, so we + // still have a motion event every given ms. + // + + memcpy(lastMotion_, inputMessage, 32); + + #ifdef TEST + *logofs << "handleRead: Saved suppressed motion event for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + continue; + } + else if (inputOpcode == X_Error) + { + // + // Check if this is an error that matches a + // sequence number for which we are expecting + // a reply. + // + + unsigned short int errorSequenceNum; + unsigned char errorOpcode; + + if (sequenceQueue_.peek(errorSequenceNum, errorOpcode) && + ((unsigned int) errorSequenceNum == inputSequence)) + { + sequenceQueue_.pop(errorSequenceNum, errorOpcode); + } + + // + // Check if error is due to an image commit + // generated at the end of a split. + // + + if (checkCommitError(*(inputMessage + 1), inputSequence, inputMessage) > 0) + { + #ifdef TEST + *logofs << "handleRead: Skipping error on image commit for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + continue; + } + + // + // Check if it's an error generated by a request + // concerning shared memory support. + // + + else if (shmemState_ != NULL && (shmemState_ -> sequence == + inputSequence || (shmemState_ -> enabled == 1 && + (shmemState_ -> opcode == *(inputMessage + 10) || + shmemState_ -> error == *(inputMessage + 1)))) && + checkShmemError(*(inputMessage + 1), inputSequence, + inputMessage) > 0) + { + #ifdef TEST + *logofs << "handleRead: Skipping error on shmem operation for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + continue; + } + } + // + // Check if user pressed the CTRL+ALT+SHIFT+ESC key + // sequence because was unable to kill the session + // through the normal procedure. + // + + if (inputOpcode == KeyPress) + { + if (checkKeyboardEvent(inputOpcode, inputSequence, inputMessage) == 1) + { + #ifdef TEST + *logofs << "handleRead: Removing the key sequence from the " + << "event stream for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + continue; + } + } + + // + // We are going to handle an event or error + // that's not a mouse motion. Prepend any + // saved motion to it. + // + + if (lastMotion_[0] != '\0') + { + if (handleMotion(encodeBuffer) < 0) + { + #ifdef PANIC + *logofs << "handleRead: PANIC! Can't encode motion event for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't encode motion event for FD#" + << fd_ << ".\n"; + + return -1; + } + } + + // + // Encode opcode and difference between + // current sequence and the last one. + // + + encodeBuffer.encodeOpcodeValue(inputOpcode, serverCache_ -> opcodeCache); + + unsigned int sequenceDiff = inputSequence - serverSequence_; + + serverSequence_ = inputSequence; + + #ifdef DEBUG + *logofs << "handleRead: Last server sequence number for FD#" + << fd_ << " is " << serverSequence_ << " with " + << "difference " << sequenceDiff << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(sequenceDiff, 16, + serverCache_ -> eventSequenceCache, 7); + + // + // If differential compression is disabled + // then use the most simple encoding. + // + + if (control -> LocalDeltaCompression == 0) + { + int result = handleFastReadEvent(encodeBuffer, inputOpcode, + inputMessage, inputLength); + if (result < 0) + { + return -1; + } + else if (result > 0) + { + continue; + } + } + + switch (inputOpcode) + { + case X_Error: + { + // + // Set the priority flag in the case of + // a X protocol error. This may restart + // the client if it was waiting for the + // reply. + // + + priority_++; + + unsigned char errorCode = *(inputMessage + 1); + + encodeBuffer.encodeCachedValue(errorCode, 8, + serverCache_ -> errorCodeCache); + + if (errorCode != 11 && errorCode != 8 && + errorCode != 15 && errorCode != 1) + { + encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 16); + } + + if (errorCode >= 18) + { + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, + serverCache_ -> errorMinorCache); + } + + encodeBuffer.encodeCachedValue(inputMessage[10], 8, + serverCache_ -> errorMajorCache); + + if (errorCode >= 18) + { + const unsigned char *nextSrc = inputMessage + 11; + for (unsigned int i = 11; i < 32; i++) + encodeBuffer.encodeValue(*nextSrc++, 8); + } + } + break; + case ButtonPress: + case ButtonRelease: + case KeyPress: + case KeyRelease: + case MotionNotify: + case EnterNotify: + case LeaveNotify: + { + // + // Set the priority in the case this is + // an event that the remote side may + // care to receive as soon as possible. + // + + switch (inputOpcode) + { + case ButtonPress: + case ButtonRelease: + case KeyPress: + case KeyRelease: + { + priority_++; + } + } + + unsigned char detail = inputMessage[1]; + if (*inputMessage == MotionNotify) + encodeBuffer.encodeBoolValue((unsigned int) detail); + else if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify)) + encodeBuffer.encodeValue((unsigned int) detail, 3); + else if (*inputMessage == KeyRelease) + { + if (detail == serverCache_ -> keyPressLastKey) + encodeBuffer.encodeBoolValue(1); + else + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeValue((unsigned int) detail, 8); + } + } + else if ((*inputMessage == ButtonPress) || (*inputMessage == ButtonRelease)) + encodeBuffer.encodeCachedValue(detail, 8, + serverCache_ -> buttonCache); + else + encodeBuffer.encodeValue((unsigned int) detail, 8); + unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_); + unsigned int timestampDiff = + timestamp - serverCache_ -> lastTimestamp; + serverCache_ -> lastTimestamp = timestamp; + encodeBuffer.encodeCachedValue(timestampDiff, 32, + serverCache_ -> motionNotifyTimestampCache, 9); + int skipRest = 0; + if (*inputMessage == KeyRelease) + { + skipRest = 1; + for (unsigned int i = 8; i < 31; i++) + { + if (inputMessage[i] != serverCache_ -> keyPressCache[i - 8]) + { + skipRest = 0; + break; + } + } + encodeBuffer.encodeBoolValue(skipRest); + } + + if (!skipRest) + { + const unsigned char *nextSrc = inputMessage + 8; + for (unsigned int i = 0; i < 3; i++) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29, + *serverCache_ -> motionNotifyWindowCache[i], 6); + nextSrc += 4; + } + unsigned int rootX = GetUINT(inputMessage + 20, bigEndian_); + unsigned int rootY = GetUINT(inputMessage + 22, bigEndian_); + unsigned int eventX = GetUINT(inputMessage + 24, bigEndian_); + unsigned int eventY = GetUINT(inputMessage + 26, bigEndian_); + eventX -= rootX; + eventY -= rootY; + encodeBuffer.encodeCachedValue(rootX - + serverCache_ -> motionNotifyLastRootX, 16, + serverCache_ -> motionNotifyRootXCache, 6); + serverCache_ -> motionNotifyLastRootX = rootX; + encodeBuffer.encodeCachedValue(rootY - + serverCache_ -> motionNotifyLastRootY, 16, + serverCache_ -> motionNotifyRootYCache, 6); + serverCache_ -> motionNotifyLastRootY = rootY; + encodeBuffer.encodeCachedValue(eventX, 16, + serverCache_ -> motionNotifyEventXCache, 6); + encodeBuffer.encodeCachedValue(eventY, 16, + serverCache_ -> motionNotifyEventYCache, 6); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 28, bigEndian_), + 16, serverCache_ -> motionNotifyStateCache); + if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify)) + encodeBuffer.encodeValue((unsigned int) inputMessage[30], 2); + else + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[30]); + if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify)) + encodeBuffer.encodeValue((unsigned int) inputMessage[31], 2); + else if (*inputMessage == KeyPress) + { + serverCache_ -> keyPressLastKey = detail; + for (unsigned int i = 8; i < 31; i++) + { + serverCache_ -> keyPressCache[i - 8] = inputMessage[i]; + } + } + } + } + break; + case ColormapNotify: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, serverCache_ -> colormapNotifyWindowCache, 8); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> colormapNotifyColormapCache, 8); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[12]); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[13]); + } + break; + case ConfigureNotify: + { + const unsigned char *nextSrc = inputMessage + 4; + for (unsigned int i = 0; i < 3; i++) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29, + *serverCache_ -> configureNotifyWindowCache[i], 9); + nextSrc += 4; + } + for (unsigned int j = 0; j < 5; j++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *serverCache_ -> configureNotifyGeomCache[j], 8); + nextSrc += 2; + } + encodeBuffer.encodeBoolValue(*nextSrc); + } + break; + case CreateNotify: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, serverCache_ -> createNotifyWindowCache, 9); + unsigned int window = GetULONG(inputMessage + 8, bigEndian_); + encodeBuffer.encodeValue(window - + serverCache_ -> createNotifyLastWindow, 29, 5); + serverCache_ -> createNotifyLastWindow = window; + const unsigned char* nextSrc = inputMessage + 12; + for (unsigned int i = 0; i < 5; i++) + { + encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16, 9); + nextSrc += 2; + } + encodeBuffer.encodeBoolValue(*nextSrc); + } + break; + case Expose: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29, + serverCache_ -> exposeWindowCache, 9); + const unsigned char *nextSrc = inputMessage + 8; + for (unsigned int i = 0; i < 5; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16, + *serverCache_ -> exposeGeomCache[i], 6); + nextSrc += 2; + } + } + break; + case FocusIn: + case FocusOut: + { + encodeBuffer.encodeValue((unsigned int) inputMessage[1], 3); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, serverCache_ -> focusInWindowCache, 9); + encodeBuffer.encodeValue((unsigned int) inputMessage[8], 2); + } + break; + case KeymapNotify: + { + if (ServerCache::lastKeymap.compare(31, inputMessage + 1)) + encodeBuffer.encodeBoolValue(1); + else + { + encodeBuffer.encodeBoolValue(0); + const unsigned char *nextSrc = inputMessage + 1; + for (unsigned int i = 1; i < 32; i++) + encodeBuffer.encodeValue((unsigned int) *nextSrc++, 8); + } + } + break; + case MapNotify: + case UnmapNotify: + case DestroyNotify: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, serverCache_ -> mapNotifyEventCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> mapNotifyWindowCache, 9); + if ((*inputMessage == MapNotify) || (*inputMessage == UnmapNotify)) + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[12]); + } + break; + case NoExpose: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, serverCache_ -> noExposeDrawableCache, 9); + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16, + serverCache_ -> noExposeMinorCache); + encodeBuffer.encodeCachedValue(inputMessage[10], 8, + serverCache_ -> noExposeMajorCache); + } + break; + case PropertyNotify: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, serverCache_ -> propertyNotifyWindowCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> propertyNotifyAtomCache, 9); + unsigned int timestamp = GetULONG(inputMessage + 12, bigEndian_); + unsigned int timestampDiff = + timestamp - serverCache_ -> lastTimestamp; + serverCache_ -> lastTimestamp = timestamp; + encodeBuffer.encodeValue(timestampDiff, 32, 9); + encodeBuffer.encodeBoolValue((unsigned int) inputMessage[16]); + } + break; + case ReparentNotify: + { + const unsigned char* nextSrc = inputMessage + 4; + for (unsigned int i = 0; i < 3; i++) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), + 29, serverCache_ -> reparentNotifyWindowCache, 9); + nextSrc += 4; + } + encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16, 6); + encodeBuffer.encodeValue(GetUINT(nextSrc + 2, bigEndian_), 16, 6); + encodeBuffer.encodeBoolValue((unsigned int)inputMessage[20]); + } + break; + case SelectionClear: + { + unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_); + unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp; + serverCache_ -> lastTimestamp = timestamp; + encodeBuffer.encodeValue(timestampDiff, 32, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> selectionClearWindowCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), + 29, serverCache_ -> selectionClearAtomCache, 9); + } + break; + case SelectionRequest: + { + unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_); + unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp; + serverCache_ -> lastTimestamp = timestamp; + encodeBuffer.encodeValue(timestampDiff, 32, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), + 29, serverCache_ -> selectionClearWindowCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), + 29, serverCache_ -> selectionClearWindowCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_), + 29, serverCache_ -> selectionClearAtomCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 20, bigEndian_), + 29, serverCache_ -> selectionClearAtomCache, 9); + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 24, bigEndian_), + 29, serverCache_ -> selectionClearAtomCache, 9); + } + break; + case VisibilityNotify: + { + encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), + 29, serverCache_ -> visibilityNotifyWindowCache, 9); + encodeBuffer.encodeValue((unsigned int) inputMessage[8], 2); + } + break; + default: + { + #ifdef TEST + *logofs << "handleRead: Using generic event compression " + << "for OPCODE#" << (unsigned int) inputOpcode + << ".\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(*(inputMessage + 1), 8, + serverCache_ -> genericEventCharCache); + + for (unsigned int i = 0; i < 14; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(inputMessage + i * 2 + 4, bigEndian_), + 16, *serverCache_ -> genericEventIntCache[i]); + } + } + + } // switch (inputOpcode)... + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + + if (*inputMessage == X_Error) + { + unsigned char code = *(inputMessage + 1); + + *logofs << "handleRead: Handled error ERR_CODE#" + << (unsigned int) code << " for FD#" << fd_; + + *logofs << " RES_ID#" << GetULONG(inputMessage + 4, bigEndian_); + + *logofs << " MIN_OP#" << GetUINT(inputMessage + 8, bigEndian_); + + *logofs << " MAJ_OP#" << (unsigned int) *(inputMessage + 10); + + *logofs << " sequence " << inputSequence << ". " << inputLength + << " bytes in, " << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + } + else + { + *logofs << "handleRead: Handled event OPCODE#" + << (unsigned int) *inputMessage << " for FD#" << fd_ + << " sequence " << inputSequence << ". " << inputLength + << " bytes in, " << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + } + + #endif + + statistics -> addEventBits(*inputMessage, inputLength << 3, bits); + + } // End of if (inputMessage[0] == X_Reply) ... else ... + + } // End of if (firstReply_) ... else ... + + } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != 0) ... + + // + // Check if we need to flush because of + // prioritized data. + // + + if (priority_ > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: WARNING! Requesting flush " + << "because of " << priority_ << " prioritized " + << "messages for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + if (proxy -> handleAsyncPriority() < 0) + { + return -1; + } + + // + // Reset the priority flag. + // + + priority_ = 0; + } + + // + // Flush if we produced enough data. + // + + if (proxy -> canAsyncFlush() == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleRead: WARNING! Requesting flush " + << "because of token length exceeded.\n" + << logofs_flush; + #endif + + if (proxy -> handleAsyncFlush() < 0) + { + return -1; + } + } + + #if defined(TEST) || defined(INFO) + + if (transport_ -> pending() != 0 || + readBuffer_.checkMessage() != 0) + { + *logofs << "handleRead: PANIC! Buffer for X descriptor FD#" + << fd_ << " has " << transport_ -> pending() + << " bytes to read.\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + // + // Reset the read buffer. + // + + readBuffer_.fullReset(); + + return 1; +} + +// +// End of handleRead(). +// + +// +// Beginning of handleWrite(). +// + +int ServerChannel::handleWrite(const unsigned char *message, unsigned int length) +{ + #ifdef TEST + *logofs << "handleWrite: Called for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + // + // Create the buffer from which to + // decode messages. + // + + DecodeBuffer decodeBuffer(message, length); + + #if defined(TEST) || defined(INFO) || defined(FLUSH) + *logofs << "handleWrite: Decoding messages for FD#" << fd_ + << " with " << length << " bytes in the buffer.\n" + << logofs_flush; + #endif + + if (firstRequest_) + { + // + // Need to add the length of the first request + // because it was not present in the previous + // versions. Length of the first request was + // assumed to be the same as the encode buffer + // but this may be not the case if a different + // encoding is used. + // + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeValue(length, 8); + + unsigned int nextByte; + unsigned char *outputMessage = writeBuffer_.addMessage(length); + unsigned char *nextDest = outputMessage; + + for (unsigned int i = 0; i < length; i++) + { + decodeBuffer.decodeValue(nextByte, 8); + + *nextDest++ = (unsigned char) nextByte; + } + + if (*outputMessage == 0x42) + { + setBigEndian(1); + } + else + { + setBigEndian(0); + } + + #ifdef TEST + *logofs << "handleWrite: First request detected.\n" << logofs_flush; + #endif + + // + // Handle the fake authorization cookie. + // + + if (handleAuthorization(outputMessage) < 0) + { + return -1; + } + + firstRequest_ = 0; + + } // End of if (firstRequest_) + + // + // This was previously in a 'else' block. + // Due to the way the first request was + // handled, we could not decode multiple + // messages in the first frame. + // + + { // Start of the decoding block. + + unsigned char outputOpcode; + + unsigned char *outputMessage; + unsigned int outputLength; + + // + // Set when message is found in cache. + // + + int hit; + + while (decodeBuffer.decodeOpcodeValue(outputOpcode, clientCache_ -> opcodeCache, 1)) + { + hit = 0; + + // + // Splits are sent by client proxy outside the + // normal read loop. As we 'insert' splits in + // the real client-server X protocol, we must + // avoid to increment the sequence number or + // our clients would get confused. + // + + if (outputOpcode != opcodeStore_ -> splitData) + { + clientSequence_++; + clientSequence_ &= 0xffff; + + #ifdef DEBUG + *logofs << "handleWrite: Last client sequence number for FD#" + << fd_ << " is " << clientSequence_ << ".\n" + << logofs_flush; + #endif + } + else + { + // + // It's a split, not a normal + // burst of proxy data. + // + + handleSplit(decodeBuffer); + + continue; + } + + #ifdef SUSPEND + + if (clientSequence_ == 1000) + { + cerr << "Warning" << ": Exiting to test the resilience of the agent.\n"; + + sleep(2); + + HandleAbort(); + } + + #endif + + // + // Is differential encoding disabled? + // + + if (control -> RemoteDeltaCompression == 0) + { + int result = handleFastWriteRequest(decodeBuffer, outputOpcode, + outputMessage, outputLength); + if (result < 0) + { + return -1; + } + else if (result > 0) + { + continue; + } + } + + // + // General-purpose temp variables for + // decoding ints and chars. + // + + unsigned int value; + unsigned char cValue; + + #ifdef DEBUG + *logofs << "handleWrite: Going to handle request OPCODE#" + << (unsigned int) outputOpcode << " (" << DumpOpcode(outputOpcode) + << ") for FD#" << fd_ << " sequence " << clientSequence_ + << ".\n" << logofs_flush; + #endif + + switch (outputOpcode) + { + case X_AllocColor: + { + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> colormapCache); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned char *nextDest = outputMessage + 8; + unsigned int colorData[3]; + + for (unsigned int i = 0; i < 3; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *(clientCache_ -> allocColorRGBCache[i]), 4); + PutUINT(value, nextDest, bigEndian_); + colorData[i] = value; + nextDest += 2; + } + + sequenceQueue_.push(clientSequence_, outputOpcode, + colorData[0], colorData[1], colorData[2]); + } + break; + case X_ReparentWindow: + { + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeValue(value, 16, 11); + PutUINT(value, outputMessage + 12, bigEndian_); + decodeBuffer.decodeValue(value, 16, 11); + PutUINT(value, outputMessage + 14, bigEndian_); + } + break; + case X_ChangeProperty: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ChangeProperty); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + unsigned char format; + decodeBuffer.decodeCachedValue(format, 8, + clientCache_ -> changePropertyFormatCache); + unsigned int dataLength; + decodeBuffer.decodeValue(dataLength, 32, 6); + outputLength = 24 + RoundUp4(dataLength * (format >> 3)); + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 2); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> changePropertyPropertyCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> changePropertyTypeCache, 9); + PutULONG(value, outputMessage + 12, bigEndian_); + outputMessage[16] = format; + PutULONG(dataLength, outputMessage + 20, bigEndian_); + unsigned char *nextDest = outputMessage + 24; + + if (format == 8) + { + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, dataLength); + } + else if (format == 32) + { + for (unsigned int i = 0; i < dataLength; i++) + { + decodeBuffer.decodeCachedValue(value, 32, + clientCache_ -> changePropertyData32Cache); + + PutULONG(value, nextDest, bigEndian_); + + nextDest += 4; + } + } + else + { + for (unsigned int i = 0; i < dataLength; i++) + { + decodeBuffer.decodeValue(value, 16); + + PutUINT(value, nextDest, bigEndian_); + + nextDest += 2; + } + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_SendEvent: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_SendEvent); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 44; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeBoolValue(value); + *(outputMessage + 1) = value; + decodeBuffer.decodeBoolValue(value); + if (value) + { + decodeBuffer.decodeBoolValue(value); + } + else + { + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + } + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 32, + clientCache_ -> sendEventMaskCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(*(outputMessage + 12), 8, + clientCache_ -> sendEventCodeCache); + decodeBuffer.decodeCachedValue(*(outputMessage + 13), 8, + clientCache_ -> sendEventByteDataCache); + decodeBuffer.decodeValue(value, 16, 4); + clientCache_ -> sendEventLastSequence += value; + clientCache_ -> sendEventLastSequence &= 0xffff; + PutUINT(clientCache_ -> sendEventLastSequence, outputMessage + 14, bigEndian_); + decodeBuffer.decodeCachedValue(value, 32, + clientCache_ -> sendEventIntDataCache); + PutULONG(value, outputMessage + 16, bigEndian_); + + for (unsigned int i = 20; i < 44; i++) + { + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache_ -> sendEventEventCache); + *(outputMessage + i) = cValue; + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_ChangeWindowAttributes: + { + unsigned int numAttrs; + decodeBuffer.decodeValue(numAttrs, 4); + outputLength = 12 + (numAttrs << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned int bitmask; + decodeBuffer.decodeCachedValue(bitmask, 15, + clientCache_ -> createWindowBitmaskCache); + PutULONG(bitmask, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + unsigned int mask = 0x1; + for (unsigned int i = 0; i < 15; i++) + { + if (bitmask & mask) + { + decodeBuffer.decodeCachedValue(value, 32, + *clientCache_ -> createWindowAttrCache[i]); + PutULONG(value, nextDest, bigEndian_); + nextDest += 4; + } + mask <<= 1; + } + } + break; + case X_ClearArea: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ClearArea); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeBoolValue(value); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned char *nextDest = outputMessage + 8; + for (unsigned int i = 0; i < 4; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> clearAreaGeomCache[i], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_CloseFont: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 29, 5); + clientCache_ -> lastFont += value; + clientCache_ -> lastFont &= 0x1fffffff; + PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_); + } + break; + case X_ConfigureWindow: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ConfigureWindow); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 12; + outputMessage = writeBuffer_.addMessage(outputLength); + writeBuffer_.registerPointer(&outputMessage); + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned int bitmask; + decodeBuffer.decodeCachedValue(bitmask, 7, + clientCache_ -> configureWindowBitmaskCache); + PutUINT(bitmask, outputMessage + 8, bigEndian_); + unsigned int mask = 0x1; + for (unsigned int i = 0; i < 7; i++) + { + if (bitmask & mask) + { + unsigned char* nextDest = writeBuffer_.addMessage(4); + outputLength += 4; + decodeBuffer.decodeCachedValue(value, CONFIGUREWINDOW_FIELD_WIDTH[i], + *clientCache_ -> configureWindowAttrCache[i], 8); + PutULONG(value, nextDest, bigEndian_); + nextDest += 4; + } + mask <<= 1; + } + writeBuffer_.unregisterPointer(); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_ConvertSelection: + { + outputLength = 24; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> convertSelectionRequestorCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned char* nextDest = outputMessage + 8; + for (unsigned int i = 0; i < 3; i++) + { + decodeBuffer.decodeCachedValue(value, 29, + *(clientCache_ -> convertSelectionAtomCache[i]), 9); + PutULONG(value, nextDest, bigEndian_); + nextDest += 4; + } + decodeBuffer.decodeValue(value, 32, 4); + clientCache_ -> convertSelectionLastTimestamp += value; + PutULONG(clientCache_ -> convertSelectionLastTimestamp, + nextDest, bigEndian_); + } + break; + case X_CopyArea: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_CopyArea); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 28; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 12, bigEndian_); + unsigned char *nextDest = outputMessage + 16; + for (unsigned int i = 0; i < 6; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> copyAreaGeomCache[i], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_CopyGC: + { + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 23, + clientCache_ -> createGCBitmaskCache); + PutULONG(value, outputMessage + 12, bigEndian_); + } + break; + case X_CopyPlane: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 12, bigEndian_); + unsigned char *nextDest = outputMessage + 16; + for (unsigned int i = 0; i < 6; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> copyPlaneGeomCache[i], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + decodeBuffer.decodeCachedValue(value, 32, + clientCache_ -> copyPlaneBitPlaneCache, 10); + PutULONG(value, outputMessage + 28, bigEndian_); + } + break; + case X_CreateGC: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_CreateGC); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + writeBuffer_.registerPointer(&outputMessage); + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeNewXidValue(value, clientCache_ -> lastId, + clientCache_ -> lastIdCache, clientCache_ -> gcCache, + clientCache_ -> freeGCCache); + + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned int offset = 8; + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + offset, bigEndian_); + offset += 4; + unsigned int bitmask; + decodeBuffer.decodeCachedValue(bitmask, 23, + clientCache_ -> createGCBitmaskCache); + PutULONG(bitmask, outputMessage + offset, bigEndian_); + unsigned int mask = 0x1; + for (unsigned int i = 0; i < 23; i++) + { + if (bitmask & mask) + { + unsigned char* nextDest = writeBuffer_.addMessage(4); + outputLength += 4; + unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i]; + if (fieldWidth <= 4) + decodeBuffer.decodeValue(value, fieldWidth); + else + decodeBuffer.decodeCachedValue(value, fieldWidth, + *clientCache_ -> createGCAttrCache[i]); + PutULONG(value, nextDest, bigEndian_); + } + mask <<= 1; + } + writeBuffer_.unregisterPointer(); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_ChangeGC: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ChangeGC); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 12; + outputMessage = writeBuffer_.addMessage(outputLength); + writeBuffer_.registerPointer(&outputMessage); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned int offset = 8; + unsigned int bitmask; + decodeBuffer.decodeCachedValue(bitmask, 23, + clientCache_ -> createGCBitmaskCache); + PutULONG(bitmask, outputMessage + offset, bigEndian_); + unsigned int mask = 0x1; + for (unsigned int i = 0; i < 23; i++) + { + if (bitmask & mask) + { + unsigned char* nextDest = writeBuffer_.addMessage(4); + outputLength += 4; + unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i]; + if (fieldWidth <= 4) + decodeBuffer.decodeValue(value, fieldWidth); + else + decodeBuffer.decodeCachedValue(value, fieldWidth, + *clientCache_ -> createGCAttrCache[i]); + PutULONG(value, nextDest, bigEndian_); + } + mask <<= 1; + } + writeBuffer_.unregisterPointer(); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_CreatePixmap: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_CreatePixmap); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + } + break; + case X_CreateWindow: + { + outputLength = 32; + outputMessage = writeBuffer_.addMessage(outputLength); + writeBuffer_.registerPointer(&outputMessage); + decodeBuffer.decodeCachedValue(cValue, 8, clientCache_ -> depthCache); + outputMessage[1] = cValue; + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 8, bigEndian_); + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeNewXidValue(value, clientCache_ -> lastId, + clientCache_ -> lastIdCache, clientCache_ -> windowCache, + clientCache_ -> freeWindowCache); + + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + unsigned int i; + for (i = 0; i < 6; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> createWindowGeomCache[i], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> visualCache); + PutULONG(value, outputMessage + 24, bigEndian_); + unsigned int bitmask; + decodeBuffer.decodeCachedValue(bitmask, 15, + clientCache_ -> createWindowBitmaskCache); + PutULONG(bitmask, outputMessage + 28, bigEndian_); + unsigned int mask = 0x1; + for (i = 0; i < 15; i++) + { + if (bitmask & mask) + { + nextDest = writeBuffer_.addMessage(4); + outputLength += 4; + decodeBuffer.decodeCachedValue(value, 32, + *clientCache_ -> createWindowAttrCache[i]); + PutULONG(value, nextDest, bigEndian_); + } + mask <<= 1; + } + writeBuffer_.unregisterPointer(); + } + break; + case X_DeleteProperty: + { + outputLength = 12; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeValue(value, 29, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + } + break; + case X_FillPoly: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_FillPoly); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + unsigned int numPoints; + + // Since ProtoStep10 (#issue 108) + decodeBuffer.decodeCachedValue(numPoints, 16, + clientCache_ -> fillPolyNumPointsCache, 4); + + outputLength = 16 + (numPoints << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeValue(value, 2); + outputMessage[12] = (unsigned char) value; + unsigned int relativeCoordMode; + decodeBuffer.decodeBoolValue(relativeCoordMode); + outputMessage[13] = (unsigned char) relativeCoordMode; + unsigned char *nextDest = outputMessage + 16; + unsigned int pointIndex = 0; + for (unsigned int i = 0; i < numPoints; i++) + { + if (relativeCoordMode) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> fillPolyXRelCache[pointIndex], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> fillPolyYRelCache[pointIndex], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + else + { + unsigned int x, y; + decodeBuffer.decodeBoolValue(value); + if (value) + { + decodeBuffer.decodeValue(value, 3); + x = clientCache_ -> fillPolyRecentX[value]; + y = clientCache_ -> fillPolyRecentY[value]; + } + else + { + decodeBuffer.decodeCachedValue(x, 16, + *clientCache_ -> fillPolyXAbsCache[pointIndex], 8); + decodeBuffer.decodeCachedValue(y, 16, + *clientCache_ -> fillPolyYAbsCache[pointIndex], 8); + clientCache_ -> fillPolyRecentX[clientCache_ -> fillPolyIndex] = x; + clientCache_ -> fillPolyRecentY[clientCache_ -> fillPolyIndex] = y; + clientCache_ -> fillPolyIndex++; + if (clientCache_ -> fillPolyIndex == 8) + clientCache_ -> fillPolyIndex = 0; + } + PutUINT(x, nextDest, bigEndian_); + nextDest += 2; + PutUINT(y, nextDest, bigEndian_); + nextDest += 2; + } + + if (++pointIndex == 10) pointIndex = 0; + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_FreeColors: + { + unsigned int numPixels; + decodeBuffer.decodeValue(numPixels, 16, 4); + outputLength = 12 + (numPixels << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> colormapCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeValue(value, 32, 4); + PutULONG(value, outputMessage + 8, bigEndian_); + unsigned char* nextDest = outputMessage + 12; + while (numPixels) + { + decodeBuffer.decodeValue(value, 32, 8); + PutULONG(value, nextDest, bigEndian_); + nextDest += 4; + numPixels--; + } + } + break; + case X_FreeCursor: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> cursorCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + } + break; + case X_FreeGC: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeGCCache); + + PutULONG(value, outputMessage + 4, bigEndian_); + } + break; + case X_FreePixmap: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeDrawableCache); + + PutULONG(value, outputMessage + 4, bigEndian_); + } + break; + case X_GetAtomName: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 29, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_GetGeometry: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_GetInputFocus: + { + outputLength = 4; + outputMessage = writeBuffer_.addMessage(outputLength); + + sequenceQueue_.push(clientSequence_, outputOpcode, outputOpcode); + } + break; + case X_GetModifierMapping: + { + outputLength = 4; + outputMessage = writeBuffer_.addMessage(outputLength); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_GetKeyboardMapping: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 8); + outputMessage[4] = value; + decodeBuffer.decodeValue(value, 8); + outputMessage[5] = value; + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_GetProperty: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_GetProperty); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + // + // Save a reference to identify the reply. + // + + unsigned int property = GetULONG(outputMessage + 8, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode, property); + + break; + } + + outputLength = 24; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeBoolValue(value); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned int property; + decodeBuffer.decodeValue(property, 29, 9); + PutULONG(property, outputMessage + 8, bigEndian_); + decodeBuffer.decodeValue(value, 29, 9); + PutULONG(value, outputMessage + 12, bigEndian_); + decodeBuffer.decodeValue(value, 32, 2); + PutULONG(value, outputMessage + 16, bigEndian_); + decodeBuffer.decodeValue(value, 32, 8); + PutULONG(value, outputMessage + 20, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode, property); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_GetSelectionOwner: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> getSelectionOwnerSelectionCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_GrabButton: + case X_GrabPointer: + { + outputLength = 24; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeBoolValue(value); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> grabButtonEventMaskCache); + PutUINT(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeBoolValue(value); + outputMessage[10] = (unsigned char) value; + decodeBuffer.decodeBoolValue(value); + outputMessage[11] = (unsigned char) value; + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> grabButtonConfineCache, 9); + PutULONG(value, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> cursorCache, 9); + PutULONG(value, outputMessage + 16, bigEndian_); + if (outputOpcode == X_GrabButton) + { + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache_ -> grabButtonButtonCache); + outputMessage[20] = cValue; + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> grabButtonModifierCache); + PutUINT(value, outputMessage + 22, bigEndian_); + } + else + { + decodeBuffer.decodeValue(value, 32, 4); + clientCache_ -> grabKeyboardLastTimestamp += value; + PutULONG(clientCache_ -> grabKeyboardLastTimestamp, + outputMessage + 20, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + } + break; + case X_GrabKeyboard: + { + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeBoolValue(value); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeValue(value, 32, 4); + clientCache_ -> grabKeyboardLastTimestamp += value; + PutULONG(clientCache_ -> grabKeyboardLastTimestamp, outputMessage + 8, + bigEndian_); + decodeBuffer.decodeBoolValue(value); + outputMessage[12] = (unsigned char) value; + decodeBuffer.decodeBoolValue(value); + outputMessage[13] = (unsigned char) value; + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_GrabServer: + case X_UngrabServer: + case X_NoOperation: + { + #ifdef DEBUG + *logofs << "handleWrite: Managing (probably tainted) X_NoOperation request for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + outputLength = 4; + outputMessage = writeBuffer_.addMessage(outputLength); + } + break; + case X_PolyText8: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyText8); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> polyTextCacheX); + clientCache_ -> polyTextLastX += value; + clientCache_ -> polyTextLastX &= 0xffff; + PutUINT(clientCache_ -> polyTextLastX, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> polyTextCacheY); + clientCache_ -> polyTextLastY += value; + clientCache_ -> polyTextLastY &= 0xffff; + PutUINT(clientCache_ -> polyTextLastY, outputMessage + 14, bigEndian_); + unsigned int addedLength = 0; + writeBuffer_.registerPointer(&outputMessage); + for (;;) + { + decodeBuffer.decodeBoolValue(value); + if (!value) + break; + unsigned int textLength; + decodeBuffer.decodeValue(textLength, 8); + if (textLength == 255) + { + addedLength += 5; + unsigned char *nextSegment = writeBuffer_.addMessage(5); + *nextSegment = (unsigned char) textLength; + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> polyTextFontCache); + PutULONG(value, nextSegment + 1, 1); + } + else + { + addedLength += (textLength + 2); + unsigned char *nextSegment = + writeBuffer_.addMessage(textLength + 2); + *nextSegment = (unsigned char) textLength; + unsigned char *nextDest = nextSegment + 1; + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache_ -> polyTextDeltaCache); + *nextDest++ = cValue; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, textLength); + + nextDest += textLength; + } + } + outputLength += addedLength; + unsigned int mod4 = (addedLength & 0x3); + if (mod4) + { + unsigned int extra = 4 - mod4; + unsigned char *nextDest = writeBuffer_.addMessage(extra); + for (unsigned int i = 0; i < extra; i++) + *nextDest++ = 0; + outputLength += extra; + } + writeBuffer_.unregisterPointer(); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_PolyText16: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyText16); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> polyTextCacheX); + clientCache_ -> polyTextLastX += value; + clientCache_ -> polyTextLastX &= 0xffff; + PutUINT(clientCache_ -> polyTextLastX, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> polyTextCacheY); + clientCache_ -> polyTextLastY += value; + clientCache_ -> polyTextLastY &= 0xffff; + PutUINT(clientCache_ -> polyTextLastY, outputMessage + 14, bigEndian_); + unsigned int addedLength = 0; + writeBuffer_.registerPointer(&outputMessage); + for (;;) + { + decodeBuffer.decodeBoolValue(value); + if (!value) + break; + unsigned int textLength; + decodeBuffer.decodeValue(textLength, 8); + if (textLength == 255) + { + addedLength += 5; + unsigned char *nextSegment = writeBuffer_.addMessage(5); + *nextSegment = (unsigned char) textLength; + decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> polyTextFontCache); + PutULONG(value, nextSegment + 1, 1); + } + else + { + addedLength += (textLength * 2 + 2); + unsigned char *nextSegment = + writeBuffer_.addMessage(textLength * 2 + 2); + *nextSegment = (unsigned char) textLength; + unsigned char *nextDest = nextSegment + 1; + decodeBuffer.decodeCachedValue(cValue, 8, clientCache_ -> polyTextDeltaCache); + *nextDest++ = cValue; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, textLength * 2); + + nextDest += textLength * 2; + } + } + outputLength += addedLength; + + unsigned int mod4 = (addedLength & 0x3); + if (mod4) + { + unsigned int extra = 4 - mod4; + unsigned char *nextDest = writeBuffer_.addMessage(extra); + for (unsigned int i = 0; i < extra; i++) + *nextDest++ = 0; + outputLength += extra; + } + writeBuffer_.unregisterPointer(); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_ImageText8: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ImageText8); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + unsigned int textLength; + decodeBuffer.decodeCachedValue(textLength, 8, + clientCache_ -> imageTextLengthCache, 4); + outputLength = 16 + RoundUp4(textLength); + outputMessage = writeBuffer_.addMessage(outputLength); + outputMessage[1] = (unsigned char) textLength; + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> imageTextCacheX); + clientCache_ -> imageTextLastX += value; + clientCache_ -> imageTextLastX &= 0xffff; + PutUINT(clientCache_ -> imageTextLastX, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> imageTextCacheY); + clientCache_ -> imageTextLastY += value; + clientCache_ -> imageTextLastY &= 0xffff; + PutUINT(clientCache_ -> imageTextLastY, outputMessage + 14, bigEndian_); + unsigned char *nextDest = outputMessage + 16; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, textLength); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_ImageText16: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_ImageText16); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + unsigned int textLength; + decodeBuffer.decodeCachedValue(textLength, 8, + clientCache_ -> imageTextLengthCache, 4); + outputLength = 16 + RoundUp4(textLength * 2); + outputMessage = writeBuffer_.addMessage(outputLength); + outputMessage[1] = (unsigned char) textLength; + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> imageTextCacheX); + clientCache_ -> imageTextLastX += value; + clientCache_ -> imageTextLastX &= 0xffff; + PutUINT(clientCache_ -> imageTextLastX, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> imageTextCacheY); + clientCache_ -> imageTextLastY += value; + clientCache_ -> imageTextLastY &= 0xffff; + PutUINT(clientCache_ -> imageTextLastY, outputMessage + 14, bigEndian_); + unsigned char *nextDest = outputMessage + 16; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, textLength * 2); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_InternAtom: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_InternAtom); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + sequenceQueue_.push(clientSequence_, outputOpcode); + + break; + } + + unsigned int nameLength; + decodeBuffer.decodeValue(nameLength, 16, 6); + outputLength = RoundUp4(nameLength) + 8; + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(nameLength, outputMessage + 4, bigEndian_); + decodeBuffer.decodeBoolValue(value); + outputMessage[1] = (unsigned char) value; + unsigned char *nextDest = outputMessage + 8; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, nameLength); + + sequenceQueue_.push(clientSequence_, outputOpcode); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_ListExtensions: + { + outputLength = 4; + outputMessage = writeBuffer_.addMessage(outputLength); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_ListFonts: + { + unsigned int textLength; + decodeBuffer.decodeValue(textLength, 16, 6); + outputLength = 8 + RoundUp4(textLength); + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(textLength, outputMessage + 6, bigEndian_); + decodeBuffer.decodeValue(value, 16, 6); + PutUINT(value, outputMessage + 4, bigEndian_); + unsigned char* nextDest = outputMessage + 8; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, textLength); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_LookupColor: + case X_AllocNamedColor: + { + unsigned int textLength; + decodeBuffer.decodeValue(textLength, 16, 6); + outputLength = 12 + RoundUp4(textLength); + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> colormapCache); + PutULONG(value, outputMessage + 4, bigEndian_); + PutUINT(textLength, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, textLength); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_MapWindow: + case X_UnmapWindow: + case X_MapSubwindows: + case X_GetWindowAttributes: + case X_DestroyWindow: + case X_DestroySubwindows: + case X_QueryPointer: + case X_QueryTree: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + + if (outputOpcode == X_DestroyWindow) // Since ProtoStep7 (#issue 108) + { + decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeWindowCache); + } + else + { + decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache); + } + + PutULONG(value, outputMessage + 4, bigEndian_); + if (outputOpcode == X_QueryPointer || + outputOpcode == X_GetWindowAttributes || + outputOpcode == X_QueryTree) + { + sequenceQueue_.push(clientSequence_, outputOpcode); + } + } + break; + case X_OpenFont: + { + unsigned int nameLength; + decodeBuffer.decodeValue(nameLength, 16, 7); + outputLength = RoundUp4(12 + nameLength); + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(nameLength, outputMessage + 8, bigEndian_); + decodeBuffer.decodeValue(value, 29, 5); + clientCache_ -> lastFont += value; + clientCache_ -> lastFont &= 0x1fffffff; + PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeTextData(nextDest, nameLength); + } + break; + case X_PolyFillRectangle: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyFillRectangle); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 12; + outputMessage = writeBuffer_.addMessage(outputLength); + writeBuffer_.registerPointer(&outputMessage); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0, lastWidth = 0, lastHeight = 0; + unsigned int numRectangles = 0; + + for (;;) + { + outputLength += 8; + writeBuffer_.addMessage(8); + unsigned char *nextDest = outputMessage + 12 + + (numRectangles << 3); + numRectangles++; + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillRectangleCacheX[index], 8); + value += lastX; + PutUINT(value, nextDest, bigEndian_); + lastX = value; + nextDest += 2; + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillRectangleCacheY[index], 8); + value += lastY; + PutUINT(value, nextDest, bigEndian_); + lastY = value; + nextDest += 2; + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillRectangleCacheWidth[index], 8); + value += lastWidth; + PutUINT(value, nextDest, bigEndian_); + lastWidth = value; + nextDest += 2; + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillRectangleCacheHeight[index], 8); + value += lastHeight; + PutUINT(value, nextDest, bigEndian_); + lastHeight = value; + nextDest += 2; + + if (++index == 4) index = 0; + + decodeBuffer.decodeBoolValue(value); + + if (!value) break; + } + writeBuffer_.unregisterPointer(); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_PolyFillArc: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyFillArc); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 12; + outputMessage = writeBuffer_.addMessage(outputLength); + writeBuffer_.registerPointer(&outputMessage); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0, + lastWidth = 0, lastHeight = 0, + lastAngle1 = 0, lastAngle2 = 0; + + unsigned int numArcs = 0; + + for (;;) + { + outputLength += 12; + writeBuffer_.addMessage(12); + + unsigned char *nextDest = outputMessage + 12 + + (numArcs * 12); + numArcs++; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillArcCacheX[index], 8); + value += lastX; + PutUINT(value, nextDest, bigEndian_); + lastX = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillArcCacheY[index], 8); + value += lastY; + PutUINT(value, nextDest, bigEndian_); + lastY = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillArcCacheWidth[index], 8); + value += lastWidth; + PutUINT(value, nextDest, bigEndian_); + lastWidth = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillArcCacheHeight[index], 8); + value += lastHeight; + PutUINT(value, nextDest, bigEndian_); + lastHeight = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillArcCacheAngle1[index], 8); + value += lastAngle1; + PutUINT(value, nextDest, bigEndian_); + lastAngle1 = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyFillArcCacheAngle2[index], 8); + value += lastAngle2; + PutUINT(value, nextDest, bigEndian_); + lastAngle2 = value; + nextDest += 2; + + if (++index == 2) index = 0; + + decodeBuffer.decodeBoolValue(value); + + if (!value) break; + } + writeBuffer_.unregisterPointer(); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_PolyArc: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyArc); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + outputLength = 12; + outputMessage = writeBuffer_.addMessage(outputLength); + writeBuffer_.registerPointer(&outputMessage); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0, + lastWidth = 0, lastHeight = 0, + lastAngle1 = 0, lastAngle2 = 0; + + unsigned int numArcs = 0; + + for (;;) + { + outputLength += 12; + writeBuffer_.addMessage(12); + + unsigned char *nextDest = outputMessage + 12 + + (numArcs * 12); + numArcs++; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyArcCacheX[index], 8); + value += lastX; + PutUINT(value, nextDest, bigEndian_); + lastX = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyArcCacheY[index], 8); + value += lastY; + PutUINT(value, nextDest, bigEndian_); + lastY = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyArcCacheWidth[index], 8); + value += lastWidth; + PutUINT(value, nextDest, bigEndian_); + lastWidth = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyArcCacheHeight[index], 8); + value += lastHeight; + PutUINT(value, nextDest, bigEndian_); + lastHeight = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyArcCacheAngle1[index], 8); + value += lastAngle1; + PutUINT(value, nextDest, bigEndian_); + lastAngle1 = value; + nextDest += 2; + + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyArcCacheAngle2[index], 8); + value += lastAngle2; + PutUINT(value, nextDest, bigEndian_); + lastAngle2 = value; + nextDest += 2; + + if (++index == 2) index = 0; + + decodeBuffer.decodeBoolValue(value); + + if (!value) break; + } + writeBuffer_.unregisterPointer(); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_PolyPoint: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyPoint); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + unsigned int numPoints; + decodeBuffer.decodeValue(numPoints, 16, 4); + outputLength = (numPoints << 2) + 12; + outputMessage = writeBuffer_.addMessage(outputLength); + unsigned int relativeCoordMode; + decodeBuffer.decodeBoolValue(relativeCoordMode); + outputMessage[1] = (unsigned char) relativeCoordMode; + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0; + + for (unsigned int i = 0; i < numPoints; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyPointCacheX[index], 8); + lastX += value; + PutUINT(lastX, nextDest, bigEndian_); + nextDest += 2; + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyPointCacheY[index], 8); + lastY += value; + PutUINT(lastY, nextDest, bigEndian_); + nextDest += 2; + + if (++index == 2) index = 0; + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_PolyLine: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolyLine); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + unsigned int numPoints; + decodeBuffer.decodeValue(numPoints, 16, 4); + outputLength = (numPoints << 2) + 12; + outputMessage = writeBuffer_.addMessage(outputLength); + unsigned int relativeCoordMode; + decodeBuffer.decodeBoolValue(relativeCoordMode); + outputMessage[1] = (unsigned char) relativeCoordMode; + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + + unsigned int index = 0; + unsigned int lastX = 0, lastY = 0; + + for (unsigned int i = 0; i < numPoints; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyLineCacheX[index], 8); + lastX += value; + PutUINT(lastX, nextDest, bigEndian_); + nextDest += 2; + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyLineCacheY[index], 8); + lastY += value; + PutUINT(lastY, nextDest, bigEndian_); + nextDest += 2; + + if (++index == 2) index = 0; + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_PolyRectangle: + { + unsigned int numRectangles; + decodeBuffer.decodeValue(numRectangles, 16, 3); + outputLength = (numRectangles << 3) + 12; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + for (unsigned int i = 0; i < numRectangles; i++) + for (unsigned int k = 0; k < 4; k++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> polyRectangleGeomCache[k], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + } + break; + case X_PolySegment: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PolySegment); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + unsigned int numSegments; + decodeBuffer.decodeValue(numSegments, 16, 4); + outputLength = (numSegments << 3) + 12; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + + for (numSegments *= 2; numSegments; numSegments--) + { + unsigned int index; + decodeBuffer.decodeBoolValue(index); + unsigned int x; + decodeBuffer.decodeCachedValue(x, 16, + clientCache_ -> polySegmentCacheX, 6); + x += clientCache_ -> polySegmentLastX[index]; + PutUINT(x, nextDest, bigEndian_); + nextDest += 2; + + unsigned int y; + decodeBuffer.decodeCachedValue(y, 16, + clientCache_ -> polySegmentCacheY, 6); + y += clientCache_ -> polySegmentLastY[index]; + PutUINT(y, nextDest, bigEndian_); + nextDest += 2; + + clientCache_ -> polySegmentLastX[clientCache_ -> polySegmentCacheIndex] = x; + clientCache_ -> polySegmentLastY[clientCache_ -> polySegmentCacheIndex] = y; + + if (clientCache_ -> polySegmentCacheIndex == 1) + clientCache_ -> polySegmentCacheIndex = 0; + else + clientCache_ -> polySegmentCacheIndex = 1; + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_PutImage: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_PutImage); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + + if (outputOpcode == X_PutImage) + { + handleImage(outputOpcode, outputMessage, outputLength); + } + } + break; + case X_QueryBestSize: + { + outputLength = 12; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 2); + outputMessage[1] = (unsigned char)value; + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeValue(value, 16, 8); + PutUINT(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeValue(value, 16, 8); + PutUINT(value, outputMessage + 10, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_QueryColors: + { + // Differential or plain data compression? + decodeBuffer.decodeBoolValue(value); + + if (value) + { + unsigned int numColors; + decodeBuffer.decodeValue(numColors, 16, 5); + outputLength = (numColors << 2) + 8; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> colormapCache); + PutULONG(value, outputMessage + 4, bigEndian_); + unsigned char *nextDest = outputMessage + 8; + unsigned int predictedPixel = clientCache_ -> queryColorsLastPixel; + for (unsigned int i = 0; i < numColors; i++) + { + unsigned int pixel; + decodeBuffer.decodeBoolValue(value); + if (value) + pixel = predictedPixel; + else + decodeBuffer.decodeValue(pixel, 32, 9); + PutULONG(pixel, nextDest, bigEndian_); + if (i == 0) + clientCache_ -> queryColorsLastPixel = pixel; + predictedPixel = pixel + 1; + nextDest += 4; + } + } + else + { + // Request length. + unsigned int requestLength; + decodeBuffer.decodeValue(requestLength, 16, 10); + outputLength = (requestLength << 2); + outputMessage = writeBuffer_.addMessage(outputLength); + + const unsigned char *compressedData = NULL; + unsigned int compressedDataSize = 0; + + int decompressed = handleDecompress(decodeBuffer, outputOpcode, 4, + outputMessage, outputLength, compressedData, + compressedDataSize); + if (decompressed < 0) + { + return -1; + } + } + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_QueryExtension: + { + unsigned int nameLength; + decodeBuffer.decodeValue(nameLength, 16, 6); + outputLength = 8 + RoundUp4(nameLength); + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(nameLength, outputMessage + 4, bigEndian_); + unsigned char *nextDest = outputMessage + 8; + for (unsigned int i = 0; i < nameLength; i++) + { + decodeBuffer.decodeValue(value, 8); + *nextDest++ = (unsigned char) value; + } + + unsigned int hide = 0; + + #ifdef HIDE_MIT_SHM_EXTENSION + + if (!strncmp((char *) outputMessage + 8, "MIT-SHM", 7)) + { + #ifdef TEST + *logofs << "handleWrite: Going to hide MIT-SHM extension in reply.\n" + << logofs_flush; + #endif + + hide = 1; + } + + #endif + + #ifdef HIDE_BIG_REQUESTS_EXTENSION + + if (!strncmp((char *) outputMessage + 8, "BIG-REQUESTS", 12)) + { + #ifdef TEST + *logofs << "handleWrite: Going to hide BIG-REQUESTS extension in reply.\n" + << logofs_flush; + #endif + + hide = 1; + } + + #endif + + #ifdef HIDE_XKEYBOARD_EXTENSION + + else if (!strncmp((char *) outputMessage + 8, "XKEYBOARD", 9)) + { + #ifdef TEST + *logofs << "handleWrite: Going to hide XKEYBOARD extension in reply.\n" + << logofs_flush; + #endif + + hide = 1; + } + + #endif + + #ifdef HIDE_XFree86_Bigfont_EXTENSION + + else if (!strncmp((char *) outputMessage + 8, "XFree86-Bigfont", 15)) + { + #ifdef TEST + *logofs << "handleWrite: Going to hide XFree86-Bigfont extension in reply.\n" + << logofs_flush; + #endif + + hide = 1; + } + + #endif + + // + // This is if you want to experiment disabling SHAPE extensions. + // + + #ifdef HIDE_SHAPE_EXTENSION + + if (!strncmp((char *) outputMessage + 8, "SHAPE", 5)) + { + #ifdef DEBUG + *logofs << "handleWrite: Going to hide SHAPE extension in reply.\n" + << logofs_flush; + #endif + + hide = 1; + } + + #endif + + // + // Check if user disabled RENDER extension. + // + + if (control -> HideRender == 1 && + strncmp((char *) outputMessage + 8, "RENDER", 6) == 0) + { + #ifdef TEST + *logofs << "handleWrite: Going to hide RENDER extension in reply.\n" + << logofs_flush; + #endif + + hide = 1; + } + + unsigned int extension = 0; + + if (strncmp((char *) outputMessage + 8, "SHAPE", 5) == 0) + { + extension = X_NXInternalShapeExtension; + } + else if (strncmp((char *) outputMessage + 8, "RENDER", 6) == 0) + { + extension = X_NXInternalRenderExtension; + } + + sequenceQueue_.push(clientSequence_, outputOpcode, + outputOpcode, hide, extension); + } + break; + case X_QueryFont: + { + outputLength = 8; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 29, 5); + clientCache_ -> lastFont += value; + clientCache_ -> lastFont &= 0x1fffffff; + PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_SetClipRectangles: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_SetClipRectangles); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + break; + } + + unsigned int numRectangles; + + // Since ProtoStep9 (#issue 108) + decodeBuffer.decodeValue(numRectangles, 15, 4); + + outputLength = (numRectangles << 3) + 12; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeValue(value, 2); + outputMessage[1] = (unsigned char) value; + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> setClipRectanglesXCache, 8); + PutUINT(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> setClipRectanglesYCache, 8); + PutUINT(value, outputMessage + 10, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + for (unsigned int i = 0; i < numRectangles; i++) + { + for (unsigned int k = 0; k < 4; k++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache_ -> setClipRectanglesGeomCache[k], 8); + PutUINT(value, nextDest, bigEndian_); + nextDest += 2; + } + } + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_SetDashes: + { + unsigned int numDashes; + decodeBuffer.decodeCachedValue(numDashes, 16, + clientCache_ -> setDashesLengthCache, 5); + outputLength = 12 + RoundUp4(numDashes); + outputMessage = writeBuffer_.addMessage(outputLength); + PutUINT(numDashes, outputMessage + 10, bigEndian_); + decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> setDashesOffsetCache, 5); + PutUINT(value, outputMessage + 8, bigEndian_); + unsigned char *nextDest = outputMessage + 12; + for (unsigned int i = 0; i < numDashes; i++) + { + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache_ -> setDashesDashCache_[i & 1], 5); + *nextDest++ = cValue; + } + } + break; + case X_SetSelectionOwner: + { + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> setSelectionOwnerCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> getSelectionOwnerSelectionCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 32, + clientCache_ -> setSelectionOwnerTimestampCache, 9); + PutULONG(value, outputMessage + 12, bigEndian_); + } + break; + case X_TranslateCoords: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_TranslateCoords); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + sequenceQueue_.push(clientSequence_, outputOpcode); + + break; + } + + outputLength = 16; + outputMessage = writeBuffer_.addMessage(outputLength); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> translateCoordsSrcCache, 9); + PutULONG(value, outputMessage + 4, bigEndian_); + decodeBuffer.decodeCachedValue(value, 29, + clientCache_ -> translateCoordsDstCache, 9); + PutULONG(value, outputMessage + 8, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> translateCoordsXCache, 8); + PutUINT(value, outputMessage + 12, bigEndian_); + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> translateCoordsYCache, 8); + PutUINT(value, outputMessage + 14, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_GetImage: + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_GetImage); + + if (handleDecodeCached(decodeBuffer, clientCache_, messageStore, + outputMessage, outputLength)) + { + sequenceQueue_.push(clientSequence_, outputOpcode); + + break; + } + + outputLength = 20; + outputMessage = writeBuffer_.addMessage(outputLength); + // Format. + unsigned int format; + decodeBuffer.decodeValue(format, 2); + outputMessage[1] = (unsigned char) format; + // Drawable. + decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache); + PutULONG(value, outputMessage + 4, bigEndian_); + // X. + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> putImageXCache, 8); + clientCache_ -> putImageLastX += value; + clientCache_ -> putImageLastX &= 0xffff; + PutUINT(clientCache_ -> putImageLastX, outputMessage + 8, bigEndian_); + // Y. + decodeBuffer.decodeCachedValue(value, 16, + clientCache_ -> putImageYCache, 8); + clientCache_ -> putImageLastY += value; + clientCache_ -> putImageLastY &= 0xffff; + PutUINT(clientCache_ -> putImageLastY, outputMessage + 10, bigEndian_); + // Width. + unsigned int width; + decodeBuffer.decodeCachedValue(width, 16, + clientCache_ -> putImageWidthCache, 8); + PutUINT(width, outputMessage + 12, bigEndian_); + // Height. + unsigned int height; + decodeBuffer.decodeCachedValue(height, 16, + clientCache_ -> putImageHeightCache, 8); + PutUINT(height, outputMessage + 14, bigEndian_); + // Plane mask. + decodeBuffer.decodeCachedValue(value, 32, + clientCache_ -> getImagePlaneMaskCache, 5); + PutULONG(value, outputMessage + 16, bigEndian_); + + sequenceQueue_.push(clientSequence_, outputOpcode); + + handleSave(messageStore, outputMessage, outputLength); + } + break; + case X_GetPointerMapping: + { + outputLength = 4; + outputMessage = writeBuffer_.addMessage(outputLength); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + case X_GetKeyboardControl: + { + outputLength = 4; + outputMessage = writeBuffer_.addMessage(outputLength); + + sequenceQueue_.push(clientSequence_, outputOpcode); + } + break; + default: + { + if (outputOpcode == opcodeStore_ -> renderExtension) + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXInternalRenderExtension); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> shapeExtension) + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXInternalShapeExtension); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> putPackedImage) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoding packed image request for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXPutPackedImage); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + + if (outputOpcode == opcodeStore_ -> putPackedImage) + { + handleImage(outputOpcode, outputMessage, outputLength); + } + } + else if (outputOpcode == opcodeStore_ -> setUnpackColormap) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoding set unpack colormap request " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXSetUnpackColormap); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + // + // Message could have been split. + // + + if (outputOpcode == opcodeStore_ -> setUnpackColormap) + { + handleColormap(outputOpcode, outputMessage, outputLength); + } + } + else if (outputOpcode == opcodeStore_ -> setUnpackAlpha) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoding unpack alpha request for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXSetUnpackAlpha); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + // + // Message could have been split. + // + + if (outputOpcode == opcodeStore_ -> setUnpackAlpha) + { + handleAlpha(outputOpcode, outputMessage, outputLength); + } + } + else if (outputOpcode == opcodeStore_ -> setUnpackGeometry) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoding set unpack geometry request " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXSetUnpackGeometry); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + + handleGeometry(outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> startSplit) + { + handleStartSplitRequest(decodeBuffer, outputOpcode, + outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> endSplit) + { + handleEndSplitRequest(decodeBuffer, outputOpcode, + outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> commitSplit) + { + int result = handleCommitSplitRequest(decodeBuffer, outputOpcode, + outputMessage, outputLength); + + // + // Check if message has been successfully + // extracted from the split store. In this + // case post-process it in the usual way. + // + + if (result > 0) + { + if (outputOpcode == opcodeStore_ -> putPackedImage || + outputOpcode == X_PutImage) + { + handleImage(outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> setUnpackColormap) + { + handleColormap(outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> setUnpackAlpha) + { + handleAlpha(outputOpcode, outputMessage, outputLength); + } + } + else if (result < 0) + { + return -1; + } + } + else if (outputOpcode == opcodeStore_ -> abortSplit) + { + handleAbortSplitRequest(decodeBuffer, outputOpcode, + outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> finishSplit) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoding finish split request " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache_ -> resourceCache); + + handleNullRequest(outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> freeSplit) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoding free split request " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache_ -> resourceCache); + + handleNullRequest(outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> freeUnpack) + { + #ifdef DEBUG + *logofs << "handleWrite: Decoding free unpack request " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache_ -> resourceCache); + + #ifdef DEBUG + *logofs << "handleWrite: Freeing unpack state for resource " + << (unsigned int) cValue << ".\n" << logofs_flush; + #endif + + handleUnpackStateRemove(cValue); + + handleNullRequest(outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> setExposeParameters) + { + // + // Send expose events according to agent's wish. + // + + decodeBuffer.decodeBoolValue(enableExpose_); + decodeBuffer.decodeBoolValue(enableGraphicsExpose_); + decodeBuffer.decodeBoolValue(enableNoExpose_); + + handleNullRequest(outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> getUnpackParameters) + { + // + // Client proxy needs the list of supported + // unpack methods. We would need an encode + // buffer, but this is in proxy, not here in + // channel. + // + + #ifdef TEST + *logofs << "handleWrite: Sending X_GetInputFocus request for FD#" + << fd_ << " due to OPCODE#" << (unsigned int) outputOpcode + << ".\n" << logofs_flush; + #endif + + outputOpcode = X_GetInputFocus; + + outputLength = 4; + outputMessage = writeBuffer_.addMessage(outputLength); + + sequenceQueue_.push(clientSequence_, outputOpcode, + opcodeStore_ -> getUnpackParameters); + } + else if (outputOpcode == opcodeStore_ -> getControlParameters || + outputOpcode == opcodeStore_ -> getCleanupParameters || + outputOpcode == opcodeStore_ -> getImageParameters) + { + handleNullRequest(outputOpcode, outputMessage, outputLength); + } + else if (outputOpcode == opcodeStore_ -> getShmemParameters) + { + if (handleShmemRequest(decodeBuffer, outputOpcode, + outputMessage, outputLength) < 0) + { + return -1; + } + } + else if (outputOpcode == opcodeStore_ -> setCacheParameters) + { + if (handleCacheRequest(decodeBuffer, outputOpcode, + outputMessage, outputLength) < 0) + { + return -1; + } + } + else if (outputOpcode == opcodeStore_ -> getFontParameters) + { + if (handleFontRequest(decodeBuffer, outputOpcode, + outputMessage, outputLength) < 0) + { + return -1; + } + } + else + { + MessageStore *messageStore = clientStore_ -> + getRequestStore(X_NXInternalGenericRequest); + + hit = handleDecode(decodeBuffer, clientCache_, messageStore, + outputOpcode, outputMessage, outputLength); + } + } + } // End of switch on opcode. + + // + // TODO: at the moment the variable hit was being set + // but not used, so to avoid the corresponding warning + // this logging block has been added. + // This code will probably be optimized away when none + // of the defines is set, but if there is no additional + // use for the hit variable in the future, then maybe + // it could be removed completely. + // + + if (hit) + { + #if defined(TEST) || defined(OPCODES) + *logofs << "handleWrite: Cached flag enabled in handled request.\n" + << logofs_flush; + #endif + } + + // + // A packed image request can generate more than just + // a single X_PutImage. Write buffer is handled inside + // handleUnpack(). Cannot simply assume that the final + // opcode and size must be put at the buffer offset as + // as buffer could have been grown or could have been + // replaced by a scratch buffer. The same is true in + // the case of a shared memory image. + // + + if (outputOpcode != 0) + { + // + // Commit opcode and size to the buffer. + // + + *outputMessage = (unsigned char) outputOpcode; + + PutUINT(outputLength >> 2, outputMessage + 2, bigEndian_); + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleWrite: Handled request OPCODE#" + << (unsigned int) outputOpcode << " (" + << DumpOpcode(outputOpcode) << ") for FD#" + << fd_ << " sequence " << clientSequence_ + << ". " << outputLength << " bytes out.\n" + << logofs_flush; + #endif + } + #if defined(TEST) || defined(OPCODES) + else + { + // + // In case of shared memory images the log doesn't + // reflect the actual opcode of the request that is + // going to be written. It would be possible to find + // the opcode of the original request received from + // the remote proxy in member imageState_ -> opcode, + // but we have probably already deleted the struct. + // + + *logofs << "handleWrite: Handled image request for FD#" + << fd_ << " new sequence " << clientSequence_ + << ". " << outputLength << " bytes out.\n" + << logofs_flush; + } + #endif + + // + // Check if we produced enough data. We need to + // decode all the proxy messages or the decode + // buffer will be left in an inconsistent state, + // so we just update the finish flag in case of + // failure. + // + + handleFlush(flush_if_needed); + + } // End of while (decodeBuffer.decodeOpcodeValue(outputOpcode, 8, ... + + } // End of the decoding block. + + // + // Write any remaining data to the X connection. + // + + if (handleFlush(flush_if_any) < 0) + { + return -1; + } + + // + // Reset offset at which we read the + // last event looking for the shared + // memory completion. + // + + if (shmemState_ != NULL) + { + shmemState_ -> checked = 0; + } + + return 1; +} + +// +// End of handleWrite(). +// + +// +// Other members. +// + +int ServerChannel::handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, + T_store_action action, int position, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + // Since ProtoStep7 (#issue 108) + splitState_.current = splitState_.resource; + + handleSplitStoreAlloc(&splitResources_, splitState_.current); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Message OPCODE#" + << (unsigned int) store -> opcode() << " of size " << size + << " [split] with resource " << splitState_.current + << " position " << position << " and action [" + << DumpAction(action) << "] at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + // + // Get the MD5 of the message being + // split. + // + + T_checksum checksum = NULL; + + if (action != IS_HIT) + { + handleSplitChecksum(decodeBuffer, checksum); + } + + // + // The method must abort the connection + // if it can't allocate the split. + // + + Split *splitMessage = clientStore_ -> getSplitStore(splitState_.current) -> + add(store, splitState_.current, position, + action, checksum, buffer, size); + + // + // If the encoding side didn't provide + // a checksum, then don't send the split + // report. + // + + if (checksum == NULL) + { + if (action == IS_HIT) + { + splitMessage -> setState(split_loaded); + } + else + { + splitMessage -> setState(split_missed); + } + + #if defined(TEST) || defined(SPLIT) + + *logofs << "handleSplit: SPLIT! There are " << clientStore_ -> + getSplitTotalSize() << " messages and " << clientStore_ -> + getSplitTotalStorageSize() << " bytes to send in " + << "the split stores.\n" << logofs_flush; + + clientStore_ -> dumpSplitStore(splitState_.current); + + #endif + + return 1; + } + + delete [] checksum; + + // + // Tell the split store if it must use + // the disk cache to retrieve and save + // the message. + // + + splitMessage -> setPolicy(splitState_.load, splitState_.save); + + // + // Try to locate the message on disk. + // + + if (clientStore_ -> getSplitStore(splitState_.current) -> + load(splitMessage) == 1) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Loaded the message " + << "from the image cache.\n" << logofs_flush; + #endif + + splitMessage -> setState(split_loaded); + } + else + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: WARNING! SPLIT! Can't find the message " + << "in the image cache.\n" << logofs_flush; + #endif + + splitMessage -> setState(split_missed); + } + + #if defined(TEST) || defined(SPLIT) + + T_timestamp startTs = getTimestamp(); + + *logofs << "handleSplit: SPLIT! Encoding abort " + << "split events for FD#" << fd_ << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + + if (proxy -> handleAsyncSplit(fd_, splitMessage) < 0) + { + return -1; + } + + // + // Send the encoded data immediately. We + // want the abort split message to reach + // the remote proxy as soon as possible. + // + + if (proxy -> handleAsyncFlush() < 0) + { + return -1; + } + + #if defined(TEST) || defined(SPLIT) + + *logofs << "handleSplit: SPLIT! Spent " + << diffTimestamp(startTs, getTimestamp()) << " Ms " + << "handling abort split events for FD#" << fd_ + << ".\n" << logofs_flush; + + *logofs << "handleSplit: SPLIT! There are " << clientStore_ -> + getSplitTotalSize() << " messages and " << clientStore_ -> + getSplitTotalStorageSize() << " bytes to send in " + << "the split stores.\n" << logofs_flush; + + clientStore_ -> dumpSplitStore(splitState_.current); + + #endif + + return 1; +} + +int ServerChannel::handleSplit(DecodeBuffer &decodeBuffer) +{ + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Going to handle splits " + << "for FD#" << fd_ << " at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + unsigned char resource; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + splitState_.current = resource; + + handleSplitStoreAlloc(&splitResources_, splitState_.current); + + SplitStore *splitStore = clientStore_ -> getSplitStore(splitState_.current); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Handling splits for " + << "resource [" << splitState_.current << "] with " + << splitStore -> getSize() << " elements " + << "in the split store.\n" << logofs_flush; + #endif + + int result = splitStore -> receive(decodeBuffer); + + if (result < 0) + { + #ifdef PANIC + *logofs << "handleSplit: PANIC! Receive of split for FD#" << fd_ + << " failed.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Receive of split for FD#" << fd_ + << " failed.\n"; + + return -1; + } + else if (result == 0) + { + // + // The split is still incomplete. It's time + // to check if we need to start the house- + // keeping process to take care of the image + // cache. + // + + if (proxy -> handleAsyncKeeperCallback() < 0) + { + return -1; + } + } + else + { + // + // Note that we don't need the resource id at the + // X server side and, thus, we don't provide it + // at the time we add split to the split store. + // + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Remote agent should " + << "now commit a new split for resource [" + << splitState_.current << "].\n" + << logofs_flush; + + clientStore_ -> dumpCommitStore(); + + #endif + + if (splitStore -> getSize() == 0) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! Removing split store " + << "for resource [" << splitState_.current + << "] at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + handleSplitStoreRemove(&splitResources_, splitState_.current); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: SPLIT! There are [" << clientStore_ -> + getSplitTotalSize() << "] messages and " << clientStore_ -> + getSplitTotalStorageSize() << " bytes to send in " + << "the split stores.\n" << logofs_flush; + #endif + } + else + { + // + // If the next split is discarded, it can be + // that, since the beginning of the split, we + // have saved the message on the disk, due to + // a more recent split operation. This is also + // the case when we had to discard the message + // because it was locked but, since then, we + // completed the transferral of the split. + // + + Split *splitMessage = splitStore -> getFirstSplit(); + + if (splitMessage -> getAction() == is_discarded && + splitMessage -> getState() == split_missed && + splitStore -> load(splitMessage) == 1) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplit: WARNING! SPLIT! Asynchronously " + << "loaded the message from the image cache.\n" + << logofs_flush; + #endif + + splitMessage -> setState(split_loaded); + + #if defined(TEST) || defined(SPLIT) + + T_timestamp startTs = getTimestamp(); + + *logofs << "handleSplit: WARNING! SPLIT! Asynchronously " + << "encoding abort split events for FD#" << fd_ + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + if (proxy -> handleAsyncSplit(fd_, splitMessage) < 0) + { + return -1; + } + + // + // Send the encoded data immediately. We + // want the abort split message to reach + // the remote proxy as soon as possible. + // + + if (proxy -> handleAsyncFlush() < 0) + { + return -1; + } + + #if defined(TEST) || defined(SPLIT) + + *logofs << "handleSplit: WARNING! SPLIT! Spent " + << diffTimestamp(startTs, getTimestamp()) << " Ms " + << "handling asynchronous abort split events for " + << "FD#" << fd_ << ".\n" << logofs_flush; + + *logofs << "handleSplit: SPLIT! There are " << clientStore_ -> + getSplitTotalSize() << " messages and " << clientStore_ -> + getSplitTotalStorageSize() << " bytes to send in " + << "the split stores.\n" << logofs_flush; + + clientStore_ -> dumpSplitStore(splitState_.current); + + #endif + } + } + } + + return 1; +} + +int ServerChannel::handleSplitEvent(EncodeBuffer &encodeBuffer, Split *splitMessage) +{ + int resource = splitMessage -> getResource(); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Going to send a " + << "split report for resource " << resource + << ".\n" << logofs_flush; + #endif + + // + // This function is called only after the message + // has been searched in the disk cache. We need to + // inform the other side if the data transfer can + // start or it must be aborted to let the local + // side use the copy that was found on the disk. + // + + #if defined(TEST) || defined(INFO) + + if (splitMessage -> getState() != split_loaded && + splitMessage -> getState() != split_missed) + { + *logofs << "handleSplitEvent: PANIC! Can't find the split to be aborted.\n" + << logofs_flush; + + HandleCleanup(); + } + + #endif + + // + // We need to send a boolean telling if the split + // was found or not, followed by the checksum of + // message we are referencing. + // + + T_checksum checksum = splitMessage -> getChecksum(); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Sending split report for " + << "checksum [" << DumpChecksum(checksum) << "].\n" + << logofs_flush; + #endif + + if (proxy -> handleAsyncSwitch(fd_) < 0) + { + return -1; + } + + encodeBuffer.encodeOpcodeValue(opcodeStore_ -> splitEvent, + serverCache_ -> opcodeCache); + + // + // The encoding in older protocol versions + // is different but we will never try to + // send a split report if the remote does + // not support our version. + // + + encodeBuffer.encodeCachedValue(resource, 8, + serverCache_ -> resourceCache); + + if (splitMessage -> getState() == split_loaded) + { + encodeBuffer.encodeBoolValue(1); + + encodeBuffer.encodeOpcodeValue(splitMessage -> getStore() -> opcode(), + serverCache_ -> abortOpcodeCache); + + encodeBuffer.encodeValue(splitMessage -> compressedSize(), 32, 14); + } + else + { + encodeBuffer.encodeBoolValue(0); + } + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + encodeBuffer.encodeValue((unsigned int) checksum[i], 8); + } + + // + // Update statistics for this special opcode. + // + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) || defined(INFO) || defined(SPLIT) + *logofs << "handleSplitEvent: SPLIT! Handled event OPCODE#" + << (unsigned int) opcodeStore_ -> splitEvent << " (" + << DumpOpcode(opcodeStore_ -> splitEvent) << ")" << " for FD#" + << fd_ << " sequence none. 0 bytes in, " << bits << " bits (" + << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; + #endif + + statistics -> addEventBits(opcodeStore_ -> splitEvent, 0, bits); + + return 1; +} + +int ServerChannel::handleAbortSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + unsigned char resource; + + decodeBuffer.decodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Handling abort split " + << "request for FD#" << fd_ << " and resource " + << (unsigned) resource << ".\n" + << logofs_flush; + #endif + + int splits = 0; + + SplitStore *splitStore = clientStore_ -> getSplitStore(resource); + + if (splitStore != NULL) + { + // + // Discard from the memory cache the messages + // that are still incomplete and then get rid + // of the splits in the store. + // + + #if defined(TEST) || defined(SPLIT) + + clientStore_ -> dumpSplitStore(resource); + + #endif + + Split *splitMessage; + + for (;;) + { + splitMessage = splitStore -> getFirstSplit(); + + if (splitMessage == NULL) + { + // + // Check if we had created the store + // but no message was added yet. + // + + #ifdef WARNING + + if (splits == 0) + { + *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The " + << "split store for resource [" << (unsigned int) + resource << "] is unexpectedly empty.\n" + << logofs_flush; + } + + #endif + + break; + } + + // + // Splits already aborted can't be in the + // split store. + // + + #if defined(TEST) || defined(SPLIT) + + if (splitMessage -> getState() == split_aborted) + { + *logofs << "handleAbortSplitRequest: PANIC! SPLIT! Found an " + << "aborted split in store [" << (unsigned int) resource + << "].\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + if (splitMessage -> getAction() == IS_HIT) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Removing the " + << "split from the memory cache.\n" + << logofs_flush; + #endif + + splitMessage -> getStore() -> remove(splitMessage -> getPosition(), + discard_checksum, use_data); + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Removing the " + << "split from the split store.\n" + << logofs_flush; + #endif + + splitMessage = splitStore -> pop(); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleAbortSplitRequest: SPLIT! Freeing up the " + << "aborted split.\n" << logofs_flush; + #endif + + delete splitMessage; + + splits++; + } + } + #ifdef WARNING + else + { + *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The " + << "split store for resource [" << (unsigned int) + resource << "] is already empty.\n" + << logofs_flush; + } + #endif + + handleNullRequest(opcode, buffer, size); + + return (splits > 0); +} + +int ServerChannel::handleCommitSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + // + // Get request type and position of the image + // to commit. + // + + unsigned char request; + + decodeBuffer.decodeOpcodeValue(request, clientCache_ -> opcodeCache); + + unsigned int diffCommit; + + decodeBuffer.decodeValue(diffCommit, 32, 5); + + splitState_.commit += diffCommit; + + unsigned char resource = 0; + unsigned int commit = 1; + + // + // Send the resource id and the commit flag. + // The resource id is ignored at the moment. + // The message will be handled based on the + // resource id that was sent together with + // the original message. + // + + decodeBuffer.decodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + decodeBuffer.decodeBoolValue(commit); + + Split *split = handleSplitCommitRemove(request, resource, splitState_.commit); + + if (split == NULL) + { + return -1; + } + + clientStore_ -> getCommitStore() -> update(split); + + if (commit == 1) + { + #if defined(TEST) || defined(SPLIT) + *logofs << "handleCommitSplitRequest: SPLIT! Handling split commit " + << "for FD#" << fd_ << " with commit " << commit + << " request " << (unsigned) request << " resource " + << (unsigned) resource << " and position " + << splitState_.commit << ".\n" + << logofs_flush; + #endif + + // + // Allocate as many bytes in the write + // buffer as the final length of the + // message in uncompressed form. + // + + size = split -> plainSize(); + + buffer = writeBuffer_.addMessage(size); + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleCommitSplitRequest: SPLIT! Prepared an " + << "outgoing buffer of " << size << " bytes.\n" + << logofs_flush; + #endif + + if (clientStore_ -> getCommitStore() -> expand(split, buffer, size) < 0) + { + writeBuffer_.removeMessage(size); + + commit = 0; + } + } + + // + // Free the split. + // + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleCommitSplitRequest: SPLIT! Freeing up the " + << "committed split.\n" << logofs_flush; + #endif + + delete split; + + // + // Discard the operation and send a null + // message. + // + + if (commit == 0) + { + handleNullRequest(opcode, buffer, size); + } + else + { + // + // Save the sequence number to be able + // to mask any error generated by the + // request. + // + + updateCommitQueue(clientSequence_); + + // + // Now in the write buffer there is + // a copy of this request. + // + + opcode = request; + } + + return commit; +} + +int ServerChannel::handleGeometry(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size) +{ + // + // Replace the old geometry and taint + // the message into a X_NoOperation. + // + + int resource = *(buffer + 1); + + #ifdef TEST + *logofs << "handleGeometry: Setting new unpack geometry " + << "for resource " << resource << ".\n" + << logofs_flush; + #endif + + handleUnpackStateInit(resource); + + handleUnpackAllocGeometry(resource); + + unpackState_[resource] -> geometry -> depth1_bpp = *(buffer + 4); + unpackState_[resource] -> geometry -> depth4_bpp = *(buffer + 5); + unpackState_[resource] -> geometry -> depth8_bpp = *(buffer + 6); + unpackState_[resource] -> geometry -> depth16_bpp = *(buffer + 7); + unpackState_[resource] -> geometry -> depth24_bpp = *(buffer + 8); + unpackState_[resource] -> geometry -> depth32_bpp = *(buffer + 9); + + unpackState_[resource] -> geometry -> red_mask = GetULONG(buffer + 12, bigEndian_); + unpackState_[resource] -> geometry -> green_mask = GetULONG(buffer + 16, bigEndian_); + unpackState_[resource] -> geometry -> blue_mask = GetULONG(buffer + 20, bigEndian_); + + handleCleanAndNullRequest(opcode, buffer, size); + + return 1; +} + +int ServerChannel::handleColormap(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size) +{ + // + // Replace the old colormap and taint + // the message into a X_NoOperation. + // + + int resource = *(buffer + 1); + + #ifdef TEST + *logofs << "handleColormap: Setting new unpack colormap " + << "for resource " << resource << ".\n" + << logofs_flush; + #endif + + handleUnpackStateInit(resource); + + handleUnpackAllocColormap(resource); + + // + // New protocol versions send the alpha + // data in compressed form. + // + + // + // Since ProtoStep7 (#issue 108) + // + + { // An anonymous block is used here to limit the scope of local variables + unsigned int packed = GetULONG(buffer + 8, bigEndian_); + unsigned int unpacked = GetULONG(buffer + 12, bigEndian_); + + validateSize("colormap", packed, unpacked, 16, size); + + if (unpackState_[resource] -> colormap -> entries != unpacked >> 2 && + unpackState_[resource] -> colormap -> data != NULL) + { + #ifdef TEST + *logofs << "handleColormap: Freeing previously allocated " + << "unpack colormap data.\n" << logofs_flush; + #endif + + delete [] unpackState_[resource] -> colormap -> data; + + unpackState_[resource] -> colormap -> data = NULL; + unpackState_[resource] -> colormap -> entries = 0; + } + + #ifdef TEST + *logofs << "handleColormap: Setting " << unpacked + << " bytes of unpack colormap data for resource " + << resource << ".\n" << logofs_flush; + #endif + + if (unpackState_[resource] -> colormap -> data == NULL) + { + unpackState_[resource] -> colormap -> data = + (unsigned int *) new unsigned char[unpacked]; + + if (unpackState_[resource] -> colormap -> data == NULL) + { + #ifdef PANIC + *logofs << "handleColormap: PANIC! Can't allocate " + << unpacked << " entries for unpack colormap data " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + goto handleColormapEnd; + } + + #ifdef DEBUG + *logofs << "handleColormap: Size of new colormap data is " + << unpacked << ".\n" << logofs_flush; + #endif + } + + unsigned int method = *(buffer + 4); + + if (method == PACK_COLORMAP) + { + if (UnpackColormap(method, buffer + 16, packed, + (unsigned char *) unpackState_[resource] -> + colormap -> data, unpacked) < 0) + { + #ifdef PANIC + *logofs << "handleColormap: PANIC! Can't unpack " << packed + << " bytes to " << unpacked << " entries for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + delete [] unpackState_[resource] -> colormap -> data; + + unpackState_[resource] -> colormap -> data = NULL; + unpackState_[resource] -> colormap -> entries = 0; + + goto handleColormapEnd; + } + } + else + { + memcpy((unsigned char *) unpackState_[resource] -> + colormap -> data, buffer + 16, unpacked); + } + + unpackState_[resource] -> colormap -> entries = unpacked >> 2; + + #if defined(DEBUG) && defined(DUMP) + + *logofs << "handleColormap: Dumping colormap entries:\n" + << logofs_flush; + + const unsigned char *p = (const unsigned char *) unpackState_[resource] -> colormap -> data; + + for (unsigned int i = 0; i < unpackState_[resource] -> + colormap -> entries; i++) + { + *logofs << "handleColormap: [" << i << "] [" + << (void *) ((int) p[i]) << "].\n" + << logofs_flush; + } + + #endif + } // end anonymous block + +handleColormapEnd: + + handleCleanAndNullRequest(opcode, buffer, size); + + return 1; +} + +int ServerChannel::handleAlpha(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size) +{ + int resource = *(buffer + 1); + + #ifdef TEST + *logofs << "handleAlpha: Setting new unpack alpha " + << "for resource " << resource << ".\n" + << logofs_flush; + #endif + + handleUnpackStateInit(resource); + + handleUnpackAllocAlpha(resource); + + // + // New protocol versions send the alpha + // data in compressed form. + // + + // + // Since ProtoStep7 (#issue 108) + // + + { // An anonymous block is used here to limit the scope of local variables + unsigned int packed = GetULONG(buffer + 8, bigEndian_); + unsigned int unpacked = GetULONG(buffer + 12, bigEndian_); + + validateSize("alpha", packed, unpacked, 16, size); + + if (unpackState_[resource] -> alpha -> entries != unpacked && + unpackState_[resource] -> alpha -> data != NULL) + { + #ifdef TEST + *logofs << "handleAlpha: Freeing previously allocated " + << "unpack alpha data.\n" << logofs_flush; + #endif + + delete [] unpackState_[resource] -> alpha -> data; + + unpackState_[resource] -> alpha -> data = NULL; + unpackState_[resource] -> alpha -> entries = 0; + } + + #ifdef TEST + *logofs << "handleAlpha: Setting " << unpacked + << " bytes of unpack alpha data for resource " + << resource << ".\n" << logofs_flush; + #endif + + if (unpackState_[resource] -> alpha -> data == NULL) + { + unpackState_[resource] -> alpha -> data = new unsigned char[unpacked]; + + if (unpackState_[resource] -> alpha -> data == NULL) + { + #ifdef PANIC + *logofs << "handleAlpha: PANIC! Can't allocate " + << unpacked << " entries for unpack alpha data " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + goto handleAlphaEnd; + } + + #ifdef DEBUG + *logofs << "handleAlpha: Size of new alpha data is " + << unpacked << ".\n" << logofs_flush; + #endif + } + + unsigned int method = *(buffer + 4); + + if (method == PACK_ALPHA) + { + if (UnpackAlpha(method, buffer + 16, packed, + unpackState_[resource] -> alpha -> + data, unpacked) < 0) + { + #ifdef PANIC + *logofs << "handleAlpha: PANIC! Can't unpack " << packed + << " bytes to " << unpacked << " entries for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + delete [] unpackState_[resource] -> alpha -> data; + + unpackState_[resource] -> alpha -> data = NULL; + unpackState_[resource] -> alpha -> entries = 0; + + goto handleAlphaEnd; + } + } + else + { + memcpy((unsigned char *) unpackState_[resource] -> + alpha -> data, buffer + 16, unpacked); + } + + unpackState_[resource] -> alpha -> entries = unpacked; + + #if defined(DEBUG) && defined(DUMP) + + *logofs << "handleAlpha: Dumping alpha entries:\n" + << logofs_flush; + + const unsigned char *p = unpackState_[resource] -> alpha -> data; + + for (unsigned int i = 0; i < unpackState_[resource] -> + alpha -> entries; i++) + { + *logofs << "handleAlpha: [" << i << "] [" + << (void *) ((int) p[i]) << "].\n" + << logofs_flush; + } + + #endif + } //end anonymous block + +handleAlphaEnd: + + handleCleanAndNullRequest(opcode, buffer, size); + + return 1; +} + +int ServerChannel::handleImage(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size) +{ + int result = 1; + + // + // Save the original opcode together with + // the image state so we can later find if + // this is a plain or a packed image when + // moving data to the shared memory area. + // + + handleImageStateAlloc(opcode); + + if (opcode == opcodeStore_ -> putPackedImage) + { + // + // Unpack the image and put a X_PutImage in a + // new buffer. Save the expected output size, + // so, in the case of a decoding error we can + // still update the statistics. + // + + int length = GetULONG(buffer + 20, bigEndian_); + + #ifdef TEST + *logofs << "handleImage: Sending image for FD#" << fd_ + << " due to OPCODE#" << (unsigned int) opcode << " with " + << GetULONG(buffer + 16, bigEndian_) << " bytes packed " + << "and " << GetULONG(buffer + 20, bigEndian_) + << " bytes unpacked.\n" << logofs_flush; + #endif + + statistics -> addPackedBytesIn(size); + + result = handleUnpack(opcode, buffer, size); + + if (result < 0) + { + // + // Recover from the error. Send a X_NoOperation + // to keep the sequence counter in sync with + // the remote peer. + // + + size = 4; + buffer = writeBuffer_.addMessage(size); + + *buffer = X_NoOperation; + + PutUINT(size >> 2, buffer + 2, bigEndian_); + + #ifdef PANIC + *logofs << "handleImage: PANIC! Sending X_NoOperation for FD#" + << fd_ << " to recover from failed unpack.\n" + << logofs_flush; + #endif + + // + // Set the output length to reflect the amount of + // data that would have been produced by unpacking + // the image. This is advisable to keep the count- + // ers in sync with those at remote proxy. Setting + // the size here doesn't have any effect on the + // size of data sent to the X server as the actual + // size will be taken from the content of the write + // buffer. + // + + size = length; + } + + statistics -> addPackedBytesOut(size); + + // + // Refrain the write loop from putting + // opcode and size in the output buffer. + // + + opcode = 0; + } + + // + // Now image is unpacked as a X_PutImage + // in write buffer. Check if we can send + // the image using the MIT-SHM extension. + // + + if (result > 0) + { + result = handleShmem(opcode, buffer, size); + + // + // We already put opcode and size in + // the resulting buffer. + // + + if (result > 0) + { + opcode = 0; + } + } + + return 1; +} + +int ServerChannel::handleMotion(EncodeBuffer &encodeBuffer) +{ + #if defined(TEST) || defined(INFO) + + if (lastMotion_[0] == '\0') + { + *logofs << "handleMotion: PANIC! No motion events to send " + << "for FD#" << fd_ << ".\n" << logofs_flush; + + HandleCleanup(); + } + + #endif + + #if defined(TEST) || defined(INFO) + *logofs << "handleMotion: Sending motion events for FD#" + << fd_ << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + // + // Replicate code from read loop. When have + // time and wish, try to split everything + // in functions. + // + + if (proxy -> handleAsyncSwitch(fd_) < 0) + { + return -1; + } + + const unsigned char *buffer = lastMotion_; + unsigned char opcode = *lastMotion_; + unsigned int size = 32; + + if (GetUINT(buffer + 2, bigEndian_) < serverSequence_) + { + PutUINT(serverSequence_, (unsigned char *) buffer + 2, bigEndian_); + } + + encodeBuffer.encodeOpcodeValue(opcode, serverCache_ -> opcodeCache); + + unsigned int sequenceNum = GetUINT(buffer + 2, bigEndian_); + + unsigned int sequenceDiff = sequenceNum - serverSequence_; + + serverSequence_ = sequenceNum; + + #ifdef DEBUG + *logofs << "handleMotion: Last server sequence number for FD#" + << fd_ << " is " << serverSequence_ << " with " + << "difference " << sequenceDiff << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(sequenceDiff, 16, + serverCache_ -> eventSequenceCache, 7); + + // + // If we fast encoded the message + // then skip the rest. + // + + if (control -> LocalDeltaCompression == 0) + { + int result = handleFastReadEvent(encodeBuffer, opcode, + buffer, size); + + #ifdef DEBUG + *logofs << "handleMotion: Sent saved motion event for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + lastMotion_[0] = '\0'; + + #ifdef DEBUG + *logofs << "handleMotion: Reset last motion event for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + if (result < 0) + { + return -1; + } + else if (result > 0) + { + return 1; + } + } + + // + // This should be just the part specific + // for motion events but is currently a + // copy-paste of code from the read loop. + // + + unsigned char detail = buffer[1]; + if (*buffer == MotionNotify) + encodeBuffer.encodeBoolValue((unsigned int) detail); + else if ((*buffer == EnterNotify) || (*buffer == LeaveNotify)) + encodeBuffer.encodeValue((unsigned int) detail, 3); + else if (*buffer == KeyRelease) + { + if (detail == serverCache_ -> keyPressLastKey) + encodeBuffer.encodeBoolValue(1); + else + { + encodeBuffer.encodeBoolValue(0); + encodeBuffer.encodeValue((unsigned int) detail, 8); + } + } + else if ((*buffer == ButtonPress) || (*buffer == ButtonRelease)) + encodeBuffer.encodeCachedValue(detail, 8, + serverCache_ -> buttonCache); + else + encodeBuffer.encodeValue((unsigned int) detail, 8); + unsigned int timestamp = GetULONG(buffer + 4, bigEndian_); + unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp; + serverCache_ -> lastTimestamp = timestamp; + encodeBuffer.encodeCachedValue(timestampDiff, 32, + serverCache_ -> motionNotifyTimestampCache, 9); + int skipRest = 0; + if (*buffer == KeyRelease) + { + skipRest = 1; + for (unsigned int i = 8; i < 31; i++) + { + if (buffer[i] != serverCache_ -> keyPressCache[i - 8]) + { + skipRest = 0; + break; + } + } + encodeBuffer.encodeBoolValue(skipRest); + } + if (!skipRest) + { + const unsigned char *nextSrc = buffer + 8; + for (unsigned int i = 0; i < 3; i++) + { + encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29, + *serverCache_ -> motionNotifyWindowCache[i], 6); + nextSrc += 4; + } + unsigned int rootX = GetUINT(buffer + 20, bigEndian_); + unsigned int rootY = GetUINT(buffer + 22, bigEndian_); + unsigned int eventX = GetUINT(buffer + 24, bigEndian_); + unsigned int eventY = GetUINT(buffer + 26, bigEndian_); + eventX -= rootX; + eventY -= rootY; + encodeBuffer.encodeCachedValue(rootX - + serverCache_ -> motionNotifyLastRootX, 16, + serverCache_ -> motionNotifyRootXCache, 6); + serverCache_ -> motionNotifyLastRootX = rootX; + encodeBuffer.encodeCachedValue(rootY - + serverCache_ -> motionNotifyLastRootY, 16, + serverCache_ -> motionNotifyRootYCache, 6); + serverCache_ -> motionNotifyLastRootY = rootY; + encodeBuffer.encodeCachedValue(eventX, 16, + serverCache_ -> motionNotifyEventXCache, 6); + encodeBuffer.encodeCachedValue(eventY, 16, + serverCache_ -> motionNotifyEventYCache, 6); + encodeBuffer.encodeCachedValue(GetUINT(buffer + 28, bigEndian_), + 16, serverCache_ -> motionNotifyStateCache); + if ((*buffer == EnterNotify) || (*buffer == LeaveNotify)) + encodeBuffer.encodeValue((unsigned int) buffer[30], 2); + else + encodeBuffer.encodeBoolValue((unsigned int) buffer[30]); + if ((*buffer == EnterNotify) || (*buffer == LeaveNotify)) + encodeBuffer.encodeValue((unsigned int) buffer[31], 2); + else if (*buffer == KeyPress) + { + serverCache_ -> keyPressLastKey = detail; + for (unsigned int i = 8; i < 31; i++) + { + serverCache_ -> keyPressCache[i - 8] = buffer[i]; + } + } + } + + // + // Print info about achieved compression + // and update the statistics. + // + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleMotion: Handled event OPCODE#" << (unsigned int) buffer[0] + << " for FD#" << fd_ << " sequence " << sequenceNum << ". " + << size << " bytes in, " << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + #endif + + statistics -> addEventBits(*buffer, size << 3, bits); + + #ifdef DEBUG + *logofs << "handleMotion: Sent saved motion event for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + lastMotion_[0] = '\0'; + + #ifdef DEBUG + *logofs << "handleMotion: Reset last motion event for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ServerChannel::handleConfiguration() +{ + #ifdef TEST + *logofs << "ServerChannel: Setting new buffer parameters " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + readBuffer_.setSize(control -> ServerInitialReadSize, + control -> ServerMaximumBufferSize); + + writeBuffer_.setSize(control -> TransportXBufferSize, + control -> TransportXBufferThreshold, + control -> TransportMaximumBufferSize); + + transport_ -> setSize(control -> TransportXBufferSize, + control -> TransportXBufferThreshold, + control -> TransportMaximumBufferSize); + return 1; +} + +int ServerChannel::handleFinish() +{ + #ifdef TEST + *logofs << "ServerChannel: Finishing connection for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + congestion_ = 0; + priority_ = 0; + + finish_ = 1; + + // + // Reset the motion event. + // + + lastMotion_[0] = '\0'; + + transport_ -> fullReset(); + + return 1; +} + +int ServerChannel::handleAsyncEvents() +{ + // + // Encode more events while decoding the + // proxy messages. + // + + if (transport_ -> readable() > 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleAsyncEvents: WARNING! Encoding events " + << "for FD#" << fd_ << " at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + #if defined(TEST) || defined(INFO) + + T_timestamp startTs = getTimestamp(); + + #endif + + if (proxy -> handleAsyncRead(fd_) < 0) + { + return -1; + } + + #if defined(TEST) || defined(INFO) + *logofs << "handleAsyncEvents: Spent " << diffTimestamp(startTs, + getTimestamp()) << " Ms handling events for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + return 1; + } + + return 0; +} + +int ServerChannel::handleUnpack(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size) +{ + int resource = *(buffer + 1); + + #ifdef DEBUG + *logofs << "handleUnpack: Unpacking image for resource " << resource + << " with method " << (unsigned int) *(buffer + 12) + << ".\n" << logofs_flush; + #endif + + handleUnpackStateInit(resource); + + T_geometry *geometryState = unpackState_[resource] -> geometry; + T_colormap *colormapState = unpackState_[resource] -> colormap; + T_alpha *alphaState = unpackState_[resource] -> alpha; + + if (geometryState == NULL) + { + #ifdef PANIC + *logofs << "handleUnpack: PANIC! Missing geometry unpacking " + << "image for resource " << resource << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Missing geometry unpacking " + << "image for resource " << resource << ".\n"; + + return -1; + } + + // + // Get the image data from the buffer. + // + + imageState_ -> drawable = GetULONG(buffer + 4, bigEndian_); + imageState_ -> gcontext = GetULONG(buffer + 8, bigEndian_); + + imageState_ -> method = *(buffer + 12); + + imageState_ -> format = *(buffer + 13); + imageState_ -> srcDepth = *(buffer + 14); + imageState_ -> dstDepth = *(buffer + 15); + + imageState_ -> srcLength = GetULONG(buffer + 16, bigEndian_); + imageState_ -> dstLength = GetULONG(buffer + 20, bigEndian_); + + imageState_ -> srcX = GetUINT(buffer + 24, bigEndian_); + imageState_ -> srcY = GetUINT(buffer + 26, bigEndian_); + imageState_ -> srcWidth = GetUINT(buffer + 28, bigEndian_); + imageState_ -> srcHeight = GetUINT(buffer + 30, bigEndian_); + + imageState_ -> dstX = GetUINT(buffer + 32, bigEndian_); + imageState_ -> dstY = GetUINT(buffer + 34, bigEndian_); + imageState_ -> dstWidth = GetUINT(buffer + 36, bigEndian_); + imageState_ -> dstHeight = GetUINT(buffer + 38, bigEndian_); + + #ifdef TEST + *logofs << "handleUnpack: Source X is " << imageState_ -> srcX + << " Y is " << imageState_ -> srcY << " width is " + << imageState_ -> srcWidth << " height is " + << imageState_ -> srcHeight << ".\n" + << logofs_flush; + #endif + + #ifdef TEST + *logofs << "handleUnpack: Destination X is " << imageState_ -> dstX + << " Y is " << imageState_ -> dstY << " width is " + << imageState_ -> dstWidth << " height is " + << imageState_ -> dstHeight << ".\n" + << logofs_flush; + #endif + + if (imageState_ -> srcX != 0 || imageState_ -> srcY != 0) + { + #ifdef PANIC + *logofs << "handleUnpack: PANIC! Unsupported source coordinates " + << "in unpack request.\n" << logofs_flush; + #endif + + return -1; + } + else if (imageState_ -> method == PACK_COLORMAP_256_COLORS && + (colormapState == NULL || colormapState -> data == NULL)) + { + #ifdef PANIC + *logofs << "handleUnpack: PANIC! Cannot find any unpack colormap.\n" + << logofs_flush; + #endif + + return -1; + } + + // + // Field srcLength carries size of image data in + // packed format. Field dstLength is size of the + // image in the original X bitmap format. + // + + unsigned int srcDataOffset = 40; + + unsigned int srcSize = imageState_ -> srcLength; + + unsigned int removeSize = size; + + unsigned char *srcData = buffer + srcDataOffset; + + // + // Get source and destination bits per pixel. + // + + int srcBitsPerPixel = MethodBitsPerPixel(imageState_ -> method); + + if (srcBitsPerPixel <= 0) + { + #ifdef PANIC + *logofs << "handleUnpack: PANIC! Can't identify source " + << "bits per pixel for method " << (unsigned int) + imageState_ -> method << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify source bits " + << "per pixel for method " << (unsigned int) + imageState_ -> method << ".\n"; + + writeBuffer_.removeMessage(removeSize); + + return -1; + } + + #ifdef TEST + *logofs << "handleUnpack: Source bits per pixel are " + << srcBitsPerPixel << " source data size is " + << srcSize << ".\n" << logofs_flush; + #endif + + int dstBitsPerPixel = UnpackBitsPerPixel(geometryState, imageState_ -> dstDepth); + + if (dstBitsPerPixel <= 0) + { + #ifdef PANIC + *logofs << "handleUnpack: PANIC! Can't identify " + << "destination bits per pixel for depth " + << (unsigned int) imageState_ -> dstDepth + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't identify " + << "destination bits per pixel for depth " + << (unsigned int) imageState_ -> dstDepth + << ".\n"; + + writeBuffer_.removeMessage(removeSize); + + return -1; + } + + // + // Destination is a PutImage request. + // + + unsigned int dstDataOffset = 24; + + // + // Output buffer size must match the number of input + // pixels multiplied by the number of bytes per pixel + // of current geometry. + // + + size = (RoundUp4(imageState_ -> dstWidth * dstBitsPerPixel / 8) * + imageState_ -> dstHeight) + dstDataOffset; + + #ifdef TEST + *logofs << "handleUnpack: Destination bits per pixel are " + << dstBitsPerPixel << " destination data size is " + << size - dstDataOffset << ".\n" << logofs_flush; + #endif + + unsigned int dstSize = size - dstDataOffset; + + imageState_ -> dstLines = imageState_ -> dstHeight; + + unsigned char *dstData; + + // + // Size of the final output buffer had to be stored + // in the offset field of XImage/NXPackedImage. + // + + #ifdef WARNING + + if (dstSize != imageState_ -> dstLength) + { + *logofs << "handleUnpack: WARNING! Destination size mismatch " + << "with reported " << imageState_ -> dstLength + << " and actual " << dstSize << ".\n" + << logofs_flush; + } + + #endif + + // + // The decoding algorithm has put the packed image + // in the plain write buffer. Let's use the scratch + // buffer to uncompress the image. + // + + buffer = writeBuffer_.addScratchMessage(size); + + dstData = buffer + dstDataOffset; + + // + // Unpack image into the buffer. + // + + *buffer = (unsigned char) X_PutImage; + + *(buffer + 1) = imageState_ -> format; + + PutUINT(size >> 2, buffer + 2, bigEndian_); + + PutULONG(imageState_ -> drawable, buffer + 4, bigEndian_); + PutULONG(imageState_ -> gcontext, buffer + 8, bigEndian_); + + PutUINT(imageState_ -> dstWidth, buffer + 12, bigEndian_); + PutUINT(imageState_ -> dstLines, buffer + 14, bigEndian_); + + PutUINT(imageState_ -> dstX, buffer + 16, bigEndian_); + PutUINT(imageState_ -> dstY, buffer + 18, bigEndian_); + + *(buffer + 20) = 0; + *(buffer + 21) = imageState_ -> dstDepth; + + #ifdef TEST + *logofs << "handleUnpack: Write buffer size is " + << writeBuffer_.getLength() << " scratch size is " + << writeBuffer_.getScratchLength() << ".\n" + << logofs_flush; + #endif + + int result = 0; + + switch (imageState_ -> method) + { + case PACK_JPEG_8_COLORS: + case PACK_JPEG_64_COLORS: + case PACK_JPEG_256_COLORS: + case PACK_JPEG_512_COLORS: + case PACK_JPEG_4K_COLORS: + case PACK_JPEG_32K_COLORS: + case PACK_JPEG_64K_COLORS: + case PACK_JPEG_256K_COLORS: + case PACK_JPEG_2M_COLORS: + case PACK_JPEG_16M_COLORS: + { + result = UnpackJpeg(geometryState, imageState_ -> method, srcData, + srcSize, dstBitsPerPixel, imageState_ -> dstWidth, + imageState_ -> dstHeight, dstData, dstSize); + break; + } + case PACK_PNG_8_COLORS: + case PACK_PNG_64_COLORS: + case PACK_PNG_256_COLORS: + case PACK_PNG_512_COLORS: + case PACK_PNG_4K_COLORS: + case PACK_PNG_32K_COLORS: + case PACK_PNG_64K_COLORS: + case PACK_PNG_256K_COLORS: + case PACK_PNG_2M_COLORS: + case PACK_PNG_16M_COLORS: + { + result = UnpackPng(geometryState, imageState_ -> method, srcData, + srcSize, dstBitsPerPixel, imageState_ -> dstWidth, + imageState_ -> dstHeight, dstData, dstSize); + break; + } + case PACK_RGB_16M_COLORS: + { + result = UnpackRgb(geometryState, imageState_ -> method, srcData, + srcSize, dstBitsPerPixel, imageState_ -> dstWidth, + imageState_ -> dstHeight, dstData, dstSize); + break; + } + case PACK_RLE_16M_COLORS: + { + result = UnpackRle(geometryState, imageState_ -> method, srcData, + srcSize, dstBitsPerPixel, imageState_ -> dstWidth, + imageState_ -> dstHeight, dstData, dstSize); + break; + } + case PACK_BITMAP_16M_COLORS: + { + result = UnpackBitmap(geometryState, imageState_ -> method, srcData, + srcSize, dstBitsPerPixel, imageState_ -> dstWidth, + imageState_ -> dstHeight, dstData, dstSize); + break; + } + case PACK_COLORMAP_256_COLORS: + { + result = Unpack8(geometryState, colormapState, srcBitsPerPixel, + imageState_ -> srcWidth, imageState_ -> srcHeight, srcData, + srcSize, dstBitsPerPixel, imageState_ -> dstWidth, + imageState_ -> dstHeight, dstData, dstSize); + + break; + } + default: + { + const T_colormask *colorMask = MethodColorMask(imageState_ -> method); + + switch (imageState_ -> method) + { + case PACK_MASKED_8_COLORS: + case PACK_MASKED_64_COLORS: + case PACK_MASKED_256_COLORS: + { + result = Unpack8(geometryState, colorMask, imageState_ -> srcDepth, + imageState_ -> srcWidth, imageState_ -> srcHeight, + srcData, srcSize, imageState_ -> dstDepth, + imageState_ -> dstWidth, imageState_ -> dstHeight, + dstData, dstSize); + break; + } + case PACK_MASKED_512_COLORS: + case PACK_MASKED_4K_COLORS: + case PACK_MASKED_32K_COLORS: + case PACK_MASKED_64K_COLORS: + { + result = Unpack16(geometryState, colorMask, imageState_ -> srcDepth, + imageState_ -> srcWidth, imageState_ -> srcHeight, + srcData, srcSize, imageState_ -> dstDepth, + imageState_ -> dstWidth, imageState_ -> dstHeight, + dstData, dstSize); + break; + } + case PACK_MASKED_256K_COLORS: + case PACK_MASKED_2M_COLORS: + case PACK_MASKED_16M_COLORS: + { + result = Unpack24(geometryState, colorMask, imageState_ -> srcDepth, + imageState_ -> srcWidth, imageState_ -> srcHeight, + srcData, srcSize, imageState_ -> dstDepth, + imageState_ -> dstWidth, imageState_ -> dstHeight, + dstData, dstSize); + break; + } + default: + { + break; + } + } + } + } + + writeBuffer_.removeMessage(removeSize); + + if (result <= 0) + { + #ifdef PANIC + *logofs << "handleUnpack: PANIC! Failed to unpack image " + << "with method '" << (unsigned int) imageState_ -> method + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Failed to unpack image " + << "with method '" << (unsigned int) imageState_ -> method + << "'.\n"; + + // + // TODO: We should mark the image somehow, + // and force the remote to remove it from + // the cache. + // + + writeBuffer_.removeScratchMessage(); + + return -1; + } + + // + // Alpha channel is used only on some 32 bits pixmaps + // and only if render extension is in use. Presently + // we don't have an efficient way to know in advance + // if mask must be applied or not to the image. If an + // alpha channel is set, the function will check if + // the size of the alpha data matches the size of the + // image. In the worst case we'll create an useless + // alpha plane for a pixmap that doesn't need it. + // + + if (alphaState != NULL && alphaState -> data != NULL && + imageState_ -> dstDepth == 32) + { + UnpackAlpha(alphaState, dstData, dstSize, imageByteOrder_); + } + + return 1; +} + +int ServerChannel::handleAuthorization(unsigned char *buffer) +{ + // + // At the present moment we don't support more than + // a single display for each proxy, so authorization + // data is shared among all the channels. + // + // Use the following code to simulate authentication + // failures on a LSB machine: + // + // memcpy(buffer + 12 + (((buffer[6] + 256 * + // buffer[7]) + 3) & ~3), "1234567890123456", 16); + // + + if (auth == NULL) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleAuthorization: Forwarding the real cookie " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + return 0; + } + else if (auth -> checkCookie(buffer) == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleAuthorization: Matched the fake cookie " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + return 1; + } + else + { + #if defined(TEST) || defined(INFO) + *logofs << "handleAuthorization: WARNING! Failed to match " + << "the fake cookie for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + return -1; + } +} + +int ServerChannel::handleAuthorization(const unsigned char *buffer, int size) +{ + // + // Check the X server's response and, in the case of + // an error, print the textual information reported + // by the server. + // + + if (*buffer != 1) + { + const char *reason = NULL; + + // + // At the moment we don't take into account the end- + // ianess of the reply. This should work in any case + // because we simply try to match a few well-known + // error strings. + // + + if (size >= INVALID_COOKIE_SIZE + 8 && + memcmp(buffer + 8, INVALID_COOKIE_DATA, + INVALID_COOKIE_SIZE) == 0) + { + reason = INVALID_COOKIE_DATA; + } + else if (size >= NO_AUTH_PROTO_SIZE + 8 && + memcmp(buffer + 8, NO_AUTH_PROTO_DATA, + NO_AUTH_PROTO_SIZE) == 0) + { + reason = NO_AUTH_PROTO_DATA; + } + else + { + reason = "Unknown"; + } + + #ifdef WARNING + *logofs << "handleAuthorization: WARNING! X connection failed " + << "with error '" << reason << "' on FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + cerr << "Warning" << ": X connection failed " + << "with error '" << reason << "'.\n"; + } + #if defined(TEST) || defined(INFO) + else + { + *logofs << "handleAuthorization: X connection successful " + << "on FD#" << fd_ << ".\n" << logofs_flush; + } + #endif + + return 1; +} + +// +// Use a simple encoding. Need to handle the image +// requests in the usual way and the X_ListExtensions +// and X_QueryExtension to hide MIT-SHM and RENDER +// in the reply. +// + +int ServerChannel::handleFastWriteRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + // + // All the NX requests are handled in the + // main message loop. + // + + // + // Since ProtoStep7 (#issue 108) + // + // The X_PutImage can be handled here only + // if a split was not requested. + // + + if ((opcode >= X_NXFirstOpcode && opcode <= X_NXLastOpcode) || + (opcode == X_PutImage && splitState_.resource != nothing) || + opcode == X_ListExtensions || + opcode == X_QueryExtension) + { + return 0; + } + + #ifdef DEBUG + *logofs << "handleFastWriteRequest: Decoding raw request OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + buffer = writeBuffer_.addMessage(4); + + #ifndef __sun + + unsigned int *next = (unsigned int *) decodeBuffer.decodeMemory(4); + + *((unsigned int *) buffer) = *next; + + #else /* #ifndef __sun */ + + memcpy(buffer, decodeBuffer.decodeMemory(4), 4); + + #endif /* #ifndef __sun */ + + size = GetUINT(buffer + 2, bigEndian_) << 2; + + if (size < 4) + { + #ifdef WARNING + *logofs << "handleFastWriteRequest: WARNING! Assuming size 4 " + << "for suspicious message of size " << size + << ".\n" << logofs_flush; + #endif + + size = 4; + } + + writeBuffer_.registerPointer(&buffer); + + if (writeBuffer_.getAvailable() < size - 4 || + (int) size >= control -> TransportFlushBufferSize) + { + #ifdef DEBUG + *logofs << "handleFastWriteRequest: Using scratch buffer for OPCODE#" + << (unsigned int) opcode << " with size " << size << " and " + << writeBuffer_.getLength() << " bytes in buffer.\n" + << logofs_flush; + #endif + + // + // The procedure moving data to shared memory + // assumes that the full message is stored in + // the scratch buffer. We can safely let the + // scratch buffer inherit the decode buffer + // at the next offset. + // + + writeBuffer_.removeMessage(4); + + buffer = writeBuffer_.addScratchMessage(((unsigned char *) + decodeBuffer.decodeMemory(size - 4)) - 4, size); + } + else + { + writeBuffer_.addMessage(size - 4); + + #ifndef __sun + + if (size <= 32) + { + next = (unsigned int *) decodeBuffer.decodeMemory(size - 4); + + for (unsigned int i = 4; i < size; i += sizeof(unsigned int)) + { + *((unsigned int *) (buffer + i)) = *next++; + } + } + else + { + memcpy(buffer + 4, decodeBuffer.decodeMemory(size - 4), size - 4); + } + + #else /* #ifndef __sun */ + + memcpy(buffer + 4, decodeBuffer.decodeMemory(size - 4), size - 4); + + #endif /* #ifndef __sun */ + } + + // + // Opcode could have been tainted by the client + // proxy. Replace the original opcode with the + // one sent in the decode buffer. + // + + *buffer = opcode; + + writeBuffer_.unregisterPointer(); + + if (opcode == X_PutImage) + { + handleImage(opcode, buffer, size); + } + + #if defined(TEST) || defined(OPCODES) + + if (opcode != 0) + { + *logofs << "handleFastWriteRequest: Handled request " + << "OPCODE#" << (unsigned int) opcode << " (" + << DumpOpcode(opcode) << ") for FD#" << fd_ + << " sequence " << clientSequence_ << ". " + << size << " bytes out.\n" << logofs_flush; + } + else + { + *logofs << "handleFastWriteRequest: Handled image or " + << "other request for FD#" << fd_ + << " sequence " << clientSequence_ << ". " + << size << " bytes out.\n" << logofs_flush; + } + + #endif + + handleFlush(flush_if_needed); + + return 1; +} + +// +// Use the simplest encoding except for replies that +// need to be managed some way. +// + +int ServerChannel::handleFastReadReply(EncodeBuffer &encodeBuffer, const unsigned char &opcode, + const unsigned char *&buffer, const unsigned int &size) +{ + // + // If we pushed a X_GetInputFocus in the sequence + // queue this means that the original message was + // a NX request for which we have to provide a NX + // reply. + // + + if ((opcode >= X_NXFirstOpcode && + opcode <= X_NXLastOpcode) || + opcode == X_QueryExtension || + opcode == X_ListExtensions || + opcode == X_GetInputFocus) + { + return 0; + } + + #ifdef DEBUG + *logofs << "handleFastReadReply: Encoding raw reply OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ + << " with size " << size << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeMemory(buffer, size); + + // + // Send back the reply as soon + // as possible. + // + + priority_++; + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + *logofs << "handleFastReadReply: Handled raw reply OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ << " sequence " + << serverSequence_ << ". " << size << " bytes in, " + << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + #endif + + statistics -> addReplyBits(opcode, size << 3, bits); + + return 1; +} + +int ServerChannel::handleFastReadEvent(EncodeBuffer &encodeBuffer, const unsigned char &opcode, + const unsigned char *&buffer, const unsigned int &size) +{ + #ifdef DEBUG + *logofs << "handleFastReadEvent: Encoding raw " + << (opcode == X_Error ? "error" : "event") << " OPCODE#" + << (unsigned int) opcode << " for FD#" << fd_ + << " with size " << size << ".\n" + << logofs_flush; + #endif + + encodeBuffer.encodeMemory(buffer, size); + + switch (opcode) + { + case X_Error: + case ButtonPress: + case ButtonRelease: + case KeyPress: + case KeyRelease: + { + priority_++; + } + } + + int bits = encodeBuffer.diffBits(); + + #if defined(TEST) || defined(OPCODES) + + if (opcode == X_Error) + { + unsigned char code = *(buffer + 1); + + *logofs << "handleFastReadEvent: Handled error ERR_CODE#" + << (unsigned int) code << " for FD#" << fd_; + + *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_); + + *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_); + + *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10); + + *logofs << " sequence " << serverSequence_ << ". " << size + << " bytes in, " << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + } + else + { + *logofs << "handleFastReadEvent: Handled event OPCODE#" + << (unsigned int) *buffer << " for FD#" << fd_ + << " sequence " << serverSequence_ << ". " << size + << " bytes in, " << bits << " bits (" << ((float) bits) / 8 + << " bytes) out.\n" << logofs_flush; + } + + #endif + + statistics -> addEventBits(opcode, size << 3, bits); + + return 1; +} + +void ServerChannel::initCommitQueue() +{ + #ifdef TEST + *logofs << "initCommitQueue: Resetting the queue of split commits " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE; i++) + { + commitSequenceQueue_[i] = 0; + } +} + +void ServerChannel::updateCommitQueue(unsigned short sequence) +{ + for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE - 1; i++) + { + commitSequenceQueue_[i + 1] = commitSequenceQueue_[i]; + } + + #ifdef TEST + *logofs << "updateCommitQueue: Saved " << sequence + << " as last sequence number of image to commit.\n" + << logofs_flush; + #endif + + commitSequenceQueue_[0] = sequence; +} + +int ServerChannel::checkCommitError(unsigned char error, unsigned short sequence, + const unsigned char *buffer) +{ + // + // Check if error is due to an image commit + // generated at the end of a split. + // + // TODO: It should zero the head of the list + // when an event comes with a sequence number + // greater than the value of the last element + // added. + // + + for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE && + commitSequenceQueue_[i] != 0; i++) + { + #ifdef TEST + *logofs << "checkCommitError: Checking committed image's " + << "sequence number " << commitSequenceQueue_[i] + << " with input sequence " << sequence << ".\n" + << logofs_flush; + #endif + + if (commitSequenceQueue_[i] == sequence) + { + #ifdef WARNING + + *logofs << "checkCommitError: WARNING! Failed operation for " + << "FD#" << fd_ << " with ERR_CODE#" + << (unsigned int) *(buffer + 1); + + *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_); + + *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_); + + *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10); + + *logofs << " sequence " << sequence << ".\n"; + + *logofs << logofs_flush; + + #endif + + cerr << "Warning" << ": Failed commit operation " + << "with ERR_CODE#" << (unsigned int) error; + + cerr << " RES_ID#" << GetULONG(buffer + 4, bigEndian_); + + cerr << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_); + + cerr << " MAJ_OP#" << (unsigned int) *(buffer + 10); + + cerr << ".\n"; + + #ifdef WARNING + *logofs << "checkCommitError: WARNING! Suppressing error on " + << "OPCODE#" << (unsigned int) opcodeStore_ -> commitSplit + << " for FD#" << fd_ << " with sequence " << sequence + << " at position " << i << ".\n" << logofs_flush; + #endif + + return 0; + } + } + + return 0; +} + +// +// Check if the user pressed the CTRL+ALT+SHIFT+ESC +// keystroke. At the present moment it uses different +// keycodes based on the client OS. This should be +// implemented in a way that is platform independent +// (that's not an easy task, considered that we don't +// have access to the higher level X libraries). +// + +int ServerChannel::checkKeyboardEvent(unsigned char event, unsigned short sequence, + const unsigned char *buffer) +{ + #ifdef TEST + *logofs << "checkKeyboardEvent: Checking escape sequence with byte [1] " + << (void *) ((unsigned) *(buffer + 1)) << " and bytes [28-29] " + << (void *) ((unsigned) GetUINT(buffer + 28, bigEndian_)) + << " for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + #ifdef __APPLE__ + + int alert = (*(buffer + 1) == 0x3d && + GetUINT(buffer + 28, bigEndian_) == 0x2005); + + #else + + int alert = (*(buffer + 1) == 0x09 && + ((GetUINT(buffer + 28, bigEndian_) & + 0x0d) == 0x0d)); + + #endif + + if (alert == 1) + { + #ifdef PANIC + *logofs << "checkKeyboardEvent: PANIC! Received sequence " + << "CTRL+ALT+SHIFT+ESC " << "for FD#"<< fd_ + << ". Showing the abort dialog.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Received sequence CTRL+ALT+SHIFT+ESC. " + << "Showing the abort dialog.\n"; + + HandleAlert(CLOSE_UNRESPONSIVE_X_SERVER_ALERT, 1); + } + + return alert; +} + +// +// Handle the MIT-SHM initialization +// messages exchanged with the remote +// proxy. +// + +int ServerChannel::handleShmemReply(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned int stage, const unsigned char *buffer, + const unsigned int size) +{ + #ifdef TEST + *logofs << "handleShmemReply: Returning shmem reply for " + << "stage " << stage << ".\n" << logofs_flush; + #endif + + if (opcode == X_QueryExtension) + { + encodeBuffer.encodeValue(stage, 2); + +#ifndef ANDROID + shmemState_ -> present = *(buffer + 8); +#else + shmemState_ -> present = 0; + cerr << "Info: handleShmemReply: In android no shared memory. Setting present to 0 hardcoded\n"; +#endif + shmemState_ -> opcode = *(buffer + 9); + shmemState_ -> event = *(buffer + 10); + shmemState_ -> error = *(buffer + 11); + + #ifdef TEST + *logofs << "handleShmemReply: Extension present is " + << shmemState_ -> present << " with base OPCODE#" + << (unsigned int) shmemState_ -> opcode << " base event " + << (unsigned int) shmemState_ -> event << " base error " + << (unsigned int) shmemState_ -> error << ".\n" + << logofs_flush; + #endif + } + else if (opcode == X_GetInputFocus) + { + encodeBuffer.encodeValue(stage, 2); + + encodeBuffer.encodeBoolValue(0); + + if (shmemState_ -> present == 1 && + shmemState_ -> address != NULL && + shmemState_ -> segment > 0 && + shmemState_ -> id > 0) + { + cerr << "Info" << ": Using shared memory parameters 1/" + << (shmemState_ -> size / 1024) << "K.\n"; + +#ifndef ANDROID + shmemState_ -> enabled = 1; +#else + cerr << "Info: handleShmemReply: In android no shared memory. Setting enabled to -1. This should not be displayed\n"; + shmemState_ -> enabled = -1; +#endif + + encodeBuffer.encodeBoolValue(1); + } + else + { + #ifdef TEST + *logofs << "handleShmemReply: WARNING! Not using shared memory " + << "support in X server for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + cerr << "Info" << ": Using shared memory parameters 0/0K.\n"; + + handleShmemStateRemove(); + + encodeBuffer.encodeBoolValue(0); + } + } + else + { + #ifdef PANIC + *logofs << "handleShmemReply: PANIC! Conversation error " + << "handling shared memory support for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Conversation error handling " + << "shared memory support.\n"; + + return -1; + } + + return 1; +} + +int ServerChannel::handleShmemRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + // + // We need to query and initialize MIT-SHM on + // the real X server. To do this we'll need 3 + // requests. At the end we'll have to encode + // the final reply for the X client side. + // + + handleShmemStateAlloc(); + + unsigned int stage; + + decodeBuffer.decodeValue(stage, 2); + + unsigned int expected = shmemState_ -> stage + 1; + + if (stage != expected || stage > 2) + { + #ifdef PANIC + *logofs << "handleShmemRequest: PANIC! Unexpected stage " + << stage << " in handling shared memory " + << "support for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Unexpected stage " + << stage << " in handling shared memory " + << "support for FD#" << fd_ << ".\n"; + + return -1; + } + + switch (stage) + { + case 0: + { + unsigned int enableClient; + unsigned int enableServer; + + decodeBuffer.decodeBoolValue(enableClient); + decodeBuffer.decodeBoolValue(enableServer); + + unsigned int clientSegment; + unsigned int serverSegment; + + decodeBuffer.decodeValue(clientSegment, 29, 9); + decodeBuffer.decodeValue(serverSegment, 29, 9); + + shmemState_ -> segment = serverSegment; + + #ifdef TEST + *logofs << "handleShmemRequest: Size of the shared memory " + << "segment will be " << control -> ShmemServerSize + << ".\n" << logofs_flush; + #endif + + #ifdef TEST + *logofs << "handleShmemRequest: Sending X_QueryExtension request " + << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int) + opcodeStore_ -> getShmemParameters << " in stage " + << stage << ".\n" << logofs_flush; + #endif + + opcode = X_QueryExtension; + + size = 16; + buffer = writeBuffer_.addMessage(size); + + PutUINT(7, buffer + 4, bigEndian_); + + // + // Simply make the query fail if shared + // memory support is disabled by the + // user. + // +#ifndef ANDROID + if (control -> ShmemServer == 1 && + control -> ShmemServerSize > 0 && + enableServer == 1) + { + memcpy(buffer + 8, "MIT-SHM", 7); + } + else + { + memcpy(buffer + 8, "NO-MIT-", 7); + } +#else + cerr << "Info: handleShmemRequest: In android no shared memory. Returning NO-MIT- answer\n"; + + memcpy(buffer + 8, "NO-MIT-", 7); +#endif + sequenceQueue_.push(clientSequence_, opcode, + opcodeStore_ -> getShmemParameters, stage); + + // + // Save the sequence number so we can + // later identify any matching X error + // received from server. + // + + shmemState_ -> sequence = clientSequence_; + + break; + } + case 1: + { + if (shmemState_ -> present == 1) + { + // + // Make the segment read-write for everybody on + // Cygwin (to avoid any lack of support or any + // performance issue) and on MacOS/X (where the + // 0600 mask doesn't seem to work). + // + + #if defined(__CYGWIN32__) || defined(__APPLE__) + + int permissions = 0777; + + #else + + int permissions = 0600; + + #endif + + shmemState_ -> size = control -> ShmemServerSize; + +#ifndef ANDROID + shmemState_ -> id = shmget(IPC_PRIVATE, shmemState_ -> size, + IPC_CREAT | permissions); +#else + cerr << "Info: handleShmemReqyest: In android no shared memory (shmget). This message should not be displayed present should never be 1 in android\n"; + shmemState_ -> id = -1; +#endif + if (shmemState_ -> id >= 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleShmemRequest: Allocated shared memory " + << "segment of " << shmemState_ -> size + << " bytes with id " << shmemState_ -> id + << ".\n" << logofs_flush; + #endif + + +#ifndef ANDROID + shmemState_ -> address = shmat(shmemState_ -> id, 0, 0); +#else + cerr << "Info: handleShmemReqyest: In android no shared memory (shmat). This message should not be displayed. present should never be 1 in android\n"; + shmemState_ -> address = NULL; +#endif + if (shmemState_ -> address != NULL) + { + #ifdef TEST + *logofs << "handleShmemRequest: Sending X_ShmAttach request " + << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int) + opcodeStore_ -> getShmemParameters << " in stage " + << stage << ".\n" << logofs_flush; + #endif + + opcode = shmemState_ -> opcode; + + size = 16; + buffer = writeBuffer_.addMessage(size); + + *(buffer + 1) = X_ShmAttach; + + PutULONG(shmemState_ -> segment, buffer + 4, bigEndian_); + PutULONG(shmemState_ -> id, buffer + 8, bigEndian_); + + *(buffer + 12) = 1; + + shmemState_ -> sequence = clientSequence_; + + break; + } + else + { + #ifdef WARNING + *logofs << "handleShmemRequest: WARNING! Can't attach the shared " + << "memory segment. Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Can't attach the shared memory " + << "segment. Error is " << EGET() << " '" + << ESTR() << "'.\n"; + } + } + else + { + #ifndef __CYGWIN32__ + + #ifdef WARNING + *logofs << "handleShmemRequest: WARNING! Can't create the shared " + << "memory segment. Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Can't create the shared memory " + << "segment. Error is " << EGET() << " '" + << ESTR() << "'.\n"; + + #else + + #ifdef TEST + *logofs << "handleShmemRequest: WARNING! Can't create the shared " + << "memory segment. Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + #endif + } + } + + if (shmemState_ -> present != 0) + { + #ifdef TEST + *logofs << "handleShmemRequest: Resetting shared memory " + << "presence flag for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + shmemState_ -> present = 0; + } + + handleNullRequest(opcode, buffer, size); + + break; + } + default: + { + #ifdef TEST + *logofs << "handleShmemRequest: Sending X_GetInputFocus request " + << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int) + opcodeStore_ -> getShmemParameters << " in stage " + << stage << ".\n" << logofs_flush; + #endif + + opcode = X_GetInputFocus; + + size = 4; + buffer = writeBuffer_.addMessage(size); + + sequenceQueue_.push(clientSequence_, opcode, + opcodeStore_ -> getShmemParameters, stage); + break; + } + } + + shmemState_ -> stage += 1; + + return 1; +} + +// +// Handling of MIT-SHM extension has been plugged late in +// the design, so we have to make some assumptions. Image +// is a X_PutImage request contained either in the scratch +// buffer or in the normal write buffer. We need to move +// the image data to the shared memory segment and replace +// the X_PutImage request with a X_ShmPutImage. +// + +int ServerChannel::handleShmem(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size) +{ + if (shmemState_ == NULL || shmemState_ -> enabled != 1) + { + #ifdef TEST + + if (shmemState_ != NULL) + { + *logofs << "handleShmem: PANIC! Shared memory " + << "state found but support is not enabled " + << "for FD#" << fd_ << " in stage " + << shmemState_ -> stage << ".\n" + << logofs_flush; + } + + #endif + + return 0; + } +#ifdef ANDROID + cerr << "Info: handleShmem: In android no shared memory. enabled should never be 1. This should not be displayed\n"; + return 0; +#endif + + // + // Ignore null requests and requests that will not result + // in a single X_PutImage. To conform with the other func- + // tions, we get the opcode passed as a parameter. It can + // be zero if we don't want the write loop to put opcode + // and length in the resulting buffer. Anyway we are only + // interested in the original opcode of the request, that + // is stored in the image state. + // + + unsigned char *dstData = buffer + 24; + unsigned int dstDataSize = size - 24; + + if (dstDataSize == 0 || dstDataSize > + (unsigned int) control -> MaximumRequestSize) + { + #ifdef TEST + *logofs << "handleShmem: Ignoring image with opcode " + << (unsigned int) imageState_ -> opcode + << " and size " << size << " for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + return 0; + } + + #ifdef TEST + *logofs << "handleShmem: Handling image with opcode " + << (unsigned int) imageState_ -> opcode + << " and size " << size << " for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + // + // Get image data from buffer. + // + + if (imageState_ -> opcode == X_PutImage) + { + // + // We still need to get the image's data. + // + + imageState_ -> format = *(buffer + 1); + + imageState_ -> drawable = GetULONG(buffer + 4, bigEndian_); + imageState_ -> gcontext = GetULONG(buffer + 8, bigEndian_); + + imageState_ -> dstWidth = GetUINT(buffer + 12, bigEndian_); + imageState_ -> dstHeight = GetUINT(buffer + 14, bigEndian_); + + imageState_ -> srcX = 0; + imageState_ -> srcY = 0; + + imageState_ -> srcWidth = imageState_ -> dstWidth; + imageState_ -> srcHeight = imageState_ -> dstHeight; + + imageState_ -> dstX = GetUINT(buffer + 16, bigEndian_); + imageState_ -> dstY = GetUINT(buffer + 18, bigEndian_); + + imageState_ -> leftPad = *(buffer + 20); + imageState_ -> dstDepth = *(buffer + 21); + + imageState_ -> dstLines = imageState_ -> dstHeight; + + imageState_ -> dstLength = size - 24; + } + + // + // Skip the MIT-SHM operation if the image + // is 1 bits-per-plane. + // + + if (imageState_ -> dstDepth == 1) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleShmem: Ignoring image with opcode " + << (unsigned int) imageState_ -> opcode << " depth " + << (unsigned int) imageState_ -> dstDepth << " and " + << "size " << size << " for FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + return 0; + } + + // + // If the image can't fit in the available + // space, check if the completion event is + // arrived. + // + + #if defined(TEST) || defined(INFO) + + if (isTimestamp(shmemState_ -> last) == 0 && + shmemState_ -> offset != 0) + { + *logofs << "handleShmem: PANIC! No timestamp for sequence " + << shmemState_ -> sequence << " with offset " + << shmemState_ -> offset << ".\n" + << logofs_flush; + } + + #endif + + if (shmemState_ -> offset + imageState_ -> dstLength > + shmemState_ -> size) + { + if (imageState_ -> dstLength > shmemState_ -> size) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleShmem: WARNING! Can't fit the image " + << "in the available memory segment for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + return 0; + } + else if (handleShmemEvent() <= 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleShmem: WARNING! Missing completion " + << "after " << diffTimestamp(shmemState_ -> last, + getTimestamp()) << " Ms for shared memory " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + return 0; + } + } + + // + // Let image start at current offset + // in the shared segment. + // + + #ifdef TEST + *logofs << "handleShmem: Copying " << dstDataSize + << " bytes to shared memory at offset " + << shmemState_ -> offset << " for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + memcpy((unsigned char *) shmemState_ -> address + + shmemState_ -> offset, dstData, dstDataSize); + + // + // Get rid of the original X_PutImage + // request. + // + + if (writeBuffer_.getScratchData() != NULL) + { + writeBuffer_.removeScratchMessage(); + } + else + { + writeBuffer_.removeMessage(size); + } + + // + // Add a X_ShmPutImage request to the + // write buffer. + // + + buffer = writeBuffer_.addMessage(40); + + *buffer = shmemState_ -> opcode; + + *(buffer + 1) = X_ShmPutImage; + + PutUINT(40 >> 2, buffer + 2, bigEndian_); + + PutULONG(imageState_ -> drawable, buffer + 4, bigEndian_); + PutULONG(imageState_ -> gcontext, buffer + 8, bigEndian_); + + PutUINT(imageState_ -> dstWidth, buffer + 12, bigEndian_); + PutUINT(imageState_ -> dstLines, buffer + 14, bigEndian_); + + PutUINT(imageState_ -> srcX, buffer + 16, bigEndian_); + PutUINT(imageState_ -> srcY, buffer + 18, bigEndian_); + + PutUINT(imageState_ -> dstWidth, buffer + 20, bigEndian_); + PutUINT(imageState_ -> dstLines, buffer + 22, bigEndian_); + + PutUINT(imageState_ -> dstX, buffer + 24, bigEndian_); + PutUINT(imageState_ -> dstY, buffer + 26, bigEndian_); + + *(buffer + 28) = imageState_ -> dstDepth; + *(buffer + 29) = imageState_ -> format; + *(buffer + 30) = 1; + + PutULONG(shmemState_ -> segment, buffer + 32, bigEndian_); + PutULONG(shmemState_ -> offset, buffer + 36, bigEndian_); + + shmemState_ -> offset += dstDataSize; + + shmemState_ -> sequence = clientSequence_; + shmemState_ -> last = getTimestamp(); + + #ifdef TEST + *logofs << "handleShmem: Saved shared memory sequence " + << shmemState_ -> sequence << " for FD#" << fd_ + << " with offset " << shmemState_ -> offset + << " at " << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + + // + // Make the X server read immediately + // from the shared memory buffer and + // produce the completion event. + // + + handleFlush(flush_if_any); + + return 1; +} + +// +// Try to read more events from the socket in the +// attempt to get the completion event required +// to reset the MIT-SHM segment. +// + +int ServerChannel::handleShmemEvent() +{ + #if defined(TEST) || defined(INFO) + *logofs << "handleShmemEvent: Waiting for shared memory " + << "sequence " << shmemState_ -> sequence + << " for X server FD#" << fd_ << ".\n" + << logofs_flush; + + T_timestamp startTs = getTimestamp(); + + #endif + + while (isTimestamp(shmemState_ -> last) != 0) + { + if (handleWait(control -> ShmemTimeout) <= 0) + { + break; + } + #if defined(TEST) || defined(INFO) + else + { + *logofs << "handleShmemEvent: WARNING! Encoded events " + << "for FD#" << fd_ << " at " << strMsTimestamp() + << ".\n" << logofs_flush; + } + #endif + } + + if (isTimestamp(shmemState_ -> last) == 0) + { + #if defined(TEST) || defined(INFO) + *logofs << "handleShmemEvent: Spent " + << diffTimestamp(startTs, getTimestamp()) << " Ms " + << "waiting for shared memory sequence for FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + return 1; + } + + #if defined(TEST) || defined(INFO) + *logofs << "handleShmemEvent: WARNING! Can't reset shared " + << "memory sequence for FD#" << fd_ << " after " + << diffTimestamp(shmemState_ -> last, getTimestamp()) + << " Ms.\n" << logofs_flush; + #endif + + return 0; +} + +int ServerChannel::checkShmemEvent(unsigned char event, unsigned short sequence, + const unsigned char *buffer) +{ + if (isTimestamp(shmemState_ -> last) == 1 && + sequence == shmemState_ -> sequence) + { + #ifdef TEST + *logofs << "checkShmemEvent: Reset shared memory sequence " + << shmemState_ -> sequence << " for FD#" << fd_ + << " after " << diffTimestamp(shmemState_ -> last, + getTimestamp()) << " Ms.\n" << logofs_flush; + #endif + + shmemState_ -> sequence = 0; + shmemState_ -> offset = 0; + shmemState_ -> last = nullTimestamp(); + } + #ifdef TEST + else + { + *logofs << "checkShmemEvent: Skipping past shared memory " + << "image sequence " << sequence << " for FD#" + << fd_ << ".\n" << logofs_flush; + } + #endif + + return 1; +} + +int ServerChannel::checkShmemError(unsigned char error, unsigned short sequence, + const unsigned char *buffer) +{ + #ifdef TEST + + *logofs << "checkShmemError: WARNING! Failed operation for " + << "FD#" << fd_ << " in stage " << shmemState_ -> stage + << " with ERR_CODE#" << (unsigned int) *(buffer + 1); + + *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_); + + *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_); + + *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10); + + *logofs << " sequence " << sequence << ".\n"; + + *logofs << logofs_flush; + + #endif + + // + // If enabled flag is <= 0 we are still + // in the inizialization phase. In this + // case force presence to false. + // + + if (shmemState_ -> enabled != 1) + { + if (shmemState_ -> present != 0) + { + #ifdef TEST + *logofs << "checkShmemError: Resetting shared memory " + << "presence flag for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + shmemState_ -> present = 0; + } + + return 0; + } + + if (shmemState_ -> sequence == sequence) + { + // + // Reset the sequence and timestamp. + // + + shmemState_ -> sequence = 0; + shmemState_ -> offset = 0; + shmemState_ -> last = nullTimestamp(); + } + + return 1; +} + +int ServerChannel::handleFontRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + // + // Send a synchronization request and use + // the reply to return the requested font + // path. + // + + #ifdef TEST + *logofs << "handleFontRequest: Sending X_GetInputFocus request " + << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int) + opcodeStore_ -> getFontParameters << ".\n" + << logofs_flush; + #endif + + opcode = X_GetInputFocus; + + size = 4; + buffer = writeBuffer_.addMessage(size); + + sequenceQueue_.push(clientSequence_, X_GetInputFocus, + opcodeStore_ -> getFontParameters); + + return 1; +} + +int ServerChannel::handleFontReply(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) +{ + #ifdef TEST + *logofs << "handleFontReply: Encoding font operation " + << "reply with size " << size << ".\n" + << logofs_flush; + #endif + + char data[256]; + + if (fontPort_ != -1) + { + sprintf(data + 1, "tcp/localhost:%d", fontPort_); + } + else + { + *(data + 1) = '\0'; + } + + *data = strlen(data + 1); + + unsigned char *next = (unsigned char *) data; + + unsigned int length = (unsigned int) (*next++); + + encodeBuffer.encodeValue(length, 8); + + encodeBuffer.encodeTextData(next, length); + + return 1; +} + +int ServerChannel::handleCacheRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + unsigned int mask; + + decodeBuffer.decodeCachedValue(mask, 32, clientCache_ -> + setCacheParametersCache); + + splitState_.save = (mask >> 8) & 0xff; + splitState_.load = mask & 0xff; + + #ifdef TEST + *logofs << "handleCacheRequest: Set cache parameters to " + << "save " << splitState_.save << " load " + << splitState_.load << ".\n" << logofs_flush; + #endif + + handleNullRequest(opcode, buffer, size); + + return 1; +} + +int ServerChannel::handleStartSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + // + // Prepare for the split for the selected + // resource. Old proxy versions only used + // the split store at position 0. + // + + // Since ProtoStep7 (#issue 108) + unsigned char resource; + + decodeBuffer.decodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + splitState_.resource = resource; + + splitState_.current = splitState_.resource; + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleStartSplitRequest: SPLIT! Registered id " + << splitState_.resource << " as resource " + << "waiting for a split.\n" << logofs_flush; + #endif + + handleNullRequest(opcode, buffer, size); + + return 1; +} + +int ServerChannel::handleEndSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size) +{ + // + // Verify that the agent resource matches. + // + + // Since ProtoStep7 (#issue 108) + unsigned char resource; + + decodeBuffer.decodeCachedValue(resource, 8, + clientCache_ -> resourceCache); + + #ifdef TEST + + if (splitState_.resource == nothing) + { + #ifdef PANIC + *logofs << "handleEndSplitRequest: PANIC! SPLIT! Received an end of " + << "split for resource id " << (unsigned int) *(buffer + 1) + << " without a previous start.\n" + << logofs_flush; + #endif + + HandleCleanup(); + } + else if (resource != splitState_.resource) + { + #ifdef PANIC + *logofs << "handleEndSplitRequest: PANIC! SPLIT! Invalid resource id " + << resource << " received while waiting for resource id " + << splitState_.resource << ".\n" << logofs_flush; + #endif + + HandleCleanup(); + } + + #endif + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleEndSplitRequest: SPLIT! Reset id " + << splitState_.resource << " as resource " + << "selected for splits.\n" << logofs_flush; + #endif + + splitState_.resource = nothing; + + handleNullRequest(opcode, buffer, size); + + return 1; +} + +int ServerChannel::handleSplitChecksum(DecodeBuffer &decodeBuffer, T_checksum &checksum) +{ + unsigned int receive; + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeBoolValue(receive); + + if (receive == 1) + { + checksum = new md5_byte_t[MD5_LENGTH]; + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + decodeBuffer.decodeValue(receive, 8); + + if (checksum != NULL) + { + checksum[i] = (unsigned char) receive; + } + } + + #if defined(TEST) || defined(SPLIT) + *logofs << "handleSplitChecksum: SPLIT! Received checksum " + << "[" << DumpChecksum(checksum) << "].\n" + << logofs_flush; + #endif + + return 1; + } + + return 0; +} + +void ServerChannel::handleShmemStateAlloc() +{ + if (shmemState_ == NULL) + { + shmemState_ = new T_shmem_state(); + + shmemState_ -> stage = -1; + shmemState_ -> present = -1; + shmemState_ -> enabled = -1; + + shmemState_ -> segment = -1; + shmemState_ -> id = -1; + shmemState_ -> address = NULL; + shmemState_ -> size = 0; + + shmemState_ -> opcode = 0xff; + shmemState_ -> event = 0xff; + shmemState_ -> error = 0xff; + + shmemState_ -> sequence = 0; + shmemState_ -> offset = 0; + shmemState_ -> last = nullTimestamp(); + + shmemState_ -> checked = 0; + } +} + +void ServerChannel::handleShmemStateRemove() +{ + if (shmemState_ != NULL) + { + if (shmemState_ -> address != NULL) + { +#ifndef ANDROID + shmdt((char *) shmemState_ -> address); +#else + cerr << "Info: handleShmemStateRemove: In android no shared memory. This should not be displayed. address should always be NULL\n"; +#endif + } + + if (shmemState_ -> id > 0) + { +#ifndef ANDROID + shmctl(shmemState_ -> id, IPC_RMID, 0); +#else + cerr << "Info: handleShmemStateRemove: In android no shared memory. This should not be displayed. id should always be 0\n"; +#endif + } + + delete shmemState_; + + shmemState_ = NULL; + } +} + +void ServerChannel::handleUnpackStateInit(int resource) +{ + if (unpackState_[resource] == NULL) + { + unpackState_[resource] = new T_unpack_state(); + + if (unpackState_[resource] == NULL) + { + #ifdef PANIC + *logofs << "handleUnpackStateInit: PANIC! Can't allocate " + << "memory for unpack state in context [A].\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "unpack state in context [A].\n"; + + HandleAbort(); + } + + unpackState_[resource] -> geometry = NULL; + unpackState_[resource] -> colormap = NULL; + unpackState_[resource] -> alpha = NULL; + } +} + +void ServerChannel::handleUnpackAllocGeometry(int resource) +{ + if (unpackState_[resource] -> geometry == NULL) + { + unpackState_[resource] -> geometry = new T_geometry(); + + if (unpackState_[resource] -> geometry == NULL) + { + #ifdef PANIC + *logofs << "handleUnpackAllocGeometry: PANIC! Can't allocate " + << "memory for unpack state in context [B].\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "unpack state in context [B].\n"; + + HandleAbort(); + } + + unpackState_[resource] -> geometry -> depth1_bpp = 4; + unpackState_[resource] -> geometry -> depth4_bpp = 4; + unpackState_[resource] -> geometry -> depth8_bpp = 8; + unpackState_[resource] -> geometry -> depth16_bpp = 16; + unpackState_[resource] -> geometry -> depth24_bpp = 32; + unpackState_[resource] -> geometry -> depth32_bpp = 32; + + unpackState_[resource] -> geometry -> red_mask = 0xff0000; + unpackState_[resource] -> geometry -> green_mask = 0x00ff00; + unpackState_[resource] -> geometry -> blue_mask = 0x0000ff; + + unpackState_[resource] -> geometry -> image_byte_order = imageByteOrder_; + unpackState_[resource] -> geometry -> bitmap_bit_order = bitmapBitOrder_; + unpackState_[resource] -> geometry -> scanline_unit = scanlineUnit_; + unpackState_[resource] -> geometry -> scanline_pad = scanlinePad_; + } +} + +void ServerChannel::handleUnpackAllocColormap(int resource) +{ + if (unpackState_[resource] -> colormap == NULL) + { + unpackState_[resource] -> colormap = new T_colormap(); + + if (unpackState_[resource] -> colormap == NULL) + { + #ifdef PANIC + *logofs << "handleUnpackAllocColormap: PANIC! Can't allocate " + << "memory for unpack state in context [C].\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "unpack state in context [C].\n"; + + HandleAbort(); + } + + unpackState_[resource] -> colormap -> entries = 0; + unpackState_[resource] -> colormap -> data = NULL; + } +} + +void ServerChannel::handleUnpackAllocAlpha(int resource) +{ + if (unpackState_[resource] -> alpha == NULL) + { + unpackState_[resource] -> alpha = new T_alpha(); + + if (unpackState_[resource] -> alpha == NULL) + { + #ifdef PANIC + *logofs << "handleUnpackAllocAlpha: PANIC! Can't allocate " + << "memory for unpack state in context [D].\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "unpack state in context [D].\n"; + + HandleAbort(); + } + + unpackState_[resource] -> alpha -> entries = 0; + unpackState_[resource] -> alpha -> data = NULL; + } +} + +void ServerChannel::handleUnpackStateRemove(int resource) +{ + if (unpackState_[resource] != NULL) + { + delete unpackState_[resource] -> geometry; + + if (unpackState_[resource] -> colormap != NULL) + { + delete [] unpackState_[resource] -> colormap -> data; + } + + delete unpackState_[resource] -> colormap; + + if (unpackState_[resource] -> alpha != NULL) + { + delete [] unpackState_[resource] -> alpha -> data; + } + + delete unpackState_[resource] -> alpha; + + delete unpackState_[resource]; + + unpackState_[resource] = NULL; + } +} + +void ServerChannel::handleEncodeCharInfo(const unsigned char *nextSrc, EncodeBuffer &encodeBuffer) +{ + unsigned int value = GetUINT(nextSrc, bigEndian_) | + (GetUINT(nextSrc + 10, bigEndian_) << 16); + + encodeBuffer.encodeCachedValue(value, 32, + *serverCache_ -> queryFontCharInfoCache[0], 6); + + nextSrc += 2; + + for (unsigned int i = 1; i < 5; i++) + { + unsigned int value = GetUINT(nextSrc, bigEndian_); + + nextSrc += 2; + + encodeBuffer.encodeCachedValue(value, 16, + *serverCache_ -> queryFontCharInfoCache[i], 6); + } +} + +int ServerChannel::setBigEndian(int flag) +{ + bigEndian_ = flag; + + readBuffer_.setBigEndian(flag); + + return 1; +} + +int ServerChannel::setReferences() +{ + #ifdef TEST + *logofs << "ServerChannel: Initializing the static " + << "members for the server channels.\n" + << logofs_flush; + #endif + + #ifdef REFERENCES + + references_ = 0; + + #endif + + return 1; +} diff --git a/nxcomp/src/ServerChannel.h b/nxcomp/src/ServerChannel.h new file mode 100644 index 000000000..374e52896 --- /dev/null +++ b/nxcomp/src/ServerChannel.h @@ -0,0 +1,529 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ServerChannel_H +#define ServerChannel_H + +#include "List.h" +#include "Channel.h" + +#include "SequenceQueue.h" + +#include "ServerReadBuffer.h" + +#include "Unpack.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// How many sequence numbers of split commit +// requests we are going to save in order to +// mask errors. +// + +#define MAX_COMMIT_SEQUENCE_QUEUE 16 + +// +// Define this to know when a channel +// is created or destroyed. +// + +#undef REFERENCES + +// +// This class implements the X server +// side compression of X protocol. +// + +class ServerChannel : public Channel +{ + public: + + ServerChannel(Transport *transport, StaticCompressor *compressor); + + virtual ~ServerChannel(); + + virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, + unsigned int length); + + virtual int handleWrite(const unsigned char *message, unsigned int length); + + virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, + T_store_action action, int position, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size) + { + return 0; + } + + virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, + T_store_action action, int position, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + virtual int handleSplit(EncodeBuffer &encodeBuffer) + { + return 0; + } + + virtual int handleSplit(DecodeBuffer &decodeBuffer); + + virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split); + + virtual int handleSplitEvent(DecodeBuffer &decodeBuffer) + { + return 0; + } + + // + // Send the last motion notify event + // received from the X server to the + // remote proxy. + // + + virtual int handleMotion(EncodeBuffer &encodeBuffer); + + virtual int handleCompletion(EncodeBuffer &encodeBuffer) + { + return 0; + } + + virtual int handleConfiguration(); + + virtual int handleFinish(); + + virtual int handleAsyncEvents(); + + virtual int needSplit() const + { + return 0; + } + + virtual int needMotion() const + { + return (lastMotion_[0] != '\0'); + } + + virtual T_channel_type getType() const + { + return channel_x11; + } + + int setBigEndian(int flag); + + // + // Initialize the static members. + // + + static int setReferences(); + + private: + + int handleFastReadReply(EncodeBuffer &encodeBuffer, const unsigned char &opcode, + const unsigned char *&buffer, const unsigned int &size); + + int handleFastReadEvent(EncodeBuffer &encodeBuffer, const unsigned char &opcode, + const unsigned char *&buffer, const unsigned int &size); + + int handleFastWriteRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + // + // Handle the fake authorization cookie + // and the X server's reply. + // + + int handleAuthorization(unsigned char *buffer); + int handleAuthorization(const unsigned char *buffer, int size); + + // + // Set the unpack colormap and the alpha + // blending data to be used to unpack + // images. + // + + int handleGeometry(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size); + + int handleColormap(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size); + + int handleAlpha(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size); + + // + // Manage the decoded buffer to unpack + // the image and move the data to the + // shared memory segment. + // + + int handleImage(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size); + + // + // Uncompress a packed image in one + // or more graphic X requests. + // + + int handleUnpack(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size); + + // + // Move the image to the shared + // memory buffer. + // + + int handleShmem(unsigned char &opcode, unsigned char *&buffer, + unsigned int &size); + + // + // Handle suppression of error on + // commit of image splits. + // + + void initCommitQueue(); + + void updateCommitQueue(unsigned short sequence); + + int checkCommitError(unsigned char error, unsigned short sequence, + const unsigned char *buffer); + + void clearCommitQueue() + { + if (commitSequenceQueue_[0] != 0) + { + initCommitQueue(); + } + } + + // + // Check if the user pressed the + // CTRL+ALT+SHIFT+ESC keystroke. + // + + int checkKeyboardEvent(unsigned char event, unsigned short sequence, + const unsigned char *buffer); + + // + // Other utilities. + // + + void handleEncodeCharInfo(const unsigned char *nextSrc, EncodeBuffer &encodeBuffer); + + // + // Handle the MIT-SHM initialization + // messages exchanged with the remote + // proxy. + // + + int handleShmemRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + + int handleShmemReply(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned int stage, const unsigned char *buffer, + const unsigned int size); + + // + // Try to read more events in the attempt to + // get the MIT-SHM image completion event + // from the X server. + // + + int handleShmemEvent(); + + // + // Handle the MIT-SHM events as they are read + // from the socket. + // + + int checkShmemEvent(unsigned char event, unsigned short sequence, + const unsigned char *buffer); + + int checkShmemError(unsigned char error, unsigned short sequence, + const unsigned char *buffer); + + // + // Query the port used to tunnel + // the font server connections. + // + + int handleFontRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + int handleFontReply(EncodeBuffer &encodeBuffer, const unsigned char opcode, + const unsigned char *buffer, const unsigned int size); + + // + // Set the cache policy for image + // requests. + // + + int handleCacheRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + // + // Decode the start and end split + // requests. + // + + int handleStartSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + int handleEndSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + // + // Remove the split store and the + // incomplete messages from the + // memory cache. + // + + int handleAbortSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + // + // Send the split requests to the + // X server once they have been + // recomposed. + // + + int handleCommitSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode, + unsigned char *&buffer, unsigned int &size); + + int handleSplitChecksum(DecodeBuffer &decodeBuffer, T_checksum &checksum); + + // + // Allocate and free the shared memory + // support resources. + // + + void handleShmemStateAlloc(); + void handleShmemStateRemove(); + + // + // Temporary storage for the image info. + // + + void handleImageStateAlloc(unsigned char opcode) + { + if (imageState_ == NULL) + { + imageState_ = new T_image_state(); + } + + imageState_ -> opcode = opcode; + } + + void handleImageStateRemove() + { + if (imageState_ != NULL) + { + delete imageState_; + + imageState_ = NULL; + } + } + + // + // Store the information needed to unpack + // images per each known agent's client. + // + + void handleUnpackStateInit(int resource); + + void handleUnpackAllocGeometry(int resource); + void handleUnpackAllocColormap(int resource); + void handleUnpackAllocAlpha(int resource); + + void handleUnpackStateRemove(int resource); + + typedef struct + { + T_geometry *geometry; + T_colormap *colormap; + T_alpha *alpha; + + } T_unpack_state; + + T_unpack_state *unpackState_[256]; + + // + // Own read buffer. It is able to identify + // full messages read from X descriptor. + // + + ServerReadBuffer readBuffer_; + + // + // Sequence number of last request coming + // from X client or X server. + // + + unsigned int clientSequence_; + unsigned int serverSequence_; + + // + // Used to identify replies based on sequence + // number of original request. + // + + SequenceQueue sequenceQueue_; + + // + // Last motion notify read from the X server. + // + + unsigned char lastMotion_[32]; + + // + // Sequence numbers of last auto-generated + // put image requests. Needed to intercept + // and suppress errors generated by such + // requests. + // + + unsigned int commitSequenceQueue_[MAX_COMMIT_SEQUENCE_QUEUE]; + + // + // Let agent select which expose + // events is going to receive. + // + + unsigned int enableExpose_; + unsigned int enableGraphicsExpose_; + unsigned int enableNoExpose_; + + // + // Used in initialization and handling + // of MIT-SHM shared memory put images. + // + + typedef struct + { + int stage; + int present; + int enabled; + int segment; + int id; + void *address; + unsigned int size; + + unsigned char opcode; + unsigned char event; + unsigned char error; + + unsigned int sequence; + unsigned int offset; + T_timestamp last; + + unsigned int checked; + + } T_shmem_state; + + T_shmem_state *shmemState_; + + // + // Used to pass current image data between + // the different decompression stages. + // + + typedef struct + { + unsigned char opcode; + + unsigned int drawable; + unsigned int gcontext; + + unsigned char method; + + unsigned char format; + unsigned char srcDepth; + unsigned char dstDepth; + + unsigned int srcLength; + unsigned int dstLength; + unsigned int dstLines; + + short int srcX; + short int srcY; + unsigned short srcWidth; + unsigned short srcHeight; + + short int dstX; + short int dstY; + unsigned short dstWidth; + unsigned short dstHeight; + + unsigned char leftPad; + + } T_image_state; + + T_image_state *imageState_; + + // + // The flags is set according to the + // split load and save policy set by + // the encoding side. + // + + typedef struct + { + int resource; + int current; + int load; + int save; + int commit; + + } T_split_state; + + T_split_state splitState_; + + // + // List of agent resources. + // + + List splitResources_; + + // + // Keep track of object creation and + // deletion. + // + + private: + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +#endif /* ServerChannel_H */ diff --git a/nxcomp/src/ServerProxy.cpp b/nxcomp/src/ServerProxy.cpp new file mode 100644 index 000000000..28f94842a --- /dev/null +++ b/nxcomp/src/ServerProxy.cpp @@ -0,0 +1,621 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "NXalert.h" + +#include "Socket.h" + +#include "ServerProxy.h" + +#include "ServerChannel.h" +#include "GenericChannel.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Log the operations related to sending +// and receiving the control tokens. +// + +#undef TOKEN + +ServerProxy::ServerProxy(int proxyFd) : Proxy(proxyFd) + +{ + xServerAddrFamily_ = -1; + xServerAddrLength_ = 0; + + xServerAddr_ = NULL; + xServerDisplay_ = NULL; + + cupsServerPort_ = NULL; + smbServerPort_ = NULL; + mediaServerPort_ = NULL; + httpServerPort_ = NULL; + + fontServerPort_ = NULL; + + #ifdef DEBUG + *logofs << "ServerProxy: Created new object at " << this + << ".\n" << logofs_flush; + #endif +} + +ServerProxy::~ServerProxy() +{ + delete xServerAddr_; + + delete [] xServerDisplay_; + + delete [] fontServerPort_; + + #ifdef DEBUG + *logofs << "ServerProxy: Deleted object at " << this + << ".\n" << logofs_flush; + #endif +} + +void ServerProxy::handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, + sockaddr *xServerAddr, unsigned int xServerAddrLength) +{ + delete xServerAddr_; + + xServerAddr_ = xServerAddr; + + xServerAddrFamily_ = xServerAddrFamily; + xServerAddrLength_ = xServerAddrLength; + + delete [] xServerDisplay_; + + xServerDisplay_ = new char[strlen(xServerDisplay) + 1]; + + strcpy(xServerDisplay_, xServerDisplay); + + #ifdef DEBUG + *logofs << "ServerProxy: Set display configuration to display '" + << xServerDisplay_ << "'.\n" + << logofs_flush; + #endif +} + +void ServerProxy::handlePortConfiguration(ChannelEndPoint &cupsServerPort, + ChannelEndPoint &smbServerPort, + ChannelEndPoint &mediaServerPort, + ChannelEndPoint &httpServerPort, + const char *fontServerPort) +{ + cupsServerPort_ = cupsServerPort; + smbServerPort_ = smbServerPort; + mediaServerPort_ = mediaServerPort; + httpServerPort_ = httpServerPort; + + delete [] fontServerPort_; + + fontServerPort_ = new char[strlen(fontServerPort) + 1]; + + strcpy(fontServerPort_, fontServerPort); + + #ifdef DEBUG + *logofs << "ServerProxy: Set port configuration to CUPS " + << cupsServerPort_ << ", SMB " << smbServerPort_ + << ", media " << mediaServerPort_ << ", HTTP " + << httpServerPort_ << ".\n" + << logofs_flush; + #endif +} + +int ServerProxy::handleNewConnection(T_channel_type type, int clientFd) +{ + switch (type) + { + case channel_font: + { + return handleNewGenericConnection(clientFd, channel_font, "font"); + } + case channel_slave: + { + return handleNewSlaveConnection(clientFd); + } + default: + { + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Unsupported channel with type '" + << getTypeName(type) << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unsupported channel with type '" + << getTypeName(type) << "'.\n"; + + return -1; + } + } +} + +int ServerProxy::handleNewConnectionFromProxy(T_channel_type type, int channelId) +{ + switch (type) + { + case channel_x11: + { + return handleNewXConnectionFromProxy(channelId); + } + case channel_cups: + { + return handleNewGenericConnectionFromProxy(channelId, channel_cups, + cupsServerPort_, "CUPS"); + } + case channel_smb: + { + smbServerPort_.setDefaultTCPInterface(1); + return handleNewGenericConnectionFromProxy(channelId, channel_smb, + smbServerPort_, "SMB"); + } + case channel_media: + { + return handleNewGenericConnectionFromProxy(channelId, channel_media, + mediaServerPort_, "media"); + } + case channel_http: + { + return handleNewGenericConnectionFromProxy(channelId, channel_http, + httpServerPort_, "HTTP"); + } + case channel_slave: + { + return handleNewSlaveConnectionFromProxy(channelId); + } + default: + { + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Unsupported channel with type '" + << getTypeName(type) << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Unsupported channel with type '" + << getTypeName(type) << "'.\n"; + + return -1; + } + } +} + +int ServerProxy::handleNewAgentConnection(Agent *agent) +{ + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Can't create an agent " + << "connection at this side.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't create an agent " + << "connection at this side.\n"; + + return -1; +} + +int ServerProxy::handleNewXConnection(int clientFd) +{ + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Can't create a new X channel " + << "with FD#" << clientFd << " at this side.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't create a new X channel " + << "with FD#" << clientFd << " at this side.\n"; + + return -1; +} + +int ServerProxy::handleNewXConnectionFromProxy(int channelId) +{ + // + // Connect to the real X server. + // + + int retryConnect = control -> OptionServerRetryConnect; + + int xServerFd; + + for (;;) + { + xServerFd = socket(xServerAddrFamily_, SOCK_STREAM, PF_UNSPEC); + + if (xServerFd < 0) + { + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Call to socket failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Call to socket failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + return -1; + } + + #ifdef TEST + *logofs << "ServerProxy: Trying to connect to X server '" + << xServerDisplay_ << "'.\n" << logofs_flush; + #endif + + int result = connect(xServerFd, xServerAddr_, xServerAddrLength_); + + getNewTimestamp(); + + if (result < 0) + { + #ifdef WARNING + *logofs << "ServerProxy: WARNING! Connection to '" + << xServerDisplay_ << "' failed with error '" + << ESTR() << "'. Retrying.\n" << logofs_flush; + #endif + + close(xServerFd); + + if (--retryConnect == 0) + { + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Connection to '" + << xServerDisplay_ << "' for channel ID#" + << channelId << " failed. Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Connection to '" + << xServerDisplay_ << "' failed. Error is " + << EGET() << " '" << ESTR() << "'.\n"; + + close(xServerFd); + + return -1; + } + + if (activeChannels_.getSize() == 0) + { + sleep(2); + } + else + { + sleep(1); + } + } + else + { + break; + } + } + + assignChannelMap(channelId, xServerFd); + + #ifdef TEST + *logofs << "ServerProxy: X server descriptor FD#" << xServerFd + << " mapped to channel ID#" << channelId << ".\n" + << logofs_flush; + #endif + + // + // Turn queuing off for path proxy-to-X-server. + // + + if (control -> OptionServerNoDelay == 1) + { + SetNoDelay(xServerFd, control -> OptionServerNoDelay); + } + + // + // If requested, set the size of the TCP send + // and receive buffers. + // + + if (control -> OptionServerSendBuffer != -1) + { + SetSendBuffer(xServerFd, control -> OptionServerSendBuffer); + } + + if (control -> OptionServerReceiveBuffer != -1) + { + SetReceiveBuffer(xServerFd, control -> OptionServerReceiveBuffer); + } + + if (allocateTransport(xServerFd, channelId) < 0) + { + return -1; + } + + // + // Starting from protocol level 3 client and server + // caches are created in proxy and shared between all + // channels. If remote proxy has older protocol level + // pointers are NULL and channels must create their + // own instances. + // + + channels_[channelId] = new ServerChannel(transports_[channelId], compressor_); + + if (channels_[channelId] == NULL) + { + deallocateTransport(channelId); + + return -1; + } + + increaseChannels(channelId); + + // + // Propagate channel stores and caches to the new + // channel. + // + + channels_[channelId] -> setOpcodes(opcodeStore_); + + channels_[channelId] -> setStores(clientStore_, serverStore_); + + channels_[channelId] -> setCaches(clientCache_, serverCache_); + + int port = atoi(fontServerPort_); + + if (port > 0) + { + channels_[channelId] -> setPorts(port); + } + + // + // Let channel configure itself according + // to control parameters. + // + + channels_[channelId] -> handleConfiguration(); + + // + // Check if we have successfully loaded the + // selected cache and, if not, remove it + // from disk. + // + + handleCheckLoad(); + + return 1; +} + +// +// Check if we still need to drop a channel. We need +// to check this explicitly at the time we receive a +// request to load or save the cache because we could +// receive the control message before having entered +// the function handling the channel events. +// + +int ServerProxy::handleCheckDrop() +{ + T_list channelList = activeChannels_.copyList(); + + for (T_list::iterator j = channelList.begin(); + j != channelList.end(); j++) + { + int channelId = *j; + + if (channels_[channelId] != NULL && + (channels_[channelId] -> getDrop() == 1 || + channels_[channelId] -> getClosing() == 1)) + { + #ifdef TEST + *logofs << "ServerProxy: Dropping the descriptor FD#" + << getFd(channelId) << " channel ID#" + << channelId << ".\n" << logofs_flush; + #endif + + handleDrop(channelId); + } + } + + return 1; +} + +int ServerProxy::handleCheckLoad() +{ + // + // Check if we just created the first X channel + // but the client side didn't tell us to load + // the cache selected at the session negotiation. + // This is very likely because the load operation + // failed at the remote side, for example because + // the cache was invalid or corrupted. + // + + int channelCount = getChannels(channel_x11); + + if (channelCount != 1) + { + return 0; + } + + if (control -> PersistentCacheEnableLoad == 1 && + control -> PersistentCachePath != NULL && + control -> PersistentCacheName != NULL && + isTimestamp(timeouts_.loadTs) == 0) + { + #ifdef WARNING + *logofs << "ServerProxy: WARNING! Cache file '" << control -> PersistentCachePath + << "/" << control -> PersistentCacheName << "' not loaded.\n" + << logofs_flush; + #endif + + // + // Remove the cache file. + // + + #ifdef WARNING + *logofs << "ServerProxy: WARNING! Removing supposedly " + << "incompatible cache '" << control -> PersistentCachePath + << "/" << control -> PersistentCacheName + << "'.\n" << logofs_flush; + #endif + + handleResetPersistentCache(); + } + + return 1; +} + +int ServerProxy::handleLoadFromProxy() +{ + // + // Be sure we drop any confirmed channel. + // + + handleCheckDrop(); + + // + // Check that either no X channel is + // remaining or we are inside a reset. + // + + int channelCount = getChannels(channel_x11); + + if (channelCount > 0) + { + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Protocol violation " + << "in command load with " << channelCount + << " channels.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Protocol violation " + << "in command load from proxy.\n"; + + return -1; + } + else if (handleLoadStores() < 0) + { + #ifdef WARNING + *logofs << "ServerProxy: WARNING! Failed to load content " + << "of persistent cache.\n" << logofs_flush; + #endif + + return -1; + } + + return 1; +} + +int ServerProxy::handleSaveFromProxy() +{ + // + // Be sure we drop any confirmed channel. + // + + handleCheckDrop(); + + // + // Now verify that all channels are gone. + // + + int channelCount = getChannels(channel_x11); + + if (channelCount > 0) + { + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Protocol violation " + << "in command save with " << channelCount + << " channels.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Protocol violation " + << "in command save from proxy.\n"; + + return -1; + } + else if (handleSaveStores() < 0) + { + #ifdef PANIC + *logofs << "ServerProxy: PANIC! Failed to save stores " + << "to persistent cache.\n" << logofs_flush; + #endif + + return -1; + } + + return 1; +} + +int ServerProxy::handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient) const +{ + if (clientStore_ -> saveRequestStores(cachefs, md5StateStream, md5StateClient, + discard_checksum, use_data) < 0) + { + return -1; + } + else if (serverStore_ -> saveReplyStores(cachefs, md5StateStream, md5StateClient, + use_checksum, discard_data) < 0) + { + return -1; + } + else if (serverStore_ -> saveEventStores(cachefs, md5StateStream, md5StateClient, + use_checksum, discard_data) < 0) + { + return -1; + } + + return 1; +} + +int ServerProxy::handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const +{ + if (clientStore_ -> loadRequestStores(cachefs, md5StateStream, + discard_checksum, use_data) < 0) + { + return -1; + } + else if (serverStore_ -> loadReplyStores(cachefs, md5StateStream, + use_checksum, discard_data) < 0) + { + return -1; + } + else if (serverStore_ -> loadEventStores(cachefs, md5StateStream, + use_checksum, discard_data) < 0) + { + return -1; + } + + return 1; +} diff --git a/nxcomp/src/ServerProxy.h b/nxcomp/src/ServerProxy.h new file mode 100644 index 000000000..e169c4aec --- /dev/null +++ b/nxcomp/src/ServerProxy.h @@ -0,0 +1,154 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ServerProxy_H +#define ServerProxy_H + +#include +#include + +#include "Proxy.h" + +#include "Misc.h" +#include "ChannelEndPoint.h" + +// +// Set the verbosity level. +// + +#undef TEST +#undef DEBUG + +class ServerProxy : public Proxy +{ + public: + + ServerProxy(int proxyFd); + + virtual ~ServerProxy(); + + virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily, + sockaddr *xServerAddr, unsigned int xServerAddrLength); + + virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort, + ChannelEndPoint &smbServerPort, + ChannelEndPoint &mediaServerPort, + ChannelEndPoint &httpServerPort, + const char *fontServerPort); + + protected: + + // + // Create a new channel. + // + + virtual int handleNewConnection(T_channel_type type, int clientFd); + + virtual int handleNewConnectionFromProxy(T_channel_type type, int channelId); + + virtual int handleNewAgentConnection(Agent *agent); + + virtual int handleNewXConnection(int clientFd); + + virtual int handleNewXConnectionFromProxy(int channelId); + + // + // Implement persistence according + // to our proxy mode. + // + + virtual int handleLoad(T_load_type type) + { + return 0; + } + + virtual int handleSave() + { + return 0; + } + + virtual int handleAsyncEvents() + { + return 0; + } + + virtual int handleLoadFromProxy(); + virtual int handleSaveFromProxy(); + + virtual int handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient) const; + + virtual int handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const; + + int handleCheckDrop(); + int handleCheckLoad(); + + // + // Utility function used to realize + // a new connection. + // + + protected: + + virtual int checkLocalChannelMap(int channelId) + { + // Since ProtoStep7 (#issue 108) + return ((channelId & control -> ChannelMask) == 0); + } + + private: + + // FIXME: Use a ChannelEndPoint object also for the X server! + int xServerAddrFamily_; + sockaddr *xServerAddr_; + unsigned int xServerAddrLength_; + + // + // This is the name of the X display where + // we are going to forward connections. + // + + char *xServerDisplay_; + + // + // Ports where to forward extended services' + // TCP connections. + // + + ChannelEndPoint cupsServerPort_; + ChannelEndPoint smbServerPort_; + ChannelEndPoint mediaServerPort_; + ChannelEndPoint httpServerPort_; + + // + // It will have to be passed to the channel + // so that it can set the port where the + // font server connections are tunneled. + // + + char *fontServerPort_; +}; + +#endif /* ServerProxy_H */ diff --git a/nxcomp/src/ServerReadBuffer.cpp b/nxcomp/src/ServerReadBuffer.cpp new file mode 100644 index 000000000..277b85216 --- /dev/null +++ b/nxcomp/src/ServerReadBuffer.cpp @@ -0,0 +1,247 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ServerReadBuffer.h" +#include "ServerChannel.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +unsigned int ServerReadBuffer::suggestedLength(unsigned int pendingLength) +{ + // + // Always read all the data that + // is available. + // + + int readable = transport_ -> readable(); + + unsigned int readLength = (readable == -1 ? 0 : (unsigned int) readable); + + if (readLength < pendingLength) + { + readLength = pendingLength; + } + + // + // Even if the readable data is not + // enough to make a complete message, + // resize the buffer to accommodate + // it all. + // + + if (pendingLength < remaining_) + { + readLength = remaining_; + } + + return readLength; +} + +int ServerReadBuffer::locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength) +{ + unsigned int size = end - start; + + #ifdef TEST + *logofs << "ServerReadBuffer: Locating message for FD#" + << transport_ -> fd() << " with " << size + << " bytes.\n" << logofs_flush; + #endif + + if (firstMessage_) + { + if (size < 8) + { + remaining_ = 8 - size; + + #ifdef TEST + *logofs << "ServerReadBuffer: No message was located " + << "with remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + dataLength = 8 + (GetUINT(start + 6, bigEndian_) << 2); + } + else + { + if (size < 32) + { + remaining_ = 32 - size; + + #ifdef TEST + *logofs << "ServerReadBuffer: No message was located " + << "with remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + if (*start == 1) + { + dataLength = 32 + (GetULONG(start + 4, bigEndian_) << 2); + } + else + { + dataLength = 32; + } + + if (dataLength < 32) + { + #ifdef TEST + *logofs << "ServerReadBuffer: WARNING! Assuming length 32 " + << "for suspicious message of length " << dataLength + << ".\n" << logofs_flush; + #endif + + dataLength = 32; + } + } + + #ifdef TEST + *logofs << "ServerReadBuffer: Length of the next message is " + << dataLength << ".\n" << logofs_flush; + #endif + + if (size < dataLength) + { + remaining_ = dataLength - size; + + #ifdef TEST + *logofs << "ServerReadBuffer: No message was located " + << "with remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + firstMessage_ = 0; + + controlLength = 0; + trailerLength = 0; + + remaining_ = 0; + + #ifdef TEST + *logofs << "ServerReadBuffer: Located message with " + << "remaining " << remaining_ << ".\n" + << logofs_flush; + #endif + + return 1; +} + +// +// Check if the data already read contains a +// message matching the opcode and sequence, +// starting at the given offset. +// + +unsigned char *ServerReadBuffer::peekMessage(unsigned int &offset, unsigned char opcode, + unsigned short sequence) +{ + #ifdef TEST + *logofs << "ServerReadBuffer: Peeking message " + << "for FD#" << transport_ -> fd() << " with size " + << length_ << " offset " << offset << " opcode " + << (unsigned int) opcode << " and sequence " + << sequence << ".\n" << logofs_flush; + #endif + + if (firstMessage_) + { + return NULL; + } + + unsigned char *next = buffer_ + start_ + offset; + unsigned char *end = buffer_ + start_ + length_; + + int found = 0; + + while (end - next >= 32) + { + #ifdef DEBUG + *logofs << "ServerReadBuffer: Checking opcode " + << (unsigned int) *next << " sequence " + << GetUINT(next + 2, bigEndian_) + << " at " << next - buffer_ + start_ + << ".\n" << logofs_flush; + #endif + + if (*next == opcode && GetUINT(next + 2, bigEndian_) == sequence) + { + found = 1; + + break; + } + else if (*next == 1) + { + next += (32 + (GetULONG(next + 4, bigEndian_) << 2)); + } + else + { + next += 32; + } + } + + offset = next - buffer_ + start_; + + if (found == 1) + { + #ifdef TEST + *logofs << "ServerReadBuffer: Found message at " + << "offset " << next - buffer_ + start_ + << ".\n" << logofs_flush; + #endif + + return next; + } + + #ifdef TEST + *logofs << "ServerReadBuffer: Quitting loop at " + << "offset " << next - buffer_ + start_ + << ".\n" << logofs_flush; + #endif + + return NULL; +} diff --git a/nxcomp/src/ServerReadBuffer.h b/nxcomp/src/ServerReadBuffer.h new file mode 100644 index 000000000..d6c207ead --- /dev/null +++ b/nxcomp/src/ServerReadBuffer.h @@ -0,0 +1,73 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ServerReadBuffer_H +#define ServerReadBuffer_H + +#include "ReadBuffer.h" +#include "Control.h" + +class ServerChannel; + +class ServerReadBuffer : public ReadBuffer +{ + public: + + ServerReadBuffer(Transport *transport, ServerChannel *channel) + + : ReadBuffer(transport), firstMessage_(1), channel_(channel) + { + } + + virtual ~ServerReadBuffer() + { + } + + void setBigEndian(int flag) + { + bigEndian_ = flag; + } + + unsigned char *peekMessage(unsigned int &offset, unsigned char opcode, + unsigned short sequence); + + protected: + + virtual unsigned int suggestedLength(unsigned int pendingLength); + + virtual int locateMessage(const unsigned char *start, + const unsigned char *end, + unsigned int &controlLength, + unsigned int &dataLength, + unsigned int &trailerLength); + + int bigEndian_; + + int firstMessage_; + + ServerChannel *channel_; +}; + +#endif /* ServerReadBuffer_H */ diff --git a/nxcomp/src/ServerStore.cpp b/nxcomp/src/ServerStore.cpp new file mode 100644 index 000000000..8123b6de0 --- /dev/null +++ b/nxcomp/src/ServerStore.cpp @@ -0,0 +1,183 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ServerStore.h" + +// +// Cached reply classes. +// + +#include "GetImageReply.h" +#include "ListFontsReply.h" +#include "QueryFontReply.h" +#include "GetPropertyReply.h" +#include "GenericReply.h" + +// +// Set the verbosity level. +// + +#define WARNING +#define PANIC +#undef TEST + +ServerStore::ServerStore(StaticCompressor *compressor) +{ + if (logofs == NULL) + { + logofs = &cout; + } + + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + replies_[i] = NULL; + events_[i] = NULL; + } + + replies_[X_ListFonts] = new ListFontsReplyStore(compressor); + replies_[X_QueryFont] = new QueryFontReplyStore(compressor); + replies_[X_GetImage] = new GetImageReplyStore(compressor); + replies_[X_GetProperty] = new GetPropertyReplyStore(compressor); + + replies_[X_NXInternalGenericReply] = new GenericReplyStore(compressor); +} + +ServerStore::~ServerStore() +{ + if (logofs == NULL) + { + logofs = &cout; + } + + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + delete replies_[i]; + delete events_[i]; + } +} + +int ServerStore::saveReplyStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient, T_checksum_action checksumAction, + T_data_action dataAction) const +{ + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + if (replies_[i] != NULL && + replies_[i] -> saveStore(cachefs, md5StateStream, md5StateClient, + checksumAction, dataAction, + storeBigEndian()) < 0) + { + #ifdef PANIC + *logofs << "ServerStore: PANIC! Error saving reply store " + << "for OPCODE#" << (unsigned int) i << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error saving reply store " + << "for opcode '" << (unsigned int) i << "'.\n"; + + return -1; + } + } + + return 1; +} + +int ServerStore::saveEventStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient, T_checksum_action checksumAction, + T_data_action dataAction) const +{ + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + if (events_[i] != NULL && + events_[i] -> saveStore(cachefs, md5StateStream, md5StateClient, + checksumAction, dataAction, + storeBigEndian()) < 0) + { + #ifdef PANIC + *logofs << "ServerStore: PANIC! Error saving event store " + << "for OPCODE#" << (unsigned int) i << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Error saving event store " + << "for opcode '" << (unsigned int) i << "'.\n"; + + return -1; + } + } + + return 1; +} + +int ServerStore::loadReplyStores(istream *cachefs, md5_state_t *md5StateStream, + T_checksum_action checksumAction, T_data_action dataAction) const +{ + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + if (replies_[i] != NULL && + replies_[i] -> loadStore(cachefs, md5StateStream, + checksumAction, dataAction, + storeBigEndian()) < 0) + { + #ifdef PANIC + *logofs << "ServerStore: PANIC! Error loading reply store " + << "for OPCODE#" << (unsigned int) i << ".\n" + << logofs_flush; + #endif + + return -1; + } + } + + return 1; +} + +int ServerStore::loadEventStores(istream *cachefs, md5_state_t *md5StateStream, + T_checksum_action checksumAction, T_data_action dataAction) const +{ + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + if (events_[i] != NULL && + events_[i] -> loadStore(cachefs, md5StateStream, + checksumAction, dataAction, + storeBigEndian()) < 0) + { + #ifdef PANIC + *logofs << "ServerStore: PANIC! Error loading event store " + << "for OPCODE#" << (unsigned int) i << ".\n" + << logofs_flush; + #endif + + return -1; + } + } + + return 1; +} diff --git a/nxcomp/src/ServerStore.h b/nxcomp/src/ServerStore.h new file mode 100644 index 000000000..dbbb968e5 --- /dev/null +++ b/nxcomp/src/ServerStore.h @@ -0,0 +1,83 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ServerStore_H +#define ServerStore_H + +#include "Message.h" + +#include "ChannelStore.h" + +class StaticCompressor; + +class ServerStore : public ChannelStore +{ + public: + + ServerStore(StaticCompressor *compressor); + + virtual ~ServerStore(); + + MessageStore *getReplyStore(unsigned char opcode) const + { + return replies_[opcode]; + } + + MessageStore *getEventStore(unsigned char opcode) const + { + return events_[opcode]; + } + + // + // Actually save the message store + // to disk according to proxy mode. + // + + int saveReplyStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient, T_checksum_action checksumAction, + T_data_action dataAction) const; + + int saveEventStores(ostream *cachefs, md5_state_t *md5StateStream, + md5_state_t *md5StateClient, T_checksum_action checksumAction, + T_data_action dataAction) const; + + + int loadReplyStores(istream *cachefs, md5_state_t *md5StateStream, + T_checksum_action checksumAction, T_data_action dataAction) const; + + int loadEventStores(istream *cachefs, md5_state_t *md5StateStream, + T_checksum_action checksumAction, T_data_action dataAction) const; + + private: + + // + // A server store contains replies and events. + // + + MessageStore *replies_[CHANNEL_STORE_OPCODE_LIMIT]; + MessageStore *events_[CHANNEL_STORE_OPCODE_LIMIT]; +}; + +#endif /* ServerStore_H */ diff --git a/nxcomp/src/SetClipRectangles.cpp b/nxcomp/src/SetClipRectangles.cpp new file mode 100644 index 000000000..b43cea938 --- /dev/null +++ b/nxcomp/src/SetClipRectangles.cpp @@ -0,0 +1,154 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SetClipRectangles.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int SetClipRectanglesStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; + + // + // Here is the fingerprint. + // + + setClipRectangles -> ordering = *(buffer + 1); + + setClipRectangles -> gcontext = GetULONG(buffer + 4, bigEndian); + + setClipRectangles -> x_origin = GetUINT(buffer + 8, bigEndian); + setClipRectangles -> y_origin = GetUINT(buffer + 10, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int SetClipRectanglesStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; + + // + // Fill all the message's fields. + // + + *(buffer + 1) = setClipRectangles -> ordering; + + PutULONG(setClipRectangles -> gcontext, buffer + 4, bigEndian); + + PutUINT(setClipRectangles -> x_origin, buffer + 8, bigEndian); + PutUINT(setClipRectangles -> y_origin, buffer + 10, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void SetClipRectanglesStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; + + *logofs << name() << ": Identity ordering " << (unsigned int) setClipRectangles -> ordering + << ", gcontext " << setClipRectangles -> gcontext << ", x_origin " + << setClipRectangles -> x_origin << ", y_origin " + << setClipRectangles -> y_origin << ", size " + << setClipRectangles -> size_ << ".\n" << logofs_flush; + #endif +} + +void SetClipRectanglesStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 1, 1); + md5_append(md5_state_, buffer + 8, 4); +} + +void SetClipRectanglesStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; + SetClipRectanglesMessage *cachedSetClipRectangles = (SetClipRectanglesMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " << setClipRectangles -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeXidValue(setClipRectangles -> gcontext, clientCache -> gcCache); + + cachedSetClipRectangles -> gcontext = setClipRectangles -> gcontext; +} + +void SetClipRectanglesStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + SetClipRectanglesMessage *setClipRectangles = (SetClipRectanglesMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + decodeBuffer.decodeXidValue(value, clientCache -> gcCache); + + setClipRectangles -> gcontext = value; + + #ifdef DEBUG + *logofs << name() << ": Decoded value " << setClipRectangles -> gcontext + << " as gcontext field.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/SetClipRectangles.h b/nxcomp/src/SetClipRectangles.h new file mode 100644 index 000000000..a2245360c --- /dev/null +++ b/nxcomp/src/SetClipRectangles.h @@ -0,0 +1,187 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef SetClipRectangles_H +#define SetClipRectangles_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define SETCLIPRECTANGLES_ENABLE_CACHE 1 +#define SETCLIPRECTANGLES_ENABLE_DATA 0 +#define SETCLIPRECTANGLES_ENABLE_SPLIT 0 +#define SETCLIPRECTANGLES_ENABLE_COMPRESS 0 + +#define SETCLIPRECTANGLES_DATA_LIMIT 2048 +#define SETCLIPRECTANGLES_DATA_OFFSET 12 + +#define SETCLIPRECTANGLES_CACHE_SLOTS 3000 +#define SETCLIPRECTANGLES_CACHE_THRESHOLD 3 +#define SETCLIPRECTANGLES_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class SetClipRectanglesMessage : public Message +{ + friend class SetClipRectanglesStore; + + public: + + SetClipRectanglesMessage() + { + } + + ~SetClipRectanglesMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char ordering; + unsigned int gcontext; + unsigned short x_origin; + unsigned short y_origin; +}; + +class SetClipRectanglesStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + SetClipRectanglesStore() : MessageStore() + { + enableCache = SETCLIPRECTANGLES_ENABLE_CACHE; + enableData = SETCLIPRECTANGLES_ENABLE_DATA; + enableSplit = SETCLIPRECTANGLES_ENABLE_SPLIT; + enableCompress = SETCLIPRECTANGLES_ENABLE_COMPRESS; + + dataLimit = SETCLIPRECTANGLES_DATA_LIMIT; + dataOffset = SETCLIPRECTANGLES_DATA_OFFSET; + + cacheSlots = SETCLIPRECTANGLES_CACHE_SLOTS; + cacheThreshold = SETCLIPRECTANGLES_CACHE_THRESHOLD; + cacheLowerThreshold = SETCLIPRECTANGLES_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~SetClipRectanglesStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "SetClipRectangles"; + } + + virtual unsigned char opcode() const + { + return X_SetClipRectangles; + } + + virtual unsigned int storage() const + { + return sizeof(SetClipRectanglesMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new SetClipRectanglesMessage(); + } + + virtual Message *create(const Message &message) const + { + return new SetClipRectanglesMessage((const SetClipRectanglesMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (SetClipRectanglesMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* SetClipRectangles_H */ diff --git a/nxcomp/src/SetUnpackAlpha.cpp b/nxcomp/src/SetUnpackAlpha.cpp new file mode 100644 index 000000000..5a352d26a --- /dev/null +++ b/nxcomp/src/SetUnpackAlpha.cpp @@ -0,0 +1,266 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SetUnpackAlpha.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +SetUnpackAlphaStore::SetUnpackAlphaStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = SETUNPACKALPHA_ENABLE_CACHE; + enableData = SETUNPACKALPHA_ENABLE_DATA; + enableCompress = SETUNPACKALPHA_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = SETUNPACKALPHA_DATA_LIMIT; + dataOffset = SETUNPACKALPHA_DATA_OFFSET_IF_PROTO_STEP_7; + + cacheSlots = SETUNPACKALPHA_CACHE_SLOTS; + cacheThreshold = SETUNPACKALPHA_CACHE_THRESHOLD; + cacheLowerThreshold = SETUNPACKALPHA_CACHE_LOWER_THRESHOLD; + + // Since ProtoStep8 (#issue 108) + enableSplit = SETUNPACKALPHA_ENABLE_SPLIT_IF_PROTO_STEP_8; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +SetUnpackAlphaStore::~SetUnpackAlphaStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int SetUnpackAlphaStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; + #endif + + // + // Encode the source length first because + // we need it to determine the size of + // the output buffer. + // + + // SrcLength. + encodeBuffer.encodeValue(GetULONG(buffer + 8, bigEndian), 32, 9); + + // Client. + encodeBuffer.encodeCachedValue(*(buffer + 1), 8, + clientCache -> resourceCache); + // Method. + encodeBuffer.encodeCachedValue(*(buffer + 4), 8, + clientCache -> methodCache); + // DstLength. + encodeBuffer.encodeValue(GetULONG(buffer + 12, bigEndian), 32, 9); + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackAlphaStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; + #endif + + unsigned int value; + unsigned char cValue; + + // SrcLength. + decodeBuffer.decodeValue(value, 32, 9); + + size = RoundUp4(value) + 16; + + buffer = writeBuffer -> addMessage(size); + + PutULONG(value, buffer + 8, bigEndian); + + // Client. + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> resourceCache); + + *(buffer + 1) = cValue; + + // Method. + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> methodCache); + + *(buffer + 4) = cValue; + + // DstLength. + decodeBuffer.decodeValue(value, 32, 9); + + PutULONG(value, buffer + 12, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackAlphaStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; + + setUnpackAlpha -> client = *(buffer + 1); + setUnpackAlpha -> method = *(buffer + 4); + + setUnpackAlpha -> src_length = GetULONG(buffer + 8, bigEndian); + setUnpackAlpha -> dst_length = GetULONG(buffer + 12, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackAlphaStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; + + *(buffer + 1) = setUnpackAlpha -> client; + *(buffer + 4) = setUnpackAlpha -> method; + + PutULONG(setUnpackAlpha -> src_length, buffer + 8, bigEndian); + PutULONG(setUnpackAlpha -> dst_length, buffer + 12, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void SetUnpackAlphaStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; + + *logofs << name() << ": Identity client " + << (unsigned int) setUnpackAlpha -> client << " method " + << (unsigned int) setUnpackAlpha -> method << " source length " + << setUnpackAlpha -> src_length << " destination length " + << setUnpackAlpha -> dst_length << " size " + << setUnpackAlpha -> size_ << ".\n"; + + #endif +} + +void SetUnpackAlphaStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Include the pack method and the source + // and destination length. + // + + md5_append(md5_state_, buffer + 4, 1); + md5_append(md5_state_, buffer + 8, 8); +} + +void SetUnpackAlphaStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; + SetUnpackAlphaMessage *cachedSetUnpackAlpha = (SetUnpackAlphaMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(setUnpackAlpha -> client, 8, + clientCache -> resourceCache); + + cachedSetUnpackAlpha -> client = setUnpackAlpha -> client; +} + +void SetUnpackAlphaStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + SetUnpackAlphaMessage *setUnpackAlpha = (SetUnpackAlphaMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(setUnpackAlpha -> client, 8, + clientCache -> resourceCache); +} diff --git a/nxcomp/src/SetUnpackAlpha.h b/nxcomp/src/SetUnpackAlpha.h new file mode 100644 index 000000000..54714efaa --- /dev/null +++ b/nxcomp/src/SetUnpackAlpha.h @@ -0,0 +1,162 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef SetUnpackAlpha_H +#define SetUnpackAlpha_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define SETUNPACKALPHA_ENABLE_CACHE 1 +#define SETUNPACKALPHA_ENABLE_DATA 1 + +#define SETUNPACKALPHA_DATA_LIMIT 16384 + +#define SETUNPACKALPHA_CACHE_SLOTS 2000 +#define SETUNPACKALPHA_CACHE_THRESHOLD 10 +#define SETUNPACKALPHA_CACHE_LOWER_THRESHOLD 5 + +#define SETUNPACKALPHA_DATA_OFFSET_IF_PROTO_STEP_7 16 +#define SETUNPACKALPHA_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +#define SETUNPACKALPHA_ENABLE_SPLIT_IF_PROTO_STEP_8 0 + +// +// The message class. +// + +class SetUnpackAlphaMessage : public Message +{ + friend class SetUnpackAlphaStore; + + public: + + SetUnpackAlphaMessage() + { + } + + ~SetUnpackAlphaMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char client; + unsigned char method; + + unsigned int src_length; + unsigned int dst_length; +}; + +class SetUnpackAlphaStore : public MessageStore +{ + public: + + SetUnpackAlphaStore(StaticCompressor *compressor); + + virtual ~SetUnpackAlphaStore(); + + virtual const char *name() const + { + return "SetUnpackAlpha"; + } + + virtual unsigned char opcode() const + { + return X_NXSetUnpackAlpha; + } + + virtual unsigned int storage() const + { + return sizeof(SetUnpackAlphaMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new SetUnpackAlphaMessage(); + } + + virtual Message *create(const Message &message) const + { + return new SetUnpackAlphaMessage((const SetUnpackAlphaMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (SetUnpackAlphaMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* SetUnpackAlpha_H */ diff --git a/nxcomp/src/SetUnpackColormap.cpp b/nxcomp/src/SetUnpackColormap.cpp new file mode 100644 index 000000000..2c9bba1bd --- /dev/null +++ b/nxcomp/src/SetUnpackColormap.cpp @@ -0,0 +1,266 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SetUnpackColormap.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +SetUnpackColormapStore::SetUnpackColormapStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = SETUNPACKCOLORMAP_ENABLE_CACHE; + enableData = SETUNPACKCOLORMAP_ENABLE_DATA; + enableCompress = SETUNPACKCOLORMAP_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = SETUNPACKCOLORMAP_DATA_LIMIT; + dataOffset = SETUNPACKCOLORMAP_DATA_OFFSET_IF_PROTO_STEP_7; + + cacheSlots = SETUNPACKCOLORMAP_CACHE_SLOTS; + cacheThreshold = SETUNPACKCOLORMAP_CACHE_THRESHOLD; + cacheLowerThreshold = SETUNPACKCOLORMAP_CACHE_LOWER_THRESHOLD; + + // Since ProtoStep8 (#issue 108) + enableSplit = SETUNPACKCOLORMAP_ENABLE_SPLIT_IF_PROTO_STEP_8; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +SetUnpackColormapStore::~SetUnpackColormapStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int SetUnpackColormapStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; + #endif + + // + // Encode the source length first because + // we need it to determine the size of + // the output buffer. + // + + // SrcLength. + encodeBuffer.encodeValue(GetULONG(buffer + 8, bigEndian), 32, 9); + + // Client. + encodeBuffer.encodeCachedValue(*(buffer + 1), 8, + clientCache -> resourceCache); + // Method. + encodeBuffer.encodeCachedValue(*(buffer + 4), 8, + clientCache -> methodCache); + // DstLength. + encodeBuffer.encodeValue(GetULONG(buffer + 12, bigEndian), 32, 9); + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackColormapStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; + #endif + + unsigned int value; + unsigned char cValue; + + // SrcLength. + decodeBuffer.decodeValue(value, 32, 9); + + size = RoundUp4(value) + 16; + + buffer = writeBuffer -> addMessage(size); + + PutULONG(value, buffer + 8, bigEndian); + + // Client. + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> resourceCache); + + *(buffer + 1) = cValue; + + // Method. + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> methodCache); + + *(buffer + 4) = cValue; + + // DstLength. + decodeBuffer.decodeValue(value, 32, 9); + + PutULONG(value, buffer + 12, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackColormapStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; + + setUnpackColormap -> client = *(buffer + 1); + setUnpackColormap -> method = *(buffer + 4); + + setUnpackColormap -> src_length = GetULONG(buffer + 8, bigEndian); + setUnpackColormap -> dst_length = GetULONG(buffer + 12, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackColormapStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; + + *(buffer + 1) = setUnpackColormap -> client; + *(buffer + 4) = setUnpackColormap -> method; + + PutULONG(setUnpackColormap -> src_length, buffer + 8, bigEndian); + PutULONG(setUnpackColormap -> dst_length, buffer + 12, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void SetUnpackColormapStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; + + *logofs << name() << ": Identity client " + << (unsigned int) setUnpackColormap -> client << " method " + << (unsigned int) setUnpackColormap -> method << " source length " + << setUnpackColormap -> src_length << " destination length " + << setUnpackColormap -> dst_length << " size " + << setUnpackColormap -> size_ << ".\n"; + + #endif +} + +void SetUnpackColormapStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Include the pack method and the source + // and destination length. + // + + md5_append(md5_state_, buffer + 4, 1); + md5_append(md5_state_, buffer + 8, 8); +} + +void SetUnpackColormapStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; + SetUnpackColormapMessage *cachedSetUnpackColormap = (SetUnpackColormapMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + encodeBuffer.encodeCachedValue(setUnpackColormap -> client, 8, + clientCache -> resourceCache); + + cachedSetUnpackColormap -> client = setUnpackColormap -> client; +} + +void SetUnpackColormapStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + SetUnpackColormapMessage *setUnpackColormap = (SetUnpackColormapMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(setUnpackColormap -> client, 8, + clientCache -> resourceCache); +} diff --git a/nxcomp/src/SetUnpackColormap.h b/nxcomp/src/SetUnpackColormap.h new file mode 100644 index 000000000..779366531 --- /dev/null +++ b/nxcomp/src/SetUnpackColormap.h @@ -0,0 +1,162 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef SetUnpackColormap_H +#define SetUnpackColormap_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define SETUNPACKCOLORMAP_ENABLE_CACHE 1 +#define SETUNPACKCOLORMAP_ENABLE_DATA 1 + +#define SETUNPACKCOLORMAP_DATA_LIMIT 4096 + +#define SETUNPACKCOLORMAP_CACHE_SLOTS 2000 +#define SETUNPACKCOLORMAP_CACHE_THRESHOLD 5 +#define SETUNPACKCOLORMAP_CACHE_LOWER_THRESHOLD 0 + +#define SETUNPACKCOLORMAP_DATA_OFFSET_IF_PROTO_STEP_7 16 +#define SETUNPACKCOLORMAP_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +#define SETUNPACKCOLORMAP_ENABLE_SPLIT_IF_PROTO_STEP_8 0 + +// +// The message class. +// + +class SetUnpackColormapMessage : public Message +{ + friend class SetUnpackColormapStore; + + public: + + SetUnpackColormapMessage() + { + } + + ~SetUnpackColormapMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char client; + unsigned char method; + + unsigned int src_length; + unsigned int dst_length; +}; + +class SetUnpackColormapStore : public MessageStore +{ + public: + + SetUnpackColormapStore(StaticCompressor *compressor); + + virtual ~SetUnpackColormapStore(); + + virtual const char *name() const + { + return "SetUnpackColormap"; + } + + virtual unsigned char opcode() const + { + return X_NXSetUnpackColormap; + } + + virtual unsigned int storage() const + { + return sizeof(SetUnpackColormapMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new SetUnpackColormapMessage(); + } + + virtual Message *create(const Message &message) const + { + return new SetUnpackColormapMessage((const SetUnpackColormapMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (SetUnpackColormapMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* SetUnpackColormap_H */ diff --git a/nxcomp/src/SetUnpackGeometry.cpp b/nxcomp/src/SetUnpackGeometry.cpp new file mode 100644 index 000000000..edff6a544 --- /dev/null +++ b/nxcomp/src/SetUnpackGeometry.cpp @@ -0,0 +1,305 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SetUnpackGeometry.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +SetUnpackGeometryStore::SetUnpackGeometryStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = SETUNPACKGEOMETRY_ENABLE_CACHE; + enableData = SETUNPACKGEOMETRY_ENABLE_DATA; + enableSplit = SETUNPACKGEOMETRY_ENABLE_SPLIT; + enableCompress = SETUNPACKGEOMETRY_ENABLE_COMPRESS; + + dataLimit = SETUNPACKGEOMETRY_DATA_LIMIT; + dataOffset = SETUNPACKGEOMETRY_DATA_OFFSET; + + cacheSlots = SETUNPACKGEOMETRY_CACHE_SLOTS; + cacheThreshold = SETUNPACKGEOMETRY_CACHE_THRESHOLD; + cacheLowerThreshold = SETUNPACKGEOMETRY_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +SetUnpackGeometryStore::~SetUnpackGeometryStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int SetUnpackGeometryStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(*(buffer + 1), 8, + clientCache -> resourceCache); + + const unsigned char *nextChar = buffer + 4; + + for (int i = 0; i < 6; i++) + { + encodeBuffer.encodeCachedValue(*nextChar++, 8, + clientCache -> depthCache); + } + + encodeBuffer.encodeValue(GetULONG(buffer + 12, bigEndian), 32); + encodeBuffer.encodeValue(GetULONG(buffer + 16, bigEndian), 32); + encodeBuffer.encodeValue(GetULONG(buffer + 20, bigEndian), 32); + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackGeometryStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; + #endif + + size = 24; + buffer = writeBuffer -> addMessage(size); + + unsigned char cValue; + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> resourceCache); + *(buffer + 1) = cValue; + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + *(buffer + 4) = cValue; + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + *(buffer + 5) = cValue; + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + *(buffer + 6) = cValue; + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + *(buffer + 7) = cValue; + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + *(buffer + 8) = cValue; + + decodeBuffer.decodeCachedValue(cValue, 8, + clientCache -> depthCache); + *(buffer + 9) = cValue; + + unsigned int value; + + decodeBuffer.decodeValue(value, 32); + PutULONG(value, buffer + 12, bigEndian); + + decodeBuffer.decodeValue(value, 32); + PutULONG(value, buffer + 16, bigEndian); + + decodeBuffer.decodeValue(value, 32); + PutULONG(value, buffer + 20, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackGeometryStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; + + setUnpackGeometry -> client = *(buffer + 1); + + setUnpackGeometry -> depth_1_bpp = *(buffer + 4); + setUnpackGeometry -> depth_4_bpp = *(buffer + 5); + setUnpackGeometry -> depth_8_bpp = *(buffer + 6); + setUnpackGeometry -> depth_16_bpp = *(buffer + 7); + setUnpackGeometry -> depth_24_bpp = *(buffer + 8); + setUnpackGeometry -> depth_32_bpp = *(buffer + 9); + + setUnpackGeometry -> red_mask = GetULONG(buffer + 12, bigEndian); + setUnpackGeometry -> green_mask = GetULONG(buffer + 16, bigEndian); + setUnpackGeometry -> blue_mask = GetULONG(buffer + 20, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +int SetUnpackGeometryStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; + + *(buffer + 1) = setUnpackGeometry -> client; + + *(buffer + 4) = setUnpackGeometry -> depth_1_bpp; + *(buffer + 5) = setUnpackGeometry -> depth_4_bpp; + *(buffer + 6) = setUnpackGeometry -> depth_8_bpp; + *(buffer + 7) = setUnpackGeometry -> depth_16_bpp; + *(buffer + 8) = setUnpackGeometry -> depth_24_bpp; + *(buffer + 9) = setUnpackGeometry -> depth_32_bpp; + + PutULONG(setUnpackGeometry -> red_mask, buffer + 12, bigEndian); + PutULONG(setUnpackGeometry -> green_mask, buffer + 16, bigEndian); + PutULONG(setUnpackGeometry -> blue_mask, buffer + 20, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << message << ".\n" << logofs_flush; + #endif + + return 1; +} + +void SetUnpackGeometryStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; + + *logofs << name() << ": Identity client " + << (unsigned) setUnpackGeometry -> client << " depth_1_bpp " + << (unsigned) setUnpackGeometry -> depth_1_bpp << " depth_4_bpp " + << (unsigned int) setUnpackGeometry -> depth_4_bpp << " depth_8_bpp " + << (unsigned int) setUnpackGeometry -> depth_8_bpp << " depth_16_bpp " + << (unsigned int) setUnpackGeometry -> depth_16_bpp << " depth_24_bpp " + << (unsigned int) setUnpackGeometry -> depth_24_bpp << " depth_32_bpp " + << (unsigned int) setUnpackGeometry -> depth_32_bpp + + << " red_mask " << setUnpackGeometry -> red_mask + << " green_mask " << setUnpackGeometry -> green_mask + << " blue_mask " << setUnpackGeometry -> blue_mask + + << " size " << setUnpackGeometry -> size_ << ".\n"; + + #endif +} + +void SetUnpackGeometryStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 4, 6); + md5_append(md5_state_, buffer + 12, 12); +} + +void SetUnpackGeometryStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; + SetUnpackGeometryMessage *cachedSetUnpackGeometry = (SetUnpackGeometryMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef TEST + *logofs << name() << ": Encoding value " + << (unsigned int) setUnpackGeometry -> client + << " as client field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue(setUnpackGeometry -> client, 8, + clientCache -> resourceCache); + + cachedSetUnpackGeometry -> client = setUnpackGeometry -> client; +} + +void SetUnpackGeometryStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + SetUnpackGeometryMessage *setUnpackGeometry = (SetUnpackGeometryMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + decodeBuffer.decodeCachedValue(setUnpackGeometry -> client, 8, + clientCache -> resourceCache); + + #ifdef DEBUG + *logofs << name() << ": Decoded value " + << (unsigned int) setUnpackGeometry -> client + << " as client field.\n" << logofs_flush; + #endif +} diff --git a/nxcomp/src/SetUnpackGeometry.h b/nxcomp/src/SetUnpackGeometry.h new file mode 100644 index 000000000..96104f57f --- /dev/null +++ b/nxcomp/src/SetUnpackGeometry.h @@ -0,0 +1,167 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef SetUnpackGeometry_H +#define SetUnpackGeometry_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define SETUNPACKGEOMETRY_ENABLE_CACHE 1 +#define SETUNPACKGEOMETRY_ENABLE_DATA 0 +#define SETUNPACKGEOMETRY_ENABLE_SPLIT 0 +#define SETUNPACKGEOMETRY_ENABLE_COMPRESS 0 + +#define SETUNPACKGEOMETRY_DATA_LIMIT 24 +#define SETUNPACKGEOMETRY_DATA_OFFSET 24 + +#define SETUNPACKGEOMETRY_CACHE_SLOTS 20 +#define SETUNPACKGEOMETRY_CACHE_THRESHOLD 1 +#define SETUNPACKGEOMETRY_CACHE_LOWER_THRESHOLD 0 + +// +// The message class. +// + +class SetUnpackGeometryMessage : public Message +{ + friend class SetUnpackGeometryStore; + + public: + + SetUnpackGeometryMessage() + { + } + + ~SetUnpackGeometryMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned char client; + + unsigned char depth_1_bpp; + unsigned char depth_4_bpp; + unsigned char depth_8_bpp; + unsigned char depth_16_bpp; + unsigned char depth_24_bpp; + unsigned char depth_32_bpp; + + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; +}; + +class SetUnpackGeometryStore : public MessageStore +{ + public: + + SetUnpackGeometryStore(StaticCompressor *compressor); + + virtual ~SetUnpackGeometryStore(); + + virtual const char *name() const + { + return "SetUnpackGeometry"; + } + + virtual unsigned char opcode() const + { + return X_NXSetUnpackGeometry; + } + + virtual unsigned int storage() const + { + return sizeof(SetUnpackGeometryMessage); + } + + // + // Message handling methods. + // + + protected: + + virtual Message *create() const + { + return new SetUnpackGeometryMessage(); + } + + virtual Message *create(const Message &message) const + { + return new SetUnpackGeometryMessage((const SetUnpackGeometryMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (SetUnpackGeometryMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* SetUnpackGeometry_H */ diff --git a/nxcomp/src/ShapeExtension.cpp b/nxcomp/src/ShapeExtension.cpp new file mode 100644 index 000000000..2ee2b67db --- /dev/null +++ b/nxcomp/src/ShapeExtension.cpp @@ -0,0 +1,305 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ShapeExtension.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "WriteBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Constructors and destructors. +// + +ShapeExtensionStore::ShapeExtensionStore(StaticCompressor *compressor) + + : MessageStore(compressor) +{ + enableCache = SHAPEEXTENSION_ENABLE_CACHE; + enableData = SHAPEEXTENSION_ENABLE_DATA; + enableSplit = SHAPEEXTENSION_ENABLE_SPLIT; + + // Since ProtoStep7 (#issue 108) + enableCompress = SHAPEEXTENSION_ENABLE_COMPRESS_IF_PROTO_STEP_7; + + dataLimit = SHAPEEXTENSION_DATA_LIMIT; + dataOffset = SHAPEEXTENSION_DATA_OFFSET; + + cacheSlots = SHAPEEXTENSION_CACHE_SLOTS; + cacheThreshold = SHAPEEXTENSION_CACHE_THRESHOLD; + cacheLowerThreshold = SHAPEEXTENSION_CACHE_LOWER_THRESHOLD; + + opcode_ = X_NXInternalShapeExtension; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; +} + +ShapeExtensionStore::~ShapeExtensionStore() +{ + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); +} + +// +// Here are the methods to handle messages' content. +// + +int ShapeExtensionStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const +{ + // + // Handle this extension in a way similar to shape. + // + + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Encoding full message identity.\n" << logofs_flush; + #endif + + // + // We handle all possible requests of this extension + // using the same opcode. We give to message a data + // offset of 4 (or 16 if proto is >= 3) and handle + // the first 16 bytes through an array of caches. + // + + encodeBuffer.encodeValue(size >> 2, 16, 10); + + encodeBuffer.encodeCachedValue(*(buffer + 1), 8, + clientCache -> shapeOpcodeCache); + + for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) + { + encodeBuffer.encodeCachedValue(GetUINT(buffer + (i * 2) + 4, bigEndian), 16, + *clientCache -> shapeDataCache[i]); + } + + #ifdef DEBUG + *logofs << name() << ": Encoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int ShapeExtensionStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const +{ + ClientCache *clientCache = (ClientCache *) channelCache; + + #ifdef DEBUG + *logofs << name() << ": Decoding full message identity.\n" << logofs_flush; + #endif + + decodeBuffer.decodeValue(size, 16, 10); + + size <<= 2; + + buffer = writeBuffer -> addMessage(size); + + decodeBuffer.decodeCachedValue(*(buffer + 1), 8, + clientCache -> shapeOpcodeCache); + + unsigned int value; + + for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache -> shapeDataCache[i]); + + PutUINT(value, buffer + 4 + (i * 2), bigEndian); + } + + #ifdef DEBUG + *logofs << name() << ": Decoded full message identity.\n" << logofs_flush; + #endif + + return 1; +} + +int ShapeExtensionStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; + + shapeExtension -> opcode = *(buffer + 1); + + for (unsigned int i = 0; i < 8; i++) + { + if ((i * 2 + 4) < size) + { + shapeExtension -> data[i] = GetUINT(buffer + i * 2 + 4, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed data[" << i << "].\n" + << logofs_flush; + #endif + } + else + { + shapeExtension -> data[i] = 0; + } + } + + #ifdef DEBUG + *logofs << name() << ": Parsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int ShapeExtensionStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; + + *(buffer + 1) = shapeExtension -> opcode; + + for (unsigned int i = 0; i < 8 && (i * 2 + 4) < size; i++) + { + PutUINT(shapeExtension -> data[i], buffer + i * 2 + 4, bigEndian); + } + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " + << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void ShapeExtensionStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; + + *logofs << name() << ": Identity opcode " << (unsigned) shapeExtension -> opcode; + + for (int i = 0; i < 8; i++) + { + *logofs << ", data[" << i << "] " << shapeExtension -> data[i]; + } + + *logofs << ", size " << shapeExtension -> size_ << ".\n" << logofs_flush; + + #endif +} + +void ShapeExtensionStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + // + // Include minor opcode in the checksum. As data + // offset can be beyond the real end of message, + // we need to include size or we will match any + // message of size less or equal to data offset. + // + + md5_append(md5_state_, buffer + 1, 3); +} + +void ShapeExtensionStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const +{ + // + // Encode the variant part. + // + + ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; + ShapeExtensionMessage *cachedShapeExtension = (ShapeExtensionMessage *) cachedMessage; + + ClientCache *clientCache = (ClientCache *) channelCache; + + for (int i = 0; i < 8 && (i * 2 + 4) < shapeExtension -> size_; i++) + { + #ifdef TEST + *logofs << name() << ": Encoding value " << shapeExtension -> data[i] + << " as data[" << i << "] field.\n" << logofs_flush; + #endif + + encodeBuffer.encodeCachedValue((unsigned int) shapeExtension -> data[i], 16, + *clientCache -> shapeDataCache[i]); + + cachedShapeExtension -> data[i] = shapeExtension -> data[i]; + } +} + +void ShapeExtensionStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const +{ + ShapeExtensionMessage *shapeExtension = (ShapeExtensionMessage *) message; + + ClientCache *clientCache = (ClientCache *) channelCache; + + unsigned int value; + + for (int i = 0; i < 8 && (i * 2 + 4) < shapeExtension -> size_; i++) + { + decodeBuffer.decodeCachedValue(value, 16, + *clientCache -> shapeDataCache[i]); + + shapeExtension -> data[i] = (unsigned short) value; + + #ifdef TEST + *logofs << name() << ": Decoded value " << shapeExtension -> data[i] + << " as data[" << i << "] field.\n" << logofs_flush; + #endif + } +} diff --git a/nxcomp/src/ShapeExtension.h b/nxcomp/src/ShapeExtension.h new file mode 100644 index 000000000..4dd636847 --- /dev/null +++ b/nxcomp/src/ShapeExtension.h @@ -0,0 +1,164 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef ShapeExtension_H +#define ShapeExtension_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define SHAPEEXTENSION_ENABLE_CACHE 1 +#define SHAPEEXTENSION_ENABLE_DATA 1 +#define SHAPEEXTENSION_ENABLE_SPLIT 0 + +#define SHAPEEXTENSION_DATA_LIMIT 3200 +#define SHAPEEXTENSION_DATA_OFFSET 20 + +#define SHAPEEXTENSION_CACHE_SLOTS 3000 +#define SHAPEEXTENSION_CACHE_THRESHOLD 10 +#define SHAPEEXTENSION_CACHE_LOWER_THRESHOLD 5 + +#define SHAPEEXTENSION_ENABLE_COMPRESS_IF_PROTO_STEP_7 0 + +// +// The message class. +// + +class ShapeExtensionMessage : public Message +{ + friend class ShapeExtensionStore; + + public: + + ShapeExtensionMessage() + { + } + + ~ShapeExtensionMessage() + { + } + + // + // Note for encoding in protocol level 1: we consider + // for this message a data offset of 4. Bytes from 5 + // to 20, if present, are taken as part of identity + // and encoded through an array of int caches. + // + + private: + + unsigned char opcode; + unsigned short data[8]; +}; + +class ShapeExtensionStore : public MessageStore +{ + public: + + ShapeExtensionStore(StaticCompressor *compressor); + + virtual ~ShapeExtensionStore(); + + virtual const char *name() const + { + return "ShapeExtension"; + } + + virtual unsigned char opcode() const + { + return opcode_; + } + + virtual unsigned int storage() const + { + return sizeof(ShapeExtensionMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new ShapeExtensionMessage(); + } + + virtual Message *create(const Message &message) const + { + return new ShapeExtensionMessage((const ShapeExtensionMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (ShapeExtensionMessage *) message; + } + + virtual int encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer, + const unsigned int size, int bigEndian, + ChannelCache *channelCache) const; + + virtual int decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer, + unsigned int &size, int bigEndian, WriteBuffer *writeBuffer, + ChannelCache *channelCache) const; + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message, + const Message *cachedMessage, + ChannelCache *channelCache) const; + + virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message, + ChannelCache *channelCache) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; + + private: + + unsigned char opcode_; +}; + +#endif /* ShapeExtension_H */ diff --git a/nxcomp/src/Socket.cpp b/nxcomp/src/Socket.cpp new file mode 100644 index 000000000..8be04d76d --- /dev/null +++ b/nxcomp/src/Socket.cpp @@ -0,0 +1,757 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#if defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun) +#include +#endif + +#ifdef __sun +#include +#include +#endif + +#include +#include +#include +#include + +#include +#include + +// +// System specific defines. +// + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun) +#define SOL_IP IPPROTO_IP +#endif + +#ifdef __sun +#define INADDR_NONE ((unsigned int) -1) +#endif + +// +// The TIOCOUTQ ioctl is not implemented on Cygwin. +// Note also that TIOCOUTQ and IPTOS_LOWDELAY are +// disabled when running on MacOS/X. +// + +#ifdef __CYGWIN32__ +#define TIOCOUTQ ((unsigned int) -1) +#endif + +// +// NX includes. +// + +#include "Misc.h" +#include "Socket.h" + +// +// Set verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Set this only once by querying OS details. +// + +static int _kernelStep = -1; + +int GetKernelStep() +{ + if (_kernelStep < 0) + { + // + // At the moment only NX clients run on Win32 + // and MacOS/X so we are not really interested + // in the relevant OS dependent functions. + // + + #if defined(__CYGWIN32__) || defined(__APPLE__) + + _kernelStep = 0; + + #else + + struct utsname buffer; + + if (uname(&buffer) < 0) + { + #ifdef WARNING + *logofs << "Socket: WARNING! Failed to get system info. Error is " + << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; + + *logofs << "Socket: WARNING! Assuming lowest system support.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Failed to get system info. Error is " + << EGET() << " '" << ESTR() << "'.\n"; + + cerr << "Warning" << ": Assuming lowest system support.\n"; + + _kernelStep = 0; + } + else + { + #ifdef TEST + *logofs << "Socket: System is '" << buffer.sysname + << "' nodename '" << buffer.nodename << "' release '" + << buffer.release << "'.\n" << logofs_flush; + + *logofs << "Socket: Version is '" << buffer.version << "' machine '" + << buffer.machine << "'.\n" << logofs_flush; + #endif + + // + // Should test support on other operating systems. + // + + if (strcmp(buffer.sysname, "Linux") == 0) + { + if (strncmp(buffer.release, "2.0.", 4) == 0 || + strncmp(buffer.release, "2.2.", 4) == 0) + { + #ifdef TEST + *logofs << "Socket: Assuming level 2 system support.\n" + << logofs_flush; + #endif + + _kernelStep = 2; + } + else + { + #ifdef TEST + *logofs << "Socket: Assuming level 3 system support.\n" + << logofs_flush; + #endif + + _kernelStep = 3; + } + } + else if (strcmp(buffer.sysname, "SunOS") == 0) + { + #ifdef TEST + *logofs << "Socket: Assuming level 1 system support.\n" + << logofs_flush; + #endif + + _kernelStep = 1; + } + else + { + #ifdef TEST + *logofs << "Socket: Assuming level 0 system support.\n" + << logofs_flush; + #endif + + _kernelStep = 0; + } + } + + #endif /* #if defined(__CYGWIN32__) || defined(__APPLE__) */ + } + + return _kernelStep; +} + +int SetReuseAddress(int fd) +{ + int flag = 1; + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, + (char *) &flag, sizeof(flag)) < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to set SO_REUSEADDR flag on FD#" + << fd << ". Error is " << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to set SO_REUSEADDR flag on FD#" + << fd << ". Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + return -1; + } + #ifdef TEST + else + { + *logofs << "Socket: Set SO_REUSEADDR flag on FD#" + << fd << ".\n" << logofs_flush; + } + #endif + + return 1; +} + +int SetNonBlocking(int fd, int value) +{ + int flags = fcntl(fd, F_GETFL); + + if (flags >= 0) + { + if (value == 0) + { + flags &= ~O_NONBLOCK; + } + else + { + flags |= O_NONBLOCK; + } + } + + if (flags < 0 || fcntl(fd, F_SETFL, flags) < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to set O_NONBLOCK flag on FD#" + << fd << " to " << value << ". Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to set O_NONBLOCK flag on FD#" + << fd << " to " << value << ". Error is " << EGET() + << " '" << ESTR() << "'.\n"; + + return -1; + } + #ifdef TEST + else + { + *logofs << "Socket: Set O_NONBLOCK flag on FD#" + << fd << " to " << value << ".\n" + << logofs_flush; + } + #endif + + return 1; +} + +int SetLingerTimeout(int fd, int timeout) +{ + struct linger linger_value; + + if (timeout > 0) + { + linger_value.l_onoff = 1; + linger_value.l_linger = timeout; + } + else + { + linger_value.l_onoff = 0; + linger_value.l_linger = 0; + } + + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger_value, sizeof(linger_value)) < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to set SO_LINGER values to " + << linger_value.l_onoff << " and " << linger_value.l_linger + << " on FD#" << fd << ". Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to set SO_LINGER values to " + << linger_value.l_onoff << " and " << linger_value.l_linger + << " on FD#" << fd << ". Error is " << EGET() << " '" + << ESTR() << "'.\n"; + + return -1; + } + #ifdef TEST + else + { + *logofs << "Socket: Set SO_LINGER values to " + << linger_value.l_onoff << " and " << linger_value.l_linger + << " on FD#" << fd << ".\n" << logofs_flush; + } + #endif + + return 1; +} + +int SetSendBuffer(int fd, int size) +{ + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to set SO_SNDBUF size to " + << size << " on FD#" << fd << ". Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to set SO_SNDBUF size to " + << size << " on FD#" << fd << ". Error is " + << EGET() << " '" << ESTR() << "'.\n"; + + return -1; + } + #ifdef TEST + else + { + *logofs << "Socket: Set SO_SNDBUF on FD#" << fd + << " to " << size << " bytes.\n" + << logofs_flush; + } + #endif + + return 1; +} + +int SetReceiveBuffer(int fd, int size) +{ + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to set SO_RCVBUF size to " + << size << " on FD#" << fd << ". Error is " + << EGET() << " '" << ESTR() << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed to set SO_RCVBUF size to " + << size << " on FD#" << fd << ". Error is " + << EGET() << " '" << ESTR() << "'.\n"; + + return -1; + } + #ifdef TEST + else + { + *logofs << "Socket: Set SO_RCVBUF on FD#" << fd + << " to " << size << " bytes.\n" + << logofs_flush; + } + #endif + + return 1; +} + +int SetNoDelay(int fd, int value) +{ + int result = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); + + if (result == 0) + { + result = 1; + } + else if (result < 0) + { + // + // Is it become a different error on + // Mac OSX 10.4? + // + + #if defined(__APPLE__) + + result = 0; + + #endif + + #if defined(__sun) + + if (EGET() == ENOPROTOOPT) + { + result = 0; + } + + #endif + + #if !defined(__APPLE__) && !defined(__sun) + + if (EGET() == EOPNOTSUPP) + { + result = 0; + } + + #endif + } + + if (result < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to set TCP_NODELAY flag on " + << "FD#" << fd << " to " << value << ". Error is " + << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to set TCP_NODELAY flag on " + << "FD#" << fd << " to " << value << ". Error is " + << EGET() << " '" << ESTR() << "'.\n"; + } + #ifdef TEST + else if (result == 0) + { + #ifdef TEST + *logofs << "Socket: Option TCP_NODELAY not supported " + << "on FD#" << fd << ".\n" << logofs_flush; + #endif + } + else + { + *logofs << "Socket: Set TCP_NODELAY flag on FD#" + << fd << " to " << value << ".\n" + << logofs_flush; + } + #endif + + return result; +} + +int SetKeepAlive(int fd) +{ + int flag = 1; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(flag)) < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to set SO_KEEPALIVE flag on " + << "FD#" << fd << ". Error is " << EGET() << " '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to set SO_KEEPALIVE flag on " + << "FD#" << fd << ". Error is " << EGET() << " '" + << ESTR() << "'.\n"; + + return -1; + } + #ifdef TEST + else + { + *logofs << "Socket: Set SO_KEEPALIVE flag on FD#" + << fd << ".\n" << logofs_flush; + } + #endif + + return 1; +} + +int SetLowDelay(int fd) +{ + if (_kernelStep < 0) + { + GetKernelStep(); + } + + switch (_kernelStep) + { + case 3: + case 2: + case 1: + { + int flag = IPTOS_LOWDELAY; + + if (setsockopt(fd, SOL_IP, IP_TOS, &flag, sizeof(flag)) < 0) + { + if (EGET() == EOPNOTSUPP) + { + #ifdef TEST + *logofs << "Socket: Option IPTOS_LOWDELAY not supported " + << "on FD#" << fd << ".\n" << logofs_flush; + #endif + + return 0; + } + else + { + #ifdef WARNING + *logofs << "Socket: WARNING! Failed to set IPTOS_LOWDELAY flag on " + << "FD#" << fd << ". Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Failed to set IPTOS_LOWDELAY flag on " + << "FD#" << fd << ". Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + return -1; + } + } + #ifdef TEST + else + { + *logofs << "Socket: Set IPTOS_LOWDELAY flag on FD#" + << fd << ".\n" << logofs_flush; + } + #endif + + return 1; + } + default: + { + #ifdef TEST + *logofs << "Socket: Option IPTOS_LOWDELAY not " + << "supported on FD#" << fd << ".\n" + << logofs_flush; + #endif + + return 0; + } + } +} + +int SetCloseOnExec(int fd) +{ + if (fcntl(fd, F_SETFD, 1) != 0) + { + #ifdef TEST + *logofs << "NXClient: PANIC! Cannot set close-on-exec " + << "on FD#" << fd << ". Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot set close-on-exec on FD#" + << fd << ". Error is " << EGET() << " '" << ESTR() + << "'.\n"; + + return -1; + } + + return 1; +} + +int GetBytesReadable(int fd) +{ + long readable = 0; + + // + // It may fail, for example at session + // shutdown. + // + + if (ioctl(fd, FIONREAD, &readable) < 0) + { + #ifdef TEST + *logofs << "Socket: PANIC! Failed to get bytes readable " + << "from FD#" << fd << ". Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + return -1; + } + + #ifdef TEST + *logofs << "Socket: Returning " << (int) readable + << " bytes readable on FD#" << fd << ".\n" + << logofs_flush; + #endif + + return (int) readable; +} + +int GetBytesWritable(int fd) +{ + if (_kernelStep < 0) + { + GetKernelStep(); + } + + long writable; + + switch (_kernelStep) + { + case 3: + { + // + // TODO: Should query the real size + // of the TCP write buffer. + // + + writable = 16384 - GetBytesQueued(fd); + + if (writable < 0) + { + writable = 0; + } + + break; + } + case 2: + { + if (ioctl(fd, TIOCOUTQ, (void *) &writable) < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to get bytes writable " + << "on FD#" << fd << ". Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to get bytes writable " + << "on FD#" << fd << ". Error is " << EGET() + << " '" << ESTR() << "'.\n"; + + return -1; + } + + break; + } + default: + { + #ifdef TEST + *logofs << "Socket: Option TIOCOUTQ not supported " + << "on FD#" << fd << ",\n" << logofs_flush; + #endif + + // + // TODO: Should query the real size + // of the TCP write buffer. + // + + writable = 16384; + + break; + } + } + + #ifdef TEST + *logofs << "Socket: Returning " << writable + << " bytes writable on FD#" << fd + << ".\n" << logofs_flush; + #endif + + return (int) writable; +} + +int GetBytesQueued(int fd) +{ + // + // The TIOCOUTQ ioctl is not implemented on Cygwin + // and returns the space available on Linux Kernels + // 2.0 and 2.2 (like current MIPS for PS/2). + // + + if (_kernelStep < 0) + { + GetKernelStep(); + } + + long queued; + + switch (_kernelStep) + { + case 3: + { + if (ioctl(fd, TIOCOUTQ, (void *) &queued) < 0) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to get bytes queued " + << "on FD#" << fd << ". Error is " << EGET() + << " '" << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to get bytes queued " + << "on FD#" << fd << ". Error is " << EGET() + << " '" << ESTR() << "'.\n"; + + return -1; + } + + break; + } + case 2: + { + // + // TODO: Should query the real size + // of the TCP write buffer. + // + + queued = 16384 - GetBytesWritable(fd); + + if (queued < 0) + { + queued = 0; + } + + break; + } + default: + { + #ifdef TEST + *logofs << "Socket: Option TIOCOUTQ not supported " + << "on FD#" << fd << ",\n" << logofs_flush; + #endif + + queued = 0; + + break; + } + } + + #ifdef TEST + *logofs << "Socket: Returning " << queued + << " bytes queued on FD#" << fd + << ".\n" << logofs_flush; + #endif + + return (int) queued; +} + +int GetHostAddress(const char *name) +{ + hostent *host = gethostbyname(name); + + if (host == NULL) + { + // + // On some Unices gethostbyname() doesn't + // accept IP addresses, so try inet_addr. + // + + IN_ADDR_T address = inet_addr(name); + + if (address == INADDR_NONE) + { + #ifdef PANIC + *logofs << "Socket: PANIC! Failed to resolve address of '" + << name << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed to resolve address of '" + << name << "'.\n"; + + return 0; + } + + return (int) address; + } + else + { + return (*((int *) host -> h_addr_list[0])); + } +} diff --git a/nxcomp/src/Socket.h b/nxcomp/src/Socket.h new file mode 100644 index 000000000..5e7e47705 --- /dev/null +++ b/nxcomp/src/Socket.h @@ -0,0 +1,96 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Socket_H +#define Socket_H + +#include +#include +#include + +#ifdef __sun +#include +#include +#endif + +// +// Set socket options. +// + +int SetReuseAddress(int fd); +int SetNonBlocking(int fd, int value); +int SetLingerTimeout(int fd, int timeout); +int SetSendBuffer(int fd, int size); +int SetReceiveBuffer(int fd, int size); +int SetNoDelay(int fd, int value); +int SetKeepAlive(int fd); +int SetLowDelay(int fd); +int SetCloseOnExec(int fd); + +// +// Get kernel support level. +// + +int GetKernelStep(); + +// +// Get socket info. +// + +int GetBytesReadable(int fd); +int GetBytesWritable(int fd); +int GetBytesQueued(int fd); + +// +// Inline version, providing direct access +// to the interface. +// + +#include "Misc.h" + +inline int GetBytesReadable(int fd, int *readable) +{ + long t; + + int result = ioctl(fd, FIONREAD, &t); + + #ifdef DEBUG + *logofs << "Socket: Bytes readable from FD#" + << fd << " are " << t << " with result " + << result << ".\n" << logofs_flush; + #endif + + *readable = (int) t; + + return result; +} + +// +// Query Internet address. +// + +int GetHostAddress(const char *name); + +#endif /* Socket_H */ diff --git a/nxcomp/src/Split.cpp b/nxcomp/src/Split.cpp new file mode 100644 index 000000000..e2fea97cc --- /dev/null +++ b/nxcomp/src/Split.cpp @@ -0,0 +1,1839 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "Misc.h" + +#include "Split.h" + +#include "Control.h" +#include "Statistics.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "StaticCompressor.h" + +#include "Unpack.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Define this to trace elements +// allocated and deallocated. +// + +#undef REFERENCES + +// +// Counters used for store control. +// + +int SplitStore::totalSplitSize_; +int SplitStore::totalSplitStorageSize_; + +// +// This is used for reference count. +// + +#ifdef REFERENCES + +int Split::references_ = 0; + +#endif + +Split::Split() +{ + resource_ = nothing; + position_ = nothing; + + store_ = NULL; + + d_size_ = 0; + i_size_ = 0; + c_size_ = 0; + r_size_ = 0; + + next_ = 0; + load_ = 0; + save_ = 0; + + checksum_ = NULL; + state_ = split_undefined; + mode_ = split_none; + action_ = is_discarded; + + #ifdef REFERENCES + + references_++; + + *logofs << "Split: Created new Split at " + << this << " out of " << references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +Split::~Split() +{ + delete [] checksum_; + + #ifdef REFERENCES + + references_--; + + *logofs << "Split: Deleted Split at " + << this << " out of " << references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +SplitStore::SplitStore(StaticCompressor *compressor, CommitStore *commits, int resource) + + : compressor_(compressor), commits_(commits), resource_(resource) +{ + splits_ = new T_splits(); + + current_ = splits_ -> end(); + + splitStorageSize_ = 0; + + #ifdef TEST + *logofs << "SplitStore: Created new store ["; + + if (resource_ != nothing) + { + *logofs << resource_; + } + else + { + *logofs << "commit"; + } + + *logofs << "].\n" << logofs_flush; + + *logofs << "SplitStore: Total messages in stores are " + << totalSplitSize_ << " with total storage size " + << totalSplitStorageSize_ << ".\n" + << logofs_flush; + #endif +} + +SplitStore::~SplitStore() +{ + totalSplitSize_ -= splits_ -> size(); + + totalSplitStorageSize_ -= splitStorageSize_; + + for (T_splits::iterator i = splits_ -> begin(); + i != splits_ -> end(); i++) + { + delete *i; + } + + delete splits_; + + #ifdef TEST + *logofs << "SplitStore: Deleted store ["; + + if (resource_ != nothing) + { + *logofs << resource_; + } + else + { + *logofs << "commit"; + } + + *logofs << "] with storage size " << splitStorageSize_ + << ".\n" << logofs_flush; + + *logofs << "SplitStore: Total messages in stores are " + << totalSplitSize_ << " with total storage size " + << totalSplitStorageSize_ << ".\n" + << logofs_flush; + #endif +} + +// +// This is called at the encoding side. +// + +Split *SplitStore::add(MessageStore *store, int resource, T_split_mode mode, + int position, T_store_action action, T_checksum checksum, + const unsigned char *buffer, const int size) +{ + #ifdef TEST + *logofs << "SplitStore: Adding message [" << (unsigned int) store -> + opcode() << "] resource " << resource << " mode " << mode + << " position " << position << " action [" << DumpAction(action) + << "] and checksum [" << DumpChecksum(checksum) << "]" + << ".\n" << logofs_flush; + #endif + + Split *split = new Split(); + + if (split == NULL) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Can't allocate " + << "memory for the split.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory " + << "for the split.\n"; + + HandleAbort(); + } + + split -> store_ = store; + split -> resource_ = resource; + split -> mode_ = mode; + split -> position_ = position; + split -> action_ = action; + + split -> store_ -> validateSize(size); + + // + // The checksum is not provided if the + // message is cached. + // + + if (checksum != NULL) + { + split -> checksum_ = new md5_byte_t[MD5_LENGTH]; + + memcpy(split -> checksum_, checksum, MD5_LENGTH); + } + + // + // We don't need the identity data at the + // encoding side. This qualifies the split + // as a split generated at the encoding + // side. + // + + split -> i_size_ = store -> identitySize(buffer, size); + + split -> d_size_ = size - split -> i_size_; + + if (action == IS_ADDED || action == is_discarded) + { + // + // If the message was added to message + // store or discarded we need to save + // the real data so we can transfer it + // at later time. + // + + split -> data_.resize(split -> d_size_); + + memcpy(split -> data_.begin(), buffer + split -> i_size_, split -> d_size_); + + // + // If the message was added, lock it so + // it will not be used by the encoding + // side until it is recomposed. + // + + if (action == IS_ADDED) + { + split -> store_ -> lock(split -> position_); + + #ifdef TEST + + commits_ -> validate(split); + + #endif + } + } + #ifdef WARNING + else + { + *logofs << "SplitStore: WARNING! Not copying data for the cached message.\n" + << logofs_flush; + } + #endif + + push(split); + + return split; +} + +// +// This is called at decoding side. If checksum +// is provided, the message can be searched on +// disk, then, if message is found, an event is +// sent to abort the data transfer. +// + +Split *SplitStore::add(MessageStore *store, int resource, int position, + T_store_action action, T_checksum checksum, + unsigned char *buffer, const int size) +{ + #ifdef TEST + *logofs << "SplitStore: Adding message [" + << (unsigned int) store -> opcode() << "] resource " + << resource << " position " << position << " action [" + << DumpAction(action) << "] and checksum [" + << DumpChecksum(checksum) << "].\n" << logofs_flush; + #endif + + Split *split = new Split(); + + if (split == NULL) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Can't allocate " + << "memory for the split.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory " + << "for the split.\n"; + + HandleAbort(); + } + + split -> store_ = store; + split -> resource_ = resource; + split -> position_ = position; + split -> action_ = action; + + split -> store_ -> validateSize(size); + + // + // Check if the checksum was provided + // by the remote. + // + + if (checksum != NULL) + { + split -> checksum_ = new md5_byte_t[MD5_LENGTH]; + + memcpy(split -> checksum_, checksum, MD5_LENGTH); + } + + split -> i_size_ = store -> identitySize(buffer, size); + + // + // Copy the identity so we can expand the + // message when it is committed. + // + + split -> identity_.resize(split -> i_size_); + + memcpy(split -> identity_.begin(), buffer, split -> i_size_); + + split -> d_size_ = size - split -> i_size_; + + if (action == IS_ADDED || action == is_discarded) + { + // + // The unpack procedure will check if the + // first 2 bytes of the buffer contain the + // pattern and will not try to expand the + // image. + // + + split -> data_.resize(2); + + unsigned char *data = split -> data_.begin(); + + data[0] = SPLIT_PATTERN; + data[1] = SPLIT_PATTERN; + + // + // If the message was added to the store, + // we don't have the data part, yet, so + // we need to lock the message until it + // is recomposed. + // + + if (action == IS_ADDED) + { + split -> store_ -> lock(split -> position_); + + #ifdef TEST + + commits_ -> validate(split); + + #endif + } + } + else + { + #ifdef WARNING + *logofs << "SplitStore: WARNING! Copying data for the cached message.\n" + << logofs_flush; + #endif + + // + // We may optionally take the data from the + // message store in compressed form, but, + // as the data has been decompressed in the + // buffer, we save a further decompression. + // + + split -> data_.resize(split -> d_size_); + + memcpy(split -> data_.begin(), buffer + split -> i_size_, split -> d_size_); + } + + push(split); + + return split; +} + +void SplitStore::push(Split *split) +{ + splits_ -> push_back(split); + + splitStorageSize_ += getNodeSize(split); + + totalSplitSize_++; + + totalSplitStorageSize_ += getNodeSize(split); + + statistics -> addSplit(); + + #ifdef TEST + *logofs << "SplitStore: There are " << splits_ -> size() + << " messages in store [" << resource_ << "] with " + << "storage size " << splitStorageSize_ << ".\n" + << logofs_flush; + + *logofs << "SplitStore: Total messages in stores are " + << totalSplitSize_ << " with total storage size " + << totalSplitStorageSize_ << ".\n" + << logofs_flush; + #endif + + split -> state_ = split_added; +} + +void SplitStore::dump() +{ + #ifdef DUMP + + int n; + + Split *split; + + *logofs << "SplitStore: DUMP! Dumping content of "; + + if (commits_ == NULL) + { + *logofs << "[commits]"; + } + else + { + *logofs << "[splits] for store [" << resource_ << "]"; + } + + *logofs << " with [" << getSize() << "] elements " + << "in the store.\n" << logofs_flush; + + n = 0; + + for (T_splits::iterator i = splits_ -> begin(); i != splits_ -> end(); i++, n++) + { + split = *i; + + *logofs << "SplitStore: DUMP! Split [" << n << "] has action [" + << DumpAction(split -> action_) << "] state [" + << DumpState(split -> state_) << "] "; + + if (split -> resource_ >= 0) + { + *logofs << "resource " << split -> resource_; + } + + *logofs << " request " << (unsigned) split -> store_ -> opcode() + << " position " << split -> position_ << " size is " + << split -> data_.size() << " (" << split -> d_size_ + << "/" << split -> c_size_ << "/" << split -> r_size_ + << ") with " << split -> data_.size() - split -> next_ + << "] bytes to go.\n" << logofs_flush; + } + + #endif +} + +int SplitStore::send(EncodeBuffer &encodeBuffer, int packetSize) +{ + if (splits_ -> size() == 0) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Function send called with no splits available.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Function send called with no splits available.\n"; + + HandleAbort(); + } + + // + // A start operation must always be executed on + // the split, even in the case the split will be + // later aborted. + // + + if (current_ == splits_ -> end()) + { + start(encodeBuffer); + } + + // + // If we have matched the checksum received from + // the remote side then we must abort the current + // split, else we can send another block of data + // to the remote peer. + // + + Split *split = *current_; + + unsigned int abort = 0; + + if (split -> state_ == split_loaded) + { + abort = 1; + } + + encodeBuffer.encodeBoolValue(abort); + + if (abort == 1) + { + #ifdef TEST + *logofs << "SplitStore: Aborting split for checksum [" + << DumpChecksum(split -> checksum_) << "] position " + << split -> position_ << " with " << (split -> + data_.size() - split -> next_) << " bytes to go " + << "out of " << split -> data_.size() + << ".\n" << logofs_flush; + #endif + + statistics -> addSplitAborted(); + + statistics -> addSplitAbortedBytesOut(split -> data_.size() - split -> next_); + + split -> next_ = split -> data_.size(); + + split -> state_ = split_aborted; + } + else + { + int count = (packetSize <= 0 || split -> next_ + + packetSize > (int) split -> data_.size() ? + split -> data_.size() - split -> next_ : packetSize); + + #ifdef TEST + *logofs << "SplitStore: Sending split for checksum [" + << DumpChecksum(split -> checksum_) << "] count " + << count << " position " << split -> position_ + << ". Data size is " << split -> data_.size() << " (" + << split -> d_size_ << "/" << split -> c_size_ << "), " + << split -> data_.size() - (split -> next_ + count) + << " to go.\n" << logofs_flush; + #endif + + encodeBuffer.encodeValue(count, 32, 10); + + encodeBuffer.encodeMemory(split -> data_.begin() + split -> next_, count); + + split -> next_ += count; + } + + // + // Was data completely transferred? We are the + // sending side. We must update the message in + // store, even if split was aborted. + // + + if (split -> next_ != ((int) split -> data_.size())) + { + return 0; + } + + // + // Move the split at the head of the + // list to the commits. + // + + remove(split); + + // + // Reset current position to the + // end of repository. + // + + current_ = splits_ -> end(); + + #ifdef TEST + *logofs << "SplitStore: Removed split at head of the list. " + << "Resource is " << split -> resource_ << " request " + << (unsigned) split -> store_ -> opcode() << " position " + << split -> position_ << ".\n" << logofs_flush; + #endif + + return 1; +} + +int SplitStore::start(EncodeBuffer &encodeBuffer) +{ + // + // Get the element at the top of the + // list. + // + + current_ = splits_ -> begin(); + + Split *split = *current_; + + #ifdef TEST + *logofs << "SplitStore: Starting split for checksum [" + << DumpChecksum(split -> checksum_) << "] position " + << split -> position_ << " with " << (split -> + data_.size() - split -> next_) << " bytes to go " + << "out of " << split -> data_.size() + << ".\n" << logofs_flush; + #endif + + // + // See if compression of the data part is + // enabled. + // + + if (split -> store_ -> enableCompress) + { + // + // If the split is going to be aborted don't + // compress the data and go straight to the + // send. The new data size will be assumed + // from the disk cache. + // + + if (split -> state_ != split_loaded) + { + unsigned int compressedSize = 0; + unsigned char *compressedData = NULL; + + if (control -> LocalDataCompression && + (compressor_ -> compressBuffer(split -> data_.begin(), split -> d_size_, + compressedData, compressedSize))) + { + // + // Replace the data with the one in + // compressed form. + // + + #ifdef TEST + *logofs << "SplitStore: Split data of size " << split -> d_size_ + << " has been compressed to " << compressedSize + << " bytes.\n" << logofs_flush; + #endif + + split -> data_.clear(); + + split -> data_.resize(compressedSize); + + memcpy(split -> data_.begin(), compressedData, compressedSize); + + split -> c_size_ = compressedSize; + + // + // Inform our peer that the data is + // compressed and send the new size. + // + + encodeBuffer.encodeBoolValue(1); + + encodeBuffer.encodeValue(compressedSize, 32, 14); + + #ifdef TEST + *logofs << "SplitStore: Signaled " << split -> c_size_ + << " bytes of compressed data for this message.\n" + << logofs_flush; + #endif + + return 1; + } + } + #ifdef TEST + else + { + *logofs << "SplitStore: Not trying to compress the " + << "loaded message.\n" << logofs_flush; + } + #endif + + // + // Tell to the remote that data will + // follow uncompressed. + // + + encodeBuffer.encodeBoolValue(0); + } + + return 1; +} + +int SplitStore::start(DecodeBuffer &decodeBuffer) +{ + #ifdef TEST + *logofs << "SplitStore: Going to receive a new split from the remote side.\n" + << logofs_flush; + #endif + + // + // Get the element at the head + // of the list. + // + + current_ = splits_ -> begin(); + + Split *split = *current_; + + unsigned int compressedSize = 0; + + // + // Save the data size known by the remote. + // This information will be needed if the + // remote will not have a chance to abort + // the split. + // + + split -> r_size_ = split -> d_size_; + + // + // Find out if data was compressed by the + // remote. + // + + if (split -> store_ -> enableCompress) + { + decodeBuffer.decodeBoolValue(compressedSize); + + if (compressedSize == 1) + { + // + // Get the compressed size. + // + + // Since ProtoStep7 (#issue 108) + decodeBuffer.decodeValue(compressedSize, 32, 14); + + split -> store_ -> validateSize(split -> d_size_, compressedSize); + + split -> r_size_ = compressedSize; + } + } + + // + // Update the size if the split + // was not already loaded. + // + + if (split -> state_ != split_loaded) + { + split -> data_.clear(); + + if (compressedSize > 0) + { + split -> c_size_ = compressedSize; + + #ifdef TEST + *logofs << "SplitStore: Split data of size " + << split -> d_size_ << " was compressed to " + << split -> c_size_ << " bytes.\n" + << logofs_flush; + #endif + + split -> data_.resize(split -> c_size_); + } + else + { + split -> data_.resize(split -> d_size_); + } + + unsigned char *data = split -> data_.begin(); + + data[0] = SPLIT_PATTERN; + data[1] = SPLIT_PATTERN; + } + #ifdef TEST + else + { + // + // The message had been already + // loaded from disk. + // + + if (compressedSize > 0) + { + if ((int) compressedSize != split -> c_size_) + { + *logofs << "SplitStore: WARNING! Compressed data size is " + << "different than the loaded compressed size.\n" + << logofs_flush; + } + + *logofs << "SplitStore: Ignoring the new size with " + << "loaded compressed size " << split -> c_size_ + << ".\n" << logofs_flush; + } + } + #endif + + return 1; +} + +int SplitStore::receive(DecodeBuffer &decodeBuffer) +{ + if (splits_ -> size() == 0) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Function receive called with no splits available.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Function receive called with no splits available.\n"; + + HandleAbort(); + } + + if (current_ == splits_ -> end()) + { + start(decodeBuffer); + } + + // + // Check first if split was aborted, else add + // any new data to message being recomposed. + // + + Split *split = *current_; + + unsigned int abort = 0; + + decodeBuffer.decodeBoolValue(abort); + + if (abort == 1) + { + #ifdef TEST + *logofs << "SplitStore: Aborting split for checksum [" + << DumpChecksum(split -> checksum_) << "] position " + << split -> position_ << " with " << (split -> + data_.size() - split -> next_) << " bytes to go " + << "out of " << split -> data_.size() + << ".\n" << logofs_flush; + #endif + + statistics -> addSplitAborted(); + + statistics -> addSplitAbortedBytesOut(split -> r_size_ - split -> next_); + + split -> next_ = split -> r_size_; + + split -> state_ = split_aborted; + } + else + { + // + // Get the size of the packet. + // + + unsigned int count; + + decodeBuffer.decodeValue(count, 32, 10); + + // + // If the split was not already loaded from + // disk, decode the packet and update our + // copy of the data. The encoding side may + // have not received the abort event, yet, + // and may be unaware that the message is + // stored in compressed form at our side. + // + + #ifdef TEST + *logofs << "SplitStore: Receiving split for checksum [" + << DumpChecksum(split -> checksum_) << "] count " + << count << " position " << split -> position_ + << ". Data size is " << split -> data_.size() << " (" + << split -> d_size_ << "/" << split -> c_size_ << "/" + << split -> r_size_ << "), " << split -> r_size_ - + (split -> next_ + count) << " to go.\n" + << logofs_flush; + #endif + + if (split -> next_ + count > (unsigned) split -> r_size_) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Invalid data count " + << count << "provided in the split.\n" + << logofs_flush; + + *logofs << "SplitStore: PANIC! While receiving split for " + << "checksum [" << DumpChecksum(split -> checksum_) + << "] with count " << count << " action [" + << DumpAction(split -> action_) << "] state [" + << DumpState(split -> state_) << "]. Data size is " + << split -> data_.size() << " (" << split -> d_size_ + << "/" << split -> c_size_ << "), " << split -> + data_.size() - (split -> next_ + count) + << " to go.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Invalid data count " + << count << "provided in the split.\n"; + + HandleAbort(); + } + + if (split -> state_ != split_loaded) + { + #ifdef TEST + + if (split -> next_ + count > split -> data_.size()) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Inconsistent split data size " + << split -> data_.size() << " with expected size " + << split -> r_size_ << ".\n" + << logofs_flush; + #endif + + HandleAbort(); + } + + #endif + + memcpy(split -> data_.begin() + split -> next_, + decodeBuffer.decodeMemory(count), count); + } + else + { + #ifdef TEST + *logofs << "SplitStore: WARNING! Data discarded with split " + << "loaded from disk.\n" << logofs_flush; + #endif + + decodeBuffer.decodeMemory(count); + } + + split -> next_ += count; + } + + // + // Is unsplit complete? + // + + if (split -> next_ != split -> r_size_) + { + return 0; + } + + // + // If the persistent cache is enabled, + // we have a valid checksum and the + // split was not originally retrieved + // from disk, save the message on disk. + // + + if (split -> state_ != split_loaded && + split -> state_ != split_aborted) + { + save(split); + } + + // + // Move the split at the head of the + // list to the commits. + // + + remove(split); + + // + // Reset the current position to the + // end of the repository. + // + + current_ = splits_ -> end(); + + #ifdef TEST + *logofs << "SplitStore: Removed split at head of the list. " + << "Resource is " << split -> resource_ << " request " + << (unsigned) split -> store_ -> opcode() << " position " + << split -> position_ << ".\n" << logofs_flush; + #endif + + return 1; +} + +Split *SplitStore::pop() +{ + if (splits_ -> size() == 0) + { + #ifdef TEST + *logofs << "SplitStore: The split store is empty.\n" + << logofs_flush; + #endif + + return NULL; + } + + // + // Move the pointer at the end of the list. + // The next send operation will eventually + // start a new split. + // + + current_ = splits_ -> end(); + + Split *split = *(splits_ -> begin()); + + splits_ -> pop_front(); + + #ifdef TEST + *logofs << "SplitStore: Removed split at the head of the " + << "list with resource " << split -> resource_ + << " request " << (unsigned) split -> store_ -> + opcode() << " position " << split -> position_ + << ".\n" << logofs_flush; + #endif + + splitStorageSize_ -= getNodeSize(split); + + totalSplitSize_--; + + totalSplitStorageSize_ -= getNodeSize(split); + + #ifdef TEST + *logofs << "SplitStore: There are " << splits_ -> size() + << " messages in store [" << resource_ << "] with " + << "storage size " << splitStorageSize_ << ".\n" + << logofs_flush; + + *logofs << "SplitStore: Total messages in stores are " + << totalSplitSize_ << " with total storage size " + << totalSplitStorageSize_ << ".\n" + << logofs_flush; + #endif + + return split; +} + +void SplitStore::remove(Split *split) +{ + #ifdef TEST + *logofs << "SplitStore: Going to remove the split from the list.\n" + << logofs_flush; + #endif + + #ifdef TEST + + if (split != getFirstSplit()) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Trying to remove a split " + << "not at the head of the list.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Trying to remove a split " + << "not at the head of the list.\n"; + + HandleAbort(); + } + + #endif + + // + // Move the split to the commit store. + // + + splits_ -> pop_front(); + + commits_ -> splits_ -> push_back(split); + + splitStorageSize_ -= getNodeSize(split); + + totalSplitSize_--; + + totalSplitStorageSize_ -= getNodeSize(split); + + #ifdef TEST + *logofs << "SplitStore: There are " << splits_ -> size() + << " messages in store [" << resource_ << "] with " + << "storage size " << splitStorageSize_ << ".\n" + << logofs_flush; + + *logofs << "SplitStore: Total messages in stores are " + << totalSplitSize_ << " with total storage size " + << totalSplitStorageSize_ << ".\n" + << logofs_flush; + #endif + + #ifdef TEST + + if (splits_ -> size() == 0) + { + if (splitStorageSize_ != 0) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Internal error calculating " + << "split data size. It is " << splitStorageSize_ + << " while should be 0.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Internal error calculating " + << "split data size. It is " << splitStorageSize_ + << " while should be 0.\n"; + + HandleAbort(); + } + } + + #endif +} + +const char *SplitStore::name(const T_checksum checksum) +{ + if (checksum == NULL) + { + return NULL; + } + + char *pathName = control -> ImageCachePath; + + if (pathName == NULL) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Cannot determine directory of " + << "NX image files.\n" << logofs_flush; + #endif + + return NULL; + } + + int pathSize = strlen(pathName); + + // + // File name is "[path][/I-c/I-][checksum][\0]", + // where c is the first hex digit of checksum. + // + + int nameSize = pathSize + 7 + MD5_LENGTH * 2 + 1; + + char *fileName = new char[nameSize]; + + if (fileName == NULL) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Cannot allocate space for " + << "NX image file name.\n" << logofs_flush; + #endif + + return NULL; + } + + strcpy(fileName, pathName); + + sprintf(fileName + pathSize, "/I-%1X/I-", + *((unsigned char *) checksum) >> 4); + + for (unsigned int i = 0; i < MD5_LENGTH; i++) + { + sprintf(fileName + pathSize + 7 + (i * 2), "%02X", + ((unsigned char *) checksum)[i]); + } + + return fileName; +} + +int SplitStore::save(Split *split) +{ + // + // Check if saving the message on the + // persistent cache is enabled. + // + + if (split -> save_ == 0) + { + return 0; + } + + T_checksum checksum = split -> checksum_; + + const char *fileName = name(checksum); + + if (fileName == NULL) + { + return 0; + } + + unsigned int splitSize; + + ostream *fileStream = NULL; + + unsigned char *fileHeader = NULL; + + // + // Get the other data from the split. + // + + unsigned char opcode = split -> store_ -> opcode(); + + unsigned char *data = split -> data_.begin(); + + int dataSize = split -> d_size_; + int compressedSize = split -> c_size_; + + #ifdef DEBUG + *logofs << "SplitStore: Going to save split OPCODE#" + << (unsigned int) opcode << " to file '" << fileName + << "' with size " << dataSize << " and compressed size " + << compressedSize << ".\n" << logofs_flush; + #endif + + DisableSignals(); + + // + // Change the mask to make the file only + // readable by the user, then restore the + // old mask. + // + + mode_t fileMode; + + // + // Check if the file already exists. We try to + // load the message when the split is started + // and save it only if it is not found. Still + // the remote side may send the same image mul- + // tiple time and we may not have the time to + // notify the abort. + // + + struct stat fileStat; + + if (stat(fileName, &fileStat) == 0) + { + #ifdef TEST + *logofs << "SplitStore: Image file '" << fileName + << "' already present on disk.\n" + << logofs_flush; + #endif + + goto SplitStoreSaveError; + } + + fileMode = umask(0077); + + fileStream = new ofstream(fileName, ios::out | ios::binary); + + umask(fileMode); + + if (CheckData(fileStream) < 0) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Cannot open file '" << fileName + << "' for output.\n" << logofs_flush; + #endif + + goto SplitStoreSaveError; + } + + fileHeader = new unsigned char[SPLIT_HEADER_SIZE]; + + if (fileHeader == NULL) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Cannot allocate space for " + << "NX image header.\n" << logofs_flush; + #endif + + goto SplitStoreSaveError; + } + + // + // Leave 3 bytes for future use. Please note + // that, on some CPUs, we can't use PutULONG() + // to write integers that are not aligned to + // the word boundary. + // + + *fileHeader = opcode; + + *(fileHeader + 1) = 0; + *(fileHeader + 2) = 0; + *(fileHeader + 3) = 0; + + PutULONG(dataSize, fileHeader + 4, false); + PutULONG(compressedSize, fileHeader + 8, false); + + splitSize = (compressedSize > 0 ? compressedSize : dataSize); + + if (PutData(fileStream, fileHeader, SPLIT_HEADER_SIZE) < 0 || + PutData(fileStream, data, splitSize) < 0) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Cannot write to NX " + << "image file '" << fileName << "'.\n" + << logofs_flush; + #endif + + goto SplitStoreSaveError; + } + + // + // Check if all the data was written on the + // disk and, if not, remove the faulty copy. + // + + FlushData(fileStream); + + if (CheckData(fileStream) < 0) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Failed to write NX " + << "image file '" << fileName << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Failed to write NX " + << "image file '" << fileName << "'.\n"; + + goto SplitStoreSaveError; + } + + #ifdef TEST + *logofs << "SplitStore: Saved split to file '" << fileName + << "' with data size " << dataSize << " and " + << "compressed data size " << compressedSize + << ".\n" << logofs_flush; + #endif + + delete fileStream; + + delete [] fileName; + delete [] fileHeader; + + EnableSignals(); + + // + // Update the timestamp as the operation + // may have taken some time. + // + + getNewTimestamp(); + + return 1; + +SplitStoreSaveError: + + delete fileStream; + + if (fileName != NULL) + { + unlink(fileName); + } + + delete [] fileName; + delete [] fileHeader; + + EnableSignals(); + + return -1; +} + +int SplitStore::find(Split *split) +{ + const char *fileName = name(split -> checksum_); + + if (fileName == NULL) + { + return 0; + } + + #ifdef DEBUG + *logofs << "SplitStore: Going to find split OPCODE#" + << (unsigned) split -> store_ -> opcode() + << " in file '" << fileName << "'.\n" + << logofs_flush; + #endif + + // + // Check if the file exists and, at the + // same time, update the modification + // time to prevent its deletion. + // + + if (utime(fileName, NULL) == 0) + { + #ifdef TEST + *logofs << "SplitStore: Found split OPCODE#" + << (unsigned) split -> store_ -> opcode() + << " in file '" << fileName << "'.\n" + << logofs_flush; + #endif + + delete [] fileName; + + return 1; + } + + #ifdef TEST + *logofs << "SplitStore: WARNING! Can't find split " + << "OPCODE#" << (unsigned) split -> store_ -> + opcode() << " in file '" << fileName + << "'.\n" << logofs_flush; + #endif + + delete [] fileName; + + return 0; +} + +int SplitStore::load(Split *split) +{ + // + // Check if loading the image is enabled. + // + + if (split -> load_ == 0) + { + return 0; + } + + const char *fileName = name(split -> checksum_); + + if (fileName == NULL) + { + return 0; + } + + unsigned char fileOpcode; + + int fileSize; + int fileCSize; + + istream *fileStream = NULL; + + unsigned char *fileHeader = NULL; + + DisableSignals(); + + #ifdef DEBUG + *logofs << "SplitStore: Going to load split OPCODE#" + << (unsigned int) split -> store_ -> opcode() + << " from file '" << fileName << "'.\n" + << logofs_flush; + #endif + + fileStream = new ifstream(fileName, ios::in | ios::binary); + + if (CheckData(fileStream) < 0) + { + #ifdef TEST + *logofs << "SplitStore: WARNING! Can't open image file '" + << fileName << "' on disk.\n" << logofs_flush; + #endif + + goto SplitStoreLoadError; + } + + fileHeader = new unsigned char[SPLIT_HEADER_SIZE]; + + if (fileHeader == NULL) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Cannot allocate space for " + << "NX image header.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot allocate space for " + << "NX image header.\n"; + + goto SplitStoreLoadError; + } + + if (GetData(fileStream, fileHeader, SPLIT_HEADER_SIZE) < 0) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Cannot read header from " + << "NX image file '" << fileName << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Cannot read header from " + << "NX image file '" << fileName << "'.\n"; + + goto SplitStoreLoadError; + } + + fileOpcode = *fileHeader; + + fileSize = GetULONG(fileHeader + 4, false); + fileCSize = GetULONG(fileHeader + 8, false); + + // + // Don't complain if we find that data was saved + // in compressed form even if we were not aware + // of the compressed data size. The remote side + // compresses the data only at the time it starts + // the transferral of the split. We replace our + // copy of the data with whatever we find on the + // disk. + // + + if (fileOpcode != split -> store_ -> opcode() || + fileSize != split -> d_size_ || + fileSize > control -> MaximumRequestSize || + fileCSize > control -> MaximumRequestSize) + + { + #ifdef TEST + *logofs << "SplitStore: PANIC! Corrupted image file '" << fileName + << "'. Expected " << (unsigned int) split -> store_ -> opcode() + << "/" << split -> d_size_ << "/" << split -> c_size_ << " found " + << (unsigned int) fileOpcode << "/" << fileSize << "/" + << fileCSize << ".\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Corrupted image file '" << fileName + << "'. Expected " << (unsigned int) split -> store_ -> opcode() + << "/" << split -> d_size_ << "/" << split -> c_size_ << " found " + << (unsigned int) fileOpcode << "/" << fileSize << "/" + << fileCSize << ".\n"; + + goto SplitStoreLoadError; + } + + // + // Update the data size with the size + // we got from the disk record. + // + + split -> d_size_ = fileSize; + split -> c_size_ = fileCSize; + + unsigned int splitSize; + + if (fileCSize > 0) + { + splitSize = fileCSize; + } + else + { + splitSize = fileSize; + } + + // + // Allocate a new buffer if we didn't + // do that already or if the size is + // different. + // + + if (split -> data_.size() != splitSize) + { + split -> data_.clear(); + + split -> data_.resize(splitSize); + } + + if (GetData(fileStream, split -> data_.begin(), splitSize) < 0) + { + #ifdef PANIC + *logofs << "SplitStore: PANIC! Cannot read data from " + << "NX image file '" << fileName << "'.\n" + << logofs_flush; + #endif + + cerr << "Warning" << ": Cannot read data from " + << "NX image file '" << fileName << "'.\n"; + + goto SplitStoreLoadError; + } + + delete fileStream; + + delete [] fileHeader; + delete [] fileName; + + EnableSignals(); + + // + // Update the timestamp as the operation + // may have taken some time. + // + + getNewTimestamp(); + + return 1; + +SplitStoreLoadError: + + delete fileStream; + + unlink(fileName); + + delete [] fileName; + delete [] fileHeader; + + EnableSignals(); + + return -1; +} + +Split *CommitStore::pop() +{ + if (splits_ -> size() == 0) + { + #ifdef TEST + *logofs << "CommitStore: The commit store is empty.\n" + << logofs_flush; + #endif + + return NULL; + } + + Split *split = *(splits_ -> begin()); + + splits_ -> pop_front(); + + #ifdef TEST + *logofs << "CommitStore: Removed commit split at the head " + << "of the list with resource " << split -> resource_ + << " request " << (unsigned) split -> store_ -> + opcode() << " position " << split -> position_ + << ".\n" << logofs_flush; + #endif + + return split; +} + +int CommitStore::expand(Split *split, unsigned char *buffer, const int size) +{ + #ifdef TEST + *logofs << "CommitStore: Expanding split data with " + << size << " bytes to write.\n" + << logofs_flush; + #endif + + #ifdef TEST + + if (size < split -> i_size_ + split -> d_size_) + { + #ifdef PANIC + *logofs << "CommitStore: PANIC! Wrong size of the provided " + << "buffer. It should be " << split -> i_size_ + + split -> d_size_ << " instead of " << size + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Wrong size of the provided " + << "buffer. It should be " << split -> i_size_ + + split -> d_size_ << " instead of " << size + << ".\n"; + + HandleAbort(); + } + + #endif + + #ifdef DEBUG + *logofs << "CommitStore: Copying " << split -> i_size_ + << " bytes of identity.\n" << logofs_flush; + #endif + + memcpy(buffer, split -> identity_.begin(), split -> i_size_); + + // + // Copy data, if any, to the buffer. + // + + if (size > split -> i_size_) + { + // + // Check if message has been stored + // in compressed format. + // + + if (split -> c_size_ == 0) + { + #ifdef DEBUG + *logofs << "CommitStore: Copying " << split -> d_size_ + << " bytes of plain data.\n" << logofs_flush; + #endif + + memcpy(buffer + split -> i_size_, split -> data_.begin(), split -> d_size_); + } + else + { + #ifdef DEBUG + *logofs << "CommitStore: Decompressing " << split -> c_size_ + << " bytes and copying " << split -> d_size_ + << " bytes of data.\n" << logofs_flush; + #endif + + if (compressor_ -> + decompressBuffer(buffer + split -> i_size_, + split -> d_size_, split -> data_.begin(), + split -> c_size_) < 0) + { + #ifdef PANIC + *logofs << "CommitStore: PANIC! Split data decompression failed.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Split data decompression failed.\n"; + + return -1; + } + } + } + + return 1; +} + +int CommitStore::update(Split *split) +{ + if (split -> action_ != IS_ADDED) + { + return 0; + } + + // + // We don't need the identity data at + // the encoding side. + // + + if (split -> identity_.size() == 0) + { + #ifdef TEST + *logofs << "SplitStore: Going to update the size " + << "for object at position " << split -> position_ + << " with data size " << split -> d_size_ + << " and compressed data size " << split -> + c_size_ << ".\n" << logofs_flush; + #endif + + split -> store_ -> updateData(split -> position_, split -> d_size_, + split -> c_size_); + } + else + { + #ifdef TEST + *logofs << "SplitStore: Going to update data and size " + << "for object at position " << split -> position_ + << " with data size " << split -> d_size_ + << " and compressed data size " << split -> + c_size_ << ".\n" << logofs_flush; + #endif + + split -> store_ -> updateData(split -> position_, split -> data_.begin(), + split -> d_size_, split -> c_size_); + } + + // + // Unlock message so that we can remove + // or save it on disk at shutdown. + // + + if (split -> action_ == IS_ADDED) + { + split -> store_ -> unlock(split -> position_); + + #ifdef TEST + + validate(split); + + #endif + } + + return 1; +} + +int CommitStore::validate(Split *split) +{ + MessageStore *store = split -> store_; + + int p, n, s; + + s = store -> cacheSlots; + + for (p = 0, n = 0; p < s; p++) + { + if (store -> getLocks(p) == 1) + { + n++; + } + else if (store -> getLocks(p) != 0) + { + #ifdef PANIC + *logofs << "CommitStore: PANIC! Repository for OPCODE#" + << (unsigned int) store -> opcode() << " has " + << store -> getLocks(p) << " locks for message " + << "at position " << p << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Repository for OPCODE#" + << (unsigned int) store -> opcode() << " has " + << store -> getLocks(p) << " locks for message " + << "at position " << p << ".\n"; + + HandleAbort(); + } + } + + #ifdef TEST + *logofs << "CommitStore: Repository for OPCODE#" + << (unsigned int) store -> opcode() + << " has " << n << " locked messages.\n" + << logofs_flush; + #endif + + return 1; +} diff --git a/nxcomp/src/Split.h b/nxcomp/src/Split.h new file mode 100644 index 000000000..ee5eae7fe --- /dev/null +++ b/nxcomp/src/Split.h @@ -0,0 +1,543 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Split_H +#define Split_H + +#include "Types.h" +#include "Timestamp.h" +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Define this to know how many splits +// are allocated and deallocated. +// + +#undef REFERENCES + +// +// Size of header of messages saved on +// disk. +// + +#define SPLIT_HEADER_SIZE 12 + +// +// This class is used to divide big messages +// in smaller chunks and send them at idle +// time. +// + +class EncodeBuffer; +class DecodeBuffer; + +class SplitStore; +class CommitStore; + +// +// Preferred message streaming policy. +// + +typedef enum +{ + split_none = -1, + split_async = 1, + split_sync + +} T_split_mode; + +// +// Current state of the split. Used to +// implement the state machine. +// + +typedef enum +{ + split_undefined = -1, + split_added, + split_missed, + split_loaded, + split_aborted, + split_notified + +} T_split_state; + +class Split +{ + friend class SplitStore; + friend class CommitStore; + + public: + + Split(); + + ~Split(); + + // + // Note that, differently from the message + // store, the split store doesn't account + // for the data offset when dealing with + // the data. This means that both the size_ + // and c_size members represent the actual + // size of the data part. + // + + void compressedSize(int size) + { + c_size_ = size; + + store_ -> validateSize(d_size_, c_size_); + } + + int compressedSize() + { + return c_size_; + } + + int plainSize() + { + return i_size_ + d_size_; + } + + T_checksum getChecksum() + { + return checksum_; + } + + MessageStore *getStore() + { + return store_; + } + + T_split_state getState() + { + return state_; + } + + T_store_action getAction() + { + return action_; + } + + // + // We may need to find the resource + // associated to the split message + // because old protocol version use + // a single store for all splits. + // + + int getResource() + { + return resource_; + } + + int getRequest() + { + return store_ -> opcode(); + } + + int getPosition() + { + return position_; + } + + T_split_mode getMode() + { + return mode_; + } + + void setPolicy(int load, int save) + { + load_ = load; + save_ = save; + } + + void setState(T_split_state state) + { + state_ = state; + } + + private: + + // + // The agent's resource which is splitting + // the message. + // + + int resource_; + + // + // Where to find the message in the message + // store or the X sequence number of the + // original request, in recent versions. + // + + int position_; + + // + // Which store is involved. + // + + MessageStore *store_; + + // + // Identity size of the message. + // + + int i_size_; + + // + // This is the uncompressed data size of the + // original message. + // + + int d_size_; + + // + // This is the size of the compressed data, + // if the data is stored in this form. + // + + int c_size_; + + // + // Size of the data buffer, as known by the + // encoding side. This field is only used at + // the decoding side. The remote size can be + // different from the actual data size, if + // the encoding side did not confirm that it + // received the abort split event. + // + + int r_size_; + + // + // Position in the data buffer that will be + // the target of the next send or receive + // operation while streaming the message. + // + + int next_; + + // + // Load or save the split to disk. + // + + int load_; + int save_; + + // + // Checksum of the original message. + // + + T_checksum checksum_; + + // + // Was this split confirmed or aborted? + // + + T_split_state state_; + + // + // What's the policy for sending this split? + // + + T_split_mode mode_; + + // + // Operation that had been performed on the + // store at the time the split was added. + // + + T_store_action action_; + + // + // Container for the identity and data part + // of the X message. + // + + T_data identity_; + T_data data_; + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +class SplitStore +{ + public: + + SplitStore(StaticCompressor *compressor, CommitStore *commits, int resource); + + ~SplitStore(); + + Split *getFirstSplit() const + { + if (splits_ -> size() > 0) + { + return (*(splits_ -> begin())); + } + + return NULL; + } + + Split *getLastSplit() const + { + if (splits_ -> size() > 0) + { + return (*(--(splits_ -> end()))); + } + + return NULL; + } + + int getNodeSize(const Split *split) const + { + // + // Take in account 64 bytes of overhead + // for each node. + // + + return (sizeof(class Split) + 64 + + split -> i_size_ + split -> d_size_); + } + + int getStorageSize() + { + return splitStorageSize_; + } + + static int getTotalSize() + { + return totalSplitSize_; + } + + static int getTotalStorageSize() + { + return totalSplitStorageSize_; + } + + int getResource() + { + return resource_; + } + + int getSize() + { + return splits_ -> size(); + } + + T_splits *getSplits() + { + return splits_; + } + + // + // Used, respectively, at the encoding + // and decoding side. + // + + Split *add(MessageStore *store, int resource, T_split_mode mode, + int position, T_store_action action, T_checksum checksum, + const unsigned char *buffer, const int size); + + Split *add(MessageStore *store, int resource, int position, + T_store_action action, T_checksum checksum, + unsigned char *buffer, const int size); + + // + // Handle the streaming of the message data. + // + + int send(EncodeBuffer &encodeBuffer, int packetSize); + + int receive(DecodeBuffer &decodeBuffer); + + // + // Remove the top element of the split store + // and update the storage size. + // + + void remove(Split *split); + + // + // Load the message from disk and replace the + // message in the store with the new copy. + // + + int load(Split *split); + + // + // Save the data to disk after the message has + // been recomposed at the local side. + // + + int save(Split *split); + + // + // Find the message on disk and update the last + // modification time. This is currently unused. + // + + int find(Split *split); + + // + // Remove the element on top of the queue and + // discard any split data that still needs to + // be transferred. + // + + Split *pop(); + + // + // Dump the content of the store. + // + + void dump(); + + protected: + + // + // Repository where to add the splits. + // + + T_splits *splits_; + + // + // Compress and decompress the data payload. + // + + StaticCompressor *compressor_; + + private: + + int start(EncodeBuffer &encodeBuffer); + + int start(DecodeBuffer &decodeBuffer); + + void push(Split *split); + + // + // Determine the name of the file object based + // on the checksum. + // + + const char *name(const T_checksum checksum); + + // + // The number of elements and data bytes + // in the repository. + // + + int splitStorageSize_; + + static int totalSplitSize_; + static int totalSplitStorageSize_; + + // + // Current element being transferred. + // + + T_splits::iterator current_; + + // + // Repository where to move the splits + // after they are completely recomposed. + // + + CommitStore *commits_; + + // + // Index in the client store or none, + // if this is a commit store. + // + + int resource_; + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +class CommitStore : public SplitStore +{ + // + // This is just a split store. + // + + public: + + CommitStore(StaticCompressor *compressor) + + : SplitStore(compressor, NULL, nothing) + { + } + + // + // Move identity and data of the split to the + // provided buffer, uncompressing the message, + // if needed. + // + + int expand(Split *split, unsigned char *buffer, const int size); + + // + // We recomposed the data part. If the message + // was originally added to the message store, + // replace the data and/or update the size. + // + + int update(Split *split); + + // + // Remove the split from the commit queue. + // + + Split *pop(); + + // + // This is just used for debug. It checks + // if any message in the message store has + // an invalid number of locks. + // + + int validate(Split *split); +}; + +#endif /* Split_H */ diff --git a/nxcomp/src/StaticCompressor.cpp b/nxcomp/src/StaticCompressor.cpp new file mode 100644 index 000000000..b47193354 --- /dev/null +++ b/nxcomp/src/StaticCompressor.cpp @@ -0,0 +1,432 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Z.h" +#include "Misc.h" +#include "Control.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +#include "StaticCompressor.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +StaticCompressor::StaticCompressor(int compressionLevel, + int compressionThreshold) +{ + buffer_ = NULL; + bufferSize_ = 0; + + compressionStream_.zalloc = (alloc_func) 0; + compressionStream_.zfree = (free_func) 0; + compressionStream_.opaque = (voidpf) 0; + + decompressionStream_.zalloc = (alloc_func) 0; + decompressionStream_.zfree = (free_func) 0; + decompressionStream_.opaque = (void *) 0; + + decompressionStream_.next_in = (Bytef *) 0; + decompressionStream_.avail_in = 0; + + #ifdef TEST + *logofs << "StaticCompressor: Compression level is " + << compressionLevel << ".\n" << logofs_flush; + #endif + + int result = deflateInit2(&compressionStream_, compressionLevel, Z_DEFLATED, + 15, 9, Z_DEFAULT_STRATEGY); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Cannot initialize the " + << "compression stream. Error is '" << zError(result) + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot initialize the compression " + << "stream. Error is '" << zError(result) << "'.\n"; + + HandleAbort(); + } + + result = inflateInit2(&decompressionStream_, 15); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Cannot initialize the " + << "decompression stream. Error is '" << zError(result) + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot initialize the decompression " + << "stream. Error is '" << zError(result) << "'.\n"; + + HandleAbort(); + } + + #ifdef TEST + *logofs << "StaticCompressor: Compression threshold is " + << compressionThreshold << ".\n" << logofs_flush; + #endif + + threshold_ = compressionThreshold; +} + +StaticCompressor::~StaticCompressor() +{ + int result = deflateEnd(&compressionStream_); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Cannot deinitialize the " + << "compression stream. Error is '" << zError(result) + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot deinitialize the compression " + << "stream. Error is '" << zError(result) << "'.\n"; + } + + result = inflateEnd(&decompressionStream_); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Cannot deinitialize the " + << "decompression stream. Error is '" << zError(result) + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot deinitialize the decompression " + << "stream. Error is '" << zError(result) << "'.\n"; + } + + delete [] buffer_; +} + +// +// This function compresses and encodes the compressed +// buffer. It returns a pointer to the internal buffer +// where data was compressed. +// + +int StaticCompressor::compressBuffer(const unsigned char *plainBuffer, + const unsigned int plainSize, + unsigned char *&compressedBuffer, + unsigned int &compressedSize, + EncodeBuffer &encodeBuffer) +{ + if (control -> LocalDataCompression == 0 || + compressBuffer(plainBuffer, plainSize, + compressedBuffer, compressedSize) <= 0) + { + encodeBuffer.encodeBoolValue(0); + + encodeBuffer.encodeMemory(plainBuffer, plainSize); + + return 0; + } + else + { + encodeBuffer.encodeBoolValue(1); + + encodeBuffer.encodeValue(compressedSize, 32, 14); + encodeBuffer.encodeValue(plainSize, 32, 14); + + encodeBuffer.encodeMemory(compressedBuffer, compressedSize); + + return 1; + } +} + +// +// This function compresses data into a dynamically +// allocated buffer and returns a pointer to it, so +// application must copy data before the next call. +// + +int StaticCompressor::compressBuffer(const unsigned char *plainBuffer, + const unsigned int plainSize, + unsigned char *&compressedBuffer, + unsigned int &compressedSize) +{ + #ifdef DEBUG + *logofs << "StaticCompressor: Called for buffer at " + << (void *) plainBuffer << ".\n" + << logofs_flush; + #endif + + compressedSize = plainSize; + + if (plainSize < (unsigned int) threshold_) + { + #ifdef TEST + *logofs << "StaticCompressor: Leaving buffer unchanged. " + << "Plain size is " << plainSize << " with threshold " + << (unsigned int) threshold_ << ".\n" << logofs_flush; + #endif + + return 0; + } + + // + // Determine the size of the temporary + // buffer. + // + + unsigned int newSize = plainSize + (plainSize / 1000) + 12; + + // + // Allocate a new buffer if it grows + // beyond 64K. + // + + if (buffer_ == NULL || (bufferSize_ > 65536 && + newSize < bufferSize_ / 2) || newSize > bufferSize_) + { + delete [] buffer_; + + buffer_ = new unsigned char[newSize]; + + if (buffer_ == NULL) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Can't allocate compression " + << "buffer of " << newSize << " bytes. Error is " << EGET() + << " ' " << ESTR() << "'.\n" << logofs_flush; + #endif + + cerr << "Warning" << ": Can't allocate compression buffer of " + << newSize << " bytes. Error is " << EGET() + << " '" << ESTR() << "'.\n"; + + bufferSize_ = 0; + + return 0; + } + + bufferSize_ = newSize; + } + + unsigned int resultingSize = newSize; + + int result = ZCompress(&compressionStream_, buffer_, &resultingSize, + plainBuffer, plainSize); + + if (result == Z_OK) + { + if (resultingSize > newSize) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Overflow in compression " + << "buffer size. " << "Expected size was " << newSize + << " while it is " << resultingSize << ".\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Overflow in compress buffer size. " + << "Expected size was " << newSize << " while it is " + << resultingSize << ".\n"; + + return -1; + } + else if (resultingSize >= plainSize) + { + #ifdef TEST + *logofs << "StaticCompressor: Leaving buffer unchanged. " + << "Plain size is " << plainSize << " compressed " + << "size is " << resultingSize << ".\n" + << logofs_flush; + #endif + + return 0; + } + + compressedBuffer = buffer_; + compressedSize = resultingSize; + + #ifdef TEST + *logofs << "StaticCompressor: Compressed buffer from " + << plainSize << " to " << resultingSize + << " bytes.\n" << logofs_flush; + #endif + + return 1; + } + + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Failed compression of buffer. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failed compression of buffer. " + << "Error is '" << zError(result) << "'.\n"; + + return -1; +} + +int StaticCompressor::decompressBuffer(unsigned char *plainBuffer, + unsigned int plainSize, + const unsigned char *&compressedBuffer, + unsigned int &compressedSize, + DecodeBuffer &decodeBuffer) +{ + #ifdef DEBUG + *logofs << "StaticCompressor: Called for buffer at " + << (void *) plainBuffer << ".\n" + << logofs_flush; + #endif + + unsigned int value; + + decodeBuffer.decodeBoolValue(value); + + if (value == 0) + { + memcpy(plainBuffer, + decodeBuffer.decodeMemory(plainSize), + plainSize); + + return 0; + } + + unsigned int checkSize = plainSize; + + decodeBuffer.decodeValue(value, 32, 14); + compressedSize = value; + + decodeBuffer.decodeValue(value, 32, 14); + checkSize = value; + + // + // If caller needs the original compressed + // data it must copy this to its own buffer + // before using any further decode function. + // + + compressedBuffer = decodeBuffer.decodeMemory(compressedSize); + + int result = ZDecompress(&decompressionStream_, plainBuffer, &checkSize, + compressedBuffer, compressedSize); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Failure decompressing buffer. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Failure decompressing buffer. " + << "Error is '" << zError(result) << "'.\n"; + + return -1; + } + else if (plainSize != checkSize) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Expected decompressed size was " + << plainSize << " while it is " << checkSize + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Expected decompressed size was " + << plainSize << " while it is " << checkSize + << ".\n"; + + return -1; + } + + return 1; +} + +// +// This is used to uncompress on-the-fly +// messages whose data has been stored +// in compressed format. +// + +int StaticCompressor::decompressBuffer(unsigned char *plainBuffer, + const unsigned int plainSize, + const unsigned char *compressedBuffer, + const unsigned int compressedSize) +{ + #ifdef TEST + *logofs << "StaticCompressor: Called for buffer at " + << (void *) plainBuffer << ".\n" + << logofs_flush; + #endif + + unsigned int checkSize = plainSize; + + int result = ZDecompress(&decompressionStream_, plainBuffer, &checkSize, + compressedBuffer, compressedSize); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Failure decompressing buffer. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + return -1; + } + + if (plainSize != checkSize) + { + #ifdef PANIC + *logofs << "StaticCompressor: PANIC! Expected decompressed size was " + << plainSize << " while it is " << checkSize + << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Expected decompressed size was " + << plainSize << " while it is " << checkSize + << ".\n"; + + return -1; + } + + #ifdef TEST + *logofs << "StaticCompressor: Decompressed buffer from " + << compressedSize << " to " << plainSize + << " bytes.\n" << logofs_flush; + #endif + + return 1; +} diff --git a/nxcomp/src/StaticCompressor.h b/nxcomp/src/StaticCompressor.h new file mode 100644 index 000000000..e0b81a527 --- /dev/null +++ b/nxcomp/src/StaticCompressor.h @@ -0,0 +1,80 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef StaticCompressor_H +#define StaticCompressor_H + +#include "Z.h" + +class EncodeBuffer; +class DecodeBuffer; + +class StaticCompressor +{ + public: + + StaticCompressor(int compressionLevel, int compressionThreshold); + + ~StaticCompressor(); + + int compressBuffer(const unsigned char *plainBuffer, const unsigned int plainSize, + unsigned char *&compressedBuffer, unsigned int &compressedSize, + EncodeBuffer &encodeBuffer); + + int compressBuffer(const unsigned char *plainBuffer, const unsigned int plainSize, + unsigned char *&compressedBuffer, unsigned int &compressedSize); + + int decompressBuffer(unsigned char *plainBuffer, unsigned int plainSize, + const unsigned char *&compressedBuffer, unsigned int &compressedSize, + DecodeBuffer &decodeBuffer); + + int decompressBuffer(unsigned char *plainBuffer, const unsigned int plainSize, + const unsigned char *compressedBuffer, const unsigned compressedSize); + + static int isCompressionLevel(int compressionLevel) + { + return (compressionLevel == Z_DEFAULT_COMPRESSION || + (compressionLevel >= Z_NO_COMPRESSION && + compressionLevel <= Z_BEST_COMPRESSION)); + } + + int fullReset() + { + return (deflateReset(&compressionStream_) == Z_OK && + inflateReset(&decompressionStream_) == Z_OK); + } + + private: + + z_stream compressionStream_; + z_stream decompressionStream_; + + unsigned char *buffer_; + unsigned int bufferSize_; + + int threshold_; +}; + +#endif diff --git a/nxcomp/src/Statistics.cpp b/nxcomp/src/Statistics.cpp new file mode 100644 index 000000000..ab8fd74dc --- /dev/null +++ b/nxcomp/src/Statistics.cpp @@ -0,0 +1,2007 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "Statistics.h" + +#include "Control.h" + +#include "Proxy.h" + +#include "ClientStore.h" +#include "ServerStore.h" + +// +// Length of temporary buffer +// used to format output. +// + +#define FORMAT_LENGTH 1024 + +// +// Log level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Note that when presenting statistics we invert the +// correct semantics of X client and server entities. +// This is questionable, but matches the user's pers- +// pective of running remote X applications on its +// local client. +// + +Statistics::Statistics(Proxy *proxy) : proxy_(proxy) +{ + transportPartial_.idleTime_ = 0; + transportPartial_.readTime_ = 0; + transportPartial_.writeTime_ = 0; + transportPartial_.proxyBytesIn_ = 0; + transportPartial_.proxyBytesOut_ = 0; + transportPartial_.proxyFramesIn_ = 0; + transportPartial_.proxyFramesOut_ = 0; + transportPartial_.proxyWritesOut_ = 0; + transportPartial_.compressedBytesIn_ = 0; + transportPartial_.compressedBytesOut_ = 0; + transportPartial_.decompressedBytesIn_ = 0; + transportPartial_.decompressedBytesOut_ = 0; + transportPartial_.framingBitsOut_ = 0; + + transportTotal_.idleTime_ = 0; + transportTotal_.readTime_ = 0; + transportTotal_.writeTime_ = 0; + transportTotal_.proxyBytesIn_ = 0; + transportTotal_.proxyBytesOut_ = 0; + transportTotal_.proxyFramesIn_ = 0; + transportTotal_.proxyFramesOut_ = 0; + transportTotal_.proxyWritesOut_ = 0; + transportTotal_.compressedBytesIn_ = 0; + transportTotal_.compressedBytesOut_ = 0; + transportTotal_.decompressedBytesIn_ = 0; + transportTotal_.decompressedBytesOut_ = 0; + transportTotal_.framingBitsOut_ = 0; + + for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) + { + protocolPartial_.requestCached_[i] = 0; + protocolPartial_.requestReplied_[i] = 0; + protocolPartial_.requestCount_[i] = 0; + protocolPartial_.requestBitsIn_[i] = 0; + protocolPartial_.requestBitsOut_[i] = 0; + + protocolPartial_.renderRequestCached_[i] = 0; + protocolPartial_.renderRequestCount_[i] = 0; + protocolPartial_.renderRequestBitsIn_[i] = 0; + protocolPartial_.renderRequestBitsOut_[i] = 0; + + protocolPartial_.replyCached_[i] = 0; + protocolPartial_.replyCount_[i] = 0; + protocolPartial_.replyBitsIn_[i] = 0; + protocolPartial_.replyBitsOut_[i] = 0; + + protocolPartial_.eventCached_[i] = 0; + protocolPartial_.eventCount_[i] = 0; + protocolPartial_.eventBitsIn_[i] = 0; + protocolPartial_.eventBitsOut_[i] = 0; + + protocolTotal_.requestCached_[i] = 0; + protocolTotal_.requestReplied_[i] = 0; + protocolTotal_.requestCount_[i] = 0; + protocolTotal_.requestBitsIn_[i] = 0; + protocolTotal_.requestBitsOut_[i] = 0; + + protocolTotal_.renderRequestCached_[i] = 0; + protocolTotal_.renderRequestCount_[i] = 0; + protocolTotal_.renderRequestBitsIn_[i] = 0; + protocolTotal_.renderRequestBitsOut_[i] = 0; + + protocolTotal_.replyCached_[i] = 0; + protocolTotal_.replyCount_[i] = 0; + protocolTotal_.replyBitsIn_[i] = 0; + protocolTotal_.replyBitsOut_[i] = 0; + + protocolTotal_.eventCached_[i] = 0; + protocolTotal_.eventCount_[i] = 0; + protocolTotal_.eventBitsIn_[i] = 0; + protocolTotal_.eventBitsOut_[i] = 0; + } + + protocolPartial_.cupsCount_ = 0; + protocolPartial_.cupsBitsIn_ = 0; + protocolPartial_.cupsBitsOut_ = 0; + + protocolPartial_.smbCount_ = 0; + protocolPartial_.smbBitsIn_ = 0; + protocolPartial_.smbBitsOut_ = 0; + + protocolPartial_.mediaCount_ = 0; + protocolPartial_.mediaBitsIn_ = 0; + protocolPartial_.mediaBitsOut_ = 0; + + protocolPartial_.httpCount_ = 0; + protocolPartial_.httpBitsIn_ = 0; + protocolPartial_.httpBitsOut_ = 0; + + protocolPartial_.fontCount_ = 0; + protocolPartial_.fontBitsIn_ = 0; + protocolPartial_.fontBitsOut_ = 0; + + protocolPartial_.slaveCount_ = 0; + protocolPartial_.slaveBitsIn_ = 0; + protocolPartial_.slaveBitsOut_ = 0; + + protocolTotal_.cupsCount_ = 0; + protocolTotal_.cupsBitsIn_ = 0; + protocolTotal_.cupsBitsOut_ = 0; + + protocolTotal_.smbCount_ = 0; + protocolTotal_.smbBitsIn_ = 0; + protocolTotal_.smbBitsOut_ = 0; + + protocolTotal_.mediaCount_ = 0; + protocolTotal_.mediaBitsIn_ = 0; + protocolTotal_.mediaBitsOut_ = 0; + + protocolTotal_.httpCount_ = 0; + protocolTotal_.httpBitsIn_ = 0; + protocolTotal_.httpBitsOut_ = 0; + + protocolTotal_.fontCount_ = 0; + protocolTotal_.fontBitsIn_ = 0; + protocolTotal_.fontBitsOut_ = 0; + + protocolTotal_.slaveCount_ = 0; + protocolTotal_.slaveBitsIn_ = 0; + protocolTotal_.slaveBitsOut_ = 0; + + packedPartial_.packedBytesIn_ = 0; + packedPartial_.packedBytesOut_ = 0; + + packedTotal_.packedBytesIn_ = 0; + packedTotal_.packedBytesOut_ = 0; + + splitPartial_.splitCount_ = 0; + splitPartial_.splitAborted_ = 0; + splitPartial_.splitAbortedBytesOut_ = 0; + + splitTotal_.splitCount_ = 0; + splitTotal_.splitAborted_ = 0; + splitTotal_.splitAbortedBytesOut_ = 0; + + overallPartial_.overallBytesIn_ = 0; + overallPartial_.overallBytesOut_ = 0; + + overallTotal_.overallBytesIn_ = 0; + overallTotal_.overallBytesOut_ = 0; + + proxyData_.protocolCount_ = 0; + proxyData_.controlCount_ = 0; + proxyData_.splitCount_ = 0; + proxyData_.dataCount_ = 0; + + proxyData_.streamRatio_ = 1; + + startShortFrameTs_ = getTimestamp(); + startLongFrameTs_ = getTimestamp(); + startFrameTs_ = getTimestamp(); + + bytesInShortFrame_ = 0; + bytesInLongFrame_ = 0; + + bitrateInShortFrame_ = 0; + bitrateInLongFrame_ = 0; + + topBitrate_ = 0; + + congestionInFrame_ = 0; +} + +Statistics::~Statistics() +{ +} + +int Statistics::resetPartialStats() +{ + transportPartial_.idleTime_ = 0; + transportPartial_.readTime_ = 0; + transportPartial_.writeTime_ = 0; + transportPartial_.proxyBytesIn_ = 0; + transportPartial_.proxyBytesOut_ = 0; + transportPartial_.proxyFramesIn_ = 0; + transportPartial_.proxyFramesOut_ = 0; + transportPartial_.proxyWritesOut_ = 0; + transportPartial_.compressedBytesIn_ = 0; + transportPartial_.compressedBytesOut_ = 0; + transportPartial_.decompressedBytesIn_ = 0; + transportPartial_.decompressedBytesOut_ = 0; + transportPartial_.framingBitsOut_ = 0; + + for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) + { + protocolPartial_.requestCached_[i] = 0; + protocolPartial_.requestReplied_[i] = 0; + protocolPartial_.requestCount_[i] = 0; + protocolPartial_.requestBitsIn_[i] = 0; + protocolPartial_.requestBitsOut_[i] = 0; + + protocolPartial_.renderRequestCached_[i] = 0; + protocolPartial_.renderRequestCount_[i] = 0; + protocolPartial_.renderRequestBitsIn_[i] = 0; + protocolPartial_.renderRequestBitsOut_[i] = 0; + + protocolPartial_.replyCached_[i] = 0; + protocolPartial_.replyCount_[i] = 0; + protocolPartial_.replyBitsIn_[i] = 0; + protocolPartial_.replyBitsOut_[i] = 0; + + protocolPartial_.eventCached_[i] = 0; + protocolPartial_.eventCount_[i] = 0; + protocolPartial_.eventBitsIn_[i] = 0; + protocolPartial_.eventBitsOut_[i] = 0; + } + + protocolPartial_.cupsCount_ = 0; + protocolPartial_.cupsBitsIn_ = 0; + protocolPartial_.cupsBitsOut_ = 0; + + protocolPartial_.smbCount_ = 0; + protocolPartial_.smbBitsIn_ = 0; + protocolPartial_.smbBitsOut_ = 0; + + protocolPartial_.mediaCount_ = 0; + protocolPartial_.mediaBitsIn_ = 0; + protocolPartial_.mediaBitsOut_ = 0; + + protocolPartial_.httpCount_ = 0; + protocolPartial_.httpBitsIn_ = 0; + protocolPartial_.httpBitsOut_ = 0; + + protocolPartial_.fontCount_ = 0; + protocolPartial_.fontBitsIn_ = 0; + protocolPartial_.fontBitsOut_ = 0; + + protocolPartial_.slaveCount_ = 0; + protocolPartial_.slaveBitsIn_ = 0; + protocolPartial_.slaveBitsOut_ = 0; + + packedPartial_.packedBytesIn_ = 0; + packedPartial_.packedBytesOut_ = 0; + + splitPartial_.splitCount_ = 0; + splitPartial_.splitAborted_ = 0; + splitPartial_.splitAbortedBytesOut_ = 0; + + overallPartial_.overallBytesIn_ = 0; + overallPartial_.overallBytesOut_ = 0; + + return 1; +} + +void Statistics::addCompressedBytes(unsigned int bytesIn, unsigned int bytesOut) +{ + transportPartial_.compressedBytesIn_ += bytesIn; + transportTotal_.compressedBytesIn_ += bytesIn; + + transportPartial_.compressedBytesOut_ += bytesOut; + transportTotal_.compressedBytesOut_ += bytesOut; + + double ratio = bytesIn / bytesOut; + + if (ratio < 1) + { + ratio = 1; + } + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! Old ratio was " + << proxyData_.streamRatio_ << " current is " + << (double) ratio << " new ratio is " << (double) + ((proxyData_.streamRatio_ * 2) + ratio) / 3 << ".\n" + << logofs_flush; + #endif + + proxyData_.streamRatio_ = ((proxyData_.streamRatio_ * 2) + ratio) / 3; + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! Updated compressed bytes " + << "with " << bytesIn << " in " << bytesOut << " out " + << "and ratio " << (double) proxyData_.streamRatio_ + << ".\n" << logofs_flush; + #endif +} + +// +// Recalculate the current bitrate. The bytes written +// are accounted at the time the transport actually +// writes the data to the network, not at the time it +// receives the data from the upper layers. The reason +// is that data can be compressed by the stream com- +// pressor, so we can become aware of the new bitrate +// only afer having flushed the ZLIB stream. This also +// means that, to have a reliable estimate, we need to +// flush the link often. +// + +void Statistics::updateBitrate(int bytes) +{ + T_timestamp thisFrameTs = getNewTimestamp(); + + int diffFramesInMs = diffTimestamp(startFrameTs_, thisFrameTs); + + #ifdef DEBUG + *logofs << "Statistics: Difference since previous timestamp is " + << diffFramesInMs << " Ms.\n" << logofs_flush; + #endif + + if (diffFramesInMs > 0) + { + #ifdef DEBUG + *logofs << "Statistics: Removing " << diffFramesInMs + << " Ms in short and long time frame.\n" + << logofs_flush; + #endif + + int shortBytesToRemove = (int) (((double) bytesInShortFrame_ * (double) diffFramesInMs) / + (double) control -> ShortBitrateTimeFrame); + + int longBytesToRemove = (int) (((double) bytesInLongFrame_ * (double) diffFramesInMs) / + (double) control -> LongBitrateTimeFrame); + + #ifdef DEBUG + *logofs << "Statistics: Removing " << shortBytesToRemove + << " bytes from " << bytesInShortFrame_ + << " in the short frame.\n" << logofs_flush; + #endif + + bytesInShortFrame_ -= shortBytesToRemove; + + if (bytesInShortFrame_ < 0) + { + #ifdef TEST + *logofs << "Statistics: Bytes in short frame are " + << bytesInShortFrame_ << ". Set to 0.\n" + << logofs_flush; + #endif + + bytesInShortFrame_ = 0; + } + + #ifdef DEBUG + *logofs << "Statistics: Removing " << longBytesToRemove + << " bytes from " << bytesInLongFrame_ + << " in the long frame.\n" << logofs_flush; + #endif + + bytesInLongFrame_ -= longBytesToRemove; + + if (bytesInLongFrame_ < 0) + { + #ifdef TEST + *logofs << "Statistics: Bytes in long frame are " + << bytesInLongFrame_ << ". Set to 0.\n" + << logofs_flush; + #endif + + bytesInLongFrame_ = 0; + } + + int diffStartInMs; + + diffStartInMs = diffTimestamp(thisFrameTs, startShortFrameTs_); + + if (diffStartInMs > control -> ShortBitrateTimeFrame) + { + addMsTimestamp(startShortFrameTs_, diffStartInMs); + } + + diffStartInMs = diffTimestamp(thisFrameTs, startLongFrameTs_); + + if (diffStartInMs > control -> LongBitrateTimeFrame) + { + addMsTimestamp(startLongFrameTs_, diffStartInMs); + } + + startFrameTs_ = thisFrameTs; + } + + #ifdef DEBUG + *logofs << "Statistics: Adding " << bytes << " bytes to " + << bytesInShortFrame_ << " in the short frame.\n" + << logofs_flush; + #endif + + bytesInShortFrame_ = bytesInShortFrame_ + bytes; + + #ifdef DEBUG + *logofs << "Statistics: Adding " << bytes << " bytes to " + << bytesInLongFrame_ << " in the long frame.\n" + << logofs_flush; + #endif + + bytesInLongFrame_ = bytesInLongFrame_ + bytes; + + bitrateInShortFrame_ = (int) ((double) bytesInShortFrame_ / + ((double) control -> ShortBitrateTimeFrame / 1000)); + + bitrateInLongFrame_ = (int) ((double) bytesInLongFrame_ / + ((double) control -> LongBitrateTimeFrame / 1000)); + + if (bitrateInShortFrame_ > topBitrate_) + { + topBitrate_ = bitrateInShortFrame_; + } + + #ifdef TEST + *logofs << "Statistics: Current bitrate is short " << bitrateInShortFrame_ + << " long " << bitrateInLongFrame_ << " top " << topBitrate_ + << ".\n" << logofs_flush; + #endif +} + +void Statistics::updateCongestion(int remaining, int limit) +{ + #ifdef TEST + *logofs << "Statistics: Updating the congestion " + << "counters at " << strMsTimestamp() + << ".\n" << logofs_flush; + #endif + + double current = remaining; + + if (current < 0) + { + current = 0; + } + + current = 9 * (limit - current) / limit; + + #ifdef TEST + *logofs << "Statistics: Current congestion is " + << current << " with " << limit << " tokens " + << "and " << remaining << " remaining.\n" + << logofs_flush; + #endif + + // + // If the current congestion counter is greater + // than the previous, take the current value, + // otherwise ramp down the value by calculating + // the average of the last 8 updates. + // + + #ifdef TEST + *logofs << "Statistics: Old congestion was " + << congestionInFrame_; + #endif + + if (current >= congestionInFrame_) + { + congestionInFrame_ = current; + } + else + { + congestionInFrame_ = ((congestionInFrame_ * 7) + current) / 8; + } + + #ifdef TEST + *logofs << " new congestion is " + << ((congestionInFrame_ * 7) + current) / 8 + << ".\n" << logofs_flush; + #endif + + // + // Call the function with 0 bytes flushed + // so the agent can update its congestion + // counter. + // + + FlushCallback(0); +} + +int Statistics::getClientCacheStats(int type, char *&buffer) +{ + if (type != PARTIAL_STATS && type != TOTAL_STATS) + { + #ifdef PANIC + *logofs << "Statistics: PANIC! Cannot produce statistics " + << "with qualifier '" << type << "'.\n" + << logofs_flush; + #endif + + return -1; + } + + // + // Print message cache data according + // to local and remote view. + // + + MessageStore *currentStore = NULL; + MessageStore *anyStore = NULL; + + char format[FORMAT_LENGTH]; + + strcat(buffer, "\nNX Cache Statistics\n"); + strcat(buffer, "-------------------\n\n"); + + for (int m = proxy_client; m <= proxy_server; m++) + { + if (m == proxy_client) + { + strcat(buffer, "Request\tCached\tSize at Server\t\tSize at Client\t\tCache limit\n"); + strcat(buffer, "-------\t------\t--------------\t\t--------------\t\t-----------\n"); + } + else + { + strcat(buffer, "\nReply\tCached\tSize at Server\t\tSize at Client\t\tCache limit\n"); + strcat(buffer, "-----\t------\t--------------\t\t--------------\t\t-----------\n"); + } + + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + if (m == proxy_client) + { + currentStore = proxy_ -> getClientStore() -> getRequestStore(i); + } + else + { + currentStore = proxy_ -> getServerStore() -> getReplyStore(i); + } + + if (currentStore != NULL && + (currentStore -> getLocalStorageSize() || + currentStore -> getRemoteStorageSize())) + { + anyStore = currentStore; + + sprintf(format, "#%d\t%d\t", i, currentStore -> getSize()); + + strcat(buffer, format); + + sprintf(format, "%d (%.0f KB)\t\t", currentStore -> getLocalStorageSize(), + ((double) currentStore -> getLocalStorageSize()) / 1024); + + strcat(buffer, format); + + sprintf(format, "%d (%.0f KB)\t\t", currentStore -> getRemoteStorageSize(), + ((double) currentStore -> getRemoteStorageSize()) / 1024); + + strcat(buffer, format); + + sprintf(format, "%d/%.0f KB\n", currentStore -> cacheSlots, + ((double) control -> getUpperStorageSize() / 100 * + currentStore -> cacheThreshold) / 1024); + + strcat(buffer, format); + } + } + + if (anyStore == NULL) + { + strcat(buffer, "N/A\n"); + } + } + + if (anyStore != NULL) + { + sprintf(format, "\ncache: %d bytes (%d KB) available at server.\n", + control -> ClientTotalStorageSize, + control -> ClientTotalStorageSize / 1024); + + strcat(buffer, format); + + sprintf(format, " %d bytes (%d KB) available at client.\n\n", + control -> ServerTotalStorageSize, + control -> ServerTotalStorageSize / 1024); + + strcat(buffer, format); + + sprintf(format, " %d bytes (%d KB) allocated at server.\n", + anyStore -> getLocalTotalStorageSize(), + anyStore -> getLocalTotalStorageSize() / 1024); + + strcat(buffer, format); + + sprintf(format, " %d bytes (%d KB) allocated at client.\n\n\n", + anyStore -> getRemoteTotalStorageSize(), + anyStore -> getRemoteTotalStorageSize() / 1024); + + strcat(buffer, format); + } + else + { + strcat(buffer, "\ncache: N/A\n\n"); + } + + return 1; +} + +int Statistics::getClientProtocolStats(int type, char *&buffer) +{ + if (type != PARTIAL_STATS && type != TOTAL_STATS) + { + #ifdef PANIC + *logofs << "Statistics: PANIC! Cannot produce statistics " + << "with qualifier '" << type << "'.\n" + << logofs_flush; + #endif + + return -1; + } + + struct T_transportData *transportData; + struct T_protocolData *protocolData; + struct T_overallData *overallData; + + if (type == PARTIAL_STATS) + { + transportData = &transportPartial_; + protocolData = &protocolPartial_; + overallData = &overallPartial_; + } + else + { + transportData = &transportTotal_; + protocolData = &protocolTotal_; + overallData = &overallTotal_; + } + + char format[FORMAT_LENGTH]; + + double countRequestIn = 0; + double countCachedRequestIn = 0; + double countRepliedRequestIn = 0; + + double countRequestBitsIn = 0; + double countRequestBitsOut = 0; + + double countAnyIn = 0; + double countBitsIn = 0; + double countBitsOut = 0; + + // + // Print request data. + // + + strcat(buffer, "NX Server Side Protocol Statistics\n"); + strcat(buffer, "----------------------------------\n\n"); + + // + // Print render data. + // + + strcat(buffer, "Render Total\tCached\tBits In\t\tBits Out\tBits/Request\t\tRatio\n"); + strcat(buffer, "------- -----\t------\t-------\t\t--------\t------------\t\t-----\n"); + + for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) + { + if (protocolData -> renderRequestCount_[i]) + { + sprintf(format, "#%d ", i); + + while (strlen(format) < 8) + { + strcat(format, " "); + } + + strcat(buffer, format); + + if (protocolData -> renderRequestCached_[i] > 0) + { + sprintf(format, "%.0f\t%.0f", protocolData -> renderRequestCount_[i], + protocolData -> renderRequestCached_[i]); + } + else + { + sprintf(format, "%.0f\t", protocolData -> renderRequestCount_[i]); + } + + strcat(buffer, format); + + sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", + protocolData -> renderRequestBitsIn_[i], protocolData -> renderRequestBitsIn_[i] / 8192, + protocolData -> renderRequestBitsOut_[i], protocolData -> renderRequestBitsOut_[i] / 8192, + protocolData -> renderRequestBitsIn_[i] / protocolData -> renderRequestCount_[i], + protocolData -> renderRequestBitsOut_[i] / protocolData -> renderRequestCount_[i]); + + strcat(buffer, format); + + if (protocolData -> renderRequestBitsOut_[i] > 0) + { + sprintf(format, "%5.3f:1\n", protocolData -> renderRequestBitsIn_[i] / + protocolData -> renderRequestBitsOut_[i]); + + strcat(buffer, format); + } + else + { + strcat(buffer, "1:1\n"); + } + } + + countRequestIn += protocolData -> renderRequestCount_[i]; + countCachedRequestIn += protocolData -> renderRequestCached_[i]; + + countRequestBitsIn += protocolData -> renderRequestBitsIn_[i]; + countRequestBitsOut += protocolData -> renderRequestBitsOut_[i]; + + countAnyIn += protocolData -> renderRequestCount_[i]; + countBitsIn += protocolData -> renderRequestBitsIn_[i]; + countBitsOut += protocolData -> renderRequestBitsOut_[i]; + } + + if (countRequestIn > 0) + { + if (countCachedRequestIn > 0) + { + sprintf(format, "\ntotal: %.0f\t%.0f", countRequestIn, countCachedRequestIn); + } + else + { + sprintf(format, "\ntotal: %.0f\t", countRequestIn); + } + + strcat(buffer, format); + + sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", + countRequestBitsIn, countRequestBitsIn / 8192, countRequestBitsOut, + countRequestBitsOut / 8192, countRequestBitsIn / countRequestIn, + countRequestBitsOut / countRequestIn); + + strcat(buffer, format); + + if (countRequestBitsOut > 0) + { + sprintf(format, "%5.3f:1\n", countRequestBitsIn / countRequestBitsOut); + } + else + { + sprintf(format, "1:1\n"); + } + + strcat(buffer, format); + } + else + { + strcat(buffer, "N/A\n\n"); + } + + countRequestIn = 0; + countCachedRequestIn = 0; + + countRequestBitsIn = 0; + countRequestBitsOut = 0; + + countAnyIn = 0; + countBitsIn = 0; + countBitsOut = 0; + + // + // Print other requests' data. + // + + strcat(buffer, "\nRequest Total\tCached\tBits In\t\tBits Out\tBits/Request\t\tRatio\n"); + strcat(buffer, "------- -----\t------\t-------\t\t--------\t------------\t\t-----\n"); + + for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) + { + if (protocolData -> requestCount_[i]) + { + sprintf(format, "#%d ", i); + + while (strlen(format) < 5) + { + strcat(format, " "); + } + + // + // Mark NX agent-related requests, those + // having a reply and finally those that + // have been probably tainted by client + // side. + // + + if (i >= X_NXFirstOpcode && i <= X_NXLastOpcode) + { + strcat(format, "A"); + } + + if (i != X_NXInternalGenericReply && protocolData -> requestReplied_[i] > 0) + { + strcat(format, "R"); + } + + if (i == X_NoOperation && control -> TaintReplies) + { + strcat(format, "T"); + } + + while (strlen(format) < 8) + { + strcat(format, " "); + } + + strcat(buffer, format); + + if (protocolData -> requestCached_[i] > 0) + { + sprintf(format, "%.0f\t%.0f", protocolData -> requestCount_[i], + protocolData -> requestCached_[i]); + } + else + { + sprintf(format, "%.0f\t", protocolData -> requestCount_[i]); + } + + strcat(buffer, format); + + sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", + protocolData -> requestBitsIn_[i], protocolData -> requestBitsIn_[i] / 8192, + protocolData -> requestBitsOut_[i], protocolData -> requestBitsOut_[i] / 8192, + protocolData -> requestBitsIn_[i] / protocolData -> requestCount_[i], + protocolData -> requestBitsOut_[i] / protocolData -> requestCount_[i]); + + strcat(buffer, format); + + if (protocolData -> requestBitsOut_[i] > 0) + { + sprintf(format, "%5.3f:1\n", protocolData -> requestBitsIn_[i] / + protocolData -> requestBitsOut_[i]); + + strcat(buffer, format); + } + else + { + strcat(buffer, "1:1\n"); + } + } + + countRequestIn += protocolData -> requestCount_[i]; + countCachedRequestIn += protocolData -> requestCached_[i]; + countRepliedRequestIn += protocolData -> requestReplied_[i]; + + countRequestBitsIn += protocolData -> requestBitsIn_[i]; + countRequestBitsOut += protocolData -> requestBitsOut_[i]; + + countAnyIn += protocolData -> requestCount_[i]; + countBitsIn += protocolData -> requestBitsIn_[i]; + countBitsOut += protocolData -> requestBitsOut_[i]; + } + + if (countRequestIn > 0) + { + if (countCachedRequestIn > 0) + { + sprintf(format, "\ntotal: %.0f\t%.0f", countRequestIn, countCachedRequestIn); + } + else + { + sprintf(format, "\ntotal: %.0f\t", countRequestIn); + } + + strcat(buffer, format); + + sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", + countRequestBitsIn, countRequestBitsIn / 8192, countRequestBitsOut, + countRequestBitsOut / 8192, countRequestBitsIn / countRequestIn, + countRequestBitsOut / countRequestIn); + + strcat(buffer, format); + + if (countRequestBitsOut > 0) + { + sprintf(format, "%5.3f:1\n", countRequestBitsIn / countRequestBitsOut); + } + else + { + sprintf(format, "1:1\n"); + } + + strcat(buffer, format); + } + else + { + strcat(buffer, "N/A\n\n"); + } + + // + // Print transport data. + // + + getTimeStats(type, buffer); + + countAnyIn += protocolData -> cupsCount_; + countBitsIn += protocolData -> cupsBitsIn_; + countBitsOut += protocolData -> cupsBitsOut_; + + countAnyIn += protocolData -> smbCount_; + countBitsIn += protocolData -> smbBitsIn_; + countBitsOut += protocolData -> smbBitsOut_; + + countAnyIn += protocolData -> mediaCount_; + countBitsIn += protocolData -> mediaBitsIn_; + countBitsOut += protocolData -> mediaBitsOut_; + + countAnyIn += protocolData -> httpCount_; + countBitsIn += protocolData -> httpBitsIn_; + countBitsOut += protocolData -> httpBitsOut_; + + countAnyIn += protocolData -> fontCount_; + countBitsIn += protocolData -> fontBitsIn_; + countBitsOut += protocolData -> fontBitsOut_; + + countAnyIn += protocolData -> slaveCount_; + countBitsIn += protocolData -> slaveBitsIn_; + countBitsOut += protocolData -> slaveBitsOut_; + + // + // Save the overall amount of bytes + // coming from X clients. + // + + overallData -> overallBytesIn_ = countBitsIn / 8; + + // + // Print performance data. + // + + if (transportData -> readTime_ > 0) + { + sprintf(format, " %.0f messages (%.0f KB) encoded per second.\n\n", + countAnyIn / (transportData -> readTime_ / 1000), + (countBitsIn + transportData -> framingBitsOut_) / 8192 / + (transportData -> readTime_ / 1000)); + } + else + { + sprintf(format, " %.0f messages (%.0f KB) encoded per second.\n\n", + countAnyIn, (countBitsIn + transportData -> + framingBitsOut_) / 8192); + } + + strcat(buffer, format); + + strcat(buffer, "link: "); + + // + // ZLIB compression stats. + // + + getStreamStats(type, buffer); + + // + // Save the overall amount of bytes + // sent on NX proxy link. + // + + if (transportData -> compressedBytesOut_ > 0) + { + overallData -> overallBytesOut_ = transportData -> compressedBytesOut_; + } + else + { + overallData -> overallBytesOut_ = countBitsOut / 8; + } + + // + // Print info on multiplexing overhead. + // + + getFramingStats(type, buffer); + + // + // Print stats about additional channels. + // + + getServicesStats(type, buffer); + + // + // Compression summary. + // + + double ratio = 1; + + if (transportData -> compressedBytesOut_ / 1024 > 0) + { + ratio = ((countBitsIn + transportData -> framingBitsOut_) / 8192) / + (transportData -> compressedBytesOut_ / 1024); + + } + else if (countBitsOut > 0) + { + ratio = (countBitsIn + transportData -> framingBitsOut_) / + countBitsOut; + } + + sprintf(format, " Protocol compression ratio is %5.3f:1.\n\n", + ratio); + + strcat(buffer, format); + + getBitrateStats(type, buffer); + + getSplitStats(type, buffer); + + sprintf(format, " %.0f total handled replies (%.0f unmatched).\n\n\n", + countRepliedRequestIn, protocolData -> requestReplied_[X_NXInternalGenericReply]); + + strcat(buffer, format); + + return 1; +} + +int Statistics::getClientOverallStats(int type, char *&buffer) +{ + if (type != PARTIAL_STATS && type != TOTAL_STATS) + { + #ifdef PANIC + *logofs << "Statistics: PANIC! Cannot produce statistics " + << "with qualifier '" << type << "'.\n" + << logofs_flush; + #endif + + return -1; + } + + struct T_overallData *overallData; + struct T_packedData *packedData; + + if (type == PARTIAL_STATS) + { + overallData = &overallPartial_; + packedData = &packedPartial_; + } + else + { + overallData = &overallTotal_; + packedData = &packedTotal_; + } + + char format[FORMAT_LENGTH]; + + // + // Print header including link type, + // followed by info on packed images. + // + + strcat(buffer, "NX Compression Summary\n"); + strcat(buffer, "----------------------\n\n"); + + char label[FORMAT_LENGTH]; + + switch (control -> LinkMode) + { + case LINK_TYPE_NONE: + { + strcpy(label, "NONE"); + + break; + } + case LINK_TYPE_MODEM: + { + strcpy(label, "MODEM"); + + break; + } + case LINK_TYPE_ISDN: + { + strcpy(label, "ISDN"); + + break; + } + case LINK_TYPE_ADSL: + { + strcpy(label, "ADSL"); + + break; + } + case LINK_TYPE_WAN: + { + strcpy(label, "WAN"); + + break; + } + case LINK_TYPE_LAN: + { + strcpy(label, "LAN"); + + break; + } + default: + { + strcpy(label, "Unknown"); + + break; + } + } + + sprintf(format, "link: %s", label); + + if (control -> LocalDeltaCompression == 1) + { + strcat(format, " with protocol compression enabled."); + } + else + { + strcat(format, " with protocol compression disabled."); + } + + strcat(format, "\n\n"); + + strcat(buffer, format); + + if (packedData -> packedBytesIn_ > 0) + { + sprintf(format, "images: %.0f bytes (%.0f KB) packed to %.0f (%.0f KB).\n\n", + packedData -> packedBytesOut_, packedData -> packedBytesOut_ / 1024, + packedData -> packedBytesIn_, packedData -> packedBytesIn_ / 1024); + + strcat(buffer, format); + + sprintf(format, " Images compression ratio is %5.3f:1.\n\n", + packedData -> packedBytesOut_ / packedData -> packedBytesIn_); + + strcat(buffer, format); + } + + double overallIn = overallData -> overallBytesIn_ - packedData -> packedBytesIn_ + + packedData -> packedBytesOut_; + + double overallOut = overallData -> overallBytesOut_; + + sprintf(format, "overall: %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", + overallIn, overallIn / 1024, overallOut, overallOut / 1024); + + strcat(buffer, format); + + if (overallData -> overallBytesOut_ > 0) + { + sprintf(format, " Overall NX server compression ratio is %5.3f:1.\n\n\n", + overallIn / overallOut); + } + else + { + sprintf(format, " Overall NX server compression ratio is 1:1.\n\n\n"); + } + + strcat(buffer, format); + + return 1; +} + +int Statistics::getServerCacheStats(int type, char *&buffer) +{ + if (type != PARTIAL_STATS && type != TOTAL_STATS) + { + #ifdef PANIC + *logofs << "Statistics: PANIC! Cannot produce statistics " + << "with qualifier '" << type << "'.\n" + << logofs_flush; + #endif + + return -1; + } + + // + // Print message cache data according + // to local and remote view. + // + + MessageStore *currentStore = NULL; + MessageStore *anyStore = NULL; + + char format[FORMAT_LENGTH]; + + strcat(buffer, "\nNX Cache Statistics\n"); + strcat(buffer, "-------------------\n\n"); + + for (int m = proxy_client; m <= proxy_server; m++) + { + if (m == proxy_client) + { + strcat(buffer, "Request\tCached\tSize at Server\t\tSize at Client\t\tCache limit\n"); + strcat(buffer, "-------\t------\t--------------\t\t--------------\t\t-----------\n"); + } + else + { + strcat(buffer, "\nReply\tCached\tSize at Server\t\tSize at Client\t\tCache limit\n"); + strcat(buffer, "-----\t------\t--------------\t\t--------------\t\t-----------\n"); + } + + for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++) + { + if (m == proxy_client) + { + currentStore = proxy_ -> getClientStore() -> getRequestStore(i); + } + else + { + currentStore = proxy_ -> getServerStore() -> getReplyStore(i); + } + + if (currentStore != NULL && + (currentStore -> getLocalStorageSize() || + currentStore -> getRemoteStorageSize())) + { + anyStore = currentStore; + + sprintf(format, "#%d\t%d\t", i, currentStore -> getSize()); + + strcat(buffer, format); + + sprintf(format, "%d (%.0f KB)\t\t", currentStore -> getRemoteStorageSize(), + ((double) currentStore -> getRemoteStorageSize()) / 1024); + + strcat(buffer, format); + + sprintf(format, "%d (%.0f KB)\t\t", currentStore -> getLocalStorageSize(), + ((double) currentStore -> getLocalStorageSize()) / 1024); + + strcat(buffer, format); + + sprintf(format, "%d/%.0f KB\n", currentStore -> cacheSlots, + ((double) control -> getUpperStorageSize() / 100 * + currentStore -> cacheThreshold) / 1024); + + strcat(buffer, format); + } + } + + if (anyStore == NULL) + { + strcat(buffer, "N/A\n"); + } + } + + if (anyStore != NULL) + { + sprintf(format, "\ncache: %d bytes (%d KB) available at server.\n", + control -> ClientTotalStorageSize, + control -> ClientTotalStorageSize / 1024); + + strcat(buffer, format); + + sprintf(format, " %d bytes (%d KB) available at client.\n\n", + control -> ServerTotalStorageSize, + control -> ServerTotalStorageSize / 1024); + + strcat(buffer, format); + + sprintf(format, " %d bytes (%d KB) allocated at server.\n", + anyStore -> getRemoteTotalStorageSize(), + anyStore -> getRemoteTotalStorageSize() / 1024); + + strcat(buffer, format); + + sprintf(format, " %d bytes (%d KB) allocated at client.\n\n\n", + anyStore -> getLocalTotalStorageSize(), + anyStore -> getLocalTotalStorageSize() / 1024); + + strcat(buffer, format); + } + else + { + strcat(buffer, "\ncache: N/A\n\n"); + } + + return 1; +} + +int Statistics::getServerProtocolStats(int type, char *&buffer) +{ + if (type != PARTIAL_STATS && type != TOTAL_STATS) + { + #ifdef PANIC + *logofs << "Statistics: PANIC! Cannot produce statistics " + << "with qualifier '" << type << "'.\n" + << logofs_flush; + #endif + + return -1; + } + + struct T_transportData *transportData; + struct T_protocolData *protocolData; + struct T_overallData *overallData; + + if (type == PARTIAL_STATS) + { + transportData = &transportPartial_; + protocolData = &protocolPartial_; + overallData = &overallPartial_; + } + else + { + transportData = &transportTotal_; + protocolData = &protocolTotal_; + overallData = &overallTotal_; + } + + char format[FORMAT_LENGTH]; + + double countReplyBitsIn = 0; + double countReplyBitsOut = 0; + + double countReplyIn = 0; + double countCachedReplyIn = 0; + + double countEventBitsIn = 0; + double countEventBitsOut = 0; + + double countEventIn = 0; + double countCachedEventIn = 0; + + double countAnyIn = 0; + double countBitsIn = 0; + double countBitsOut = 0; + + // + // Print reply data. + // + + strcat(buffer, "NX Client Side Protocol Statistics\n"); + strcat(buffer, "----------------------------------\n\n"); + + strcat(buffer, "Reply Total\tCached\tBits In\t\tBits Out\tBits/Reply\t\tRatio\n"); + strcat(buffer, "------- -----\t------\t-------\t\t--------\t----------\t\t-----\n"); + + for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) + { + if (protocolData -> replyCount_[i]) + { + sprintf(format, "#%d ", i); + + while (strlen(format) < 5) + { + strcat(format, " "); + } + + // + // Mark replies originated + // by NX agent requests. + // + + if (i >= X_NXFirstOpcode && i <= X_NXLastOpcode) + { + strcat(format, "A"); + } + + // + // Mark replies that we didn't + // match against a request. + // + + if (i == 1) + { + strcat(format, "U"); + } + + while (strlen(format) < 8) + { + strcat(format, " "); + } + + strcat(buffer, format); + + if (protocolData -> replyCached_[i] > 0) + { + sprintf(format, "%.0f\t%.0f", protocolData -> replyCount_[i], + protocolData -> replyCached_[i]); + } + else + { + sprintf(format, "%.0f\t", protocolData -> replyCount_[i]); + } + + strcat(buffer, format); + + sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", + protocolData -> replyBitsIn_[i], protocolData -> replyBitsIn_[i] / 8192, + protocolData -> replyBitsOut_[i], protocolData -> replyBitsOut_[i] / 8192, + protocolData -> replyBitsIn_[i] / protocolData -> replyCount_[i], + protocolData -> replyBitsOut_[i] / protocolData -> replyCount_[i]); + + strcat(buffer, format); + + if (protocolData -> replyBitsOut_[i] > 0) + { + sprintf(format, "%5.3f:1\n", protocolData -> replyBitsIn_[i] / + protocolData -> replyBitsOut_[i]); + } + else + { + sprintf(format, "1:1\n"); + } + + strcat(buffer, format); + } + + countReplyIn += protocolData -> replyCount_[i]; + countCachedReplyIn += protocolData -> replyCached_[i]; + + countReplyBitsIn += protocolData -> replyBitsIn_[i]; + countReplyBitsOut += protocolData -> replyBitsOut_[i]; + + countAnyIn += protocolData -> replyCount_[i]; + countBitsIn += protocolData -> replyBitsIn_[i]; + countBitsOut += protocolData -> replyBitsOut_[i]; + } + + if (countReplyIn > 0) + { + if (countCachedReplyIn > 0) + { + sprintf(format, "\ntotal: %.0f\t%.0f", countReplyIn, countCachedReplyIn); + } + else + { + sprintf(format, "\ntotal: %.0f\t", countReplyIn); + } + + strcat(buffer, format); + + sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", + countReplyBitsIn, countReplyBitsIn / 8192, countReplyBitsOut, + countReplyBitsOut / 8192, countReplyBitsIn / countReplyIn, + countReplyBitsOut / countReplyIn); + + strcat(buffer, format); + + if (countReplyBitsOut > 0) + { + sprintf(format, "%5.3f:1\n", countReplyBitsIn / countReplyBitsOut); + } + else + { + sprintf(format, "1:1\n"); + } + + strcat(buffer, format); + } + else + { + strcat(buffer, "N/A\n"); + } + + strcat(buffer, "\n"); + + // + // Print event and error data. + // + + strcat(buffer, "Event Total\tCached\tBits In\t\tBits Out\tBits/Event\t\tRatio\n"); + strcat(buffer, "------- -----\t------\t-------\t\t--------\t----------\t\t-----\n"); + + for (int i = 0; i < STATISTICS_OPCODE_MAX; i++) + { + if (protocolData -> eventCount_[i]) + { + sprintf(format, "#%d ", i); + + while (strlen(format) < 8) + { + strcat(format, " "); + } + + strcat(buffer, format); + + if (protocolData -> eventCached_[i] > 0) + { + sprintf(format, "%.0f\t%.0f", protocolData -> eventCount_[i], + protocolData -> eventCached_[i]); + } + else + { + sprintf(format, "%.0f\t", protocolData -> eventCount_[i]); + } + + strcat(buffer, format); + + sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", + protocolData -> eventBitsIn_[i], protocolData -> eventBitsIn_[i] / 8192, + protocolData -> eventBitsOut_[i], protocolData -> eventBitsOut_[i] / 8192, + protocolData -> eventBitsIn_[i] / protocolData -> eventCount_[i], + protocolData -> eventBitsOut_[i] / protocolData -> eventCount_[i]); + + strcat(buffer, format); + + if (protocolData -> eventBitsOut_[i] > 0) + { + sprintf(format, "%5.3f:1\n", protocolData -> eventBitsIn_[i] / + protocolData -> eventBitsOut_[i]); + } + else + { + sprintf(format, "1:1\n"); + } + + strcat(buffer, format); + } + + countEventIn += protocolData -> eventCount_[i]; + countCachedEventIn += protocolData -> eventCached_[i]; + + countEventBitsIn += protocolData -> eventBitsIn_[i]; + countEventBitsOut += protocolData -> eventBitsOut_[i]; + + countAnyIn += protocolData -> eventCount_[i]; + countBitsIn += protocolData -> eventBitsIn_[i]; + countBitsOut += protocolData -> eventBitsOut_[i]; + } + + if (countEventIn > 0) + { + if (countCachedEventIn > 0) + { + sprintf(format, "\ntotal: %.0f\t%.0f", countEventIn, countCachedEventIn); + } + else + { + sprintf(format, "\ntotal: %.0f\t", countEventIn); + } + + strcat(buffer, format); + + sprintf(format, "\t%.0f (%.0f KB)\t%.0f (%.0f KB)\t%.0f/1 -> %.0f/1 \t", + countEventBitsIn, countEventBitsIn / 8192, countEventBitsOut, + countEventBitsOut / 8192, countEventBitsIn / countEventIn, + countEventBitsOut / countEventIn); + + strcat(buffer, format); + + if (countEventBitsOut > 0) + { + sprintf(format, "%5.3f:1\n", countEventBitsIn / countEventBitsOut); + } + else + { + sprintf(format, "1:1\n"); + } + + strcat(buffer, format); + } + else + { + strcat(buffer, "N/A\n\n"); + } + + // + // Print transport data. + // + + getTimeStats(type, buffer); + + countAnyIn += protocolData -> cupsCount_; + countBitsIn += protocolData -> cupsBitsIn_; + countBitsOut += protocolData -> cupsBitsOut_; + + countAnyIn += protocolData -> smbCount_; + countBitsIn += protocolData -> smbBitsIn_; + countBitsOut += protocolData -> smbBitsOut_; + + countAnyIn += protocolData -> mediaCount_; + countBitsIn += protocolData -> mediaBitsIn_; + countBitsOut += protocolData -> mediaBitsOut_; + + countAnyIn += protocolData -> httpCount_; + countBitsIn += protocolData -> httpBitsIn_; + countBitsOut += protocolData -> httpBitsOut_; + + countAnyIn += protocolData -> fontCount_; + countBitsIn += protocolData -> fontBitsIn_; + countBitsOut += protocolData -> fontBitsOut_; + + countAnyIn += protocolData -> slaveCount_; + countBitsIn += protocolData -> slaveBitsIn_; + countBitsOut += protocolData -> slaveBitsOut_; + + // + // Save the overall amount of bytes + // coming from X clients. + // + + overallData -> overallBytesIn_ = countBitsIn / 8; + + // + // Print performance data. + // + + if (transportData -> readTime_ > 0) + { + sprintf(format, " %.0f messages (%.0f KB) encoded per second.\n\n", + countAnyIn / (transportData -> readTime_ / 1000), + (countBitsIn + transportData -> framingBitsOut_) / 8192 / + (transportData -> readTime_ / 1000)); + } + else + { + sprintf(format, " %.0f messages (%.0f KB) encoded per second.\n\n", + countAnyIn, (countBitsIn + transportData -> + framingBitsOut_) / 8192); + } + + strcat(buffer, format); + + strcat(buffer, "link: "); + + // + // ZLIB compression stats. + // + + getStreamStats(type, buffer); + + // + // Save the overall amount of bytes + // sent on NX proxy link. + // + + if (transportData -> compressedBytesOut_ > 0) + { + overallData -> overallBytesOut_ = transportData -> compressedBytesOut_; + } + else + { + overallData -> overallBytesOut_ = countBitsOut / 8; + } + + // + // Print info on multiplexing overhead. + // + + getFramingStats(type, buffer); + + // + // Print stats about additional channels. + // + + getServicesStats(type, buffer); + + // + // Compression summary. + // + + double ratio = 1; + + if (transportData -> compressedBytesOut_ / 1024 > 0) + { + ratio = ((countBitsIn + transportData -> framingBitsOut_) / 8192) / + (transportData -> compressedBytesOut_ / 1024); + + } + else if (countBitsOut > 0) + { + ratio = (countBitsIn + transportData -> framingBitsOut_) / + countBitsOut; + } + + sprintf(format, " Protocol compression ratio is %5.3f:1.\n\n", + ratio); + + strcat(buffer, format); + + getBitrateStats(type, buffer); + + // + // These are not included in output. + // + // getSplitStats(type, buffer); + // + + strcat(buffer, "\n"); + + // + // These statistics are not included in output. + // You can check it anyway to get the effective + // amount of bytes produced by unpack procedure. + // + // getClientOverallStats(type, buffer); + // + + return 1; +} + +int Statistics::getServerOverallStats(int type, char *&buffer) +{ + return 1; +} + +int Statistics::getTimeStats(int type, char *&buffer) +{ + struct T_transportData *transportData; + + if (type == PARTIAL_STATS) + { + transportData = &transportPartial_; + } + else + { + transportData = &transportTotal_; + } + + char format[FORMAT_LENGTH]; + + sprintf(format, "\ntime: %.0f Ms idle, %.0f Ms (%.0f Ms in read, %.0f Ms in write) running.\n\n", + transportData -> idleTime_, transportData -> readTime_, + transportData -> readTime_ - transportData -> writeTime_, + transportData -> writeTime_); + + strcat(buffer, format); + + return 1; +} + +int Statistics::getStreamStats(int type, char *&buffer) +{ + struct T_transportData *transportData; + + if (type == PARTIAL_STATS) + { + transportData = &transportPartial_; + } + else + { + transportData = &transportTotal_; + } + + char format[FORMAT_LENGTH]; + + if (transportData -> compressedBytesOut_ > 0) + { + sprintf(format, "%.0f bytes (%.0f KB) compressed to %.0f (%.0f KB).\n", + transportData -> compressedBytesIn_, transportData -> compressedBytesIn_ / 1024, + transportData -> compressedBytesOut_, transportData -> compressedBytesOut_ / 1024); + + strcat(buffer, format); + + sprintf(format, " %5.3f:1 stream compression ratio.\n\n", + transportData -> compressedBytesIn_ / transportData -> compressedBytesOut_); + + strcat(buffer, format); + } + + if (transportData -> decompressedBytesOut_ > 0) + { + if (transportData -> compressedBytesOut_ > 0) + { + strcat(buffer, " "); + } + + sprintf(format, "%.0f bytes (%.0f KB) decompressed to %.0f (%.0f KB).\n", + transportData -> decompressedBytesIn_, transportData -> decompressedBytesIn_ / 1024, + transportData -> decompressedBytesOut_, transportData -> decompressedBytesOut_ / 1024); + + strcat(buffer, format); + + sprintf(format, " %5.3f:1 stream compression ratio.\n\n", + transportData -> decompressedBytesOut_ / transportData -> decompressedBytesIn_); + + strcat(buffer, format); + } + + if (transportData -> compressedBytesOut_ > 0 || + transportData -> decompressedBytesOut_ > 0) + { + strcat(buffer, " "); + } + + return 1; +} + +int Statistics::getServicesStats(int type, char *&buffer) +{ + struct T_protocolData *protocolData; + + if (type == PARTIAL_STATS) + { + protocolData = &protocolPartial_; + } + else + { + protocolData = &protocolTotal_; + } + + char format[FORMAT_LENGTH]; + + if (protocolData -> cupsBitsOut_ > 0) + { + sprintf(format, " %.0f CUPS messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", + protocolData -> cupsCount_ , protocolData -> cupsBitsIn_ / 8, + protocolData -> cupsBitsIn_ / 8192, protocolData -> cupsBitsOut_ / 8, + protocolData -> cupsBitsOut_ / 8192); + + strcat(buffer, format); + } + + if (protocolData -> smbBitsOut_ > 0) + { + sprintf(format, " %.0f SMB messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", + protocolData -> smbCount_ , protocolData -> smbBitsIn_ / 8, + protocolData -> smbBitsIn_ / 8192, protocolData -> smbBitsOut_ / 8, + protocolData -> smbBitsOut_ / 8192); + + strcat(buffer, format); + } + + if (protocolData -> mediaBitsOut_ > 0) + { + sprintf(format, " %.0f multimedia messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", + protocolData -> mediaCount_ , protocolData -> mediaBitsIn_ / 8, + protocolData -> mediaBitsIn_ / 8192, protocolData -> mediaBitsOut_ / 8, + protocolData -> mediaBitsOut_ / 8192); + + strcat(buffer, format); + } + + if (protocolData -> httpBitsOut_ > 0) + { + sprintf(format, " %.0f HTTP messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", + protocolData -> httpCount_ , protocolData -> httpBitsIn_ / 8, + protocolData -> httpBitsIn_ / 8192, protocolData -> httpBitsOut_ / 8, + protocolData -> httpBitsOut_ / 8192); + + strcat(buffer, format); + } + + if (protocolData -> fontBitsOut_ > 0) + { + sprintf(format, " %.0f font server messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", + protocolData -> fontCount_ , protocolData -> fontBitsIn_ / 8, + protocolData -> fontBitsIn_ / 8192, protocolData -> fontBitsOut_ / 8, + protocolData -> fontBitsOut_ / 8192); + + strcat(buffer, format); + } + + if (protocolData -> slaveBitsOut_ > 0) + { + sprintf(format, " %.0f slave messages, %.0f bytes (%.0f KB) in, %.0f bytes (%.0f KB) out.\n\n", + protocolData -> slaveCount_ , protocolData -> slaveBitsIn_ / 8, + protocolData -> slaveBitsIn_ / 8192, protocolData -> slaveBitsOut_ / 8, + protocolData -> slaveBitsOut_ / 8192); + + strcat(buffer, format); + } + + return 1; +} + +int Statistics::getFramingStats(int type, char *&buffer) +{ + struct T_transportData *transportData; + + if (type == PARTIAL_STATS) + { + transportData = &transportPartial_; + } + else + { + transportData = &transportTotal_; + } + + char format[FORMAT_LENGTH]; + + // + // Print info on multiplexing overhead. + // + + sprintf(format, "%.0f frames in, %.0f frames out, %.0f writes out.\n\n", + transportData -> proxyFramesIn_, transportData -> proxyFramesOut_, + transportData -> proxyWritesOut_); + + strcat(buffer, format); + + sprintf(format, " %.0f bytes (%.0f KB) used for framing and multiplexing.\n\n", + transportData -> framingBitsOut_ / 8, transportData -> framingBitsOut_ / 8192); + + strcat(buffer, format); + + return 1; +} + +int Statistics::getBitrateStats(int type, char *&buffer) +{ + struct T_transportData *transportData; + struct T_overallData *overallData; + + if (type == PARTIAL_STATS) + { + transportData = &transportPartial_; + overallData = &overallPartial_; + } + else + { + transportData = &transportTotal_; + overallData = &overallTotal_; + } + + double total = 0; + + if (transportData -> idleTime_ + transportData -> readTime_ > 0) + { + total = overallData -> overallBytesOut_ / + ((transportData -> idleTime_ + transportData -> readTime_) / 1000); + } + + char format[FORMAT_LENGTH]; + + sprintf(format, " %.0f B/s average, %d B/s %ds, %d B/s %ds, %d B/s maximum.\n\n", + total, getBitrateInShortFrame(), control -> ShortBitrateTimeFrame / 1000, + getBitrateInLongFrame(), control -> LongBitrateTimeFrame / 1000, + getTopBitrate()); + + strcat(buffer, format); + + resetTopBitrate(); + + return 1; +} + +int Statistics::getSplitStats(int type, char *&buffer) +{ + // + // Don't print these statistics if persistent + // cache of images is disabled. + // + + if (control -> ImageCacheEnableLoad == 0 && + control -> ImageCacheEnableSave == 0) + { + return 0; + } + + struct T_splitData *splitData; + + if (type == PARTIAL_STATS) + { + splitData = &splitPartial_; + } + else + { + splitData = &splitTotal_; + } + + char format[FORMAT_LENGTH]; + + // + // Print info on split messages restored from disk. + // + + sprintf(format, " %.0f images streamed, %.0f restored, %.0f bytes (%.0f KB) cached.\n\n", + splitData -> splitCount_, splitData -> splitAborted_, splitData -> splitAbortedBytesOut_, + splitData -> splitAbortedBytesOut_ / 1024); + + strcat(buffer, format); + + return 1; +} diff --git a/nxcomp/src/Statistics.h b/nxcomp/src/Statistics.h new file mode 100644 index 000000000..1ffb6b5d6 --- /dev/null +++ b/nxcomp/src/Statistics.h @@ -0,0 +1,745 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Statistics_H +#define Statistics_H + +#include "NXproto.h" + +#include "Misc.h" +#include "Timestamp.h" + +class Proxy; + +// +// Opcode 255 is for generic requests, 1 is for +// generic replies (those which haven't a speci- +// fic differential encoding), opcode 0 is for +// generic messages from the auxiliary channels. +// + +#define STATISTICS_OPCODE_MAX 256 + +// +// Maximum length of the buffer allocated for +// the statistics output. +// + +#define STATISTICS_LENGTH 16384 + +// +// Query type. +// + +#define TOTAL_STATS 1 +#define PARTIAL_STATS 2 +#define NO_STATS 3 + +// +// Log level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Log the operations related to updating +// the control tokens. +// + +#undef TOKEN + +class Statistics +{ + public: + + // + // Use the proxy class to get access + // to the message stores. + // + + Statistics(Proxy *proxy); + + ~Statistics(); + + void addIdleTime(unsigned int numMs) + { + transportPartial_.idleTime_ += numMs; + transportTotal_.idleTime_ += numMs; + } + + void subIdleTime(unsigned int numMs) + { + transportPartial_.idleTime_ -= numMs; + transportTotal_.idleTime_ -= numMs; + } + + void addReadTime(unsigned int numMs) + { + transportPartial_.readTime_ += numMs; + transportTotal_.readTime_ += numMs; + } + + void subReadTime(unsigned int numMs) + { + transportPartial_.readTime_ -= numMs; + transportTotal_.readTime_ -= numMs; + } + + void addWriteTime(unsigned int numMs) + { + transportPartial_.writeTime_ += numMs; + transportTotal_.writeTime_ += numMs; + } + + void subWriteTime(unsigned int numMs) + { + transportPartial_.writeTime_ -= numMs; + transportTotal_.writeTime_ -= numMs; + } + + void addBytesIn(unsigned int numBytes) + { + transportPartial_.proxyBytesIn_ += numBytes; + transportTotal_.proxyBytesIn_ += numBytes; + } + + double getBytesIn() + { + return transportTotal_.proxyBytesIn_; + } + + void addBytesOut(unsigned int numBytes) + { + transportPartial_.proxyBytesOut_ += numBytes; + transportTotal_.proxyBytesOut_ += numBytes; + } + + double getBytesOut() + { + return transportTotal_.proxyBytesOut_; + } + + void addFrameIn() + { + transportPartial_.proxyFramesIn_++; + transportTotal_.proxyFramesIn_++; + + #ifdef TEST + *logofs << "Statistics: Updated total proxy frames in to " + << transportTotal_.proxyFramesIn_ << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + } + + void addFrameOut() + { + transportPartial_.proxyFramesOut_++; + transportTotal_.proxyFramesOut_++; + + #ifdef TEST + *logofs << "Statistics: Updated total proxy frames out to " + << transportTotal_.proxyFramesOut_ << " at " + << strMsTimestamp() << ".\n" + << logofs_flush; + #endif + } + + void addWriteOut() + { + transportPartial_.proxyWritesOut_++; + transportTotal_.proxyWritesOut_++; + + #ifdef TEST + *logofs << "Statistics: Updated total proxy writes out to " + << transportTotal_.proxyWritesOut_ << " at " + << strMsTimestamp() << ".\n" << logofs_flush; + #endif + } + + void addCompressedBytes(unsigned int bytesIn, unsigned int bytesOut); + + void addDecompressedBytes(unsigned int bytesIn, unsigned int bytesOut) + { + transportPartial_.decompressedBytesIn_ += bytesIn; + transportTotal_.decompressedBytesIn_ += bytesIn; + + transportPartial_.decompressedBytesOut_ += bytesOut; + transportTotal_.decompressedBytesOut_ += bytesOut; + } + + void addFramingBits(unsigned int bitsOut) + { + transportPartial_.framingBitsOut_ += bitsOut; + transportTotal_.framingBitsOut_ += bitsOut; + + proxyData_.protocolCount_ += bitsOut; + } + + void addCachedRequest(unsigned int opcode) + { + protocolPartial_.requestCached_[opcode]++; + protocolTotal_.requestCached_[opcode]++; + } + + void addRenderCachedRequest(unsigned int opcode) + { + protocolPartial_.renderRequestCached_[opcode]++; + protocolTotal_.renderRequestCached_[opcode]++; + } + + void addRepliedRequest(unsigned int opcode) + { + protocolPartial_.requestReplied_[opcode]++; + protocolTotal_.requestReplied_[opcode]++; + } + + void addCachedReply(unsigned int opcode) + { + protocolPartial_.replyCached_[opcode]++; + protocolTotal_.replyCached_[opcode]++; + } + + void addRequestBits(unsigned int opcode, unsigned int bitsIn, unsigned int bitsOut) + { + #ifdef DEBUG + *logofs << "Statistcs: Added " << bitsIn << " bits in and " + << bitsOut << " bits out to opcode " << opcode + << ".\n" << logofs_flush; + #endif + + protocolPartial_.requestCount_[opcode]++; + protocolTotal_.requestCount_[opcode]++; + + protocolPartial_.requestBitsIn_[opcode] += bitsIn; + protocolTotal_.requestBitsIn_[opcode] += bitsIn; + + protocolPartial_.requestBitsOut_[opcode] += bitsOut; + protocolTotal_.requestBitsOut_[opcode] += bitsOut; + + // + // Don't account the split bits + // to the control token. + // + + if (opcode != X_NXSplitData && opcode != X_NXSplitEvent) + { + proxyData_.protocolCount_ += bitsOut; + } + } + + void addRenderRequestBits(unsigned int opcode, unsigned int bitsIn, unsigned int bitsOut) + { + #ifdef DEBUG + *logofs << "Statistcs: Added " << bitsIn << " bits in and " + << bitsOut << " bits out to render opcode " << opcode + << ".\n" << logofs_flush; + #endif + + protocolPartial_.renderRequestCount_[opcode]++; + protocolTotal_.renderRequestCount_[opcode]++; + + protocolPartial_.renderRequestBitsIn_[opcode] += bitsIn; + protocolTotal_.renderRequestBitsIn_[opcode] += bitsIn; + + protocolPartial_.renderRequestBitsOut_[opcode] += bitsOut; + protocolTotal_.renderRequestBitsOut_[opcode] += bitsOut; + } + + void addReplyBits(unsigned int opcode, unsigned int bitsIn, unsigned int bitsOut) + { + protocolPartial_.replyCount_[opcode]++; + protocolTotal_.replyCount_[opcode]++; + + protocolPartial_.replyBitsIn_[opcode] += bitsIn; + protocolTotal_.replyBitsIn_[opcode] += bitsIn; + + protocolPartial_.replyBitsOut_[opcode] += bitsOut; + protocolTotal_.replyBitsOut_[opcode] += bitsOut; + + proxyData_.protocolCount_ += bitsOut; + } + + void addEventBits(unsigned int opcode, unsigned int bitsIn, unsigned int bitsOut) + { + protocolPartial_.eventCount_[opcode]++; + protocolTotal_.eventCount_[opcode]++; + + protocolPartial_.eventBitsIn_[opcode] += bitsIn; + protocolTotal_.eventBitsIn_[opcode] += bitsIn; + + protocolPartial_.eventBitsOut_[opcode] += bitsOut; + protocolTotal_.eventBitsOut_[opcode] += bitsOut; + + proxyData_.protocolCount_ += bitsOut; + } + + void addCupsBits(unsigned int bitsIn, unsigned int bitsOut) + { + protocolPartial_.cupsCount_++; + protocolTotal_.cupsCount_++; + + protocolPartial_.cupsBitsIn_ += bitsIn; + protocolTotal_.cupsBitsIn_ += bitsIn; + + protocolPartial_.cupsBitsOut_ += bitsOut; + protocolTotal_.cupsBitsOut_ += bitsOut; + } + + void addSmbBits(unsigned int bitsIn, unsigned int bitsOut) + { + protocolPartial_.smbCount_++; + protocolTotal_.smbCount_++; + + protocolPartial_.smbBitsIn_ += bitsIn; + protocolTotal_.smbBitsIn_ += bitsIn; + + protocolPartial_.smbBitsOut_ += bitsOut; + protocolTotal_.smbBitsOut_ += bitsOut; + } + + void addMediaBits(unsigned int bitsIn, unsigned int bitsOut) + { + protocolPartial_.mediaCount_++; + protocolTotal_.mediaCount_++; + + protocolPartial_.mediaBitsIn_ += bitsIn; + protocolTotal_.mediaBitsIn_ += bitsIn; + + protocolPartial_.mediaBitsOut_ += bitsOut; + protocolTotal_.mediaBitsOut_ += bitsOut; + } + + void addHttpBits(unsigned int bitsIn, unsigned int bitsOut) + { + protocolPartial_.httpCount_++; + protocolTotal_.httpCount_++; + + protocolPartial_.httpBitsIn_ += bitsIn; + protocolTotal_.httpBitsIn_ += bitsIn; + + protocolPartial_.httpBitsOut_ += bitsOut; + protocolTotal_.httpBitsOut_ += bitsOut; + } + + void addFontBits(unsigned int bitsIn, unsigned int bitsOut) + { + protocolPartial_.fontCount_++; + protocolTotal_.fontCount_++; + + protocolPartial_.fontBitsIn_ += bitsIn; + protocolTotal_.fontBitsIn_ += bitsIn; + + protocolPartial_.fontBitsOut_ += bitsOut; + protocolTotal_.fontBitsOut_ += bitsOut; + } + + void addSlaveBits(unsigned int bitsIn, unsigned int bitsOut) + { + protocolPartial_.slaveCount_++; + protocolTotal_.slaveCount_++; + + protocolPartial_.slaveBitsIn_ += bitsIn; + protocolTotal_.slaveBitsIn_ += bitsIn; + + protocolPartial_.slaveBitsOut_ += bitsOut; + protocolTotal_.slaveBitsOut_ += bitsOut; + } + + void addPackedBytesIn(unsigned int numBytes) + { + packedPartial_.packedBytesIn_ += numBytes; + packedTotal_.packedBytesIn_ += numBytes; + } + + void addPackedBytesOut(unsigned int numBytes) + { + packedPartial_.packedBytesOut_ += numBytes; + packedTotal_.packedBytesOut_ += numBytes; + } + + void addSplit() + { + splitPartial_.splitCount_++; + splitTotal_.splitCount_++; + } + + void addSplitAborted() + { + splitPartial_.splitAborted_++; + splitTotal_.splitAborted_++; + } + + void addSplitAbortedBytesOut(unsigned int numBytes) + { + splitPartial_.splitAbortedBytesOut_ += numBytes; + splitTotal_.splitAbortedBytesOut_ += numBytes; + } + + // + // Add the recorded protocol data to the proxy + // token counters. We want to send bpth the token + // request message and the data payload using a + // single system write, so we must guess how many + // output bytes we will generate. + // + + void updateControlToken(int &count) + { + // + // Total is the total number of protocol bytes + // generated so far. We have saved the number + // of bytes generated the last time the function + // was called so we can calculate the difference. + // + // The number of protocol bits is updated as soon + // as new bits are accumulated, to avoid summing + // up all the opcodes in this routine. We add a + // byte to the control bytes difference to account + // for the framing bits that are very likely to + // be added to the payload. + // + + double total = proxyData_.protocolCount_ / 8; + + double diff = total - proxyData_.controlCount_ + 1; + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! Protocol bytes are " + << total << " control bytes are " + << proxyData_.controlCount_ << " difference is " + << diff << ".\n" << logofs_flush; + #endif + + count += (int) (diff / proxyData_.streamRatio_); + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! Adding " + << (int) (diff / proxyData_.streamRatio_) + << " bytes to the control token with ratio " + << proxyData_.streamRatio_ << ".\n" + << logofs_flush; + #endif + + proxyData_.controlCount_ = total; + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! New control token has " + << count << " bytes with total control bytes " + << proxyData_.controlCount_ << ".\n" + << logofs_flush; + #endif + } + + void updateSplitToken(int &count) + { + double total = (protocolTotal_.requestBitsOut_[X_NXSplitData] + + protocolTotal_.eventBitsOut_[X_NXSplitEvent]) / 8; + + double diff = total - proxyData_.splitCount_; + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! Protocol bytes are " + << total << " split bytes are " + << proxyData_.splitCount_ << " difference is " + << diff << ".\n" << logofs_flush; + #endif + + count += (int) (diff / proxyData_.streamRatio_); + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! Adding " + << (int) (diff / proxyData_.streamRatio_) + << " bytes to the split token with ratio " + << proxyData_.streamRatio_ << ".\n" + << logofs_flush; + #endif + + proxyData_.splitCount_ = total; + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! New split token has " + << count << " bytes with total split bytes " + << proxyData_.splitCount_ << ".\n" + << logofs_flush; + #endif + } + + void updateDataToken(int &count) + { + double total = (protocolTotal_.cupsBitsOut_ + + protocolTotal_.smbBitsOut_ + + protocolTotal_.mediaBitsOut_ + + protocolTotal_.httpBitsOut_ + + protocolTotal_.fontBitsOut_ + + protocolTotal_.slaveBitsOut_) / 8; + + double diff = total - proxyData_.dataCount_; + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! Protocol bytes are " + << total << " data bytes are " + << proxyData_.dataCount_ << " difference is " + << diff << ".\n" << logofs_flush; + #endif + + count += (int) (diff / proxyData_.streamRatio_); + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! Adding " + << (int) (diff / proxyData_.streamRatio_) + << " bytes to the data token with ratio " + << proxyData_.streamRatio_ << ".\n" + << logofs_flush; + #endif + + proxyData_.dataCount_ = total; + + #if defined(TEST) || defined(TOKEN) + *logofs << "Statistics: TOKEN! New data token has " + << count << " bytes with total data bytes " + << proxyData_.dataCount_ << ".\n" + << logofs_flush; + #endif + } + + // + // Update the current bitrate. + // + + void updateBitrate(int bytes); + + // + // Return the current bitrate. + // + + int getBitrateInShortFrame() + { + return bitrateInShortFrame_; + } + + int getBitrateInLongFrame() + { + return bitrateInLongFrame_; + } + + int getTopBitrate() + { + return topBitrate_; + } + + void resetTopBitrate() + { + topBitrate_ = 0; + } + + double getStreamRatio() + { + return proxyData_.streamRatio_; + } + + // + // Manage the congestion level. + // + + void updateCongestion(int remaining, int limit); + + double getCongestionInFrame() + { + return congestionInFrame_; + } + + // + // Produce a dump of the statistics on + // the provided buffer. + // + + int getClientCacheStats(int type, char *&buffer); + int getClientProtocolStats(int type, char *&buffer); + int getClientOverallStats(int type, char *&buffer); + + int getServerCacheStats(int type, char *&buffer); + int getServerProtocolStats(int type, char *&buffer); + int getServerOverallStats(int type, char *&buffer); + + int resetPartialStats(); + + private: + + int getTimeStats(int type, char *&buffer); + int getServicesStats(int type, char *&buffer); + int getFramingStats(int type, char *&buffer); + int getBitrateStats(int type, char *&buffer); + int getStreamStats(int type, char *&buffer); + int getSplitStats(int type, char *&buffer); + + struct T_protocolData + { + double requestCached_[STATISTICS_OPCODE_MAX]; + double requestReplied_[STATISTICS_OPCODE_MAX]; + double requestCount_[STATISTICS_OPCODE_MAX]; + double requestBitsIn_[STATISTICS_OPCODE_MAX]; + double requestBitsOut_[STATISTICS_OPCODE_MAX]; + + double renderRequestCached_[STATISTICS_OPCODE_MAX]; + double renderRequestCount_[STATISTICS_OPCODE_MAX]; + double renderRequestBitsIn_[STATISTICS_OPCODE_MAX]; + double renderRequestBitsOut_[STATISTICS_OPCODE_MAX]; + + double replyCached_[STATISTICS_OPCODE_MAX]; + double replyCount_[STATISTICS_OPCODE_MAX]; + double replyBitsIn_[STATISTICS_OPCODE_MAX]; + double replyBitsOut_[STATISTICS_OPCODE_MAX]; + + double eventCached_[STATISTICS_OPCODE_MAX]; + double eventCount_[STATISTICS_OPCODE_MAX]; + double eventBitsIn_[STATISTICS_OPCODE_MAX]; + double eventBitsOut_[STATISTICS_OPCODE_MAX]; + + double cupsCount_; + double cupsBitsIn_; + double cupsBitsOut_; + + double smbCount_; + double smbBitsIn_; + double smbBitsOut_; + + double mediaCount_; + double mediaBitsIn_; + double mediaBitsOut_; + + double httpCount_; + double httpBitsIn_; + double httpBitsOut_; + + double fontCount_; + double fontBitsIn_; + double fontBitsOut_; + + double slaveCount_; + double slaveBitsIn_; + double slaveBitsOut_; + }; + + struct T_transportData + { + double idleTime_; + double readTime_; + double writeTime_; + + double proxyBytesIn_; + double proxyBytesOut_; + + double proxyFramesIn_; + double proxyFramesOut_; + double proxyWritesOut_; + + double compressedBytesIn_; + double compressedBytesOut_; + + double decompressedBytesIn_; + double decompressedBytesOut_; + + double framingBitsOut_; + }; + + struct T_packedData + { + double packedBytesIn_; + double packedBytesOut_; + }; + + struct T_splitData + { + double splitCount_; + double splitAborted_; + double splitAbortedBytesOut_; + }; + + struct T_overallData + { + double overallBytesIn_; + double overallBytesOut_; + }; + + struct T_proxyData + { + double protocolCount_; + double controlCount_; + double splitCount_; + double dataCount_; + + double streamRatio_; + }; + + T_protocolData protocolPartial_; + T_protocolData protocolTotal_; + + T_transportData transportPartial_; + T_transportData transportTotal_; + + T_packedData packedPartial_; + T_packedData packedTotal_; + + T_splitData splitPartial_; + T_splitData splitTotal_; + + T_overallData overallPartial_; + T_overallData overallTotal_; + + T_proxyData proxyData_; + + // + // Used to calculate the bandwidth usage + // of the proxy link. + // + + T_timestamp startShortFrameTs_; + T_timestamp startLongFrameTs_; + T_timestamp startFrameTs_; + + int bytesInShortFrame_; + int bytesInLongFrame_; + + int bitrateInShortFrame_; + int bitrateInLongFrame_; + + int topBitrate_; + + double congestionInFrame_; + + // + // Need the proxy pointer to print the + // statistics related to the client and + // server stores and to add the protocol + // data to the proxy token accumulators. + // + + Proxy *proxy_; +}; + +#endif /* Statistics_H */ diff --git a/nxcomp/src/Timestamp.cpp b/nxcomp/src/Timestamp.cpp new file mode 100644 index 000000000..e7e0c494a --- /dev/null +++ b/nxcomp/src/Timestamp.cpp @@ -0,0 +1,77 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Timestamp.h" + +// +// Log level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Last timestamp taken from the system. +// + +T_timestamp timestamp; + +// +// The following functions all use the ctime +// static buffer from the C library. +// + +char *strTimestamp(const T_timestamp &ts) +{ + char *ctime_now = ctime((time_t *) &ts.tv_sec); + + ctime_now[24] = '\0'; + + return ctime_now; +} + +// +// This is especially dirty. +// + +char *strMsTimestamp(const T_timestamp &ts) +{ + char *ctime_now = ctime((time_t *) &ts.tv_sec); + + char ctime_new[25]; + + sprintf(ctime_new, "%.8s:%3.3f", ctime_now + 11, + (float) ts.tv_usec / 1000); + + strncpy(ctime_now, ctime_new, 24); + + return ctime_now; +} diff --git a/nxcomp/src/Timestamp.h b/nxcomp/src/Timestamp.h new file mode 100644 index 000000000..604f5a3bc --- /dev/null +++ b/nxcomp/src/Timestamp.h @@ -0,0 +1,307 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Timestamp_H +#define Timestamp_H + +#include +#include +#include + +#include +#include + +#include "Misc.h" + +// +// Log level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// If not defined, always query the system time. +// + +#undef CACHE_TIMESTAMP + +// +// Log a warning if the time difference since +// the last update exceeds the given number +// of milliseconds. +// + +#define DRIFT_TIMESTAMP 1 + +// +// Type used for timeout manipulation. +// + +typedef struct timeval T_timestamp; + +// +// Last timestamp taken from the system. If the +// timestamp is cached, we need to explicitly +// get a new timestamp after any operation that +// may have required a relevant amount of time. +// + +extern T_timestamp timestamp; + +// +// Get a timestamp instance with values set +// at the given amount of milliseconds. +// + +inline T_timestamp getTimestamp(long ms) +{ + struct timeval ts; + + ts.tv_sec = ms / 1000; + ts.tv_usec = (ms % 1000) * 1000; + + return ts; +} + +// +// Return the difference in milliseconds +// between the two timestamps. +// + +inline long diffTimestamp(const T_timestamp &ts1, const T_timestamp &ts2) +{ + // + // Add 500 microseconds to round up + // to the nearest millisecond. + // + + return ((ts2.tv_sec * 1000 + (ts2.tv_usec + 500) / 1000) - + (ts1.tv_sec * 1000 + (ts1.tv_usec + 500) / 1000)); +} + +// +// The same in microseconds. It doesn't +// round the value. +// + +inline long diffUsTimestamp(const T_timestamp &ts1, const T_timestamp &ts2) +{ + return ((ts2.tv_sec * 1000000 + ts2.tv_usec) - + (ts1.tv_sec * 1000000 + ts1.tv_usec)); +} + +// +// Return the last timestamp taken from the +// system. It doesn't update the timestamp. +// + +inline T_timestamp getTimestamp() +{ + #ifdef CACHE_TIMESTAMP + + #ifdef TEST + + T_timestamp ts; + + gettimeofday(&ts, NULL); + + long diffTs = diffTimestamp(timestamp, ts); + + if (diffTs > DRIFT_TIMESTAMP) + { + *logofs << "Timestamp: WARNING! Time difference since the " + << "current timestamp is " << diffTs << " Ms.\n" + << logofs_flush; + } + + #endif + + return timestamp; + + #else + + gettimeofday(×tamp, NULL); + + return timestamp; + + #endif +} + +inline T_timestamp &setTimestamp(T_timestamp &ts, long ms) +{ + ts.tv_sec = ms / 1000; + ts.tv_usec = (ms % 1000) * 1000; + + return ts; +} + +// +// Return the smaller between two timestamps. +// + +inline T_timestamp &setMinTimestamp(T_timestamp &ts, long ms) +{ + if ((ts.tv_sec * 1000 + ts.tv_usec / 1000) > ms) + { + ts.tv_sec = ms / 1000; + ts.tv_usec = (ms % 1000) * 1000; + } + + return ts; +} + +inline T_timestamp &setMinTimestamp(T_timestamp &ts1, T_timestamp &ts2) +{ + if ((ts1.tv_sec * 1000000 + ts1.tv_usec) > + (ts2.tv_sec * 1000000 + ts2.tv_usec)) + { + ts1.tv_sec = ts2.tv_sec; + ts1.tv_usec = ts2.tv_usec; + } + + return ts1; +} + +// +// Convert a timestamp in the total number +// of milliseconds. +// + +inline long getMsTimestamp(const T_timestamp &ts) +{ + return ts.tv_sec * 1000 + ts.tv_usec / 1000; +} + +// +// A 0 value on both seconds and microseconds +// fields means that timestamp is invalid or +// not set. +// + +inline T_timestamp nullTimestamp() +{ + struct timeval ts; + + ts.tv_sec = 0; + ts.tv_usec = 0; + + return ts; +} + +inline bool isTimestamp(const T_timestamp &ts) +{ + if (ts.tv_sec == 0 && ts.tv_usec == 0) + { + return 0; + } + + return 1; +} + +inline void subMsTimestamp(T_timestamp &ts, long ms) +{ + ts.tv_sec -= ms / 1000; + ts.tv_usec -= (ms % 1000) * 1000; +} + +inline void addMsTimestamp(T_timestamp &ts, long ms) +{ + ts.tv_sec += ms / 1000; + ts.tv_usec += (ms % 1000) * 1000; +} + +// +// Check the difference between timestamps. +// Return 0 if the system time went backward +// compared to the second timestamp, or the +// difference between the timestamps exceeds +// the given number of milliseconds. +// + +inline int checkDiffTimestamp(const T_timestamp &ts1, const T_timestamp &ts2, + long ms = 30000) +{ + long diffTs = diffTimestamp(ts1, ts2); + + if (diffTs < 0 || diffTs > ms) + { + return 0; + } + + return 1; +} + +// +// Return a string representing the timestamp. +// + +char *strTimestamp(const T_timestamp &ts); +char *strMsTimestamp(const T_timestamp &ts); + +inline char *strTimestamp() +{ + return strTimestamp(getTimestamp()); +} + +inline char *strMsTimestamp() +{ + return strMsTimestamp(getTimestamp()); +} + +// +// Update the current timestamp. +// + +inline T_timestamp getNewTimestamp() +{ + #ifdef TEST + + T_timestamp ts; + + gettimeofday(&ts, NULL); + + *logofs << "Timestamp: Updating the current timestamp at " + << strMsTimestamp(ts) << ".\n" << logofs_flush; + + long diffTs = diffTimestamp(timestamp, ts); + + if (diffTs > DRIFT_TIMESTAMP) + { + *logofs << "Timestamp: WARNING! Time difference since the " + << "old timestamp is " << diffTs << " Ms.\n" + << logofs_flush; + } + + #endif + + gettimeofday(×tamp, NULL); + + return timestamp; +} + +#endif /* Timestamp_H */ diff --git a/nxcomp/src/TranslateCoords.cpp b/nxcomp/src/TranslateCoords.cpp new file mode 100644 index 000000000..f61caea47 --- /dev/null +++ b/nxcomp/src/TranslateCoords.cpp @@ -0,0 +1,115 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "TranslateCoords.h" + +#include "ClientCache.h" + +#include "EncodeBuffer.h" +#include "DecodeBuffer.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Here are the methods to handle messages' content. +// + +int TranslateCoordsStore::parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + TranslateCoordsMessage *translateCoords = (TranslateCoordsMessage *) message; + + // + // Here is the fingerprint. + // + + translateCoords -> src_window = GetULONG(buffer + 4, bigEndian); + translateCoords -> dst_window = GetULONG(buffer + 8, bigEndian); + + translateCoords -> src_x = GetUINT(buffer + 12, bigEndian); + translateCoords -> src_y = GetUINT(buffer + 14, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +int TranslateCoordsStore::unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + TranslateCoordsMessage *translateCoords = (TranslateCoordsMessage *) message; + + // + // Fill all the message's fields. + // + + PutULONG(translateCoords -> src_window, buffer + 4, bigEndian); + PutULONG(translateCoords -> dst_window, buffer + 8, bigEndian); + + PutUINT(translateCoords -> src_x, buffer + 12, bigEndian); + PutUINT(translateCoords -> src_y, buffer + 14, bigEndian); + + #ifdef DEBUG + *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush; + #endif + + return 1; +} + +void TranslateCoordsStore::dumpIdentity(const Message *message) const +{ + #ifdef DUMP + + TranslateCoordsMessage *translateCoords = (TranslateCoordsMessage *) message; + + *logofs << name() << ": Identity src_window " << translateCoords -> src_window << ", dst_window " + << translateCoords -> dst_window << ", src_x " << translateCoords -> src_x << ", src_y " + << translateCoords -> src_y << ", size " << translateCoords -> size_ << ".\n" << logofs_flush; + + #endif +} + +void TranslateCoordsStore::identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const +{ + md5_append(md5_state_, buffer + 4, 4); + md5_append(md5_state_, buffer + 8, 4); + md5_append(md5_state_, buffer + 12, 2); + md5_append(md5_state_, buffer + 14, 2); +} diff --git a/nxcomp/src/TranslateCoords.h b/nxcomp/src/TranslateCoords.h new file mode 100644 index 000000000..997d079e1 --- /dev/null +++ b/nxcomp/src/TranslateCoords.h @@ -0,0 +1,185 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef TranslateCoords_H +#define TranslateCoords_H + +#include "Message.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef DUMP + +// +// Set default values. +// + +#define TRANSLATECOORDS_ENABLE_CACHE 1 +#define TRANSLATECOORDS_ENABLE_DATA 0 +#define TRANSLATECOORDS_ENABLE_SPLIT 0 +#define TRANSLATECOORDS_ENABLE_COMPRESS 0 + +#define TRANSLATECOORDS_DATA_LIMIT 0 +#define TRANSLATECOORDS_DATA_OFFSET 16 + +#define TRANSLATECOORDS_CACHE_SLOTS 3000 +#define TRANSLATECOORDS_CACHE_THRESHOLD 3 +#define TRANSLATECOORDS_CACHE_LOWER_THRESHOLD 1 + +// +// The message class. +// + +class TranslateCoordsMessage : public Message +{ + friend class TranslateCoordsStore; + + public: + + TranslateCoordsMessage() + { + } + + ~TranslateCoordsMessage() + { + } + + // + // Put here the fields which constitute + // the 'identity' part of the message. + // + + private: + + unsigned int src_window; + unsigned int dst_window; + unsigned int src_x; + unsigned int src_y; + + unsigned char r_same_screen; + unsigned int r_child_window; + unsigned int r_dst_x; + unsigned int r_dst_y; +}; + +class TranslateCoordsStore : public MessageStore +{ + // + // Constructors and destructors. + // + + public: + + TranslateCoordsStore() : MessageStore() + { + enableCache = TRANSLATECOORDS_ENABLE_CACHE; + enableData = TRANSLATECOORDS_ENABLE_DATA; + enableSplit = TRANSLATECOORDS_ENABLE_SPLIT; + enableCompress = TRANSLATECOORDS_ENABLE_COMPRESS; + + dataLimit = TRANSLATECOORDS_DATA_LIMIT; + dataOffset = TRANSLATECOORDS_DATA_OFFSET; + + cacheSlots = TRANSLATECOORDS_CACHE_SLOTS; + cacheThreshold = TRANSLATECOORDS_CACHE_THRESHOLD; + cacheLowerThreshold = TRANSLATECOORDS_CACHE_LOWER_THRESHOLD; + + messages_ -> resize(cacheSlots); + + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + *i = NULL; + } + + temporary_ = NULL; + } + + virtual ~TranslateCoordsStore() + { + for (T_messages::iterator i = messages_ -> begin(); + i < messages_ -> end(); i++) + { + destroy(*i); + } + + destroy(temporary_); + } + + virtual const char *name() const + { + return "TranslateCoords"; + } + + virtual unsigned char opcode() const + { + return X_TranslateCoords; + } + + virtual unsigned int storage() const + { + return sizeof(TranslateCoordsMessage); + } + + // + // Message handling methods. + // + + public: + + virtual Message *create() const + { + return new TranslateCoordsMessage(); + } + + virtual Message *create(const Message &message) const + { + return new TranslateCoordsMessage((const TranslateCoordsMessage &) message); + } + + virtual void destroy(Message *message) const + { + delete (TranslateCoordsMessage *) message; + } + + virtual int parseIdentity(Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual int unparseIdentity(const Message *message, unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void identityChecksum(const Message *message, const unsigned char *buffer, + unsigned int size, int bigEndian) const; + + virtual void dumpIdentity(const Message *message) const; +}; + +#endif /* TranslateCoords_H */ diff --git a/nxcomp/src/Transport.cpp b/nxcomp/src/Transport.cpp new file mode 100644 index 000000000..e34544994 --- /dev/null +++ b/nxcomp/src/Transport.cpp @@ -0,0 +1,3068 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "Transport.h" + +#include "Statistics.h" + +// +// Set the verbosity level. You also +// need to define DUMP in Misc.cpp +// if DUMP is defined here. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef INSPECT +#undef DUMP + +// +// Used to lock and unlock the transport +// buffers before they are accessed by +// different threads. +// + +#undef THREADS + +// +// Define this to get logging all the +// operations performed by the parent +// thread, the one that enqueues and +// dequeues data. +// + +#define PARENT + +// +// Define this to know when a channel +// is created or destroyed. +// + +#undef REFERENCES + +// +// Reference count for allocated buffers. +// + +#ifdef REFERENCES + +int Transport::references_; +int ProxyTransport::references_; +int InternalTransport::references_; + +#endif + +// +// This is the base class providing methods for read +// and write buffering. +// + +Transport::Transport(int fd) : fd_(fd) +{ + #ifdef TEST + *logofs << "Transport: Going to create base transport " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + type_ = transport_base; + + // + // Set up the write buffer. + // + + w_buffer_.length_ = 0; + w_buffer_.start_ = 0; + + initialSize_ = TRANSPORT_BUFFER_DEFAULT_SIZE; + thresholdSize_ = TRANSPORT_BUFFER_DEFAULT_SIZE << 1; + maximumSize_ = TRANSPORT_BUFFER_DEFAULT_SIZE << 4; + + w_buffer_.data_.resize(initialSize_); + + // + // Set non-blocking IO on socket. + // + + SetNonBlocking(fd_, 1); + + blocked_ = 0; + finish_ = 0; + + #ifdef REFERENCES + *logofs << "Transport: Created new object at " + << this << " out of " << ++references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +Transport::~Transport() +{ + #ifdef TEST + *logofs << "Transport: Going to destroy base class " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + ::close(fd_); + + #ifdef REFERENCES + *logofs << "Transport: Deleted object at " + << this << " out of " << --references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +// +// Read data from its file descriptor. +// + +int Transport::read(unsigned char *data, unsigned int size) +{ + #ifdef DEBUG + *logofs << "Transport: Going to read " << size << " bytes from " + << "FD#" << fd_ << ".\n" << logofs_flush; + #endif + + // + // Read the available data from the socket. + // + + int result = ::read(fd_, data, size); + + // + // Update the current timestamp as the read + // can have scheduled some other process. + // + + getNewTimestamp(); + + if (result < 0) + { + if (EGET() == EAGAIN) + { + #ifdef TEST + *logofs << "Transport: WARNING! Read of " << size << " bytes from " + << "FD#" << fd_ << " would block.\n" << logofs_flush; + #endif + + return 0; + } + else if (EGET() == EINTR) + { + #ifdef TEST + *logofs << "Transport: Read of " << size << " bytes from " + << "FD#" << fd_ << " was interrupted.\n" + << logofs_flush; + #endif + + return 0; + } + else + { + #ifdef TEST + *logofs << "Transport: Error reading from " + << "FD#" << fd_ << ".\n" << logofs_flush; + #endif + + finish(); + + return -1; + } + } + else if (result == 0) + { + #ifdef TEST + *logofs << "Transport: No data read from " + << "FD#" << fd_ << ".\n" << logofs_flush; + #endif + + finish(); + + return -1; + } + + #ifdef TEST + *logofs << "Transport: Read " << result << " bytes out of " + << size << " from FD#" << fd_ << ".\n" << logofs_flush; + #endif + + #ifdef DUMP + + *logofs << "Transport: Dumping content of read data.\n" + << logofs_flush; + + DumpData(data, result); + + #endif + + return result; +} + +// +// Write as many bytes as possible to socket. +// Append the remaining data bytes to the end +// of the buffer and update length to reflect +// changes. +// + +int Transport::write(T_write type, const unsigned char *data, const unsigned int size) +{ + // + // If an immediate write was requested then + // flush the enqueued data first. + // + // Alternatively may try to write only if + // the socket is not blocked. + // + // if (w_buffer_.length_ > 0 && blocked_ == 0 && + // type == write_immediate) + // { + // ... + // } + // + + if (w_buffer_.length_ > 0 && type == write_immediate) + + { + #ifdef TEST + *logofs << "Transport: Writing " << w_buffer_.length_ + << " bytes of previous data to FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + int result = Transport::flush(); + + if (result < 0) + { + return -1; + } + } + + // + // If nothing is remained, write immediately + // to the socket. + // + + unsigned int written = 0; + + if (w_buffer_.length_ == 0 && blocked_ == 0 && + type == write_immediate) + { + // + // Limit the amount of data sent. + // + + unsigned int toWrite = size; + + #ifdef DUMP + + *logofs << "Transport: Going to write " << toWrite + << " bytes to FD#" << fd_ << " with checksum "; + + DumpChecksum(data, size); + + *logofs << ".\n" << logofs_flush; + + #endif + + T_timestamp writeTs; + + int diffTs; + + while (written < toWrite) + { + // + // Trace system time spent writing data. + // + + writeTs = getTimestamp(); + + int result = ::write(fd_, data + written, toWrite - written); + + diffTs = diffTimestamp(writeTs, getNewTimestamp()); + + statistics -> addWriteTime(diffTs); + + if (result <= 0) + { + if (EGET() == EAGAIN) + { + #ifdef TEST + *logofs << "Transport: Write of " << toWrite - written + << " bytes on FD#" << fd_ << " would block.\n" + << logofs_flush; + #endif + + blocked_ = 1; + + break; + } + else if (EGET() == EINTR) + { + #ifdef TEST + *logofs << "Transport: Write of " << toWrite - written + << " bytes on FD#" << fd_ << " was interrupted.\n" + << logofs_flush; + #endif + + continue; + } + else + { + #ifdef TEST + *logofs << "Transport: Write to " << "FD#" + << fd_ << " failed.\n" << logofs_flush; + #endif + + finish(); + + return -1; + } + } + else + { + #ifdef TEST + *logofs << "Transport: Immediately written " << result + << " bytes on " << "FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + written += result; + } + } + + #ifdef DUMP + + if (written > 0) + { + *logofs << "Transport: Dumping content of immediately written data.\n" + << logofs_flush; + + DumpData(data, written); + } + + #endif + } + + if (written == size) + { + // + // We will not affect the write buffer. + // + + return written; + } + + #ifdef DEBUG + *logofs << "Transport: Going to append " << size - written + << " bytes to write buffer for " << "FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + if (resize(w_buffer_, size - written) < 0) + { + return -1; + } + + memmove(w_buffer_.data_.begin() + w_buffer_.start_ + w_buffer_.length_, + data + written, size - written); + + w_buffer_.length_ += size - written; + + #ifdef TEST + *logofs << "Transport: Write buffer for FD#" << fd_ + << " has data for " << w_buffer_.length_ << " bytes.\n" + << logofs_flush; + + *logofs << "Transport: Start is " << w_buffer_.start_ + << " length is " << w_buffer_.length_ << " size is " + << w_buffer_.data_.size() << " capacity is " + << w_buffer_.data_.capacity() << ".\n" + << logofs_flush; + #endif + + // + // Note that this function always returns the whole + // size of buffer that was provided, either if not + // all the data could be actually written. + // + + return size; +} + +// +// Write pending data to its file descriptor. +// + +int Transport::flush() +{ + if (w_buffer_.length_ == 0) + { + #ifdef TEST + *logofs << "Transport: No data to flush on " + << "FD#" << fd_ << ".\n" << logofs_flush; + #endif + + #ifdef WARNING + if (blocked_ != 0) + { + *logofs << "Transport: Blocked flag is " << blocked_ + << " with no data to flush on FD#" << fd_ + << ".\n" << logofs_flush; + } + #endif + + return 0; + } + + // + // It's time to move data from the + // write buffer to the real link. + // + + int written = 0; + + int toWrite = w_buffer_.length_; + + // + // We will do our best to write any available + // data to the socket, so let's say we start + // from a clean state. + // + + blocked_ = 0; + + #ifdef TEST + *logofs << "Transport: Going to flush " << toWrite + << " bytes on FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + T_timestamp writeTs; + + int diffTs; + + while (written < toWrite) + { + writeTs = getTimestamp(); + + int result = ::write(fd_, w_buffer_.data_.begin() + w_buffer_.start_ + + written, toWrite - written); + + diffTs = diffTimestamp(writeTs, getNewTimestamp()); + + statistics -> addWriteTime(diffTs); + + if (result <= 0) + { + if (EGET() == EAGAIN) + { + #ifdef TEST + *logofs << "Transport: Write of " << toWrite - written + << " bytes on FD#" << fd_ << " would block.\n" + << logofs_flush; + #endif + + blocked_ = 1; + + break; + } + else if (EGET() == EINTR) + { + #ifdef TEST + *logofs << "Transport: Write of " << toWrite - written + << " bytes on FD#" << fd_ << " was interrupted.\n" + << logofs_flush; + #endif + + continue; + } + else + { + #ifdef TEST + *logofs << "Transport: Write to " << "FD#" + << fd_ << " failed.\n" << logofs_flush; + #endif + + finish(); + + return -1; + } + } + else + { + #ifdef TEST + *logofs << "Transport: Flushed " << result << " bytes on " + << "FD#" << fd_ << ".\n" << logofs_flush; + #endif + + written += result; + } + } + + if (written > 0) + { + #ifdef DUMP + + *logofs << "Transport: Dumping content of flushed data.\n" + << logofs_flush; + + DumpData(w_buffer_.data_.begin() + w_buffer_.start_, written); + + #endif + + // + // Update the buffer status. + // + + w_buffer_.length_ -= written; + + if (w_buffer_.length_ == 0) + { + w_buffer_.start_ = 0; + } + else + { + w_buffer_.start_ += written; + } + } + + // + // It can be that we wrote less bytes than + // available because of the write limit. + // + + if (w_buffer_.length_ > 0) + { + #ifdef TEST + *logofs << "Transport: There are still " << w_buffer_.length_ + << " bytes in write buffer for " << "FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + blocked_ = 1; + } + + #ifdef TEST + *logofs << "Transport: Write buffer for FD#" << fd_ + << " has data for " << w_buffer_.length_ << " bytes.\n" + << logofs_flush; + + *logofs << "Transport: Start is " << w_buffer_.start_ + << " length is " << w_buffer_.length_ << " size is " + << w_buffer_.data_.size() << " capacity is " + << w_buffer_.data_.capacity() << ".\n" + << logofs_flush; + #endif + + // + // No new data was produced for the link except + // any outstanding data from previous writes. + // + + return 0; +} + +int Transport::drain(int limit, int timeout) +{ + if (w_buffer_.length_ <= limit) + { + return 1; + } + + // + // Write the data accumulated in the write + // buffer until it is below the limit or + // the timeout is elapsed. + // + + int toWrite = w_buffer_.length_; + + int written = 0; + + #ifdef TEST + *logofs << "Transport: Draining " << toWrite - limit + << " bytes on FD#" << fd_ << " with limit set to " + << limit << ".\n" << logofs_flush; + #endif + + T_timestamp startTs = getNewTimestamp(); + + T_timestamp selectTs; + T_timestamp writeTs; + T_timestamp idleTs; + + T_timestamp nowTs = startTs; + + int diffTs; + + fd_set writeSet; + fd_set readSet; + + FD_ZERO(&writeSet); + FD_ZERO(&readSet); + + int result; + int ready; + + while (w_buffer_.length_ - written > limit) + { + nowTs = getNewTimestamp(); + + // + // Wait for descriptor to become + // readable or writable. + // + + FD_SET(fd_, &writeSet); + FD_SET(fd_, &readSet); + + setTimestamp(selectTs, timeout / 2); + + idleTs = nowTs; + + result = select(fd_ + 1, &readSet, &writeSet, NULL, &selectTs); + + nowTs = getNewTimestamp(); + + diffTs = diffTimestamp(idleTs, nowTs); + + statistics -> addIdleTime(diffTs); + + statistics -> subReadTime(diffTs); + + if (result < 0) + { + if (EGET() == EINTR) + { + #ifdef TEST + *logofs << "Transport: Select on FD#" << fd_ + << " was interrupted.\n" << logofs_flush; + #endif + + continue; + } + else + { + #ifdef TEST + *logofs << "Transport: Select on FD#" << fd_ + << " failed.\n" << logofs_flush; + #endif + + finish(); + + return -1; + } + } + else if (result > 0) + { + ready = result; + + if (FD_ISSET(fd_, &writeSet)) + { + writeTs = getNewTimestamp(); + + result = ::write(fd_, w_buffer_.data_.begin() + w_buffer_.start_ + + written, toWrite - written); + + nowTs = getNewTimestamp(); + + diffTs = diffTimestamp(writeTs, nowTs); + + statistics -> addWriteTime(diffTs); + + if (result > 0) + { + #ifdef TEST + *logofs << "Transport: Forced flush of " << result + << " bytes on " << "FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + written += result; + } + else if (result < 0 && EGET() == EINTR) + { + #ifdef TEST + *logofs << "Transport: Write to FD#" << fd_ + << " was interrupted.\n" << logofs_flush; + #endif + + continue; + } + else + { + #ifdef TEST + *logofs << "Transport: Write to FD#" << fd_ + << " failed.\n" << logofs_flush; + #endif + + finish(); + + return -1; + } + + ready--; + } + + if (ready > 0) + { + if (FD_ISSET(fd_, &readSet)) + { + #ifdef TEST + *logofs << "Transport: Not draining further " + << "due to data readable on FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + break; + } + } + } + #ifdef TEST + else + { + *logofs << "Transport: Timeout encountered " + << "waiting for FD#" << fd_ << ".\n" + << logofs_flush; + } + #endif + + nowTs = getNewTimestamp(); + + diffTs = diffTimestamp(startTs, nowTs); + + if (diffTs >= timeout) + { + #ifdef TEST + *logofs << "Transport: Not draining further " + << "due to the timeout on FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + break; + } + } + + if (written > 0) + { + #ifdef DUMP + + *logofs << "Transport: Dumping content of flushed data.\n" + << logofs_flush; + + DumpData(w_buffer_.data_.begin() + w_buffer_.start_, written); + + #endif + + // + // Update the buffer status. + // + + w_buffer_.length_ -= written; + + if (w_buffer_.length_ == 0) + { + w_buffer_.start_ = 0; + + blocked_ = 0; + } + else + { + w_buffer_.start_ += written; + + #ifdef TEST + *logofs << "Transport: There are still " << w_buffer_.length_ + << " bytes in write buffer for " << "FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + blocked_ = 1; + } + } + #ifdef TEST + else + { + *logofs << "Transport: WARNING! No data written to FD#" << fd_ + << " with " << toWrite << " bytes to drain and limit " + << "set to " << limit << ".\n" << logofs_flush; + } + #endif + + #ifdef TEST + *logofs << "Transport: Write buffer for FD#" << fd_ + << " has data for " << w_buffer_.length_ << " bytes.\n" + << logofs_flush; + + *logofs << "Transport: Start is " << w_buffer_.start_ + << " length is " << w_buffer_.length_ << " size is " + << w_buffer_.data_.size() << " capacity is " + << w_buffer_.data_.capacity() << ".\n" + << logofs_flush; + #endif + + return (w_buffer_.length_ <= limit); +} + +int Transport::wait(int timeout) const +{ + T_timestamp startTs = getNewTimestamp(); + + T_timestamp idleTs; + T_timestamp selectTs; + + T_timestamp nowTs = startTs; + + long available = 0; + int result = 0; + + int diffTs; + + fd_set readSet; + + FD_ZERO(&readSet); + FD_SET(fd_, &readSet); + + for (;;) + { + available = readable(); + + diffTs = diffTimestamp(startTs, nowTs); + + if (available != 0 || timeout == 0 || + (diffTs + (timeout / 10)) >= timeout) + { + #ifdef TEST + *logofs << "Transport: There are " << available + << " bytes on FD#" << fd_ << " after " + << diffTs << " Ms.\n" << logofs_flush; + #endif + + return available; + } + else if (available == 0 && result > 0) + { + #ifdef TEST + *logofs << "Transport: Read on " << "FD#" + << fd_ << " failed.\n" << logofs_flush; + #endif + + return -1; + } + + // + // TODO: Should subtract the time + // already spent in select. + // + + selectTs.tv_sec = 0; + selectTs.tv_usec = timeout * 1000; + + idleTs = nowTs; + + // + // Wait for descriptor to become readable. + // + + result = select(fd_ + 1, &readSet, NULL, NULL, &selectTs); + + nowTs = getNewTimestamp(); + + diffTs = diffTimestamp(idleTs, nowTs); + + statistics -> addIdleTime(diffTs); + + statistics -> subReadTime(diffTs); + + if (result < 0) + { + if (EGET() == EINTR) + { + #ifdef TEST + *logofs << "Transport: Select on FD#" << fd_ + << " was interrupted.\n" << logofs_flush; + #endif + + continue; + } + else + { + #ifdef TEST + *logofs << "Transport: Select on " << "FD#" + << fd_ << " failed.\n" << logofs_flush; + #endif + + return -1; + } + } + #ifdef TEST + else if (result == 0) + { + *logofs << "Transport: No data available on FD#" << fd_ + << " after " << diffTimestamp(startTs, nowTs) + << " Ms.\n" << logofs_flush; + } + else + { + *logofs << "Transport: Data became available on FD#" << fd_ + << " after " << diffTimestamp(startTs, nowTs) + << " Ms.\n" << logofs_flush; + } + #endif + } +} + +void Transport::setSize(unsigned int initialSize, unsigned int thresholdSize, + unsigned int maximumSize) +{ + initialSize_ = initialSize; + thresholdSize_ = thresholdSize; + maximumSize_ = maximumSize; + + #ifdef TEST + *logofs << "Transport: Set buffer sizes for FD#" << fd_ + << " to " << initialSize_ << "/" << thresholdSize_ + << "/" << maximumSize_ << ".\n" << logofs_flush; + #endif +} + +void Transport::fullReset() +{ + blocked_ = 0; + finish_ = 0; + + fullReset(w_buffer_); +} + +int Transport::resize(T_buffer &buffer, const int &size) +{ + if ((int) buffer.data_.size() >= (buffer.length_ + size) && + (buffer.start_ + buffer.length_ + size) > + (int) buffer.data_.size()) + { + if (buffer.length_ > 0) + { + // + // There is enough space in buffer but we need + // to move existing data at the beginning. + // + + #ifdef TEST + *logofs << "Transport: Moving " << buffer.length_ + << " bytes of data for " << "FD#" << fd_ + << " to make room in the buffer.\n" + << logofs_flush; + #endif + + memmove(buffer.data_.begin(), buffer.data_.begin() + + buffer.start_, buffer.length_); + } + + buffer.start_ = 0; + + #ifdef DEBUG + *logofs << "Transport: Made room for " + << buffer.data_.size() - buffer.start_ + << " bytes in buffer for " << "FD#" + << fd_ << ".\n" << logofs_flush; + #endif + } + else if ((buffer.length_ + size) > (int) buffer.data_.size()) + { + // + // Not enough space, so increase + // the size of the buffer. + // + + if (buffer.start_ != 0 && buffer.length_ > 0) + { + #ifdef TEST + *logofs << "Transport: Moving " << buffer.length_ + << " bytes of data for " << "FD#" << fd_ + << " to resize the buffer.\n" + << logofs_flush; + #endif + + memmove(buffer.data_.begin(), buffer.data_.begin() + + buffer.start_, buffer.length_); + } + + buffer.start_ = 0; + + unsigned int newSize = thresholdSize_; + + while (newSize < (unsigned int) buffer.length_ + size) + { + newSize <<= 1; + + if (newSize >= maximumSize_) + { + newSize = buffer.length_ + size + initialSize_; + } + } + + #ifdef DEBUG + *logofs << "Transport: Buffer for " << "FD#" << fd_ + << " will be enlarged from " << buffer.data_.size() + << " to at least " << buffer.length_ + size + << " bytes.\n" << logofs_flush; + #endif + + buffer.data_.resize(newSize); + + #ifdef TEST + if (newSize >= maximumSize_) + { + *logofs << "Transport: WARNING! Buffer for FD#" << fd_ + << " grown to reach size of " << newSize + << " bytes.\n" << logofs_flush; + } + #endif + + #ifdef TEST + *logofs << "Transport: Data buffer for " << "FD#" + << fd_ << " has now size " << buffer.data_.size() + << " and capacity " << buffer.data_.capacity() + << ".\n" << logofs_flush; + #endif + } + + return (buffer.length_ + size); +} + +void Transport::fullReset(T_buffer &buffer) +{ + // + // Force deallocation and allocation + // of the initial size. + // + + #ifdef TEST + *logofs << "Transport: Resetting buffer for " << "FD#" + << fd_ << " with size " << buffer.data_.size() + << " and capacity " << buffer.data_.capacity() + << ".\n" << logofs_flush; + #endif + + buffer.start_ = 0; + buffer.length_ = 0; + + if (buffer.data_.size() > (unsigned int) initialSize_ && + buffer.data_.capacity() > (unsigned int) initialSize_) + { + buffer.data_.clear(); + + buffer.data_.resize(initialSize_); + + #ifdef TEST + *logofs << "Transport: Data buffer for " << "FD#" + << fd_ << " shrunk to size " << buffer.data_.size() + << " and capacity " << buffer.data_.capacity() + << ".\n" << logofs_flush; + #endif + } +} + +ProxyTransport::ProxyTransport(int fd) : Transport(fd) +{ + #ifdef TEST + *logofs << "ProxyTransport: Going to create proxy transport " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + type_ = transport_proxy; + + // + // Set up the read buffer. + // + + r_buffer_.length_ = 0; + r_buffer_.start_ = 0; + + r_buffer_.data_.resize(initialSize_); + + // + // For now we own the buffer. + // + + owner_ = 1; + + // + // Set up ZLIB compression. + // + + int result; + + r_stream_.zalloc = NULL; + r_stream_.zfree = NULL; + r_stream_.opaque = NULL; + + r_stream_.next_in = NULL; + r_stream_.avail_in = 0; + + if ((result = inflateInit2(&r_stream_, 15)) != Z_OK) + { + #ifdef PANIC + *logofs << "ProxyTransport: PANIC! Failed initialization of ZLIB read stream. " + << "Error is '" << zError(result) << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed initialization of ZLIB read stream. " + << "Error is '" << zError(result) << "'.\n"; + + HandleCleanup(); + } + + if (control -> LocalStreamCompression) + { + w_stream_.zalloc = NULL; + w_stream_.zfree = NULL; + w_stream_.opaque = NULL; + + if ((result = deflateInit2(&w_stream_, control -> LocalStreamCompressionLevel, Z_DEFLATED, + 15, 9, Z_DEFAULT_STRATEGY)) != Z_OK) + { + #ifdef PANIC + *logofs << "ProxyTransport: PANIC! Failed initialization of ZLIB write stream. " + << "Error is '" << zError(result) << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Failed initialization of ZLIB write stream. " + << "Error is '" << zError(result) << "'.\n"; + + HandleCleanup(); + } + } + + // + // No ZLIB stream to flush yet. + // + + flush_ = 0; + + #ifdef REFERENCES + *logofs << "ProxyTransport: Created new object at " + << this << " out of " << ++references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +ProxyTransport::~ProxyTransport() +{ + #ifdef TEST + *logofs << "ProxyTransport: Going to destroy derived class " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + // + // Deallocate the ZLIB stream state. + // + + inflateEnd(&r_stream_); + + if (control -> LocalStreamCompression) + { + deflateEnd(&w_stream_); + } + + #ifdef REFERENCES + *logofs << "ProxyTransport: Deleted object at " + << this << " out of " << --references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +// +// Read data from its file descriptor. +// + +int ProxyTransport::read(unsigned char *data, unsigned int size) +{ + // + // If the remote peer is not compressing + // the stream then just return any byte + // read from the socket. + // + + if (control -> RemoteStreamCompression == 0) + { + int result = Transport::read(data, size); + + if (result <= 0) + { + return result; + } + + statistics -> addBytesIn(result); + + return result; + } + + // + // Return any pending data first. + // + + if (r_buffer_.length_ > 0) + { + // + // If the size of the buffer doesn't + // match the amount of data pending, + // force the caller to retry. + // + + if ((int) size < r_buffer_.length_) + { + #ifdef TEST + *logofs << "ProxyTransport: WARNING! Forcing a retry with " + << r_buffer_.length_ << " bytes pending and " + << size << " in the buffer.\n" + << logofs_flush; + #endif + + ESET(EAGAIN); + + return -1; + } + + int copied = (r_buffer_.length_ > ((int) size) ? + ((int) size) : r_buffer_.length_); + + memcpy(data, r_buffer_.data_.begin() + r_buffer_.start_, copied); + + // + // Update the buffer status. + // + + #ifdef DEBUG + *logofs << "ProxyTransport: Going to immediately return " << copied + << " bytes from proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + r_buffer_.length_ -= copied; + + if (r_buffer_.length_ == 0) + { + r_buffer_.start_ = 0; + } + else + { + r_buffer_.start_ += copied; + + #ifdef TEST + *logofs << "ProxyTransport: There are still " << r_buffer_.length_ + << " bytes in read buffer for proxy " << "FD#" + << fd_ << ".\n" << logofs_flush; + #endif + } + + return copied; + } + + // + // Read data in the user buffer. + // + + int result = Transport::read(data, size); + + if (result <= 0) + { + return result; + } + + statistics -> addBytesIn(result); + + // + // Decompress the data into the read + // buffer. + // + + #ifdef DEBUG + *logofs << "ProxyTransport: Going to decompress data for " + << "proxy FD#" << fd_ << ".\n" << logofs_flush; + #endif + + int saveTotalIn = r_stream_.total_in; + int saveTotalOut = r_stream_.total_out; + + int oldTotalIn = saveTotalIn; + int oldTotalOut = saveTotalOut; + + int diffTotalIn; + int diffTotalOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: oldTotalIn = " << oldTotalIn + << ".\n" << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: oldTotalOut = " << oldTotalOut + << ".\n" << logofs_flush; + #endif + + r_stream_.next_in = (Bytef *) data; + r_stream_.avail_in = result; + + // + // Let ZLIB use all the space already + // available in the buffer. + // + + unsigned int newAvailOut = r_buffer_.data_.size() - r_buffer_.start_ - + r_buffer_.length_; + + #ifdef TEST + *logofs << "ProxyTransport: Initial decompress buffer is " + << newAvailOut << " bytes.\n" << logofs_flush; + #endif + + for (;;) + { + #ifdef INSPECT + *logofs << "\nProxyTransport: Running the decompress loop.\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_buffer_.length_ = " << r_buffer_.length_ + << ".\n" << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_buffer_.data_.size() = " << r_buffer_.data_.size() + << ".\n" << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: newAvailOut = " << newAvailOut + << ".\n" << logofs_flush; + #endif + + if (resize(r_buffer_, newAvailOut) < 0) + { + return -1; + } + + #ifdef INSPECT + *logofs << "ProxyTransport: r_buffer_.data_.size() = " + << r_buffer_.data_.size() << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_stream_.next_in = " + << (void *) r_stream_.next_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_stream_.avail_in = " + << r_stream_.avail_in << ".\n" + << logofs_flush; + #endif + + r_stream_.next_out = r_buffer_.data_.begin() + r_buffer_.start_ + + r_buffer_.length_; + + r_stream_.avail_out = newAvailOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: r_stream_.next_out = " + << (void *) r_stream_.next_out << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_stream_.avail_out = " + << r_stream_.avail_out << ".\n" + << logofs_flush; + #endif + + int result = inflate(&r_stream_, Z_SYNC_FLUSH); + + #ifdef INSPECT + *logofs << "ProxyTransport: Called inflate() result is " + << result << ".\n" << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_stream_.avail_in = " + << r_stream_.avail_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_stream_.avail_out = " + << r_stream_.avail_out << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_stream_.total_in = " + << r_stream_.total_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_stream_.total_out = " + << r_stream_.total_out << ".\n" + << logofs_flush; + #endif + + diffTotalIn = r_stream_.total_in - oldTotalIn; + diffTotalOut = r_stream_.total_out - oldTotalOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: diffTotalIn = " + << diffTotalIn << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: diffTotalOut = " + << diffTotalOut << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: r_buffer_.length_ = " + << r_buffer_.length_ << ".\n" + << logofs_flush; + #endif + + r_buffer_.length_ += diffTotalOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: r_buffer_.length_ = " + << r_buffer_.length_ << ".\n" + << logofs_flush; + #endif + + oldTotalIn = r_stream_.total_in; + oldTotalOut = r_stream_.total_out; + + if (result == Z_OK) + { + if (r_stream_.avail_in == 0 && r_stream_.avail_out > 0) + { + break; + } + } + else if (result == Z_BUF_ERROR && r_stream_.avail_out > 0 && + r_stream_.avail_in == 0) + { + #ifdef TEST + *logofs << "ProxyTransport: WARNING! Raised Z_BUF_ERROR decompressing data.\n" + << logofs_flush; + #endif + + break; + } + else + { + #ifdef PANIC + *logofs << "ProxyTransport: PANIC! Decompression of data failed. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Decompression of data failed. Error is '" + << zError(result) << "'.\n"; + + finish(); + + return -1; + } + + // + // Add more bytes to the buffer. + // + + if (newAvailOut < thresholdSize_) + { + newAvailOut = thresholdSize_; + } + + #ifdef TEST + *logofs << "ProxyTransport: Need to add " << newAvailOut + << " bytes to the decompress buffer in read.\n" + << logofs_flush; + #endif + } + + diffTotalIn = r_stream_.total_in - saveTotalIn; + diffTotalOut = r_stream_.total_out - saveTotalOut; + + #ifdef DEBUG + *logofs << "ProxyTransport: Decompressed data from " + << diffTotalIn << " to " << diffTotalOut + << " bytes.\n" << logofs_flush; + #endif + + statistics -> addDecompressedBytes(diffTotalIn, diffTotalOut); + + // + // Check if the size of the buffer + // matches the produced data. + // + + if ((int) size < r_buffer_.length_) + { + #ifdef TEST + *logofs << "ProxyTransport: WARNING! Forcing a retry with " + << r_buffer_.length_ << " bytes pending and " + << size << " in the buffer.\n" + << logofs_flush; + #endif + + ESET(EAGAIN); + + return -1; + } + + // + // Copy the decompressed data to the + // provided buffer. + // + + int copied = (r_buffer_.length_ > ((int) size) ? + ((int) size) : r_buffer_.length_); + + #ifdef DEBUG + *logofs << "ProxyTransport: Going to return " << copied + << " bytes from proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + memcpy(data, r_buffer_.data_.begin() + r_buffer_.start_, copied); + + // + // Update the buffer status. + // + + r_buffer_.length_ -= copied; + + if (r_buffer_.length_ == 0) + { + r_buffer_.start_ = 0; + } + else + { + r_buffer_.start_ += copied; + + #ifdef TEST + *logofs << "ProxyTransport: There are still " << r_buffer_.length_ + << " bytes in read buffer for proxy FD#" << fd_ + << ".\n" << logofs_flush; + #endif + } + + return copied; +} + +// +// If required compress data, else write it to socket. +// + +int ProxyTransport::write(T_write type, const unsigned char *data, const unsigned int size) +{ + #ifdef TEST + if (size == 0) + { + *logofs << "ProxyTransport: WARNING! Write called for FD#" + << fd_ << " without any data to write.\n" + << logofs_flush; + + return 0; + } + #endif + + // + // If there is no compression revert to + // plain socket management. + // + + if (control -> LocalStreamCompression == 0) + { + int result = Transport::write(type, data, size); + + if (result <= 0) + { + return result; + } + + statistics -> addBytesOut(result); + + statistics -> updateBitrate(result); + + FlushCallback(result); + + return result; + } + + #ifdef DEBUG + *logofs << "ProxyTransport: Going to compress " << size + << " bytes to write buffer for proxy FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + // + // Compress data into the write buffer. + // + + int saveTotalIn = w_stream_.total_in; + int saveTotalOut = w_stream_.total_out; + + int oldTotalIn = saveTotalIn; + int oldTotalOut = saveTotalOut; + + int diffTotalIn; + int diffTotalOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: oldTotalIn = " << oldTotalIn + << ".\n" << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: oldTotalOut = " << oldTotalOut + << ".\n" << logofs_flush; + #endif + + w_stream_.next_in = (Bytef *) data; + w_stream_.avail_in = size; + + // + // Let ZLIB use all the space already + // available in the buffer. + // + + unsigned int newAvailOut = w_buffer_.data_.size() - w_buffer_.start_ - + w_buffer_.length_; + + #ifdef TEST + *logofs << "ProxyTransport: Initial compress buffer is " + << newAvailOut << " bytes.\n" << logofs_flush; + #endif + + for (;;) + { + #ifdef INSPECT + *logofs << "\nProxyTransport: Running the compress loop.\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.length_ = " + << w_buffer_.length_ << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.data_.size() = " + << w_buffer_.data_.size() << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: newAvailOut = " + << newAvailOut << ".\n" + << logofs_flush; + #endif + + if (resize(w_buffer_, newAvailOut) < 0) + { + return -1; + } + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.data_.size() = " + << w_buffer_.data_.size() << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.next_in = " + << (void *) w_stream_.next_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.avail_in = " + << w_stream_.avail_in << ".\n" + << logofs_flush; + #endif + + w_stream_.next_out = w_buffer_.data_.begin() + w_buffer_.start_ + + w_buffer_.length_; + + w_stream_.avail_out = newAvailOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.next_out = " + << (void *) w_stream_.next_out << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.avail_out = " + << w_stream_.avail_out << ".\n" + << logofs_flush; + #endif + + int result = deflate(&w_stream_, (type == write_delayed ? + Z_NO_FLUSH : Z_SYNC_FLUSH)); + + #ifdef INSPECT + *logofs << "ProxyTransport: Called deflate() result is " + << result << ".\n" << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.avail_in = " + << w_stream_.avail_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.avail_out = " + << w_stream_.avail_out << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.total_in = " + << w_stream_.total_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.total_out = " + << w_stream_.total_out << ".\n" + << logofs_flush; + #endif + + diffTotalOut = w_stream_.total_out - oldTotalOut; + diffTotalIn = w_stream_.total_in - oldTotalIn; + + #ifdef INSPECT + *logofs << "ProxyTransport: diffTotalIn = " + << diffTotalIn << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: diffTotalOut = " + << diffTotalOut << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.length_ = " + << w_buffer_.length_ << ".\n" + << logofs_flush; + #endif + + w_buffer_.length_ += diffTotalOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.length_ = " + << w_buffer_.length_ << ".\n" + << logofs_flush; + #endif + + oldTotalOut = w_stream_.total_out; + oldTotalIn = w_stream_.total_in; + + if (result == Z_OK) + { + if (w_stream_.avail_in == 0 && w_stream_.avail_out > 0) + { + break; + } + } + else if (result == Z_BUF_ERROR && w_stream_.avail_out > 0 && + w_stream_.avail_in == 0) + { + #ifdef TEST + *logofs << "ProxyTransport: WARNING! Raised Z_BUF_ERROR compressing data.\n" + << logofs_flush; + #endif + + break; + } + else + { + #ifdef PANIC + *logofs << "ProxyTransport: PANIC! Compression of data failed. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Compression of data failed. Error is '" + << zError(result) << "'.\n"; + + finish(); + + return -1; + } + + // + // Add more bytes to the buffer. + // + + if (newAvailOut < thresholdSize_) + { + newAvailOut = thresholdSize_; + } + + #ifdef TEST + *logofs << "ProxyTransport: Need to add " << newAvailOut + << " bytes to the compress buffer in write.\n" + << logofs_flush; + #endif + } + + diffTotalIn = w_stream_.total_in - saveTotalIn; + diffTotalOut = w_stream_.total_out - saveTotalOut; + + #ifdef TEST + + *logofs << "ProxyTransport: Compressed data from " + << diffTotalIn << " to " << diffTotalOut + << " bytes.\n" << logofs_flush; + + if (diffTotalIn != (int) size) + { + #ifdef PANIC + *logofs << "ProxyTransport: PANIC! Bytes provided to ZLIB stream " + << "should be " << size << " but they look to be " + << diffTotalIn << ".\n" << logofs_flush; + #endif + } + + #endif + + // + // Find out what we have to do with the + // produced data. + // + + if (type == write_immediate) + { + // + // If user requested an immediate write we + // flushed the ZLIB buffer. We can now reset + // the counter and write data to socket. + // + + flush_ = 0; + + #ifdef TEST + *logofs << "ProxyTransport: Write buffer for proxy FD#" << fd_ + << " has data for " << w_buffer_.length_ << " bytes.\n" + << logofs_flush; + + *logofs << "ProxyTransport: Start is " << w_buffer_.start_ + << " length is " << w_buffer_.length_ << " flush is " + << flush_ << " size is " << w_buffer_.data_.size() + << " capacity is " << w_buffer_.data_.capacity() + << ".\n" << logofs_flush; + #endif + + // + // Alternatively may try to write only if + // the socket is not blocked. + // + // if (w_buffer_.length_ > 0 && blocked_ == 0) + // { + // ... + // } + // + + if (w_buffer_.length_ > 0) + + { + #ifdef TEST + *logofs << "ProxyTransport: Writing " << w_buffer_.length_ + << " bytes of produced data to FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + int result = Transport::flush(); + + if (result < 0) + { + return -1; + } + } + } + else + { + // + // We haven't flushed the ZLIB compression + // buffer, so user will have to call proxy + // transport's flush explicitly. + // + + flush_ += diffTotalIn; + } + + // + // We either wrote the data or added it to the + // write buffer. It's convenient to update the + // counters at this stage to get the current + // bitrate earlier. + // + + statistics -> addCompressedBytes(diffTotalIn, diffTotalOut); + + statistics -> addBytesOut(diffTotalOut); + + statistics -> updateBitrate(diffTotalOut); + + FlushCallback(diffTotalOut); + + #ifdef TEST + *logofs << "ProxyTransport: Write buffer for proxy FD#" << fd_ + << " has data for " << w_buffer_.length_ << " bytes.\n" + << logofs_flush; + + *logofs << "ProxyTransport: Start is " << w_buffer_.start_ + << " length is " << w_buffer_.length_ << " flush is " + << flush_ << " size is " << w_buffer_.data_.size() + << " capacity is " << w_buffer_.data_.capacity() + << ".\n" << logofs_flush; + #endif + + return size; +} + +// +// Write data to its file descriptor. +// + +int ProxyTransport::flush() +{ + // + // If there is no compression or we already compressed + // outgoing data and just need to write it to socket + // because of previous incomplete writes then revert + // to plain socket management. + // + + if (flush_ == 0 || control -> LocalStreamCompression == 0) + { + int result = Transport::flush(); + + if (result < 0) + { + return -1; + } + + return result; + } + + #ifdef DEBUG + *logofs << "ProxyTransport: Going to flush compression on " + << "proxy FD#" << fd_ << ".\n" << logofs_flush; + #endif + + #ifdef TEST + *logofs << "ProxyTransport: Flush counter for proxy FD#" << fd_ + << " is " << flush_ << " bytes.\n" << logofs_flush; + #endif + + // + // Flush ZLIB stream into the write buffer. + // + + int saveTotalIn = w_stream_.total_in; + int saveTotalOut = w_stream_.total_out; + + int oldTotalIn = saveTotalIn; + int oldTotalOut = saveTotalOut; + + int diffTotalOut; + int diffTotalIn; + + #ifdef INSPECT + *logofs << "ProxyTransport: oldTotalIn = " << oldTotalIn + << ".\n" << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: oldTotalOut = " << oldTotalOut + << ".\n" << logofs_flush; + #endif + + w_stream_.next_in = w_buffer_.data_.begin() + w_buffer_.start_ + w_buffer_.length_; + w_stream_.avail_in = 0; + + // + // Let ZLIB use all the space already + // available in the buffer. + // + + unsigned int newAvailOut = w_buffer_.data_.size() - w_buffer_.start_ - + w_buffer_.length_; + + #ifdef DEBUG + *logofs << "ProxyTransport: Initial flush buffer is " + << newAvailOut << " bytes.\n" << logofs_flush; + #endif + + for (;;) + { + #ifdef INSPECT + *logofs << "\nProxyTransport: Running the flush loop.\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.length_ = " + << w_buffer_.length_ << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.data_.size() = " + << w_buffer_.data_.size() << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: newAvailOut = " + << newAvailOut << ".\n" + << logofs_flush; + #endif + + if (resize(w_buffer_, newAvailOut) < 0) + { + return -1; + } + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.data_.size() = " + << w_buffer_.data_.size() << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.next_in = " + << (void *) w_stream_.next_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.avail_in = " + << w_stream_.avail_in << ".\n" + << logofs_flush; + #endif + + w_stream_.next_out = w_buffer_.data_.begin() + w_buffer_.start_ + + w_buffer_.length_; + + w_stream_.avail_out = newAvailOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.next_out = " + << (void *) w_stream_.next_out << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.avail_out = " + << w_stream_.avail_out << ".\n" + << logofs_flush; + #endif + + int result = deflate(&w_stream_, Z_SYNC_FLUSH); + + #ifdef INSPECT + *logofs << "ProxyTransport: Called deflate() result is " + << result << ".\n" << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.avail_in = " + << w_stream_.avail_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.avail_out = " + << w_stream_.avail_out << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.total_in = " + << w_stream_.total_in << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_stream_.total_out = " + << w_stream_.total_out << ".\n" + << logofs_flush; + #endif + + diffTotalOut = w_stream_.total_out - oldTotalOut; + diffTotalIn = w_stream_.total_in - oldTotalIn; + + #ifdef INSPECT + *logofs << "ProxyTransport: diffTotalIn = " + << diffTotalIn << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: diffTotalOut = " + << diffTotalOut << ".\n" + << logofs_flush; + #endif + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.length_ = " + << w_buffer_.length_ << ".\n" + << logofs_flush; + #endif + + w_buffer_.length_ += diffTotalOut; + + #ifdef INSPECT + *logofs << "ProxyTransport: w_buffer_.length_ = " + << w_buffer_.length_ << ".\n" + << logofs_flush; + #endif + + oldTotalOut = w_stream_.total_out; + oldTotalIn = w_stream_.total_in; + + if (result == Z_OK) + { + if (w_stream_.avail_in == 0 && w_stream_.avail_out > 0) + { + break; + } + } + else if (result == Z_BUF_ERROR && w_stream_.avail_out > 0 && + w_stream_.avail_in == 0) + { + #ifdef TEST + *logofs << "ProxyTransport: WARNING! Raised Z_BUF_ERROR flushing data.\n" + << logofs_flush; + #endif + + break; + } + else + { + #ifdef PANIC + *logofs << "ProxyTransport: PANIC! Flush of compressed data failed. " + << "Error is '" << zError(result) << "'.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Flush of compressed data failed. Error is '" + << zError(result) << "'.\n"; + + finish(); + + return -1; + } + + // + // Add more bytes to the buffer. + // + + if (newAvailOut < thresholdSize_) + { + newAvailOut = thresholdSize_; + } + + #ifdef TEST + *logofs << "ProxyTransport: Need to add " << newAvailOut + << " bytes to the compress buffer in flush.\n" + << logofs_flush; + #endif + } + + diffTotalIn = w_stream_.total_in - saveTotalIn; + diffTotalOut = w_stream_.total_out - saveTotalOut; + + #ifdef TEST + *logofs << "ProxyTransport: Compressed flush data from " + << diffTotalIn << " to " << diffTotalOut + << " bytes.\n" << logofs_flush; + #endif + + // + // Time to move data from the write + // buffer to the real link. + // + + #ifdef DEBUG + *logofs << "ProxyTransport: Reset flush counter for proxy FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + flush_ = 0; + + #ifdef TEST + *logofs << "ProxyTransport: Write buffer for proxy FD#" << fd_ + << " has data for " << w_buffer_.length_ << " bytes.\n" + << logofs_flush; + + *logofs << "ProxyTransport: Start is " << w_buffer_.start_ + << " length is " << w_buffer_.length_ << " flush is " + << flush_ << " size is " << w_buffer_.data_.size() + << " capacity is " << w_buffer_.data_.capacity() + << ".\n" << logofs_flush; + #endif + + int result = Transport::flush(); + + if (result < 0) + { + return -1; + } + + // + // Update all the counters. + // + + statistics -> addCompressedBytes(diffTotalIn, diffTotalOut); + + statistics -> addBytesOut(diffTotalOut); + + statistics -> updateBitrate(diffTotalOut); + + FlushCallback(diffTotalOut); + + return result; +} + +unsigned int ProxyTransport::getPending(unsigned char *&data) +{ + // + // Return a pointer to the data in the + // read buffer. It is up to the caller + // to ensure that the data is consumed + // before the read buffer is reused. + // + + if (r_buffer_.length_ > 0) + { + unsigned int size = r_buffer_.length_; + + data = r_buffer_.data_.begin() + r_buffer_.start_; + + #ifdef DEBUG + *logofs << "ProxyTransport: Returning " << size + << " pending bytes from proxy FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + r_buffer_.length_ = 0; + r_buffer_.start_ = 0; + + // + // Prevent the deletion of the buffer. + // + + owner_ = 0; + + return size; + } + + #ifdef TEST + *logofs << "ProxyTransport: WARNING! No pending data " + << "for proxy FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + data = NULL; + + return 0; +} + +void ProxyTransport::fullReset() +{ + blocked_ = 0; + finish_ = 0; + flush_ = 0; + + if (control -> RemoteStreamCompression) + { + inflateReset(&r_stream_); + } + + if (control -> LocalStreamCompression) + { + deflateReset(&w_stream_); + } + + if (owner_ == 1) + { + Transport::fullReset(r_buffer_); + } + + Transport::fullReset(w_buffer_); +} + +AgentTransport::AgentTransport(int fd) : Transport(fd) +{ + #ifdef TEST + *logofs << "AgentTransport: Going to create agent transport " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + type_ = transport_agent; + + // + // Set up the read buffer. + // + + r_buffer_.length_ = 0; + r_buffer_.start_ = 0; + + r_buffer_.data_.resize(initialSize_); + + // + // For now we own the buffer. + // + + owner_ = 1; + + // + // Set up the mutexes. + // + + #ifdef THREADS + + pthread_mutexattr_t m_attributes; + + pthread_mutexattr_init(&m_attributes); + + // + // Interfaces in pthread to handle mutex + // type do not work in current version. + // + + m_attributes.__mutexkind = PTHREAD_MUTEX_ERRORCHECK_NP; + + if (pthread_mutex_init(&m_read_, &m_attributes) != 0) + { + #ifdef TEST + *logofs << "AgentTransport: Child: Creation of read mutex failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + } + + if (pthread_mutex_init(&m_write_, &m_attributes) != 0) + { + #ifdef TEST + *logofs << "AgentTransport: Child: Creation of write mutex failed. " + << "Error is " << EGET() << " '" << ESTR() + << "'.\n" << logofs_flush; + #endif + } + + #endif + + #ifdef REFERENCES + *logofs << "AgentTransport: Child: Created new object at " + << this << " out of " << ++references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +AgentTransport::~AgentTransport() +{ + #ifdef TEST + *logofs << "AgentTransport: Going to destroy derived class " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + // + // Unlock and free all mutexes. + // + + #ifdef THREADS + + pthread_mutex_unlock(&m_read_); + pthread_mutex_unlock(&m_write_); + + pthread_mutex_destroy(&m_read_); + pthread_mutex_destroy(&m_write_); + + #endif + + #ifdef REFERENCES + *logofs << "AgentTransport: Child: Deleted object at " + << this << " out of " << --references_ + << " allocated references.\n" << logofs_flush; + #endif +} + +// +// Read data enqueued by the other thread. +// + +int AgentTransport::read(unsigned char *data, unsigned int size) +{ + #ifdef THREADS + + lockRead(); + + #endif + + #ifdef DEBUG + *logofs << "AgentTransport: Child: Going to read " << size + << " bytes from " << "FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + int copied = -1; + + if (r_buffer_.length_ > 0) + { + if ((int) size < r_buffer_.length_) + { + #ifdef TEST + *logofs << "AgentTransport: WARNING! Forcing a retry with " + << r_buffer_.length_ << " bytes pending and " + << size << " in the buffer.\n" + << logofs_flush; + #endif + + ESET(EAGAIN); + } + else + { + copied = (r_buffer_.length_ > ((int) size) ? + ((int) size) : r_buffer_.length_); + + memcpy(data, r_buffer_.data_.begin() + r_buffer_.start_, copied); + + // + // Update the buffer status. + // + + #ifdef TEST + *logofs << "AgentTransport: Child: Going to immediately return " + << copied << " bytes from FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + #ifdef DUMP + + *logofs << "AgentTransport: Child: Dumping content of read data.\n" + << logofs_flush; + + DumpData(data, copied); + + #endif + + r_buffer_.length_ -= copied; + + if (r_buffer_.length_ == 0) + { + r_buffer_.start_ = 0; + } + else + { + r_buffer_.start_ += copied; + + #ifdef TEST + *logofs << "AgentTransport: Child: There are still " + << r_buffer_.length_ << " bytes in read buffer for " + << "FD#" << fd_ << ".\n" << logofs_flush; + #endif + } + } + } + else + { + #ifdef DEBUG + *logofs << "AgentTransport: Child: No data can be got " + << "from read buffer for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + ESET(EAGAIN); + } + + #ifdef THREADS + + unlockRead(); + + #endif + + return copied; +} + +// +// Write data to buffer so that the other +// thread can get it. +// + +int AgentTransport::write(T_write type, const unsigned char *data, const unsigned int size) +{ + #ifdef THREADS + + lockWrite(); + + #endif + + // + // Just append data to socket's write buffer. + // Note that we don't care if buffer exceeds + // the size limits set for this type of + // transport. + // + + #ifdef TEST + *logofs << "AgentTransport: Child: Going to append " << size + << " bytes to write buffer for " << "FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + int copied = -1; + + if (resize(w_buffer_, size) < 0) + { + finish(); + + ESET(EPIPE); + } + else + { + memmove(w_buffer_.data_.begin() + w_buffer_.start_ + w_buffer_.length_, data, size); + + w_buffer_.length_ += size; + + #ifdef DUMP + + *logofs << "AgentTransport: Child: Dumping content of written data.\n" + << logofs_flush; + + DumpData(data, size); + + #endif + + #ifdef TEST + *logofs << "AgentTransport: Child: Write buffer for FD#" << fd_ + << " has data for " << w_buffer_.length_ << " bytes.\n" + << logofs_flush; + + *logofs << "AgentTransport: Child: Start is " << w_buffer_.start_ + << " length is " << w_buffer_.length_ << " size is " + << w_buffer_.data_.size() << " capacity is " + << w_buffer_.data_.capacity() << ".\n" + << logofs_flush; + #endif + + copied = size; + } + + // + // Let child access again the read buffer. + // + + #ifdef THREADS + + unlockWrite(); + + #endif + + return copied; +} + +int AgentTransport::flush() +{ + // + // In case of memory-to-memory transport + // this function should never be called. + // + + #ifdef PANIC + *logofs << "AgentTransport: Child: PANIC! Called flush() for " + << "memory to memory transport on " << "FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Called flush() for " + << "memory to memory transport on " << "FD#" + << fd_ << ".\n"; + + HandleAbort(); +} + +int AgentTransport::drain(int limit, int timeout) +{ + // + // We can't drain the channel in the case + // of the memory-to-memory transport. Data + // is enqueued for the agent to read but + // the agent could require multiple loops + // to read it all. + // + + // + // In case of memory-to-memory transport + // this function should never be called. + // + + #ifdef PANIC + *logofs << "AgentTransport: Child: PANIC! Called drain() for " + << "memory to memory transport on " << "FD#" + << fd_ << ".\n" << logofs_flush; + #endif + + cerr << "Error" << ": Called drain() for " + << "memory to memory transport on " << "FD#" + << fd_ << ".\n"; + + HandleAbort(); +} + +unsigned int AgentTransport::getPending(unsigned char *&data) +{ + #ifdef THREADS + + lockRead(); + + #endif + + if (r_buffer_.length_ > 0) + { + unsigned int size = r_buffer_.length_; + + data = r_buffer_.data_.begin() + r_buffer_.start_; + + #ifdef DEBUG + *logofs << "AgentTransport: Child: Returning " << size + << " pending bytes from FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + r_buffer_.length_ = 0; + r_buffer_.start_ = 0; + + #ifdef THREADS + + unlockRead(); + + #endif + + // + // Prevent the deletion of the buffer. + // + + owner_ = 0; + + return size; + } + + #ifdef TEST + *logofs << "AgentTransport: WARNING! No pending data " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + #ifdef THREADS + + unlockRead(); + + #endif + + data = NULL; + + return 0; +} + +void AgentTransport::fullReset() +{ + #ifdef THREADS + + lockRead(); + lockWrite(); + + #endif + + #ifdef TEST + *logofs << "AgentTransport: Child: Resetting transport " + << "for FD#" << fd_ << ".\n" << logofs_flush; + #endif + + blocked_ = 0; + finish_ = 0; + + if (owner_ == 1) + { + Transport::fullReset(r_buffer_); + } + + Transport::fullReset(w_buffer_); +} + +int AgentTransport::enqueue(const char *data, const int size) +{ + #ifdef THREADS + + lockRead(); + + #endif + + if (finish_ == 1) + { + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: Returning EPIPE in " + << "write for finishing FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + ESET(EPIPE); + + return -1; + } + + // + // Always allow the agent to write + // all its data. + // + + int toPut = size; + + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: Going to put " << toPut + << " bytes into read buffer for FD#" << fd_ + << ". Buffer length is " << r_buffer_.length_ + << ".\n" << logofs_flush; + #endif + + if (resize(r_buffer_, toPut) < 0) + { + finish(); + + #ifdef THREADS + + unlockRead(); + + #endif + + return -1; + } + + memcpy(r_buffer_.data_.begin() + r_buffer_.start_ + r_buffer_.length_, data, toPut); + + r_buffer_.length_ += toPut; + + #if defined(DUMP) && defined(PARENT) + + *logofs << "AgentTransport: Parent: Dumping content of enqueued data.\n" + << logofs_flush; + + DumpData((const unsigned char *) data, toPut); + + #endif + + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: Read buffer for FD#" << fd_ + << " has now data for " << r_buffer_.length_ + << " bytes.\n" << logofs_flush; + + *logofs << "AgentTransport: Parent: Start is " << r_buffer_.start_ + << " length is " << r_buffer_.length_ << " size is " + << r_buffer_.data_.size() << " capacity is " + << r_buffer_.data_.capacity() << ".\n" + << logofs_flush; + #endif + + #ifdef THREADS + + unlockRead(); + + #endif + + return toPut; +} + +int AgentTransport::dequeue(char *data, int size) +{ + #ifdef THREADS + + lockWrite(); + + #endif + + if (w_buffer_.length_ == 0) + { + if (finish_ == 1) + { + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: Returning 0 in read " + << "for finishing FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + return 0; + } + + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: No data can be read " + << "from write buffer for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + ESET(EAGAIN); + + #ifdef THREADS + + unlockWrite(); + + #endif + + return -1; + } + + // + // Return as many bytes as possible. + // + + int toGet = ((int) size > w_buffer_.length_ ? w_buffer_.length_ : size); + + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: Going to get " << toGet + << " bytes from write buffer for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + memcpy(data, w_buffer_.data_.begin() + w_buffer_.start_, toGet); + + w_buffer_.start_ += toGet; + w_buffer_.length_ -= toGet; + + #if defined(DUMP) && defined(PARENT) + + *logofs << "AgentTransport: Parent: Dumping content of dequeued data.\n" + << logofs_flush; + + DumpData((const unsigned char *) data, toGet); + + #endif + + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: Write buffer for FD#" << fd_ + << " has now data for " << length() << " bytes.\n" + << logofs_flush; + + *logofs << "AgentTransport: Parent: Start is " << w_buffer_.start_ + << " length is " << w_buffer_.length_ << " size is " + << w_buffer_.data_.size() << " capacity is " + << w_buffer_.data_.capacity() << ".\n" + << logofs_flush; + #endif + + #ifdef THREADS + + unlockWrite(); + + #endif + + return toGet; +} + +int AgentTransport::dequeuable() +{ + if (finish_ == 1) + { + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: Returning EPIPE in " + << "readable for finishing FD#" << fd_ + << ".\n" << logofs_flush; + #endif + + ESET(EPIPE); + + return -1; + } + + #if defined(PARENT) && defined(TEST) + *logofs << "AgentTransport: Parent: Returning " + << w_buffer_.length_ << " as data readable " + << "from read buffer for FD#" << fd_ << ".\n" + << logofs_flush; + #endif + + return w_buffer_.length_; +} + +#ifdef THREADS + +int AgentTransport::lockRead() +{ + for (;;) + { + int result = pthread_mutex_lock(&m_read_); + + if (result == 0) + { + #ifdef DEBUG + *logofs << "AgentTransport: Read mutex locked by thread id " + << pthread_self() << ".\n" << logofs_flush; + #endif + + return 0; + } + else if (EGET() == EINTR) + { + continue; + } + else + { + #ifdef WARNING + *logofs << "AgentTransport: WARNING! Locking of read mutex by thread id " + << pthread_self() << " returned " << result << ". Error is '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + return result; + } + } +} + +int AgentTransport::lockWrite() +{ + for (;;) + { + int result = pthread_mutex_lock(&m_write_); + + if (result == 0) + { + #ifdef DEBUG + *logofs << "AgentTransport: Write mutex locked by thread id " + << pthread_self() << ".\n" << logofs_flush; + #endif + + return 0; + } + else if (EGET() == EINTR) + { + continue; + } + else + { + #ifdef WARNING + *logofs << "AgentTransport: WARNING! Locking of write mutex by thread id " + << pthread_self() << " returned " << result << ". Error is '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + return result; + } + } +} + +int AgentTransport::unlockRead() +{ + for (;;) + { + int result = pthread_mutex_unlock(&m_read_); + + if (result == 0) + { + #ifdef DEBUG + *logofs << "AgentTransport: Read mutex unlocked by thread id " + << pthread_self() << ".\n" << logofs_flush; + #endif + + return 0; + } + else if (EGET() == EINTR) + { + continue; + } + else + { + #ifdef WARNING + *logofs << "AgentTransport: WARNING! Unlocking of read mutex by thread id " + << pthread_self() << " returned " << result << ". Error is '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + return result; + } + } +} + +int AgentTransport::unlockWrite() +{ + for (;;) + { + int result = pthread_mutex_unlock(&m_write_); + + if (result == 0) + { + #ifdef DEBUG + *logofs << "AgentTransport: Write mutex unlocked by thread id " + << pthread_self() << ".\n" << logofs_flush; + #endif + + return 0; + } + else if (EGET() == EINTR) + { + continue; + } + else + { + #ifdef WARNING + *logofs << "AgentTransport: WARNING! Unlocking of write mutex by thread id " + << pthread_self() << " returned " << result << ". Error is '" + << ESTR() << "'.\n" << logofs_flush; + #endif + + return result; + } + } +} + +#endif diff --git a/nxcomp/src/Transport.h b/nxcomp/src/Transport.h new file mode 100644 index 000000000..047396af6 --- /dev/null +++ b/nxcomp/src/Transport.h @@ -0,0 +1,577 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Transport_H +#define Transport_H + +#include +#include + +#include +#include +#include + +#include "Misc.h" +#include "Control.h" + +#include "Types.h" +#include "Timestamp.h" +#include "Socket.h" + +// +// Set the verbosity level. +// + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Define this to lock and unlock the +// memory-to-memory transport buffers +// before they are accessed. The code +// is outdated and doesn't work with +// the current pthread library. +// + +#undef THREADS + +// +// Define this to know when a socket +// is created or destroyed. +// + +#undef REFERENCES + +// +// Size of buffer if not set by user. +// + +#define TRANSPORT_BUFFER_DEFAULT_SIZE 16384 + +// +// Type of transport. +// + +typedef enum +{ + transport_base, + transport_proxy, + transport_agent, + transport_last_tag + +} T_transport_type; + +// +// This class handles the buffered I/O on +// the network sockets. +// + +// +// TODO: This class is useful but adds a lot of +// overhead. There are many improvements we can +// make here: +// +// - There should be a generic Buffer class, ac- +// comodating a list of memory buffers. This +// would enable the use of the readv() and +// writev() functions to perform the I/O on +// the socket. +// +// - The buffering should be moved to the Write- +// Buffer and ReadBuffer classes. By performing +// the buffering here and there, we are dupli- +// cating a lot of code and are adding a lot +// of useless memory copies. +// +// - Stream compression should be removed. The +// proxy should compress the frames based on +// the type and should include the length of +// the decompressed data in the header of the +// packet. Besides avoiding the compression +// of packets that cannot be reduced in size, +// we would also save the additional memory +// allocations due to the fact that we don't +// know the size of the decode buffer at the +// time we read the packet from the network. +// +// - The other utilities implemented here, like +// the functions forcing a write on the socket +// or waiting for more data to become available +// should be moved to the Proxy or the Channel +// classes. +// + +class Transport +{ + public: + + // + // Member functions. + // + + Transport(int fd); + + virtual ~Transport(); + + int fd() const + { + return fd_; + } + + T_transport_type getType() + { + return type_; + } + + // + // Virtual members redefined by proxy + // and 'memory-to-memory' I/O layers. + // + + virtual int read(unsigned char *data, unsigned int size); + + virtual int write(T_write type, const unsigned char *data, const unsigned int size); + + virtual int flush(); + + virtual int drain(int limit, int timeout); + + virtual void finish() + { + fullReset(); + + finish_ = 1; + } + + virtual int length() const + { + return w_buffer_.length_; + } + + virtual int pending() const + { + return 0; + } + + virtual int readable() const + { + return GetBytesReadable(fd_); + } + + virtual int writable() const + { + return GetBytesWritable(fd_); + } + + virtual int queued() const + { + return GetBytesQueued(fd_); + } + + virtual int flushable() const + { + return 0; + } + + virtual int wait(int timeout) const; + + void setSize(unsigned int initialSize, + unsigned int thresholdSize, + unsigned int maximumSize); + + // + // Return a pointer to the data + // in the read buffer. + // + + virtual unsigned int getPending(unsigned char *&data) + { + data = NULL; + + return 0; + } + + virtual void pendingReset() + { + } + + virtual void partialReset() + { + partialReset(w_buffer_); + } + + virtual void fullReset(); + + int blocked() const + { + return blocked_; + } + + protected: + + // + // Make room in the buffer to accommodate + // at least size bytes. + // + + int resize(T_buffer &buffer, const int &size); + + void partialReset(T_buffer &buffer) + { + if (buffer.length_ == 0 && + (buffer.data_.size() > initialSize_ || + buffer.data_.capacity() > initialSize_)) + { + fullReset(buffer); + } + } + + void fullReset(T_buffer &buffer); + + // + // Data members. + // + + int fd_; + + int blocked_; + int finish_; + + T_buffer w_buffer_; + + unsigned int initialSize_; + unsigned int thresholdSize_; + unsigned int maximumSize_; + + T_transport_type type_; + + private: + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +// +// This class handles buffered I/O and +// compression of the proxy stream. +// + +class ProxyTransport : public Transport +{ + public: + + ProxyTransport(int fd); + + virtual ~ProxyTransport(); + + virtual int read(unsigned char *data, unsigned int size); + + virtual int write(T_write type, const unsigned char *data, const unsigned int size); + + virtual int flush(); + + // + // Same as in the base class. + // + // virtual int drain(int limit, int timeout); + // + // virtual void finish(); + // + + // + // Same as in the base class. + // + // virtual int length() const + // + + virtual int pending() const + { + return r_buffer_.length_; + } + + // + // Same as in the base class. + // + // virtual int readable() const; + // + // virtual int writable() const; + // + // virtual int queued() const; + // + + virtual int flushable() const + { + return flush_; + } + + // + // Same as in the base class, but + // should not be called. + // + // int drained() const; + // + // Same as in the base class. + // + // virtual int wait(int timeout) const; + // + // Same as in the base class. + // + // void setSize(unsigned int initialSize, + // unsigned int thresholdSize, + // unsigned int maximumSize); + // + + virtual unsigned int getPending(unsigned char *&data); + + virtual void pendingReset() + { + owner_ = 1; + } + + virtual void partialReset() + { + if (owner_ == 1) + { + Transport::partialReset(r_buffer_); + } + + Transport::partialReset(w_buffer_); + } + + virtual void fullReset(); + + // + // Same as in the base class. + // + // int blocked() const; + // + + protected: + + int flush_; + int owner_; + + T_buffer r_buffer_; + + z_stream r_stream_; + z_stream w_stream_; + + private: + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +// +// Handle memory-to-memory data transfers between +// an agent and the proxy. +// + +class AgentTransport : public Transport +{ + public: + + AgentTransport(int fd); + + virtual ~AgentTransport(); + + virtual int read(unsigned char *data, unsigned int size); + + virtual int write(T_write type, const unsigned char *data, const unsigned int size); + + // + // These two should never be called. + // + + virtual int flush(); + + virtual int drain(int limit, int timeout); + + // + // Same as in the base class. + // + // virtual void finish(); + // + + // + // Same as in the base class. + // + // virtual int length() const + // + + virtual int pending() const + { + return r_buffer_.length_; + } + + // + // These are intended to operate only + // on the internal buffers. + // + + virtual int readable() const + { + return r_buffer_.length_; + } + + virtual int writable() const + { + return control -> TransportMaximumBufferSize; + } + + virtual int queued() const + { + return 0; + } + + // + // Same as in the base class. + // + // virtual int flushable() const; + // + // Same as in the base class, but + // should not be called. + // + // int drained() const; + // + + // + // Return immediately or will + // block until the timeout. + // + + virtual int wait(int timeout) const + { + return 0; + } + + // + // Same as in the base class. + // + // void setSize(unsigned int initialSize, + // unsigned int thresholdSize, + // unsigned int maximumSize); + // + + virtual unsigned int getPending(unsigned char *&data); + + virtual void pendingReset() + { + owner_ = 1; + } + + virtual void partialReset() + { + if (owner_ == 1) + { + Transport::partialReset(r_buffer_); + } + + Transport::partialReset(w_buffer_); + } + + virtual void fullReset(); + + // + // Same as in the base class. + // + // int blocked() const; + // + + // + // The following are specific of the + // memory-to-memory transport. + // + + int enqueue(const char *data, const int size); + + int dequeue(char *data, int size); + + int queuable() + { + // + // Always allow the agent to enqueue + // more data. + // + + return control -> TransportMaximumBufferSize; + } + + int dequeuable(); + + protected: + + // + // Lock the buffer to handle reads and + // writes safely. + // + + #ifdef THREADS + + int lockRead(); + int lockWrite(); + + int unlockRead(); + int unlockWrite(); + + #endif + + // + // Data members. + // + + int owner_; + + T_buffer r_buffer_; + + // + // Mutexes for safe read and write. + // + + #ifdef THREADS + + pthread_mutex_t m_read_; + pthread_mutex_t m_write_; + + #endif + + private: + + #ifdef REFERENCES + + static int references_; + + #endif +}; + +#endif /* Transport_H */ diff --git a/nxcomp/src/Types.h b/nxcomp/src/Types.h new file mode 100644 index 000000000..e82664c81 --- /dev/null +++ b/nxcomp/src/Types.h @@ -0,0 +1,271 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Types_H +#define Types_H + +using namespace std; + +#include +#include +#include +#include + +#include "MD5.h" + +// +// This is MD5 length. +// + +#define MD5_LENGTH 16 + +// +// Types of repositories. Replace the original +// clear() methods from STL in order to actually +// free the unused memory. +// + +class Message; + +class T_data : public vector < unsigned char > +{ + public: + + unsigned char *begin() + { + return &*(vector < unsigned char >::begin()); + } + + const unsigned char *begin() const + { + return &*(vector < unsigned char >::begin()); + } + + // Avoid overriding clear() when using libc++. Fiddling with STL internals + // doesn't really seem like a good idea to me anyway. + #ifndef _LIBCPP_VECTOR + void clear() + { + #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) + + #if defined(__GLIBCPP_INTERNAL_VECTOR_H) + + _Destroy(_M_start, _M_finish); + + #else /* #if defined(__GLIBCPP_INTERNAL_VECTOR_H) */ + + destroy(_M_start, _M_finish); + + #endif /* #if defined(__GLIBCPP_INTERNAL_VECTOR_H) */ + + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + + _M_start = _M_finish = _M_end_of_storage = 0; + + #else /* #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) */ + + #if defined(_GLIBCXX_VECTOR) + + _Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + + _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + + this->_M_impl._M_start = this->_M_impl._M_finish = this->_M_impl._M_end_of_storage = 0; + + #else /* #if defined(_GLIBCXX_VECTOR) */ + + destroy(start, finish); + + deallocate(); + + start = finish = end_of_storage = 0; + + #endif /* #if defined(_GLIBCXX_VECTOR) */ + + #endif /* #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) */ + } + #endif /* #ifdef _LIBCPP_VECTOR */ +}; + +class T_messages : public vector < Message * > +{ + public: + + // Avoid overriding clear() when using libc++. Fiddling with STL internals + // doesn't really seem like a good idea to me anyway. + #ifndef _LIBCPP_VECTOR + void clear() + { + #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) + + #if defined(__GLIBCPP_INTERNAL_VECTOR_H) + + _Destroy(_M_start, _M_finish); + + #else /* #if defined(__GLIBCPP_INTERNAL_VECTOR_H) */ + + destroy(_M_start, _M_finish); + + #endif /* #if defined(__GLIBCPP_INTERNAL_VECTOR_H) */ + + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + + _M_start = _M_finish = _M_end_of_storage = 0; + + #else /* #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) */ + + #if defined(_GLIBCXX_VECTOR) + + _Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + + _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + + this->_M_impl._M_start = this->_M_impl._M_finish = this->_M_impl._M_end_of_storage = 0; + + #else /* #if defined(_GLIBCXX_VECTOR) */ + + destroy(start, finish); + + deallocate(); + + start = finish = end_of_storage = 0; + + #endif /* #if defined(_GLIBCXX_VECTOR) */ + + #endif /* #if defined(__STL_USE_STD_ALLOCATORS) || defined(__GLIBCPP_INTERNAL_VECTOR_H) */ + } + #endif /* #ifndef _LIBCPP_VECTOR */ +}; + +typedef md5_byte_t * T_checksum; + +struct T_less +{ + bool operator()(T_checksum a, T_checksum b) const + { + return (memcmp(a, b, MD5_LENGTH) < 0); + } +}; + +typedef map < T_checksum, int, T_less > T_checksums; + +class Split; + +typedef list < Split * > T_splits; + +class File; + +struct T_older +{ + bool operator()(File *a, File *b) const; +}; + +typedef set < File *, T_older > T_files; + +typedef list < int > T_list; + +// +// Used to accommodate data to be read and +// written to a socket. +// + +typedef struct +{ + T_data data_; + int length_; + int start_; +} +T_buffer; + +// +// The message store operation that was +// executed for the message. The channels +// use these values to determine how to +// handle the message after it has been +// received at the decoding side. +// + +// Since ProtoStep8 (#issue 108) +enum T_store_action +{ + is_hit, + is_added, + is_discarded, + is_removed +}; + +// Since ProtoStep8 (#issue 108) +#define IS_HIT is_hit +#define IS_ADDED is_added + +enum T_checksum_action +{ + use_checksum, + discard_checksum +}; + +enum T_data_action +{ + use_data, + discard_data +}; + +// +// Message is going to be weighted for +// deletion at insert or cleanup time? +// + +enum T_rating +{ + rating_for_insert, + rating_for_clean +}; + +// +// How to handle the writes to the X +// and proxy connections. +// + +enum T_write +{ + write_immediate, + write_delayed +}; + +enum T_flush +{ + flush_if_needed, + flush_if_any +}; + +// +// This is the value to indicate an +// invalid position in the message +// store. +// + +static const int nothing = -1; + +#endif /* Types_H */ diff --git a/nxcomp/src/Unpack.cpp b/nxcomp/src/Unpack.cpp new file mode 100644 index 000000000..e63e836f0 --- /dev/null +++ b/nxcomp/src/Unpack.cpp @@ -0,0 +1,1514 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Misc.h" +#include "Unpack.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +// +// Used for the ZLIB decompression +// of RGB, alpha and colormap data. +// + +z_stream unpackStream; + +static int unpackInitialized; + +int Unpack8To8(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack8To8(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack8To16(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack8To16(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack8To24(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack8To24(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack8To32(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack8To32(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack15To16(const unsigned char *data, unsigned char *out, + unsigned char *end); + +int Unpack15To24(const unsigned char *data, unsigned char *out, + unsigned char *end); + +int Unpack15To32(const unsigned char *data, unsigned char *out, + unsigned char *end); + +int Unpack16To16(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack16To16(const unsigned char *data, unsigned char *out, + unsigned char *end, int imageByteOrder); + +int Unpack16To24(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack16To24(const unsigned char *data, unsigned char *out, + unsigned char *end, int imageByteOrder); + +int Unpack16To32(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack16To32(const unsigned char *data, unsigned char *out, + unsigned char *end, int imageByteOrder); + +int Unpack24To24(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack24To24(const unsigned char *data, unsigned char *out, + unsigned char *end); + +int Unpack24To32(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + +int Unpack24To32(const unsigned char *data, unsigned char *out, unsigned char *end); + +int Unpack32To32(const T_colormask *colormask, const unsigned int *data, + unsigned int *out, unsigned int *end); + + +void UnpackInit() +{ + if (unpackInitialized == 0) + { + unpackStream.zalloc = (alloc_func) 0; + unpackStream.zfree = (free_func) 0; + unpackStream.opaque = (voidpf) 0; + + unpackStream.next_in = (Bytef *) 0; + unpackStream.avail_in = 0; + + int result = inflateInit2(&unpackStream, 15); + + if (result != Z_OK) + { + #ifdef PANIC + *logofs << "UnpackInit: PANIC! Cannot initialize the Z stream " + << "for decompression. Error is '" << zError(result) + << "'.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Cannot initialize the Z stream for " + << "decompression. Error is '" << zError(result) + << "'.\n"; + } + else + { + unpackInitialized = 1; + } + } +} + +void UnpackDestroy() +{ + if (unpackInitialized == 1) + { + inflateEnd(&unpackStream); + + unpackInitialized = 0; + } +} + +// +// Get bits per pixel set by client +// according to display geometry. +// + +int UnpackBitsPerPixel(T_geometry *geometry, unsigned int depth) +{ + switch (depth) + { + case 1: + { + return geometry -> depth1_bpp; + } + case 4: + { + return geometry -> depth4_bpp; + } + case 8: + { + return geometry -> depth8_bpp; + } + case 15: + case 16: + { + return geometry -> depth16_bpp; + } + case 24: + { + return geometry -> depth24_bpp; + } + case 32: + { + return geometry -> depth32_bpp; + } + default: + { + return 0; + } + } +} + +int Unpack8To8(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack8To8: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + memcpy(out, data, end - out); + + return 1; +} + +int Unpack8To16(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack8To16: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + unsigned short *out16 = (unsigned short *) out; + unsigned short *end16 = (unsigned short *) end; + + while (out16 < end16) + { + if (*data == 0) + { + *out16 = 0x0; + } + else if (*data == 0xff) + { + *out16 = 0xffff; + } + else + { + // + // Pixel layout: + // + // 8bits 00RRGGBB -> 16bits RR000GG0 000BB000. + // + + *out16 = (((((*data & 0x30) << 2) | colormask -> correction_mask) << 8) & 0xf800) | + (((((*data & 0xc) << 4) | colormask -> correction_mask) << 3) & 0x7e0) | + (((((*data & 0x3) << 6) | colormask -> correction_mask) >> 3) & 0x1f); + } + + out16++; + data++; + } + + return 1; +} + +int Unpack8To24(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack8To24: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + while (out < (end - 2)) + { + if (*data == 0x00) + { + out[0] = out[1] = out[2] = 0x00; + } + else if (*data == 0xff) + { + out[0] = out[1] = out[2] = 0xff; + } + else + { + // + // Pixel layout: + // + // 8bits 00RRGGBB -> 24bits RR000000 GG00000 BB000000. + // + + out[0] = (((*data & 0x30) << 2) | colormask -> correction_mask); + out[1] = (((*data & 0x0c) << 4) | colormask -> correction_mask); + out[2] = (((*data & 0x03) << 6) | colormask -> correction_mask); + } + + out += 3; + data += 1; + } + + return 1; +} + +int Unpack8To32(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack8To32: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + unsigned int *out32 = (unsigned int *) out; + unsigned int *end32 = (unsigned int *) end; + + while (out32 < end32) + { + if (*data == 0) + { + *out32 = 0x0; + } + else if (*data == 0xff) + { + *out32 = 0xffffff; + } + else + { + *out32 = ((((*data & 0x30) << 2) | colormask -> correction_mask) << 16) | + ((((*data & 0xc) << 4) | colormask -> correction_mask) << 8) | + (((*data & 0x3) << 6) | colormask -> correction_mask); + } + + out32++; + data++; + } + + return 1; +} + +int Unpack8(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size) +{ + int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); + + int (*unpack)(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + + switch (dst_bpp) + { + case 8: + { + unpack = Unpack8To8; + + break; + } + case 16: + { + unpack = Unpack8To16; + + break; + } + case 24: + { + unpack = Unpack8To24; + + break; + } + case 32: + { + unpack = Unpack8To32; + + break; + } + default: + { + #ifdef PANIC + *logofs << "Unpack8: PANIC! Bad destination bits per pixel " + << dst_bpp << ". Only 16/24/32 are supported.\n" + << logofs_flush; + #endif + + return -1; + } + } + + if (dst_bpp == 24) + { + unsigned char *dst_end = dst_data; + + #ifdef TEST + *logofs << "Unpack8: Handling 24 bits with dst_size " + << dst_size << ".\n" << logofs_flush; + #endif + + for (int y = 0; y < dst_height; y++) + { + dst_data = dst_end; + + dst_end += RoundUp4(dst_width * 3); + + (*unpack)(colormask, src_data, dst_data, dst_end); + + src_data += src_width; + } + } + else + { + unsigned char *dst_end = dst_data + dst_size; + + (*unpack)(colormask, src_data, dst_data, dst_end); + } + + return 1; +} + +int Unpack16To16(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack16To16: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + if (colormask -> correction_mask) + { + unsigned short *data16 = (unsigned short *) data; + + unsigned short *out16 = (unsigned short *) out; + unsigned short *end16 = (unsigned short *) end; + + while (out16 < end16) + { + if (*data16 == 0x0000) + { + *out16 = 0x0000; + } + else if (*data16 == 0xffff) + { + *out16 = 0xffff; + } + else + { + // + // Pixel layout: + // + // 16bit RRRRRGGG GG0BBBBB -> RRRRRGGG GGGBBBBB. + // + + *out16 = (((((*data16 & 0xf100) >> 8) | colormask -> correction_mask) << 8) & 0xf800) | + (((((*data16 & 0x7c0) >> 3) | colormask -> correction_mask) << 3) & 0x7e0) | + (((((*data16 & 0x1f) << 3) | colormask -> correction_mask) >> 3) & 0x1f); + } + + out16++; + data16++; + } + } + else + { + #ifdef TEST + *logofs << "Unpack16To16: Using bitwise copy due to null correction mask.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) out, (unsigned char *) data, end - out); + } + + return 1; +} + +int Unpack16To24(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack16To24: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + unsigned short *data16 = (unsigned short *) data; + + + while (out < end - 2) + { + if (*data16 == 0x0) + { + out[0] = 0x00; + out[1] = 0x00; + out[2] = 0x00; + } + else if (*data16 == 0xffff) + { + out[0] = 0xff; + out[1] = 0xff; + out[2] = 0xff; + } + else + { + #ifdef TEST + *logofs << "Unpack16To24: Pixel [" << *data16 << "]\n" + << logofs_flush; + #endif + + // + // Pixel layout: + // + // 16bit 0RRRRRGG GGGBBBBB -> 24 bit RRRRR000 GGGGG000 BBBBB000 + // + + out[0] = (((*data16 & 0x7c00) >> 7) | colormask -> correction_mask); + out[1] = (((*data16 & 0x03e0) >> 2) | colormask -> correction_mask); + out[2] = (((*data16 & 0x001f) << 3) | colormask -> correction_mask); + } + + out += 3; + data16 += 1; + } + + return 1; +} + +int Unpack16To32(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack16To32: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + unsigned short *data16 = (unsigned short *) data; + + unsigned int *out32 = (unsigned int *) out; + unsigned int *end32 = (unsigned int *) end; + + while (out32 < end32) + { + if (*data16 == 0x0) + { + *out32 = 0x0; + } + else if (*data16 == 0xffff) + { + *out32 = 0xffffff; + } + else + { + *out32 = ((((*data16 & 0x7c00) >> 7) | colormask -> correction_mask) << 16) | + ((((*data16 & 0x3e0) >> 2) | colormask -> correction_mask) << 8) | + (((*data16 & 0x1f) << 3) | colormask -> correction_mask); + } + + out32++; + data16++; + } + + return 1; +} + +int Unpack16(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size) +{ + int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); + + int (*unpack)(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + + switch (dst_bpp) + { + case 16: + { + unpack = Unpack16To16; + + break; + } + case 24: + { + unpack = Unpack16To24; + + break; + } + case 32: + { + unpack = Unpack16To32; + + break; + } + default: + { + #ifdef PANIC + *logofs << "Unpack16: PANIC! Bad destination bits per pixel " + << dst_bpp << ". Only 24/32 are supported.\n" + << logofs_flush; + #endif + + return -1; + } + } + + if (dst_bpp == 24) + { + unsigned char *dst_end = dst_data; + + for (int y = 0; y < dst_height; y++) + { + dst_data = dst_end; + + dst_end += RoundUp4(dst_width * 3); + + (*unpack)(colormask, src_data, dst_data, dst_end); + + src_data += (src_width * 2); + } + + } + else + { + unsigned char *dst_end = dst_data + dst_size; + + (*unpack)(colormask, src_data, dst_data, dst_end); + } + + return 1; +} + +int Unpack24To24(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack24To24: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + if (colormask -> correction_mask) + { + while (out < end) + { + if (data[0] == 0x00 && + data[1] == 0x00 && + data[2] == 0x00) + { + out[0] = out[1] = out[2] = 0x00; + } + else if (data[0] == 0xff && + data[1] == 0xff && + data[2] == 0xff) + { + out[0] = out[1] = out[2] = 0xff; + } + else + { + out[0] = (data[0] | colormask -> correction_mask); + out[1] = (data[1] | colormask -> correction_mask); + out[2] = (data[2] | colormask -> correction_mask); + } + + out += 3; + data += 3; + } + } + else + { + #ifdef TEST + *logofs << "Unpack24To24: Using bitwise copy due to null correction mask.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) out, (unsigned char *) data, end - out); + } + + return 1; +} + +int Unpack24To32(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack24To32: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + unsigned int *out32 = (unsigned int *) out; + unsigned int *end32 = (unsigned int *) end; + + while (out32 < end32) + { + if (colormask -> color_mask == 0xff) + { + *out32 = (data[0] << 16) | (data[1] << 8) | data[2]; + } + else + { + if (data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x0) + { + *out32 = 0x0; + } + else if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) + { + *out32 = 0xffffff; + } + else + { + *out32 = (((unsigned int) data[0] | colormask -> correction_mask) << 16) | + (((unsigned int) data[1] | colormask -> correction_mask) << 8) | + ((unsigned int) data[2] | colormask -> correction_mask); + } + } + + out32 += 1; + data += 3; + } + + return 1; +} + +int Unpack24(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size) +{ + int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); + + int (*unpack)(const T_colormask *colormask, const unsigned char *data, + unsigned char *out, unsigned char *end); + + switch (dst_bpp) + { + case 24: + { + unpack = Unpack24To24; + + break; + } + case 32: + { + unpack = Unpack24To32; + + break; + } + default: + { + #ifdef PANIC + *logofs << "Unpack24: PANIC! Bad destination bits per pixel " + << dst_bpp << ". Only 32 is supported.\n" + << logofs_flush; + #endif + + return -1; + } + } + + if (dst_bpp == 24) + { + unsigned char *dst_end; + unsigned long scanline_size = RoundUp4(dst_width * dst_bpp / 8); + + dst_end = dst_data; + + #ifdef TEST + *logofs << "Unpack24: Handling 24 bits with dst_height " + << dst_height << " scanline_size " << scanline_size + << " dst_size " << dst_size << ".\n" << logofs_flush; + #endif + + for (int y = 0; y < dst_height; y++) + { + dst_data = dst_end; + + dst_end += scanline_size; + + (*unpack)(colormask, src_data, dst_data, dst_end); + + src_data += scanline_size; + } + } + else + { + unsigned char *dst_end = dst_data + dst_size; + + (*unpack)(colormask, src_data, dst_data, dst_end); + } + + return 1; +} + +int Unpack8To8(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack8To8: Unpacking " << end - out + << " bytes of colormapped data.\n" + << logofs_flush; + #endif + + while (out < end) + { + *(out++) = (unsigned char) colormap -> data[*(data++)]; + } + + return 1; +} + +int Unpack8To16(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack8To16: Unpacking " << end - out + << " bytes of colormapped data.\n" + << logofs_flush; + #endif + + unsigned short *out16 = (unsigned short *) out; + unsigned short *end16 = (unsigned short *) end; + + while (out16 < end16) + { + *(out16++) = (unsigned short) colormap -> data[*(data++)]; + } + + return 1; +} + +int Unpack8To24(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack8To24: Unpacking " << end - out + << " bytes of colormapped data.\n" + << logofs_flush; + #endif + + unsigned int value; + + while (out < end) + { + value = colormap -> data[*(data++)]; + + *(out++) = value; + *(out++) = value >> 8; + *(out++) = value >> 16; + } + + return 1; +} + +int Unpack8To32(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack8To32: Unpacking " << end - out + << " bytes of colormapped data.\n" + << logofs_flush; + #endif + + unsigned int *out32 = (unsigned int *) out; + unsigned int *end32 = (unsigned int *) end; + + while (out32 < end32) + { + *(out32++) = colormap -> data[*(data++)]; + } + + return 1; +} + +int Unpack8(T_geometry *geometry, T_colormap *colormap, int src_depth, int src_width, int src_height, + unsigned char *src_data, int src_size, int dst_depth, int dst_width, + int dst_height, unsigned char *dst_data, int dst_size) +{ + if (src_depth != 8) + { + #ifdef PANIC + *logofs << "Unpack8: PANIC! Cannot unpack colormapped image of source depth " + << src_depth << ".\n" << logofs_flush; + #endif + + return -1; + } + + int (*unpack)(T_colormap *colormap, const unsigned char *data, + unsigned char *out, unsigned char *end); + + int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); + + switch (dst_bpp) + { + case 8: + { + unpack = Unpack8To8; + + break; + } + case 16: + { + unpack = Unpack8To16; + + break; + } + case 24: + { + unpack = Unpack8To24; + + break; + } + case 32: + { + unpack = Unpack8To32; + + break; + } + default: + { + #ifdef PANIC + *logofs << "Unpack8: PANIC! Bad destination bits per pixel " + << dst_bpp << ". Only 8/16/24/32 are supported.\n" + << logofs_flush; + #endif + + return -1; + } + } + + if (src_width == dst_width && + src_height == dst_height) + { + unsigned char *dst_end = dst_data + dst_size; + + (*unpack)(colormap, src_data, dst_data, dst_end); + } + else if (src_width >= dst_width && + src_height >= dst_height) + { + unsigned char *dst_end = dst_data; + + for (int y = 0; y < dst_height; y++) + { + dst_data = dst_end; + + dst_end += RoundUp4(dst_width * dst_bpp / 8); + + (*unpack)(colormap, src_data, dst_data, dst_end); + + src_data += src_width; + } + } + else + { + #ifdef PANIC + *logofs << "Unpack8: PANIC! Cannot unpack image. " + << "Destination area " << dst_width << "x" + << dst_height << " is not fully contained in " + << src_width << "x" << src_height << " source.\n" + << logofs_flush; + #endif + + return -1; + } + + return 1; +} + +int Unpack15To16(const unsigned char *data, unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack15To16: Unpacking " << end - out + << " bytes of colormapped data.\n" + << logofs_flush; + #endif + + unsigned short *data16 = (unsigned short *) data; + unsigned short *out16 = (unsigned short *) out; + unsigned short *end16 = (unsigned short *) end; + + while (out16 < end16) + { + if (*data16 == 0x0) + { + *out16 = 0x0; + } + else if (*data16 == 0x7fff) + { + *out16 = 0xffff; + } + else + { + #ifdef TEST + *logofs << "Unpack15To16: Pixel [" << *data16 << "]\n" + << logofs_flush; + #endif + + *out16 = ((*data16 & 0x7ff0) << 1) | + (*data16 & 0x001f); + } + + out16 += 1; + data16 += 1; + } + + return 1; +} + +int Unpack15To24(const unsigned char *data, unsigned char *out, unsigned char *end) + +{ + #ifdef TEST + *logofs << "Unpack15To24: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + unsigned short *data16 = (unsigned short *) data; + + while (out < end - 2) + { + if (*data16 == 0x0) + { + out[0] = 0x00; + out[1] = 0x00; + out[2] = 0x00; + } + else if (*data16 == 0x7fff) + { + out[0] = 0xff; + out[1] = 0xff; + out[2] = 0xff; + } + else + { + #ifdef TEST + *logofs << "Unpack15To24: Pixel [" << *data16 << "]\n" + << logofs_flush; + #endif + + out[0] = ((*data16 >> 7) & 0xf8) | ((*data16 >> 12) & 0x07); + out[1] = ((*data16 >> 2) & 0xf8) | ((*data16 >> 8) & 0x07); + out[2] = ((*data16 << 3) & 0xf8) | ((*data16 >> 2) & 0x07); + } + + out += 3; + data16 += 1; + } + + return 1; +} + +int Unpack15To32(const unsigned char *data, unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack15To32: Unpacking " << end - out + << " bytes of data.\n" + << logofs_flush; + #endif + + unsigned short *data16 = (unsigned short *) data; + unsigned int *out32 = (unsigned int *) out; + unsigned int *end32 = (unsigned int *) end; + + while (out32 < end32) + { + if (*data16 == 0x0) + { + *out32 = 0x0; + } + else if (*data16 == 0xffff) + { + *out32 = 0xffffff; + } + else + { + *out32 = ((((*data16 >> 7) & 0xf8) | ((*data16 >> 12) & 0x07)) << 16) | + ((((*data16 >> 2) & 0xf8) | ((*data16 >> 8) & 0x07)) << 8) | + (((*data16 << 3) & 0xf8) | ((*data16 >> 2) & 0x07)); + } + + out32++; + data16++; + } + + return 1; +} + +int Unpack15(T_geometry *geometry, int src_depth, int src_width, int src_height, + unsigned char *src_data, int src_size, int dst_depth, int dst_width, + int dst_height, unsigned char *dst_data, int dst_size) +{ + if (src_depth != 16) + { + #ifdef PANIC + *logofs << "Unpack15: PANIC! Cannot unpack colormapped image of source depth " + << src_depth << ".\n" << logofs_flush; + #endif + + return -1; + } + + int (*unpack)(const unsigned char *data, unsigned char *out, unsigned char *end); + + int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); + + switch (dst_bpp) + { + case 16: + { + unpack = Unpack15To16; + + break; + } + case 24: + { + unpack = Unpack15To24; + + break; + } + case 32: + { + unpack = Unpack15To32; + + break; + } + default: + { + #ifdef PANIC + *logofs << "Unpack15: PANIC! Bad destination bits per pixel " + << dst_bpp << ". Only 16/24/32 are supported.\n" + << logofs_flush; + #endif + + return -1; + } + } + + if (src_width == dst_width && src_height == dst_height) + { + unsigned char *dst_end = dst_data + dst_size; + + (*unpack)(src_data, dst_data, dst_end); + } + else if (src_width >= dst_width && src_height >= dst_height) + { + unsigned char *dst_end = dst_data; + + for (int y = 0; y < dst_height; y++) + { + dst_data = dst_end; + dst_end += RoundUp4(dst_width * dst_bpp / 8); + + (*unpack)(src_data, dst_data, dst_end); + + src_data += src_width * 2; + } + } + else + { + #ifdef PANIC + *logofs << "Unpack15: PANIC! Cannot unpack image. " + << "Destination area " << dst_width << "x" + << dst_height << " is not fully contained in " + << src_width << "x" << src_height << " source.\n" + << logofs_flush; + #endif + + return -1; + } + + return 1; +} + +int Unpack16To16(const unsigned char *data, unsigned char *out, + unsigned char *end, int imageByteOrder) +{ + #ifdef TEST + *logofs << "Unpack16To16: Unpacking " << end - out + << " bytes of colormapped data.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) out, (unsigned char *) data, end - out); + + return 1; +} + +int Unpack16To24(const unsigned char *data, unsigned char *out, + unsigned char *end, int imageByteOrder) + +{ + #ifdef TEST + *logofs << "Unpack16To24: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + unsigned short *data16 = (unsigned short *) data; + + while (out < end - 2) + { + if (*data16 == 0x0) + { + out[0] = 0x00; + out[1] = 0x00; + out[2] = 0x00; + } + else if (*data16 == 0xffff) + { + out[0] = 0xff; + out[1] = 0xff; + out[2] = 0xff; + } + else + { + #ifdef TEST + *logofs << "Unpack16To24: Pixel [" << *data16 << "]\n" + << logofs_flush; + #endif + + out[0] = ((*data16 >> 8) & 0xf8) | ((*data16 >> 13) & 0x07); + out[1] = ((*data16 >> 3) & 0xfc) | ((*data16 >> 9) & 0x03); + out[2] = ((*data16 << 3) & 0xf8) | ((*data16 >> 2) & 0x07); + } + + out += 3; + data16 += 1; + } + + return 1; +} + + +int Unpack16To32(const unsigned char *data, unsigned char *out, + unsigned char *end, int imageByteOrder) +{ + #ifdef TEST + *logofs << "Unpack16To32: Unpacking " << end - out + << " bytes of data.\n" + << logofs_flush; + #endif + + unsigned short *data16 = (unsigned short *) data; + unsigned int *out32 = (unsigned int *) out; + unsigned int *end32 = (unsigned int *) end; + + unsigned short pixel16; + unsigned int pixel32; + + while (out32 < end32) + { + + pixel16 = GetUINT((unsigned char *)data16, 0); + + if (pixel16 == 0x0) + { + PutULONG(0x0, (unsigned char *) out32, imageByteOrder); + } + else if (pixel16 == 0xffff) + { + PutULONG(0xffffff, (unsigned char *) out32, imageByteOrder); + } + else + { + pixel32 = ((((pixel16 >> 8) & 0xf8) | ((pixel16 >> 13) & 0x07)) << 16) | + ((((pixel16 >> 3) & 0xfc) | ((pixel16 >> 9) & 0x03)) << 8) | + (((pixel16 << 3) & 0xf8) | ((pixel16 >> 2) & 0x07)); + + PutULONG(pixel32, (unsigned char *) out32, imageByteOrder); + } + + out32++; + data16++; + } + return 1; +} + +int Unpack16(T_geometry *geometry, int src_depth, int src_width, int src_height, + unsigned char *src_data, int src_size, int dst_depth, int dst_width, + int dst_height, unsigned char *dst_data, int dst_size) +{ + int imageByteOrder = geometry -> image_byte_order; + + if (src_depth != 16) + { + #ifdef PANIC + *logofs << "Unpack16: PANIC! Cannot unpack colormapped image of source depth " + << src_depth << ".\n" << logofs_flush; + #endif + + return -1; + } + + int (*unpack)(const unsigned char *data, unsigned char *out, + unsigned char *end, int imageByteOrder); + + int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); + + switch (dst_bpp) + { + case 16: + { + unpack = Unpack16To16; + + break; + } + case 24: + { + unpack = Unpack16To24; + + break; + } + case 32: + { + unpack = Unpack16To32; + + break; + } + default: + { + #ifdef PANIC + *logofs << "Unpack16: PANIC! Bad destination bits per pixel " + << dst_bpp << ". Only 16/24/32 are supported.\n" + << logofs_flush; + #endif + + return -1; + } + } + + if (src_width == dst_width && src_height == dst_height) + { + unsigned char *dst_end = dst_data + dst_size; + + (*unpack)(src_data, dst_data, dst_end, imageByteOrder); + } + else if (src_width >= dst_width && src_height >= dst_height) + { + unsigned char *dst_end = dst_data; + + for (int y = 0; y < dst_height; y++) + { + dst_data = dst_end; + dst_end += RoundUp4(dst_width * dst_bpp / 8); + + (*unpack)(src_data, dst_data, dst_end, imageByteOrder); + + src_data += src_width * 2; + } + } + else + { + #ifdef PANIC + *logofs << "Unpack16: PANIC! Cannot unpack image. " + << "Destination area " << dst_width << "x" + << dst_height << " is not fully contained in " + << src_width << "x" << src_height << " source.\n" + << logofs_flush; + #endif + + return -1; + } + + return 1; +} + +int Unpack24To24(const unsigned char *data, + unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack124To24: Unpacking " << end - out + << " bytes of colormapped data.\n" + << logofs_flush; + #endif + + while (out < end) + { + *(out++) = *(data++); + } + + return 1; +} + +int Unpack24To32(const unsigned char *data, unsigned char *out, unsigned char *end) +{ + #ifdef TEST + *logofs << "Unpack24To32: Unpacking " << end - out + << " bytes of colormapped data.\n" + << logofs_flush; + #endif + + unsigned int *out32 = (unsigned int *) out; + unsigned int *end32 = (unsigned int *) end; + + while (out32 < end32) + { + if (data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x0) + { + *out32 = 0x0; + } + else if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) + { + *out32 = 0xffffff; + } + else + { + *out32 = (data[2] << 16) | (data[1] << 8) | data[0]; + } + + out32 += 1; + data += 3; + } + + return 1; +} + +int Unpack24(T_geometry *geometry, int src_depth, int src_width, int src_height, + unsigned char *src_data, int src_size, int dst_depth, int dst_width, + int dst_height, unsigned char *dst_data, int dst_size) + +{ + if (src_depth != 24) + { + #ifdef PANIC + *logofs << "Unpack24: PANIC! Cannot unpack colormapped image of source depth " + << src_depth << ".\n" << logofs_flush; + #endif + + return -1; + } + + int (*unpack)(const unsigned char *data, unsigned char *out, unsigned char *end); + + int dst_bpp = UnpackBitsPerPixel(geometry, dst_depth); + + switch (dst_bpp) + { + case 24: + { + unpack = Unpack24To24; + + break; + } + case 32: + { + unpack = Unpack24To32; + + break; + } + default: + { + #ifdef PANIC + *logofs << "Unpack24: PANIC! Bad destination bits per pixel " + << dst_bpp << ". Only 24/32 are supported.\n" + << logofs_flush; + #endif + + return -1; + } + } + + if (src_width == dst_width && src_height == dst_height) + { + unsigned char *dst_end = dst_data + dst_size; + + (*unpack)(src_data, dst_data, dst_end); + } + else if (src_width >= dst_width && src_height >= dst_height) + { + unsigned char *dst_end = dst_data; + + for (int y = 0; y < dst_height; y++) + { + dst_data = dst_end; + dst_end += RoundUp4(dst_width * dst_bpp / 8); + + (*unpack)(src_data, dst_data, dst_end); + + src_data += src_width * 3; + } + } + else + { + #ifdef PANIC + *logofs << "Unpack24: PANIC! Cannot unpack image. " + << "Destination area " << dst_width << "x" + << dst_height << " is not fully contained in " + << src_width << "x" << src_height << " source.\n" + << logofs_flush; + #endif + + return -1; + } + + return 1; +} + +int Unpack32To32(const T_colormask *colormask, const unsigned int *data, + unsigned int *out, unsigned int *end) +{ + #ifdef TEST + *logofs << "Unpack32To32: Unpacking " << end - out + << " bytes of data.\n" << logofs_flush; + #endif + + if (colormask -> correction_mask) + { + while (out < end) + { + if (*data == 0x00000000) + { + *out = 0x00000000; + } + else if (*data == 0xFFFFFFFF) + { + *out = 0xFFFFFFFF; + } + else + { + *out = *data | ((colormask -> correction_mask << 16) | + (colormask -> correction_mask << 8) | + colormask -> correction_mask); + } + + out += 1; + data += 1; + } + } + else + { + #ifdef TEST + *logofs << "Unpack32To32: Using bitwise copy due to null correction mask.\n" + << logofs_flush; + #endif + + memcpy((unsigned char *) out, (unsigned char *) data, end - out); + } + + return 1; +} diff --git a/nxcomp/src/Unpack.h b/nxcomp/src/Unpack.h new file mode 100644 index 000000000..faaa41d82 --- /dev/null +++ b/nxcomp/src/Unpack.h @@ -0,0 +1,149 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Unpack_H +#define Unpack_H + +#include "NXpack.h" + +#include "Z.h" + +#define LSBFirst 0 +#define MSBFirst 1 + +#define SPLIT_PATTERN 0x88 + +typedef ColorMask T_colormask; + +// +// Pixel geometry of channel's display. +// + +typedef struct +{ + unsigned int depth1_bpp; + unsigned int depth4_bpp; + unsigned int depth8_bpp; + unsigned int depth16_bpp; + unsigned int depth24_bpp; + unsigned int depth32_bpp; + + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + + unsigned int image_byte_order; + unsigned int bitmap_bit_order; + unsigned int scanline_unit; + unsigned int scanline_pad; + +} T_geometry; + +// +// Colormap is used to remap colors +// from source to destination depth. +// + +typedef struct +{ + unsigned int entries; + unsigned int *data; + +} T_colormap; + +// +// Alpha channel data is added to 32 +// bits images at the time they are +// unpacked. +// + +typedef struct +{ + unsigned int entries; + unsigned char *data; + +} T_alpha; + +// +// The ZLIB stream structure used for +// the decompression. +// + +extern z_stream unpackStream; + +// +// Initialize the ZLIB stream used for +// decompression. +// + +void UnpackInit(); + +// +// Free the ZLIB stream. +// + +void UnpackDestroy(); + +// +// Get the destination bits per pixel +// based on the drawable depth. +// + +int UnpackBitsPerPixel(T_geometry *geometry, unsigned int depth); + +// +// Unpack the source data into the X +// bitmap. +// + +int Unpack8(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size); + +int Unpack16(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size); + +int Unpack24(T_geometry *geometry, const T_colormask *colormask, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size); + +int Unpack8(T_geometry *geometry, T_colormap *colormap, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size); + +int Unpack15(T_geometry *geometry, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size); + +int Unpack16(T_geometry *geometry, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size); + +int Unpack24(T_geometry *geometry, int src_depth, int src_width, + int src_height, unsigned char *src_data, int src_size, int dst_depth, + int dst_width, int dst_height, unsigned char *dst_data, int dst_size); + +#endif /* Unpack_H */ diff --git a/nxcomp/src/Vars.c b/nxcomp/src/Vars.c new file mode 100644 index 000000000..685969677 --- /dev/null +++ b/nxcomp/src/Vars.c @@ -0,0 +1,54 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "NXvars.h" + +/* + * Allocate here instances of variables and + * pointers declared in NXvars.h. + */ + +int _NXHandleDisplayError = 0; + +NXDisplayErrorPredicate _NXDisplayErrorFunction = NULL; + +int _NXUnsetLibraryPath = 0; + +NXLostSequenceHandler _NXLostSequenceFunction = NULL; + +NXDisplayBlockHandler _NXDisplayBlockFunction = NULL; +NXDisplayWriteHandler _NXDisplayWriteFunction = NULL; +NXDisplayFlushHandler _NXDisplayFlushFunction = NULL; +NXDisplayStatisticsHandler _NXDisplayStatisticsFunction = NULL; + +#ifdef __cplusplus +} +#endif diff --git a/nxcomp/src/Version.c b/nxcomp/src/Version.c new file mode 100644 index 000000000..509bd8344 --- /dev/null +++ b/nxcomp/src/Version.c @@ -0,0 +1,101 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2015 Qindel Formacion y Servicios SL. */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License Version 2, as */ +/* published by the Free Software Foundation. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- */ +/* BILITY 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, you can request a copy from Qindel */ +/* or write to the Free Software Foundation, Inc., 51 Franklin Street, */ +/* Fifth Floor, Boston, MA 02110-1301 USA. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include "NX.h" + + +static int _NXVersionMajor = -1; +static int _NXVersionMinor = -1; +static int _NXVersionPatch = -1; +static int _NXVersionMaintenancePatch = -1; + + +const char* NXVersion() { + const char *version = VERSION; + return version; +} + +void _parseNXVersion() { + char version[32]; + int i; + strcpy(version, VERSION); + + char *value; + /* Reset values to 0 if undefined */ + _NXVersionMajor = _NXVersionMinor = _NXVersionPatch = _NXVersionMaintenancePatch = 0; + + +#define NXVERSIONSEPARATOR "." + value = strtok(version, NXVERSIONSEPARATOR); + + for (i = 0; value != NULL && i < 4; i++) + { + switch (i) + { + case 0: + _NXVersionMajor = atoi(value); + break; + + case 1: + _NXVersionMinor = atoi(value); + break; + + case 2: + _NXVersionPatch = atoi(value); + break; + + case 3: + _NXVersionMaintenancePatch = atoi(value); + break; + } + + value = strtok(NULL, NXVERSIONSEPARATOR); + } +} + +int NXMajorVersion() { + if (_NXVersionMajor == -1) + _parseNXVersion(); + return _NXVersionMajor; +} +int NXMinorVersion() { + if (_NXVersionMinor == -1) + _parseNXVersion(); + return _NXVersionMinor; +} +int NXPatchVersion() { + if (_NXVersionPatch == -1) + _parseNXVersion(); + return _NXVersionPatch; +} +int NXMaintenancePatchVersion() { + if (_NXVersionMaintenancePatch == -1) + _parseNXVersion(); + return _NXVersionMaintenancePatch; +} diff --git a/nxcomp/src/WriteBuffer.cpp b/nxcomp/src/WriteBuffer.cpp new file mode 100644 index 000000000..70b4e3b53 --- /dev/null +++ b/nxcomp/src/WriteBuffer.cpp @@ -0,0 +1,500 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "Misc.h" +#include "Control.h" + +#include "WriteBuffer.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +WriteBuffer::WriteBuffer() +{ + size_ = WRITE_BUFFER_DEFAULT_SIZE; + buffer_ = new unsigned char[size_]; + length_ = 0; + index_ = NULL; + + scratchLength_ = 0; + scratchBuffer_ = NULL; + scratchOwner_ = 1; + + initialSize_ = WRITE_BUFFER_DEFAULT_SIZE; + thresholdSize_ = WRITE_BUFFER_DEFAULT_SIZE << 1; + maximumSize_ = WRITE_BUFFER_DEFAULT_SIZE << 4; + + #ifdef VALGRIND + + memset(buffer_, '\0', size_); + + #endif +} + +WriteBuffer::~WriteBuffer() +{ + if (scratchOwner_ == 1 && + scratchBuffer_ != NULL) + { + delete [] scratchBuffer_; + } + + delete [] buffer_; +} + +void WriteBuffer::setSize(unsigned int initialSize, unsigned int thresholdSize, + unsigned int maximumSize) +{ + initialSize_ = initialSize; + thresholdSize_ = thresholdSize; + maximumSize_ = maximumSize; + + #ifdef TEST + *logofs << "WriteBuffer: Set buffer sizes to " + << initialSize_ << "/" << thresholdSize_ + << "/" << maximumSize_ << ".\n" + << logofs_flush; + #endif +} + +void WriteBuffer::partialReset() +{ + if (scratchBuffer_ != NULL) + { + if (scratchOwner_) + { + #ifdef DEBUG + *logofs << "WriteBuffer: Going to delete " + << scratchLength_ << " bytes from the " + << "scratch buffer.\n" << logofs_flush; + #endif + + delete [] scratchBuffer_; + } + + scratchLength_ = 0; + scratchBuffer_ = NULL; + scratchOwner_ = 1; + } + + length_ = 0; + index_ = NULL; + + #ifdef DEBUG + *logofs << "WriteBuffer: Performed partial reset with " + << size_ << " bytes in buffer.\n" + << logofs_flush; + #endif +} + +void WriteBuffer::fullReset() +{ + if (scratchBuffer_ != NULL) + { + if (scratchOwner_ == 1) + { + #ifdef DEBUG + *logofs << "WriteBuffer: Going to delete " + << scratchLength_ << " bytes from the " + << "scratch buffer.\n" << logofs_flush; + #endif + + delete [] scratchBuffer_; + } + + scratchLength_ = 0; + scratchBuffer_ = NULL; + scratchOwner_ = 1; + } + + length_ = 0; + index_ = NULL; + + if (size_ > initialSize_) + { + #ifdef TEST + *logofs << "WriteBuffer: Reallocating a new buffer of " + << initialSize_ << " bytes.\n" << logofs_flush; + #endif + + delete [] buffer_; + + size_ = initialSize_; + + buffer_ = new unsigned char[size_]; + + if (buffer_ == NULL) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't allocate memory for " + << "X messages in context [A].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "X messages in context [A].\n"; + + HandleAbort(); + } + + #ifdef VALGRIND + + memset(buffer_, '\0', size_); + + #endif + } + + #ifdef DEBUG + *logofs << "WriteBuffer: Performed full reset with " + << size_ << " bytes in buffer.\n" + << logofs_flush; + #endif +} + +unsigned char *WriteBuffer::addMessage(unsigned int numBytes) +{ + #ifdef DEBUG + *logofs << "WriteBuffer: Adding " << numBytes << " bytes to " + << length_ << " bytes already in buffer.\n" + << logofs_flush; + #endif + + if (numBytes > WRITE_BUFFER_OVERFLOW_SIZE) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't add a message of " + << numBytes << " bytes.\n" << logofs_flush; + + *logofs << "WriteBuffer: PANIC! Assuming error handling " + << "data in context [B].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't add a message of " + << numBytes << " bytes to write buffer.\n"; + + cerr << "Error" << ": Assuming error handling " + << "data in context [B].\n"; + + HandleAbort(); + } + else if (length_ + numBytes > size_) + { + unsigned int newSize = thresholdSize_; + + while (newSize < length_ + numBytes) + { + newSize <<= 1; + + if (newSize > maximumSize_) + { + newSize = length_ + numBytes + initialSize_; + } + } + + #ifdef TEST + *logofs << "WriteBuffer: Growing buffer from " + << size_ << " to " << newSize << " bytes.\n" + << logofs_flush; + #endif + + unsigned int indexOffset = 0; + + if (index_ && *index_) + { + indexOffset = *index_ - buffer_; + } + + size_ = newSize; + + unsigned char *newBuffer = new unsigned char[size_]; + + if (newBuffer == NULL) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't allocate memory for " + << "X messages in context [C].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "X messages in context [C].\n"; + + HandleAbort(); + } + + #ifdef TEST + if (newSize >= maximumSize_) + { + *logofs << "WriteBuffer: WARNING! Buffer grown to reach " + << "size of " << newSize << " bytes.\n" + << logofs_flush; + } + #endif + + #ifdef VALGRIND + + memset(newBuffer, '\0', size_); + + #endif + + memcpy(newBuffer, buffer_, length_); + + #ifdef DEBUG + *logofs << "WriteBuffer: Going to delete the " + << "old buffer with new size " << size_ + << ".\n" << logofs_flush; + #endif + + delete [] buffer_; + + buffer_ = newBuffer; + + if (index_ && *index_) + { + *index_ = buffer_ + indexOffset; + } + } + + unsigned char *result = buffer_ + length_; + + length_ += numBytes; + + #ifdef DEBUG + *logofs << "WriteBuffer: Bytes in buffer are " + << length_ << " while size is " << size_ + << ".\n" << logofs_flush; + #endif + + return result; +} + +unsigned char *WriteBuffer::removeMessage(unsigned int numBytes) +{ + #ifdef TEST + *logofs << "WriteBuffer: Removing " << numBytes + << " bytes from buffer.\n" << logofs_flush; + #endif + + if (numBytes > length_) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't remove " + << numBytes << " bytes with only " << length_ + << " bytes in buffer.\n" << logofs_flush; + #endif + + cerr << "Error" << ": Buffer underflow handling " + << "write buffer in context [D].\n"; + + HandleAbort(); + } + + length_ -= numBytes; + + #ifdef TEST + *logofs << "WriteBuffer: Bytes in buffer are now " + << length_ << " while size is " + << size_ << ".\n" << logofs_flush; + #endif + + return (buffer_ + length_); +} + +unsigned char *WriteBuffer::addScratchMessage(unsigned int numBytes) +{ + if (numBytes > WRITE_BUFFER_OVERFLOW_SIZE) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't add a message of " + << numBytes << " bytes.\n" << logofs_flush; + + *logofs << "WriteBuffer: PANIC! Assuming error handling " + << "data in context [E].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't add a message of " + << numBytes << " bytes to write buffer.\n"; + + cerr << "Error" << ": Assuming error handling " + << "data in context [E].\n"; + + HandleAbort(); + } + else if (scratchBuffer_ != NULL) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't add a message of " + << numBytes << " bytes with " << scratchLength_ + << " bytes already in scratch buffer.\n" + << logofs_flush; + + *logofs << "WriteBuffer: PANIC! Assuming error handling " + << "data in context [F].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't add a message of " + << numBytes << " bytes with " << scratchLength_ + << " bytes already in scratch buffer.\n"; + + cerr << "Error" << ": Assuming error handling " + << "data in context [F].\n"; + + HandleAbort(); + } + + #ifdef DEBUG + *logofs << "WriteBuffer: Adding " << numBytes << " bytes " + << "to scratch buffer.\n" << logofs_flush; + #endif + + unsigned char *newBuffer = new unsigned char[numBytes]; + + if (newBuffer == NULL) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't allocate memory for " + << "X messages in context [G].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't allocate memory for " + << "X messages in context [G].\n"; + + HandleAbort(); + } + + #ifdef VALGRIND + + memset(newBuffer, '\0', numBytes); + + #endif + + scratchBuffer_ = newBuffer; + scratchOwner_ = 1; + scratchLength_ = numBytes; + + return newBuffer; +} + +unsigned char *WriteBuffer::addScratchMessage(unsigned char *newBuffer, unsigned int numBytes) +{ + if (numBytes > WRITE_BUFFER_OVERFLOW_SIZE) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't add a message of " + << numBytes << " bytes.\n" << logofs_flush; + + *logofs << "WriteBuffer: PANIC! Assuming error handling " + << "data in context [H].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't add a message of " + << numBytes << " bytes to write buffer.\n"; + + cerr << "Error" << ": Assuming error handling " + << "data in context [H].\n"; + + HandleAbort(); + } + else if (scratchBuffer_ != NULL) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't add a foreign " + << "message of " << numBytes << " bytes with " + << scratchLength_ << " bytes already in " + << "scratch buffer.\n" << logofs_flush; + + *logofs << "WriteBuffer: PANIC! Assuming error handling " + << "data in context [I].\n" << logofs_flush; + #endif + + cerr << "Error" << ": Can't add a foreign message of " + << numBytes << " bytes with " << scratchLength_ + << " bytes already in scratch buffer.\n"; + + cerr << "Error" << ": Assuming error handling " + << "data in context [I].\n"; + + HandleAbort(); + } + + #ifdef DEBUG + *logofs << "WriteBuffer: Adding " << numBytes << " bytes " + << "from a foreign message to scratch buffer.\n" + << logofs_flush; + #endif + + scratchBuffer_ = newBuffer; + scratchLength_ = numBytes; + scratchOwner_ = 0; + + return newBuffer; +} + +void WriteBuffer::removeScratchMessage() +{ + #ifdef TEST + + if (scratchLength_ == 0 || scratchBuffer_ == NULL) + { + #ifdef PANIC + *logofs << "WriteBuffer: PANIC! Can't remove non existent scratch message.\n" + << logofs_flush; + #endif + + cerr << "Error" << ": Can't remove non existent scratch message.\n"; + + HandleAbort(); + } + + *logofs << "WriteBuffer: Removing " << scratchLength_ + << " bytes from scratch buffer.\n" + << logofs_flush; + + #endif + + if (scratchOwner_ == 1) + { + #ifdef DEBUG + *logofs << "WriteBuffer: Going to delete " + << scratchLength_ << " bytes from the " + << "scratch buffer.\n" << logofs_flush; + #endif + + delete [] scratchBuffer_; + } + + scratchLength_ = 0; + scratchBuffer_ = NULL; + scratchOwner_ = 1; +} diff --git a/nxcomp/src/WriteBuffer.h b/nxcomp/src/WriteBuffer.h new file mode 100644 index 000000000..ce408e210 --- /dev/null +++ b/nxcomp/src/WriteBuffer.h @@ -0,0 +1,134 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef WriteBuffer_H +#define WriteBuffer_H + +#include "Misc.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#define WRITE_BUFFER_DEFAULT_SIZE 16384 + +// +// Adjust for the biggest reply that we could receive. +// This is likely to be a reply to a X_ListFonts where +// user has a large amount of installed fonts. +// + +#define WRITE_BUFFER_OVERFLOW_SIZE 4194304 + +class WriteBuffer +{ + public: + + WriteBuffer(); + + ~WriteBuffer(); + + void setSize(unsigned int initialSize, unsigned int thresholdSize, + unsigned int maximumSize); + + unsigned char *addMessage(unsigned int numBytes); + + unsigned char *removeMessage(unsigned int numBytes); + + unsigned char *addScratchMessage(unsigned int numBytes); + + // + // This form allows user to provide its own + // buffer as write buffer's scratch area. + // + + unsigned char *addScratchMessage(unsigned char *newBuffer, unsigned int numBytes); + + void removeScratchMessage(); + + void partialReset(); + + void fullReset(); + + unsigned char *getData() const + { + return buffer_; + } + + unsigned int getLength() const + { + return length_; + } + + unsigned int getAvailable() const + { + return (size_ - length_); + } + + unsigned char *getScratchData() const + { + return scratchBuffer_; + } + + unsigned int getScratchLength() const + { + return scratchLength_; + } + + unsigned int getTotalLength() const + { + return (length_ + scratchLength_); + } + + void registerPointer(unsigned char **pointer) + { + index_ = pointer; + } + + void unregisterPointer() + { + index_ = 0; + } + + private: + + unsigned int size_; + unsigned int length_; + + unsigned char *buffer_; + unsigned char **index_; + + unsigned int scratchLength_; + unsigned char *scratchBuffer_; + + int scratchOwner_; + + unsigned int initialSize_; + unsigned int thresholdSize_; + unsigned int maximumSize_; +}; + +#endif /* WriteBuffer_H */ diff --git a/nxcomp/src/XidCache.cpp b/nxcomp/src/XidCache.cpp new file mode 100644 index 000000000..ab6574cc9 --- /dev/null +++ b/nxcomp/src/XidCache.cpp @@ -0,0 +1,51 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Control.h" + +#include "XidCache.h" + +XidCache::XidCache() +{ + for (int i = 0; i < 256; i++) + { + base_[i] = new IntCache(8); + } + + slot_ = 0; + last_ = 0; +} + +XidCache::~XidCache() +{ + for (int i = 0; i < 256; i++) + { + delete base_[i]; + } +} diff --git a/nxcomp/src/XidCache.h b/nxcomp/src/XidCache.h new file mode 100644 index 000000000..8a09ef9b1 --- /dev/null +++ b/nxcomp/src/XidCache.h @@ -0,0 +1,49 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef XidCache_H +#define XidCache_H + +#include "IntCache.h" + +class XidCache +{ + friend class EncodeBuffer; + friend class DecodeBuffer; + + public: + + XidCache(); + ~XidCache(); + + private: + + IntCache *base_[256]; + + unsigned int slot_; + unsigned int last_; +}; + +#endif /* XidCache_H */ diff --git a/nxcomp/src/Z.cpp b/nxcomp/src/Z.cpp new file mode 100644 index 000000000..af3b380f2 --- /dev/null +++ b/nxcomp/src/Z.cpp @@ -0,0 +1,146 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Z.h" +#include "Misc.h" + +int ZCompress(z_stream *stream, unsigned char *dest, unsigned int *destLen, + const unsigned char *source, unsigned int sourceLen) +{ + // + // Deal with the possible overflow. + // + + if (stream -> total_out & 0x80000000) + { + #ifdef TEST + *logofs << "ZCompress: Reset stream counters with " + << "total in " << stream -> total_in + << " and total out " << stream -> total_out + << ".\n" << logofs_flush; + #endif + + stream -> total_in = 0; + stream -> total_out = 0; + } + + unsigned int saveOut = stream -> total_out; + + stream -> next_in = (Bytef *) source; + stream -> avail_in = sourceLen; + + // + // Check if the source is bigger than + // 64K on 16-bit machine. + // + + #ifdef MAXSEG_64K + + if ((uLong) stream -> avail_in != sourceLen) return Z_BUF_ERROR; + + #endif + + stream -> next_out = dest; + stream -> avail_out = *destLen; + + #ifdef MAXSEG_64K + + if ((uLong) stream -> avail_out != *destLen) return Z_BUF_ERROR; + + #endif + + int result = deflate(stream, Z_FINISH); + + if (result != Z_STREAM_END) + { + deflateReset(stream); + + return (result == Z_OK ? Z_BUF_ERROR : result); + } + + *destLen = stream -> total_out - saveOut; + + result = deflateReset(stream); + + return result; +} + +int ZDecompress(z_stream *stream, unsigned char *dest, unsigned int *destLen, + const unsigned char *source, unsigned int sourceLen) +{ + stream -> next_in = (Bytef *) source; + stream -> avail_in = sourceLen; + + // + // Deal with the possible overflow. + // + + if (stream -> total_out & 0x80000000) + { + #ifdef TEST + *logofs << "ZDecompress: Reset stream counters with " + << "total in " << stream -> total_in + << " and total out " << stream -> total_out + << ".\n" << logofs_flush; + #endif + + stream -> total_in = 0; + stream -> total_out = 0; + } + + unsigned int saveOut = stream -> total_out; + + if (stream -> avail_in != sourceLen) + { + return Z_BUF_ERROR; + } + + stream -> next_out = dest; + stream -> avail_out = *destLen; + + if (stream -> avail_out != *destLen) + { + return Z_BUF_ERROR; + } + + int result = inflate(stream, Z_FINISH); + + if (result != Z_STREAM_END) + { + inflateReset(stream); + + return (result == Z_OK ? Z_BUF_ERROR : result); + } + + *destLen = stream -> total_out - saveOut; + + result = inflateReset(stream); + + return result; +} diff --git a/nxcomp/src/Z.h b/nxcomp/src/Z.h new file mode 100644 index 000000000..3a6d684c2 --- /dev/null +++ b/nxcomp/src/Z.h @@ -0,0 +1,37 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder */ +/* Copyright (c) 2014-2016 Ulrich Sibiller */ +/* Copyright (c) 2014-2016 Mihai Moldovan */ +/* Copyright (c) 2011-2016 Mike Gabriel */ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMP, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE.nxcomp which comes in the */ +/* source distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#ifndef Z_H +#define Z_H + +#include + +int ZCompress(z_stream *stream, unsigned char *dest, unsigned int *destLen, + const unsigned char *source, unsigned int sourceLen); + +int ZDecompress(z_stream *stream, unsigned char *dest, unsigned int *destLen, + const unsigned char *source, unsigned int sourceLen); + +#endif /* Z_H */ diff --git a/nxproxy/src/Makefile.am b/nxproxy/src/Makefile.am index 5ec1f9401..60ace92ce 100644 --- a/nxproxy/src/Makefile.am +++ b/nxproxy/src/Makefile.am @@ -9,9 +9,9 @@ nxproxy_SOURCES = \ $(NULL) nxproxy_LDADD = \ - -L$(top_srcdir)/../nxcomp/ -lXcomp \ + -L$(top_srcdir)/../nxcomp/src/.libs -lXcomp \ $(NULL) AM_CPPFLAGS = \ - -I$(top_srcdir)/../nxcomp/ \ + -I$(top_srcdir)/../nxcomp/include/ \ $(NULL) -- cgit v1.2.3 From 430ae6eb6c4659f3bd907ceb84b7b7bcaf65071b Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 2 Aug 2017 18:19:19 -0400 Subject: nxproxy/src/Makefile.am: Actually define nxproxy_CFLAGS, so the various compiler warning flags get enabled at build time of nxproxy. --- nxproxy/src/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'nxproxy') diff --git a/nxproxy/src/Makefile.am b/nxproxy/src/Makefile.am index 60ace92ce..c09febcf6 100644 --- a/nxproxy/src/Makefile.am +++ b/nxproxy/src/Makefile.am @@ -12,6 +12,10 @@ nxproxy_LDADD = \ -L$(top_srcdir)/../nxcomp/src/.libs -lXcomp \ $(NULL) +nxproxy_CFLAGS = \ + $(BASE_CFLAGS) \ + $(NULL) + AM_CPPFLAGS = \ -I$(top_srcdir)/../nxcomp/include/ \ $(NULL) -- cgit v1.2.3 From 55c4e407043a627b9d7b96e2b7231612a9d9dab7 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 12 Jul 2017 12:53:10 +0200 Subject: nx*/configure.ac: Use newly introduced macro NX_DEFAULT_OPTIONS instead of NX_COMPILER_FLAGS. --- nxcomp/configure.ac | 2 +- nxcompshad/configure.ac | 2 +- nxproxy/configure.ac | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'nxproxy') diff --git a/nxcomp/configure.ac b/nxcomp/configure.ac index 19328677a..efe245162 100644 --- a/nxcomp/configure.ac +++ b/nxcomp/configure.ac @@ -41,7 +41,7 @@ PKG_CHECK_MODULES([Z], [zlib]) AC_LANG([C++]) NX_COMPILER_BRAND -NX_COMPILER_FLAGS +NX_DEFAULT_OPTIONS NX_BUILD_ON_CYGWIN32 NX_BUILD_ON_AMD64 diff --git a/nxcompshad/configure.ac b/nxcompshad/configure.ac index b3abf0efb..34b1c053c 100644 --- a/nxcompshad/configure.ac +++ b/nxcompshad/configure.ac @@ -42,7 +42,7 @@ m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR], AC_LANG([C++]) NX_COMPILER_BRAND -NX_COMPILER_FLAGS +NX_DEFAULT_OPTIONS AC_CONFIG_FILES([ Makefile diff --git a/nxproxy/configure.ac b/nxproxy/configure.ac index 0a23f13d7..9663fb4a8 100644 --- a/nxproxy/configure.ac +++ b/nxproxy/configure.ac @@ -21,7 +21,7 @@ AC_SUBST([PROXY_VERSION]) AC_LANG([C]) NX_COMPILER_BRAND -NX_COMPILER_FLAGS +NX_DEFAULT_OPTIONS AC_CONFIG_FILES([ Makefile -- cgit v1.2.3 From f4afa5a5619d965bed6024c95e430e4f042edffb Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 30 Aug 2017 19:33:55 +0200 Subject: release 3.5.99.9 --- ChangeLog | 380 ++++++++++++++++++++++- VERSION | 2 +- debian/changelog | 7 + nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 2 +- nx-libs.spec | 2 +- nxproxy/man/nxproxy.1 | 2 +- 6 files changed, 388 insertions(+), 7 deletions(-) (limited to 'nxproxy') diff --git a/ChangeLog b/ChangeLog index 2953b7a33..21e8126c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,385 @@ -2017-06-30 21:21:49 +0200 Mike Gabriel (891c059f5) +2017-08-30 19:33:55 +0200 Mike Gabriel (6cf56efe7) - * release 3.5.99.8 (HEAD -> 3.6.x) + * release 3.5.99.9 (HEAD -> 3.6.x) + +2017-08-30 19:29:58 +0200 Mike Gabriel (13264ea7f) + + * debian/rules: Strip static libraries before installing them into + the lib*.dev packages. + +2017-08-30 18:24:43 +0200 Mike Gabriel (15909676e) + + * Mesa.patches: Add 5001_nasty-typo-fixes.patch. Fix some nasty typos + in Mesa's code ending up in the nxagent binary. + +2017-08-30 18:18:39 +0200 Mike Gabriel (b9e5f03ab) + + * hw/nxagent/Window.c: Fix spelling error in debug message. + +2017-08-30 18:07:59 +0200 Mike Gabriel (bdd4fc212) + + * debian/control: Bump Standards-Version: to 4.0.1. No changes + needed. + +2017-08-30 16:57:57 +0200 Mike Gabriel (9cffffe5e) + + * debian/copyright: Update copyright attributions. + +2017-08-30 16:54:24 +0200 Mike Gabriel (5ecf04c92) + + * nx-X11/extras: Drop Mesa-6.4.1 related files. + +2017-08-28 08:33:58 +0200 Mihai Moldovan (709bce6cf) + + * Merge branch 'sunweaver-pr/drop-nxcompshad-cygwin-support' into + 3.6.x (origin/HEAD, origin/3.6.x) + +2017-07-17 12:49:47 +0200 Mike Gabriel (d9e2822f5) + + * nxcompshad: Drop Cygwin/Win32 support. Has been untested and unused + for a long time. + (gh-sunweaver/pr/drop-nxcompshad-cygwin-support, + pr/drop-nxcompshad-cygwin-support) + +2017-08-26 23:29:58 +0200 Mihai Moldovan (bc66da714) + + * Merge branch 'sunweaver-pr/nxagent-render-cleanup' into 3.6.x + +2017-07-17 11:15:55 +0200 Mike Gabriel (4eade297b) + + * nx-X11/programs/Xserver/Render.c: Re-introduce + nxagentGlyphsCleanup() from libNX_Xrender's formerly + removed XRenderGlyphsCleanup(). + (gh-sunweaver/pr/nxagent-render-cleanup, + pr/nxagent-render-cleanup) + +2017-08-25 19:18:17 +0200 Mike Gabriel (7290aea3b) + + * nx-X11/Makefile: Only run full CleanEnv code, if imake is installed + in the build-system. + +2017-08-25 16:34:30 +0200 Mike Gabriel (a32f1dfa1) + + * Makefile: Check for dir existence before attempting to remove it. + +2017-08-25 16:29:29 +0200 Mike Gabriel (71878f7a9) + + * Makefile: Use $(RM_DIR) rather then plain rmdir in clean-env + target. + +2017-08-25 12:44:49 +0200 Mihai Moldovan (ae0a2bfde) + + * Merge branch 'sunweaver-pr/libnx-x11-autoreconf' into 3.6.x + +2017-08-11 12:53:50 -0400 Mike Gabriel (3b7e5a42f) + + * debian/rules: Re-order configure options for the sake of more + beauty. (gh-sunweaver/pr/libnx-x11-autoreconf, + pr/libnx-x11-autoreconf) + +2017-08-11 12:51:52 -0400 Mike Gabriel (9a79e09a5) + + * debian/rules: Use tabs as first indentation level. + +2017-08-11 16:44:24 -0400 Mike Gabriel (9edd6e055) + + * debian/control: Add D (libnx-x11-6): libx11-data. + +2017-08-11 12:48:32 -0400 Mike Gabriel (11fa0b140) + + * nx-X11/programs/Xserver/Imakefile: White-space fix. + +2017-07-21 12:31:09 +0200 Mike Gabriel (c350873c7) + + * Convert nx-X11/lib/ build flow from imake to autotools. + +2017-07-17 12:53:26 +0200 Mike Gabriel (1472e7e37) + + * debian/rules: Add configure option --disable-silent-rules. + +2017-07-12 12:53:10 +0200 Mike Gabriel (55c4e4070) + + * nx*/configure.ac: Use newly introduced macro NX_DEFAULT_OPTIONS + instead of NX_COMPILER_FLAGS. + +2017-07-12 12:08:03 +0200 Mike Gabriel (ef08aadf5) + + * m4/nx-macros.m4: Add NX_STRICT_OPTION and NX_DEFAULT_OPTIONS macros + (borrowed from X.org's xorg-macros.m4). + +2017-08-11 09:29:17 -0400 Mike Gabriel (cbe2c0e44) + + * Merge branch 'uli42-pr/versionprop' into 3.6.x + +2017-08-10 00:50:27 +0200 Ulrich Sibiller (715fcfe6d) + + * Set NX_AGENT_VERSION property for root window + (uli42-pr/versionprop) + +2017-08-09 06:46:30 +0200 Mihai Moldovan (8235925a2) + + * nxcomp/configure.ac: fix copy-and-paste typo (nxcompshad.pc.) + +2017-08-09 06:44:49 +0200 Mihai Moldovan (8b88289ee) + + * nxcomp/configure.ac: we don't need to specify empty optional + parameters. + +2017-08-09 06:43:17 +0200 Mihai Moldovan (b1b919477) + + * Merge branch 'sunweaver-pr/find-libjpeg-without-pkgconfig' into + 3.6.x + +2017-08-03 10:22:55 -0400 Mike Gabriel (4fd038dba) + + * nxcomp/configure.ac: Don't rely on pkg-config alone when it comes + to testing for presence of libjpeg shared lib and header + files. (gh-sunweaver/pr/find-libjpeg-without-pkgconfig, + pr/find-libjpeg-without-pkgconfig) + +2017-08-02 18:19:19 -0400 Mike Gabriel (430ae6eb6) + + * nxproxy/src/Makefile.am: Actually define nxproxy_CFLAGS, so the + various compiler warning flags get enabled at build time + of nxproxy. + +2017-07-31 14:14:22 +0200 Mike Gabriel (dc8e52407) + + * Merge branch 'sunweaver-pr/fix-multi-trapez-requests' into 3.6.x + +2017-07-31 13:20:12 +0200 Oleksandr Shneyder (da43f047a) + + * Render.c: Improve situation for multiple trapezoid requests. + (gh-sunweaver/pr/fix-multi-trapez-requests, + sunweaver-pr/fix-multi-trapez-requests, + pr/fix-multi-trapez-requests) + +2017-07-26 10:38:46 +0200 Mihai Moldovan (7897834ce) + + * Merge branch 'sunweaver-pr/nxcomp-autoreconf' into 3.6.x + +2017-07-12 13:35:57 +0200 Mike Gabriel (4afc641fd) + + * nxcomp: Add __attribute__((noreturn)) to more functions where + appropriate. (gh-sunweaver/pr/nxcomp-autoreconf, + pr/nxcomp-autoreconf) + +2017-07-12 21:51:40 +0200 Mike Gabriel (b3a3382ad) + + * nxcomp/src/Loop.cpp: Don't mix using global proxyFD and a local + p(roxy)FD variable (in WaitForRemote() and + ConnectToRemote()). Rename local variable name. + +2017-07-12 21:49:28 +0200 Mike Gabriel (82c218288) + + * nxcomp/src/Loop.cpp: Don't use global variables as function + paramters in handleLogReopenInLoop(). + +2017-07-14 11:22:20 +0200 Mike Gabriel (e47995370) + + * nxcomp/src/Loop.cpp: Drop global variable diffTs, declare it in + every funtion where it is needed. + +2017-07-14 11:21:34 +0200 Mike Gabriel (04e09f277) + + * nxcomp/src/Transport.cpp: Don't redeclare local variable if it can + be reused. + +2017-07-12 21:46:09 +0200 Mike Gabriel (54e7b9aa2) + + * nxcomp/src/Loop.cpp: Don't reuse global variable names as function + parameters in SetupDisplaySocket(). + +2017-07-12 21:42:46 +0200 Mike Gabriel (ca7db4fcb) + + * nxcomp/src/Loop.cpp: Rename local variable 'handler' to + 'signalHandler'. + +2017-07-12 21:41:21 +0200 Mike Gabriel (1e15760a3) + + * nxcomp/src/Loop.cpp: Drop duplicate prototypes (which already exist + in Misc.h). + +2017-07-12 21:39:32 +0200 Mike Gabriel (1894e04df) + + * nxcomp/src/Proxy.cpp: Fix index usage of nested loops. + +2017-07-12 21:36:11 +0200 Mike Gabriel (4c3872279) + + * nxcomp/src/Loop.cpp: Avoid duplicate usage of proxyFD (global + variable) and *proxyFD (function parameter). + +2017-07-12 21:32:14 +0200 Mike Gabriel (5a7b589bb) + + * nxcomp: Trivially fix local variables shadowing variables of same + name from higher scope. + +2017-07-10 13:42:32 +0200 Mike Gabriel (93c4cea66) + + * debian/rules: Drop override_dh_clean target. Not required anymore, + as configure files get removed correctly now. + +2017-07-24 12:32:18 +0200 Mike Gabriel (9c8e3f139) + + * nxcomp/configure.ac,m4/nx-macros.m4,nxcomp/src/Socket.h: Use + AC_CHECK_TYPES to detect if type 'in_addr_t' is available. + +2017-07-14 11:43:05 +0200 Mike Gabriel (9fa0a6b95) + + * nxcomp/configure.ac: Re-add previously available configure options + --with-valgrind and --with-info as renamed options + --enable-valgrind and --enable-debug. + +2017-06-30 20:13:51 +0200 Mike Gabriel (f76c82403) + + * nxcomp: Switch to autoreconf. + +2017-07-25 09:19:44 +0200 Mike Gabriel (9193d11ee) + + * Merge branch 'uli42-pr/cmdline' into 3.6.x + +2017-07-24 23:45:48 +0200 Ulrich Sibiller (3f7b30019) + + * treat options parameter as option string if it starts with nx/nx + (uli42-pr/cmdline) + +2017-07-24 23:45:24 +0200 Ulrich Sibiller (36e583cf5) + + * rename nxagentOptionFile to nxagentOptionsFilename + +2017-07-11 21:29:59 +0200 Ulrich Sibiller (b007b542d) + + * pass filename as parameter to nxagentProcessOptionsFile() + +2017-07-17 09:50:26 +0200 Mike Gabriel (4ccb7eda5) + + * Merge branch 'uli42-pr/fix_keystroke_files' into 3.6.x + +2017-07-12 20:01:44 +0200 Ulrich Sibiller (79001dd8a) + + * Improve keystroke file handling (uli42-pr/fix_keystroke_files) + +2017-07-14 10:42:15 +0200 Mike Gabriel (ccd7c6962) + + * debian/control: Add B-D: libtool (required for Debian jessie, + Ubuntu trusty and Ubuntu xenial). + +2017-07-14 10:38:47 +0200 Mike Gabriel (ad1d45349) + + * debian/copyright: White-space cleanup. + +2017-07-14 10:38:30 +0200 Mike Gabriel (96167fcdb) + + * debian/control: Process with wrap-and-sort -s. + +2017-07-14 01:25:20 +0200 Mihai Moldovan (5796ac644) + + * Merge branch 'sunweaver-pr/nxcompshad-autoreconf' into 3.6.x + +2017-07-12 22:34:11 +0200 Mike Gabriel (59e829f36) + + * nxcompshad: Rewrite Logger class methods to properly take advantage + of the 'gnu_printf' format attribute. + (gh-sunweaver/pr/nxcompshad-autoreconf, + pr/nxcompshad-autoreconf) + +2017-07-12 22:26:38 +0200 Mike Gabriel (8f5ce18d4) + + * nxcompshad: Prototype for NXShadowResetOptions() missing. Export it + as public symbol via Shadow.h." + +2017-07-12 22:26:05 +0200 Mike Gabriel (36fe0330e) + + * nxcompshad/src/Shadow.cpp: Drop duplicate prototype for + NXShadowRemoveAllUpdaters(). Already in Shadow.h. + +2017-07-12 22:23:07 +0200 Mike Gabriel (d77897462) + + * nxcompshad/src/Core.cpp: Don't redeclare (and shadow) curLine. Use + curWorkLine instead. + +2017-06-30 14:49:03 +0200 Mike Gabriel (dba850070) + + * nxcompshad/src/Regions.h: Avoid warning: ‘typedef’ was ignored in + this declaration. Drop typedef declaration from _XRegion + struct. + +2017-04-25 15:27:17 +0200 Mike Gabriel (76b486768) + + * nxcompshad: Switch to autoreconf. + +2017-07-13 11:38:17 +0200 Mike Gabriel (622360ea2) + + * debian/control: Add B-D: automake (required for Debian jessie, + Ubuntu trusty and Ubuntu xenial). + +2017-07-13 08:52:08 +0200 Mike Gabriel (107fba32e) + + * nxproxy/configure.ac: Have AC_LANG before NX_COMPILER_BRAND. Thanks + to Ionic for spotting this same flaw in nxcompshad. + +2017-07-12 23:56:42 +0200 Mihai Moldovan (06bf2a492) + + * Merge branch 'sunweaver-pr/nxproxy-autoreconf' into 3.6.x + +2017-07-10 11:47:02 +0200 Mike Gabriel (397d3ac06) + + * debian/rules: Drop redundant --with-symbols configure option, '-g' + already gets added by debhelper. + (gh-sunweaver/pr/nxproxy-autoreconf, + pr/nxproxy-autoreconf) + +2017-04-26 13:26:47 +0200 Mike Gabriel (41ea54b02) + + * nxproxy: Switch to autoreconf. + +2017-06-30 13:58:47 +0200 Mike Gabriel (322e39b79) + + * m4/nx-macros.m4: Add autotools macros derived from X.org and + nxcomp* configure.in files. + +2017-07-12 12:43:53 +0200 Mike Gabriel (e17207f18) + + * make-changelog.sh: Drop obviously not needed '--since 1970' option + from 'git log' call. + +2017-07-12 12:09:45 +0200 Mike Gabriel (ba02470a5) + + * Merge branch 'sunweaver-pr/report-window-ids' into 3.6.x + +2017-07-04 23:57:34 +0200 Mike Gabriel (84a403e27) + + * Report Xlib-side window IDs to session.log in machine readable + form. This feature can be enabled by the cmdline options + -reportwids and -reportprivatewids. + (gh-sunweaver/pr/report-window-ids, + sunweaver-pr/report-window-ids, pr/report-window-ids) + +2017-07-04 23:32:04 +0200 Mike Gabriel (000a869b3) + + * nxagent man page: Fix layout near -nxrealwindowprop option. + +2017-06-30 23:23:16 +0200 Mike Gabriel (a517c5ab6) + + * Mesa.patches: Disable + 4001_Fix-non-working-GLX-in-64bit-Xorg-7.0.patch. It + patches a file, we don't build and that we remove in + roll-tarball.sh. + +2017-06-30 23:22:22 +0200 Mike Gabriel (7838207b7) + + * roll-tarballs.sh: Remove even more files from nx-X11/extras/Mesa/. + This roll-tarball.sh version has been used for generating + the 3.5.99.8 tarball. + +2017-06-30 21:21:49 +0200 Mike Gabriel (3b15804ce) + + * release 3.5.99.8 (tag: 3.5.99.8, origin/release-builds/3.6.x, + release-builds/3.6.x) 2017-06-30 20:59:27 +0200 Mihai Moldovan (4c7641a1f) * Merge branch 'sunweaver-pr/mese-quilt-without-quilt' into 3.6.x - (origin/HEAD, origin/3.6.x) 2017-06-30 20:24:28 +0200 Mike Gabriel (79fcce3ee) diff --git a/VERSION b/VERSION index 5e5089265..8560aadcd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.99.8 +3.5.99.9 diff --git a/debian/changelog b/debian/changelog index 77c9eedc3..d92eb702d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +nx-libs (2:3.5.99.9-0.1) unstable; urgency=medium + + * Upstream-provided Debian package for nx-libs. + See upstream ChangeLog for recent changes. + + -- Mike Gabriel Wed, 30 Aug 2017 19:32:14 +0200 + nx-libs (2:3.5.99.8-0.1) unstable; urgency=medium * Upstream-provided Debian package for nx-libs. diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index ef2d387c3..cf73e84b9 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -24,7 +24,7 @@ .\" other dealings in this Software without prior written authorization .\" from The Open Group. .ds q \N'34' -.TH nxagent 1 "June 2017" "Version 3.5.99.8" "NX Agent (Xserver)" +.TH nxagent 1 "Aug 2017" "Version 3.5.99.9" "NX Agent (Xserver)" .SH NAME nxagent \- nested Xserver optimized for remote computing .SH SYNOPSIS diff --git a/nx-libs.spec b/nx-libs.spec index ce175059d..7ccd03b39 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -1,7 +1,7 @@ %global _hardened_build 1 Name: nx-libs -Version: 3.5.99.8 +Version: 3.5.99.9 Release: 0.0build1%{?dist} Summary: NX X11 protocol compression libraries diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index 30c6e983b..e6c152025 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH nxproxy 1 "June 2017" "Version 3.5.99.8" "NX Proxy" +.TH nxproxy 1 "Aug 2017" "Version 3.5.99.9" "NX Proxy" .SH NAME nxproxy \- NX Proxy Tool .SH SYNOPSIS -- cgit v1.2.3 From 6557c0043da97efcade165265f74f8e8901cd412 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 15 Sep 2017 14:57:56 +0200 Subject: release 3.5.99.10 --- ChangeLog | 65 ++++++++++++++++++++++-- VERSION | 2 +- debian/changelog | 7 +++ nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 2 +- nx-libs.spec | 2 +- nxproxy/man/nxproxy.1 | 2 +- 6 files changed, 71 insertions(+), 9 deletions(-) (limited to 'nxproxy') diff --git a/ChangeLog b/ChangeLog index 21e8126c0..75b92d380 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,62 @@ -2017-08-30 19:33:55 +0200 Mike Gabriel (6cf56efe7) +2017-09-15 14:57:56 +0200 Mike Gabriel (e6998288d) - * release 3.5.99.9 (HEAD -> 3.6.x) + * release 3.5.99.10 (HEAD -> 3.6.x) + +2017-09-14 07:45:45 +0200 Mihai Moldovan (4405c6a6b) + + * Merge branch + 'sunweaver-pr/assure-that-Mesa-includes-headers-from-libNX_X11' + into 3.6.x (origin/HEAD, origin/3.6.x) + +2017-09-13 13:06:34 +0200 Mike Gabriel (f9c23b51e) + + * Assure that headers from libNX_X11 are always included from + $(INCDIR)/nx-X11/. + (gh-sunweaver/pr/assure-that-Mesa-includes-headers-from-libNX_X11, + pr/assure-that-Mesa-includes-headers-from-libNX_X11) + +2017-09-13 11:50:40 +0200 Mihai Moldovan (0815fb06f) + + * nx-X11/programs/Xserver/hw/nxagent/Render.c: use macros obtaining + values from _XPrivDisplay instead of the other Display + structure directly. + +2017-09-06 10:25:19 +0200 Mihai Moldovan (81569ad6b) + + * Merge branch 'sunweaver-pr/sun-path-is-104-on-debian-kfreebsd' into + 3.6.x + +2017-08-31 18:17:31 +0200 Mike Gabriel (96ba6190d) + + * nxcomp/src/{Loop,Proxy}.cpp: On Debian/kFreeBSD (and other *BSD + variants) the sockaddr_un.sun_path property is 104 chars + long, not 108. Hard-coding Unix domain sockets in nxcomp + the string length 104. + (gh-sunweaver/pr/sun-path-is-104-on-debian-kfreebsd, + pr/sun-path-is-104-on-debian-kfreebsd) + +2017-08-30 22:36:05 +0200 Mike Gabriel (d3f97cea2) + + * Mesa.patches: Shrink over-zealous 5001 patch. Only patch files that + we use during build. + +2017-08-30 22:07:46 +0200 Mike Gabriel (055f52b03) + + * roll-tarball.sh: Drop m4/nx-xtrans.m4 from nx-libs-lite tarball. + +2017-08-30 22:07:28 +0200 Mike Gabriel (1047cda6d) + + * roll-tarball.sh: Some more .gitignore files to remove. + +2017-08-30 22:07:02 +0200 Mike Gabriel (bbf69e0a6) + + * roll-tarball.sh: Use -f with rm everywhere, also when tweaking the + Mesa/ dir. + +2017-08-30 19:33:55 +0200 Mike Gabriel (f4afa5a56) + + * release 3.5.99.9 (tag: 3.5.99.9, origin/release-builds/3.6.x, + release-builds/3.6.x) 2017-08-30 19:29:58 +0200 Mike Gabriel (13264ea7f) @@ -32,7 +88,7 @@ 2017-08-28 08:33:58 +0200 Mihai Moldovan (709bce6cf) * Merge branch 'sunweaver-pr/drop-nxcompshad-cygwin-support' into - 3.6.x (origin/HEAD, origin/3.6.x) + 3.6.x 2017-07-17 12:49:47 +0200 Mike Gabriel (d9e2822f5) @@ -374,8 +430,7 @@ 2017-06-30 21:21:49 +0200 Mike Gabriel (3b15804ce) - * release 3.5.99.8 (tag: 3.5.99.8, origin/release-builds/3.6.x, - release-builds/3.6.x) + * release 3.5.99.8 (tag: 3.5.99.8) 2017-06-30 20:59:27 +0200 Mihai Moldovan (4c7641a1f) diff --git a/VERSION b/VERSION index 8560aadcd..479da61ea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.99.9 +3.5.99.10 diff --git a/debian/changelog b/debian/changelog index d92eb702d..ea0c2db2c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +nx-libs (2:3.5.99.10-0.1) unstable; urgency=medium + + * Upstream-provided Debian package for nx-libs. + See upstream ChangeLog for recent changes. + + -- Mike Gabriel Fri, 15 Sep 2017 14:57:20 +0200 + nx-libs (2:3.5.99.9-0.1) unstable; urgency=medium * Upstream-provided Debian package for nx-libs. diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index cf73e84b9..85dd412b3 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -24,7 +24,7 @@ .\" other dealings in this Software without prior written authorization .\" from The Open Group. .ds q \N'34' -.TH nxagent 1 "Aug 2017" "Version 3.5.99.9" "NX Agent (Xserver)" +.TH nxagent 1 "Sep 2017" "Version 3.5.99.10" "NX Agent (Xserver)" .SH NAME nxagent \- nested Xserver optimized for remote computing .SH SYNOPSIS diff --git a/nx-libs.spec b/nx-libs.spec index 7ccd03b39..de1f0092d 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -1,7 +1,7 @@ %global _hardened_build 1 Name: nx-libs -Version: 3.5.99.9 +Version: 3.5.99.10 Release: 0.0build1%{?dist} Summary: NX X11 protocol compression libraries diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index e6c152025..e48bd9d64 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH nxproxy 1 "Aug 2017" "Version 3.5.99.9" "NX Proxy" +.TH nxproxy 1 "Sep 2017" "Version 3.5.99.10" "NX Proxy" .SH NAME nxproxy \- NX Proxy Tool .SH SYNOPSIS -- cgit v1.2.3 From 03ebe6f258ef29fc2bb6dc10fb9b829213dfd780 Mon Sep 17 00:00:00 2001 From: Simon Matter Date: Fri, 29 Sep 2017 12:31:01 +0200 Subject: nxproxy/src/Main.c: Silence compiler warning. Fixes ArcticaProject/nx-libs#506. --- nxproxy/src/Main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nxproxy') diff --git a/nxproxy/src/Main.c b/nxproxy/src/Main.c index d9fb1ef4f..dc4e0fd68 100644 --- a/nxproxy/src/Main.c +++ b/nxproxy/src/Main.c @@ -41,6 +41,7 @@ int main(int argc, const char **argv) char *options = NULL; + unsigned long int nx_commfd; char *nx_commfd_str = NULL; options = getenv("NX_DISPLAY"); @@ -48,7 +49,7 @@ int main(int argc, const char **argv) if ((nx_commfd_str = getenv("NX_COMMFD")) != NULL) { errno = 0; - unsigned long int nx_commfd = strtoul(nx_commfd_str, NULL, 10); + nx_commfd = strtoul(nx_commfd_str, NULL, 10); if ((errno) && (0 == nx_commfd)) { -- cgit v1.2.3 From 27c14b4eb3e42e1da2a3954393507b1ea4614462 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 9 Oct 2017 12:52:01 +0200 Subject: .gitignore: Improve all .gitignore files, adapt to autotools build-flow and its build cruft. --- .gitignore | 7 +++++++ nx-X11/lib/.gitignore | 11 +++++++++++ nx-X11/lib/src/.gitignore | 4 +++- nxcomp/.gitignore | 2 -- nxcompshad/.gitignore | 2 -- nxproxy/.gitignore | 3 +-- 6 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 nx-X11/lib/.gitignore (limited to 'nxproxy') diff --git a/.gitignore b/.gitignore index 3012b55cf..e86e4b5f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.o +*.lo +*.la *.so.* *.so *.a @@ -10,3 +12,8 @@ configure depend.status *~ [#]* +stamp-h* +.libs +.deps +bin/nxagent +bin/nxproxy diff --git a/nx-X11/lib/.gitignore b/nx-X11/lib/.gitignore new file mode 100644 index 000000000..dec1c61a6 --- /dev/null +++ b/nx-X11/lib/.gitignore @@ -0,0 +1,11 @@ +aclocal.m4 +config.log +config.status +configure +libtool +Makefile +Makefile.in +nx-x11.pc +m4/libtool.m4 +m4/lt*.m4 +build-aux/ diff --git a/nx-X11/lib/src/.gitignore b/nx-X11/lib/src/.gitignore index 8215e21de..f78453e57 100644 --- a/nx-X11/lib/src/.gitignore +++ b/nx-X11/lib/src/.gitignore @@ -1 +1,3 @@ -ks_tables.h \ No newline at end of file +ks_tables.h +config.h* +util/makekeys diff --git a/nxcomp/.gitignore b/nxcomp/.gitignore index a148dfa93..019202342 100644 --- a/nxcomp/.gitignore +++ b/nxcomp/.gitignore @@ -17,7 +17,5 @@ m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 nxcomp.pc -src/.deps/ src/Makefile src/Makefile.in -stamp-h1 diff --git a/nxcompshad/.gitignore b/nxcompshad/.gitignore index 1eefcb7bf..5eafb1add 100644 --- a/nxcompshad/.gitignore +++ b/nxcompshad/.gitignore @@ -17,7 +17,5 @@ m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 nxcompshad.pc -src/.deps/ src/Makefile src/Makefile.in -stamp-h1 diff --git a/nxproxy/.gitignore b/nxproxy/.gitignore index 6b771262b..35c4c4dfd 100644 --- a/nxproxy/.gitignore +++ b/nxproxy/.gitignore @@ -16,7 +16,6 @@ m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 -src/.deps/ src/Makefile src/Makefile.in -stamp-h1 +src/nxproxy -- cgit v1.2.3 From 1f717c6fdfa478f1c422bff51bc8574360dbe127 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Fri, 29 Sep 2017 17:19:06 +0200 Subject: nx{comp{,shad},proxy}: add configure flag --enable-cxx11 to enable and setup optional C++11 support. Use AX_CXX_COMPILE_STDCXX(_11) from autotools archive. Note: should only be used in tandem. Make sure that each component either uses the C++11 ABI or none uses it. Mixing and matching libraries and binaries with different C++ ABIs might lead to weird errors. --- m4/ax_cxx_compile_stdcxx.m4 | 982 ++++++++++++++++++++++++++++++ m4/ax_cxx_compile_stdcxx_11.m4 | 39 ++ nxcomp/configure.ac | 6 + nxcomp/m4/ax_cxx_compile_stdcxx.m4 | 1 + nxcomp/m4/ax_cxx_compile_stdcxx_11.m4 | 1 + nxcompshad/configure.ac | 6 + nxcompshad/m4/ax_cxx_compile_stdcxx.m4 | 1 + nxcompshad/m4/ax_cxx_compile_stdcxx_11.m4 | 1 + nxproxy/configure.ac | 6 + nxproxy/m4/ax_cxx_compile_stdcxx.m4 | 1 + nxproxy/m4/ax_cxx_compile_stdcxx_11.m4 | 1 + 11 files changed, 1045 insertions(+) create mode 100644 m4/ax_cxx_compile_stdcxx.m4 create mode 100644 m4/ax_cxx_compile_stdcxx_11.m4 create mode 120000 nxcomp/m4/ax_cxx_compile_stdcxx.m4 create mode 120000 nxcomp/m4/ax_cxx_compile_stdcxx_11.m4 create mode 120000 nxcompshad/m4/ax_cxx_compile_stdcxx.m4 create mode 120000 nxcompshad/m4/ax_cxx_compile_stdcxx_11.m4 create mode 120000 nxproxy/m4/ax_cxx_compile_stdcxx.m4 create mode 120000 nxproxy/m4/ax_cxx_compile_stdcxx_11.m4 (limited to 'nxproxy') diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 000000000..5032bba80 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,982 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016 Krzesimir Nowak +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AX_REQUIRE_DEFINED([AC_MSG_WARN]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) + m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])]) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus <= 201402L + +#error "This is not a C++17 compiler" + +#else + +#if defined(__clang__) + #define REALLY_CLANG +#else + #if defined(__GNUC__) + #define REALLY_GCC + #endif +#endif + +#include +#include +#include + +namespace cxx17 +{ + +#if !defined(REALLY_CLANG) + namespace test_constexpr_lambdas + { + + // TODO: test it with clang++ from git + + constexpr int foo = [](){return 42;}(); + + } +#endif // !defined(REALLY_CLANG) + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + +#if !defined(REALLY_CLANG) + namespace test_template_argument_deduction_for_class_templates + { + + // TODO: test it with clang++ from git + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } +#endif // !defined(REALLY_CLANG) + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + +#if !defined(REALLY_CLANG) + namespace test_structured_bindings + { + + // TODO: test it with clang++ from git + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } +#endif // !defined(REALLY_CLANG) + +#if !defined(REALLY_CLANG) + namespace test_exception_spec_type_system + { + + // TODO: test it with clang++ from git + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } +#endif // !defined(REALLY_CLANG) + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus <= 201402L + +]]) diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4 new file mode 100644 index 000000000..1733fd85f --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1,39 @@ +# ============================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +# ============================================================================= +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++11 +# standard; if necessary, add switches to CXX and CXXCPP to enable +# support. +# +# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX +# macro with the version set to C++11. The two optional arguments are +# forwarded literally as the second and third argument respectively. +# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for +# more information. If you want to use this macro, you also need to +# download the ax_cxx_compile_stdcxx.m4 file. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 18 + +AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])]) diff --git a/nxcomp/configure.ac b/nxcomp/configure.ac index 0b30915c2..89081cbb6 100644 --- a/nxcomp/configure.ac +++ b/nxcomp/configure.ac @@ -66,6 +66,12 @@ fi # If in_addr_t is not defined use unsigned int. AC_CHECK_TYPES([in_addr_t], [], [], [[#include ]]) +AC_ARG_ENABLE([cxx11], + [AS_HELP_STRING([--enable-cxx11], + [enable optional features requiring C++11 support (disabled by default)])], + [AS_IF([test x$enableval = xyes], + [AX_CXX_COMPILE_STDCXX_11([], [mandatory])])]) + AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [enable to get info session log output (disabled by default)])], diff --git a/nxcomp/m4/ax_cxx_compile_stdcxx.m4 b/nxcomp/m4/ax_cxx_compile_stdcxx.m4 new file mode 120000 index 000000000..28ebfd1a6 --- /dev/null +++ b/nxcomp/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1 @@ +../../m4/ax_cxx_compile_stdcxx.m4 \ No newline at end of file diff --git a/nxcomp/m4/ax_cxx_compile_stdcxx_11.m4 b/nxcomp/m4/ax_cxx_compile_stdcxx_11.m4 new file mode 120000 index 000000000..5fbe8790d --- /dev/null +++ b/nxcomp/m4/ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1 @@ +../../m4/ax_cxx_compile_stdcxx_11.m4 \ No newline at end of file diff --git a/nxcompshad/configure.ac b/nxcompshad/configure.ac index 34b1c053c..966add584 100644 --- a/nxcompshad/configure.ac +++ b/nxcompshad/configure.ac @@ -44,6 +44,12 @@ AC_LANG([C++]) NX_COMPILER_BRAND NX_DEFAULT_OPTIONS +AC_ARG_ENABLE([cxx11], + [AS_HELP_STRING([--enable-cxx11], + [enable optional features requiring C++11 support (disabled by default)])], + [AS_IF([test x$enableval = xyes], + [AX_CXX_COMPILE_STDCXX_11([], [mandatory])])]) + AC_CONFIG_FILES([ Makefile src/Makefile diff --git a/nxcompshad/m4/ax_cxx_compile_stdcxx.m4 b/nxcompshad/m4/ax_cxx_compile_stdcxx.m4 new file mode 120000 index 000000000..28ebfd1a6 --- /dev/null +++ b/nxcompshad/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1 @@ +../../m4/ax_cxx_compile_stdcxx.m4 \ No newline at end of file diff --git a/nxcompshad/m4/ax_cxx_compile_stdcxx_11.m4 b/nxcompshad/m4/ax_cxx_compile_stdcxx_11.m4 new file mode 120000 index 000000000..5fbe8790d --- /dev/null +++ b/nxcompshad/m4/ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1 @@ +../../m4/ax_cxx_compile_stdcxx_11.m4 \ No newline at end of file diff --git a/nxproxy/configure.ac b/nxproxy/configure.ac index 9663fb4a8..cc8e898fc 100644 --- a/nxproxy/configure.ac +++ b/nxproxy/configure.ac @@ -23,6 +23,12 @@ AC_LANG([C]) NX_COMPILER_BRAND NX_DEFAULT_OPTIONS +AC_ARG_ENABLE([cxx11], + [AS_HELP_STRING([--enable-cxx11], + [enable optional features requiring C++11 support (disabled by default)])], + [AS_IF([test x$enableval = xyes], + [AX_CXX_COMPILE_STDCXX_11([], [mandatory])])]) + AC_CONFIG_FILES([ Makefile man/Makefile diff --git a/nxproxy/m4/ax_cxx_compile_stdcxx.m4 b/nxproxy/m4/ax_cxx_compile_stdcxx.m4 new file mode 120000 index 000000000..28ebfd1a6 --- /dev/null +++ b/nxproxy/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1 @@ +../../m4/ax_cxx_compile_stdcxx.m4 \ No newline at end of file diff --git a/nxproxy/m4/ax_cxx_compile_stdcxx_11.m4 b/nxproxy/m4/ax_cxx_compile_stdcxx_11.m4 new file mode 120000 index 000000000..5fbe8790d --- /dev/null +++ b/nxproxy/m4/ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1 @@ +../../m4/ax_cxx_compile_stdcxx_11.m4 \ No newline at end of file -- cgit v1.2.3 From 1c6c9c04b56656d9ab3f486738a4950e71f29b74 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Fri, 27 Oct 2017 14:14:24 +0200 Subject: nxproxy: use ax_pthread.m4. Works around libtool bug related to using both -nostdlib and -pthread (with the former dropping latter usage.) --- nxproxy/configure.ac | 11 +++++++++++ nxproxy/m4/ax_pthread.m4 | 1 + nxproxy/src/Makefile.am | 6 ++++++ 3 files changed, 18 insertions(+) create mode 120000 nxproxy/m4/ax_pthread.m4 (limited to 'nxproxy') diff --git a/nxproxy/configure.ac b/nxproxy/configure.ac index cc8e898fc..b381862c0 100644 --- a/nxproxy/configure.ac +++ b/nxproxy/configure.ac @@ -23,6 +23,17 @@ AC_LANG([C]) NX_COMPILER_BRAND NX_DEFAULT_OPTIONS +dnl This is a workaround for a nasty libtool bug. +dnl We actually compile libXcomp with pthread support, but libtool uses g++ ... -nostdlib ... -pthread +dnl on Linux. -nostdlib causes -pthread to be ignored. +dnl According to GCC upstream, this is not a bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +dnl GCC upstream insists that libtool needs to handle -pthread in a special way when using -nostdlib. +dnl A patch has been submitted to the libtool project: http://lists.gnu.org/archive/html/libtool-patches/2013-11/msg00015.html +dnl but never applied to the code base. Boo. +dnl We will work around this bug by using AX_PTHREAD and linking with pthread support in all consumers of +dnl libXcomp for now. +AX_PTHREAD([], AC_MSG_ERROR([no POSIX threads support detected])) + AC_ARG_ENABLE([cxx11], [AS_HELP_STRING([--enable-cxx11], [enable optional features requiring C++11 support (disabled by default)])], diff --git a/nxproxy/m4/ax_pthread.m4 b/nxproxy/m4/ax_pthread.m4 new file mode 120000 index 000000000..156af3df3 --- /dev/null +++ b/nxproxy/m4/ax_pthread.m4 @@ -0,0 +1 @@ +../../m4/ax_pthread.m4 \ No newline at end of file diff --git a/nxproxy/src/Makefile.am b/nxproxy/src/Makefile.am index c09febcf6..7e55900d3 100644 --- a/nxproxy/src/Makefile.am +++ b/nxproxy/src/Makefile.am @@ -9,11 +9,17 @@ nxproxy_SOURCES = \ $(NULL) nxproxy_LDADD = \ + @PTHREAD_LIBS@ \ -L$(top_srcdir)/../nxcomp/src/.libs -lXcomp \ $(NULL) +nxproxy_LDFLAGS = \ + $(PTHREAD_LDFLAGS) \ + $(NULL) + nxproxy_CFLAGS = \ $(BASE_CFLAGS) \ + $(PTHREAD_CFLAGS) \ $(NULL) AM_CPPFLAGS = \ -- cgit v1.2.3 From 78661a19ad9e32cc8a37de6f35d55755dfbc19a3 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 22 Nov 2017 11:08:31 +0100 Subject: nxproxy.1 man page: Update explanation for NX_TEMP env variable. --- nxproxy/man/nxproxy.1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'nxproxy') diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index e48bd9d64..ecfe3b0d6 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -327,8 +327,7 @@ user's NX directory is created here. .TP 8 .B NX_TEMP -The directory where the X11 Unix Domain Sockets and all temporary files -are to be created. +The directory where all temporary files are to be created. .TP 8 .B NX_CLIENT -- cgit v1.2.3 From ca43087812afa2817ddc086591b60d593aacc954 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 21 Nov 2017 13:28:17 +0100 Subject: Drop bin wrappers for nxagent and nxproxy, directly install nxproxy and nxagent to BINDIR. Fixes ArcticaProject/nx-libs#546. --- Makefile | 43 +++++++++++++------------------------------ bin/nxagent.in | 24 ------------------------ bin/nxproxy.in | 24 ------------------------ debian/nxagent.install | 3 ++- debian/nxproxy.install | 1 - nx-X11/config/cf/X11.tmpl | 2 +- nx-libs.spec | 7 +------ nxproxy/src/Makefile.am | 2 +- 8 files changed, 18 insertions(+), 88 deletions(-) delete mode 100644 bin/nxagent.in delete mode 100644 bin/nxproxy.in (limited to 'nxproxy') diff --git a/Makefile b/Makefile index 27a6f966c..204a7310a 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ SHLIBDIR ?= $(LIBDIR) NXLIBDIR ?= $(SHLIBDIR)/nx USRLIBDIR ?= $(NXLIBDIR)/X11 INCLUDEDIR ?= $(PREFIX)/include -CONFIGURE ?= ./configure --prefix=$(DESTDIR)$(PREFIX) --libexecdir=$(NXLIBDIR)/bin +CONFIGURE ?= ./configure --prefix=$(DESTDIR)$(PREFIX) # use Xfont2 if available in the build env FONT_DEFINES ?= $(shell pkg-config --modversion xfont2 1>/dev/null 2>/dev/null && echo "-DHAS_XFONT2") @@ -75,8 +75,6 @@ NX_XTRANS_HEADERS = \ rm -Rf nx-X11/extras/Mesa/.pc/; \ rm -f nx-X11/config/cf/nxversion.def; \ rm -f nx-X11/config/cf/date.def; \ - rm -f bin/nxagent; \ - rm -f bin/nxproxy; \ ${MAKE} clean-env; \ fi @@ -168,30 +166,24 @@ install-lite: # install nxcomp library $(MAKE) -C nxcomp install - # install nxproxy wrapper script - $(INSTALL_DIR) $(DESTDIR)$(BINDIR) - sed -e 's|@@NXLIBDIR@@|$(NXLIBDIR)|g' bin/nxproxy.in > bin/nxproxy - $(INSTALL_PROGRAM) bin/nxproxy $(DESTDIR)$(BINDIR) - # install the nxproxy executable and its man page $(MAKE) -C nxproxy install install-full: - # install nxagent wrapper script - $(INSTALL_DIR) $(DESTDIR)$(BINDIR) - sed -e 's|@@NXLIBDIR@@|$(NXLIBDIR)|g' bin/nxagent.in > bin/nxagent - $(INSTALL_PROGRAM) bin/nxagent $(DESTDIR)$(BINDIR) - $(MAKE) -C nxcompshad install + $(INSTALL_DIR) $(DESTDIR)$(BINDIR)/bin + $(INSTALL_PROGRAM) nx-X11/programs/Xserver/nxagent $(DESTDIR)$(BINDIR) + $(INSTALL_DIR) $(DESTDIR)$(PREFIX)/share/pixmaps $(INSTALL_FILE) nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm $(DESTDIR)$(PREFIX)/share/pixmaps $(INSTALL_DIR) $(DESTDIR)$(PREFIX)/share/nx $(INSTALL_FILE) nx-X11/programs/Xserver/Xext/SecurityPolicy $(DESTDIR)$(PREFIX)/share/nx + # FIXME: Drop this symlink for 3.6.0. Requires that third party frameworks like X2Go have become aware of this... $(INSTALL_DIR) $(DESTDIR)$(NXLIBDIR)/bin - $(INSTALL_PROGRAM) nx-X11/programs/Xserver/nxagent $(DESTDIR)$(NXLIBDIR)/bin + $(INSTALL_SYMLINK) $(BINDIR)/nxagent $(DESTDIR)$(NXLIBDIR)/bin/nxagent $(INSTALL_DIR) $(DESTDIR)$(PREFIX)/share/man/man1/ $(INSTALL_FILE) nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 $(DESTDIR)$(PREFIX)/share/man/man1/ @@ -243,28 +235,19 @@ uninstall: uninstall-lite: if test -f nxcomp/Makefile; then ${MAKE} -C nxcomp $@; fi + if test -f nxproxy/Makefile; then ${MAKE} -C nxproxy $@; fi - # uninstall nproxy wrapper script - $(RM_FILE) $(DESTDIR)$(BINDIR)/nxproxy - # FIXME: don't use uninstall rule in nxproxy/Makefile.in, let's do - # it on our own for now... - $(RM_FILE) $(DESTDIR)$(NXLIBDIR)/bin/nxproxy - $(RM_DIR) $(DESTDIR)$(NXLIBDIR)/bin/ - $(RM_FILE) $(DESTDIR)$(PREFIX)/share/man/man1/*.1 $(RM_FILE) $(DESTDIR)$(PREFIX)/share/nx/VERSION.nxproxy $(RM_DIR) $(DESTDIR)$(PREFIX)/share/nx/ uninstall-full: - for f in nxagent; do \ - $(RM_FILE) $(DESTDIR)$(BINDIR)/$$f; done + if test -f nxcompshad/Makefile; then ${MAKE} -C nxcompshad $@; fi + if test -f nx-X11/lib/Makefile; then ${MAKE} -C nx-X11/lib $@; fi + + $(RM_FILE) $(DESTDIR)$(BINDIR)/nxagent $(RM_FILE) $(DESTDIR)$(PREFIX)/share/nx/VERSION.nxagent $(RM_DIR) $(DESTDIR)$(PREFIX)/share/nx/ - if test -d nx-X11; then \ - if test -f nxcompshad/Makefile; then ${MAKE} -C nxcompshad $@; fi; \ - if test -f nx-X11/Makefile; then \ - if test -d $(NXLIBDIR); then rm -rf $(NXLIBDIR); fi; \ - if test -d $(INCLUDEDIR)/nx; then rm -rf $(INCLUDEDIR)/nx; fi; \ - fi; \ - fi + if test -d $(DESTDIR)$(NXLIBDIR); then rm -rf $(DESTDIR)$(NXLIBDIR); fi + if test -d $(DESTDIR)$(INCLUDEDIR)/nx; then rm -rf $(DESTDIR)$(INCLUDEDIR)/nx; fi diff --git a/bin/nxagent.in b/bin/nxagent.in deleted file mode 100644 index 3a9dfc649..000000000 --- a/bin/nxagent.in +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# Copyright (C) 2012 Mike Gabriel -# -# 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 3 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, see http://www.gnu.org/licenses/. - -NX_LIBDIR=@@NXLIBDIR@@ - -# make sure nxagent starts properly with pam_tmpdir.so being in use -NX_TEMP=${NX_TEMP:-/tmp} -export NX_TEMP - -exec $NX_LIBDIR/bin/${NXAPP:-"nxagent"} "$@" diff --git a/bin/nxproxy.in b/bin/nxproxy.in deleted file mode 100644 index 0866d25ac..000000000 --- a/bin/nxproxy.in +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# Copyright (C) 2012 Mike Gabriel -# -# 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 3 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, see http://www.gnu.org/licenses/. - -NX_LIBDIR=@@NXLIBDIR@@ - -# make sure nxagent starts properly with pam_tmpdir.so being in use -NX_TEMP=${NX_TEMP:-/tmp} -export NX_TEMP - -exec $NX_LIBDIR/bin/${NXAPP:="nxproxy"} "$@" diff --git a/debian/nxagent.install b/debian/nxagent.install index 34f5c3a76..87ba3583f 100644 --- a/debian/nxagent.install +++ b/debian/nxagent.install @@ -1,8 +1,9 @@ etc/nxagent/keystrokes.cfg usr/share/nx/VERSION.nxagent usr/share/man/man1/nxagent.1* -usr/lib/*/nx/bin/nxagent usr/lib/*/nx/X11/ usr/bin/nxagent usr/share/pixmaps/nxagent.xpm etc/nxagent/nxagent.keyboard +# FIXME: compatibility symlink, drop for 3.6.0 release +usr/lib/*/nx/bin/nxagent diff --git a/debian/nxproxy.install b/debian/nxproxy.install index 8ade77d6d..988f2842f 100644 --- a/debian/nxproxy.install +++ b/debian/nxproxy.install @@ -1,4 +1,3 @@ -usr/lib/*/nx/bin/nxproxy usr/bin/nxproxy usr/share/man/man1/nxproxy.1* usr/share/nx/VERSION.nxproxy diff --git a/nx-X11/config/cf/X11.tmpl b/nx-X11/config/cf/X11.tmpl index ddd6e0bad..9b3e0e8b3 100644 --- a/nx-X11/config/cf/X11.tmpl +++ b/nx-X11/config/cf/X11.tmpl @@ -769,7 +769,7 @@ FCHOWN_DEFINES = -DHAS_FCHOWN #ifndef BinDir #ifdef ProjectRoot -#define BinDir Concat(ProjectRoot,/lib/nx/bin) +#define BinDir Concat(ProjectRoot,/bin) #else #define BinDir /usr/bin/X11 #endif diff --git a/nx-libs.spec b/nx-libs.spec index 4a64b8aed..68bec6397 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -367,10 +367,6 @@ This package provides the NX proxy (client) binary. rm -Rf nx*/configure nx*/autom4te.cache* # Install into /usr sed -i -e 's,/usr/local,/usr,' nx-X11/config/cf/site.def -# Use multilib dirs -# We're installing binaries into %%{_libdir}/nx/bin rather than %%{_libexedir}/nx -# because upstream expects libraries and binaries in the same directory -sed -i -e 's,/lib/nx,/%{_lib}/nx,' nx-X11/config/cf/X11.tmpl # Fix FSF address find -name LICENSE | xargs sed -i \ -e 's/59 Temple Place/51 Franklin Street/' -e 's/Suite 330/Fifth Floor/' \ @@ -575,6 +571,7 @@ rm -r %{buildroot}%{_includedir}/nx-X11/Xtrans %config(noreplace) %{_sysconfdir}/nxagent/nxagent.keyboard %doc doc/nxagent/README.keystrokes %{_bindir}/nxagent +# FIXME: compatibility symlink to BINDIR/nxagent, remove for 3.6.0 %dir %{_libdir}/nx/bin %{_libdir}/nx/bin/nxagent %dir %{_libdir}/nx/X11 @@ -590,8 +587,6 @@ rm -r %{buildroot}%{_includedir}/nx-X11/Xtrans %doc doc/nxproxy/README-VALGRIND %{_bindir}/nxproxy %{_datadir}/man/man1/nxproxy.1* -%dir %{_libdir}/nx/bin -%{_libdir}/nx/bin/nxproxy %dir %{_datadir}/nx %{_datadir}/nx/VERSION.nxproxy diff --git a/nxproxy/src/Makefile.am b/nxproxy/src/Makefile.am index 7e55900d3..4fd2eefd6 100644 --- a/nxproxy/src/Makefile.am +++ b/nxproxy/src/Makefile.am @@ -1,6 +1,6 @@ NULL = -nxexecdir = $(libexecdir) +nxexecdir = $(bindir) nxexec_PROGRAMS = nxproxy -- cgit v1.2.3 From 9e3381cc858e249b13777e31cfc40a87f8d10bb7 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Wed, 29 Nov 2017 00:02:01 +0100 Subject: nxproxy/nxcomp: document logging options --- nxcomp/src/Misc.cpp | 14 ++++++++++++++ nxproxy/man/nxproxy.1 | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'nxproxy') diff --git a/nxcomp/src/Misc.cpp b/nxcomp/src/Misc.cpp index 947026c82..7e468f1e2 100644 --- a/nxcomp/src/Misc.cpp +++ b/nxcomp/src/Misc.cpp @@ -131,6 +131,20 @@ static const char UsageInfo[] = -h Print this message.\n\ \n\ -v Print version information.\n\ +\n\ + -d Set log level (0=FATAL, 1=ERROR, 2=WARNING, 3=INFO,\n\ + 4=DEBUG). Default is 0.\n\ +\n\ + -o Name of the logfile. Default is stderr.\n\ +\n\ + -f Specify log format. The characters in define\n\ + how the loglines are formatted. The following characters\n\ + are supported, default is 0:\n\ + 0 only the plain text without any additions\n\ + u include time\n\ + l include loglevel\n\ + T include thread ids\n\ + L include the source code location of the log\n\ \n\ host:port Put at the end, specifies the host and port of the\n\ listening proxy.\n\ diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index ecfe3b0d6..702c7a606 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -36,6 +36,34 @@ Print this message. .B -v Print version information. .TP 8 +.B -d +Set log level (0 for FATAL, 1 for ERROR, 2 for WARNING, 3 for INFO, 4 for +DEBUG). The default is 0. +.TP 8 +.B -o +Name of the log file. Default is stderr. +.TP 8 +.B -f +Specify log format. The characters in define how the loglines +are formatted. The following characters are supported, default is '0': +.RS 8 +.TP 8 +.I 0 +only the plain text without any additions. This is the default. +.TP 8 +.I u +include time +.TP 8 +.I l +include loglevel +.TP 8 +.I T +include thread ids +.TP 8 +.I L +include the location of the log call in the source code +.RE +.TP 8 .B : Put at the end, specifies the host and port of the listening proxy. -- cgit v1.2.3 From b213c8eba636a739c91e93023cd6bae744647f86 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 15 Dec 2017 11:20:52 +0100 Subject: release 3.5.99.11 --- ChangeLog | 770 ++++++++++++++++++++++- VERSION | 2 +- nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 2 +- nx-libs.spec | 2 +- nxproxy/man/nxproxy.1 | 2 +- 5 files changed, 755 insertions(+), 23 deletions(-) (limited to 'nxproxy') diff --git a/ChangeLog b/ChangeLog index 75b92d380..b049dc3e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,12 +1,733 @@ -2017-09-15 14:57:56 +0200 Mike Gabriel (e6998288d) +2017-12-15 11:20:52 +0100 Mike Gabriel (5f673977a) - * release 3.5.99.10 (HEAD -> 3.6.x) + * release 3.5.99.11 (HEAD -> 3.6.x) + +2017-12-15 11:15:22 +0100 Mike Gabriel (4cca1b4bd) + + * Merge branch 'sunweaver-pr/more-X-memory-macro-fixes' into 3.6.x + (origin/HEAD, origin/3.6.x) + +2017-12-14 11:27:35 +0100 Mike Gabriel (5597f2ea5) + + * Xserver/hw/nxagent/Clipboard.c: Fix free calls (free back to + XFree). (gh-sunweaver/pr/more-X-memory-macro-fixes, + sunweaver-pr/more-X-memory-macro-fixes, + pr/more-X-memory-macro-fixes) + +2017-12-14 11:15:09 +0100 Mike Gabriel (d4465b719) + + * Xserver/hw/nxagent/compext: Xfree -> free and Xmalloc -> malloc. + +2017-12-15 08:26:23 +0100 Mihai Moldovan (8cca3f09d) + + * nx-libs.spec: actually use a weak dependency for xkeyboard-config. + +2017-12-15 08:10:32 +0100 Mihai Moldovan (8cf5b5b7c) + + * nx-libs.spec: add back erroneously dropped xkeyboard-config + dependency. + +2017-12-14 10:49:21 +0100 Mihai Moldovan (1d301c517) + + * Merge branch 'sunweaver-pr/fix-compiler-warnings' into 3.6.x + +2017-12-14 08:05:54 +0100 Mike Gabriel (8bb1579f4) + + * Xserver/GL/glx/glxcmds.c: Cast small-int values through intptr_t + when passed as pointers + (gh-sunweaver/pr/fix-compiler-warnings, + pr/fix-compiler-warnings) + +2017-03-17 14:06:15 +0000 Mike Gabriel (ac6a216c5) + + * lib/X11/Xrm.c: Compiler warning fix: logical-not-parentheses + +2017-02-17 13:35:48 +0000 Mike Gabriel (a6ffabda6) + + * glx: warning fixes + +2017-02-17 13:30:13 +0000 Mike Gabriel (16fbdb2a8) + + * Xserver/GL/glx/glxfb.c: Fix compiler warning: pointer-sign. + +2017-02-17 12:56:53 +0000 Mike Gabriel (a27414524) + + * hw/nxagent/Events.c: Fix compiler warnings (with NX_DEBUG_INPUT): + format. + +2017-02-17 12:28:05 +0100 Mike Gabriel (7aed70f14) + + * hw/nxagent/NXxvdisp.c: Fix compiler warnings: + misleading-indentation + +2017-02-17 10:25:03 +0000 Mike Gabriel (72152baff) + + * hw/nxagent/NXdispatch.c: Fix compiler warning: + misleading-indentation + +2017-02-16 10:06:41 +0000 Mike Gabriel (6d98e5381) + + * Xserver/Xi/chgfctl.c: Fix compiler warning: misleading-indentation. + +2017-12-14 10:39:47 +0100 Mike Gabriel (91ca51bff) + + * debian/rules: Neither overzealously remove nx-X11/Makefile. + +2017-12-14 09:51:12 +0100 Mike Gabriel (8cade97b0) + + * debian/rules: Don't remove our main Makefile. + +2017-12-14 07:44:20 +0100 Mike Gabriel (346c59516) + + * debian/rules: Fix override_dh_clean target for older Debian/Ubuntu + versions. + +2017-12-14 01:08:34 +0100 Mike Gabriel (542b5b461) + + * Add missing/renamed patches. (Ouch!). + +2017-09-22 15:32:31 -0400 Mike DePaulo (f8b2a04e0) + + * nx-libs.spec: Add missing BuildRequires and fix paths to files. + +2017-12-14 00:21:42 +0100 Mike Gabriel (5000ded30) + + * debian/control: Set Section: to "libs" for libnx-x11-6. + +2017-12-14 00:19:04 +0100 Mike Gabriel (f17d4eb26) + + * debian/control: All Priority: extras packages are required to be + changed to Priority: optional by recent Debian Policy. + +2017-12-14 00:09:35 +0100 Mike Gabriel (abaebb5b1) + + * Merge branch 'uli42-pr/improve_keyboard_light' into 3.6.x + +2017-11-13 21:06:36 +0100 Ulrich Sibiller (a02b645b2) + + * nxagent manpage: extend description of keyboard option + (gh-uli42/pr/improve_keyboard_light, + uli42-pr/improve_keyboard_light, + pr/improve_keyboard_light) + +2017-08-31 16:17:29 +0200 Ulrich Sibiller (7dbc6cf86) + + * Events.c/h: Rename & restructure some Xkb functions + +2017-07-22 22:12:51 +0200 Ulrich Sibiller (8e5b1e7a2) + + * Keyboard.c: Replace some memsets by zero initialization + +2017-07-22 19:09:10 +0200 Ulrich Sibiller (de9b4edf9) + + * Keyboard.c: Fix indentation + +2017-08-12 17:38:35 +0200 Ulrich Sibiller (88bc52615) + + * Keyboard.c: set variables to NULL after free + +2017-07-22 16:41:09 +0200 Ulrich Sibiller (94fae7497) + + * Keyboard.c: XkbDfltRepeatDelay and XkbDfltRepeatIntervall are int + not uint + +2017-07-22 15:58:08 +0200 Ulrich Sibiller (eb4abe4c5) + + * Keyboard.c: Use calloc instead of malloc + memset + +2017-07-22 15:28:59 +0200 Ulrich Sibiller (5c4a001ac) + + * nxagent manpage: Extend keyboard documentation + +2017-07-22 15:26:11 +0200 Ulrich Sibiller (8b206a261) + + * Keyboard.c: Make xkblock more robust + +2017-07-22 15:25:53 +0200 Ulrich Sibiller (1e1ea1cea) + + * Keyboard.c: Some code cleanups + +2017-07-22 14:44:46 +0200 Ulrich Sibiller (a44737855) + + * nxagent manpage: Improve explanation of -noignore and -noxkblock + +2017-07-22 14:40:53 +0200 Ulrich Sibiller (ba8076697) + + * Keyboard.c: Add some comments with changelog explanations + +2017-12-06 00:04:44 +0100 Ulrich Sibiller (9566acb5a) + + * Keyboard.c: print message class for user messages + +2017-12-06 00:04:29 +0100 Ulrich Sibiller (c37c47ac4) + + * Keyboard.c: Improve TEST output + +2017-12-13 23:43:41 +0100 Mike Gabriel (7610c0f19) + + * debian/*: Adopt from official Debian package where appropriate. + +2017-12-13 23:18:34 +0100 Mike Gabriel (c5f3c2042) + + * Merge branch 'uli42-pr/pre-rrxinerama-fallback' into 3.6.x + +2017-07-13 18:33:17 +0200 Ulrich Sibiller (bd1ca625e) + + * small code cosmetics (gh-uli42/pr/pre-rrxinerama-fallback, + uli42-pr/pre-rrxinerama-fallback, + pr/pre-rrxinerama-fallback) + +2017-07-13 15:52:47 +0200 Ulrich Sibiller (0852aa52c) + + * always notify on size changes + +2017-07-13 15:28:05 +0200 Ulrich Sibiller (1923f49dd) + + * re-implement pre-xinerama behaviour + +2017-12-13 04:50:24 +0100 Mihai Moldovan (73c113ce6) + + * nx-X11/programs/Xserver/os/xprintf.c: completely drop NX-related + changes. + +2017-12-11 13:38:59 +0100 Mihai Moldovan (3731a996d) + + * nxcomp/src/Log.cpp: only create a new queue entry if we actually + intend to write it out later. + +2017-12-11 09:49:05 +0100 Mike Gabriel (7882a39ad) + + * Merge branch 'uli42-pr/fix_shadow_warning' into 3.6.x + +2017-12-10 18:00:15 +0100 Ulrich Sibiller (018c557c4) + + * Silence warning: "ar: 'u' modifier ignored since 'D' is the + default" (gh-uli42/pr/fix_shadow_warning, + uli42-pr/fix_shadow_warning, pr/fix_shadow_warning) + +2017-12-10 16:23:03 +0100 Ulrich Sibiller (d5c3e75b3) + + * nxcomp: fix shadow warning + +2017-12-11 09:45:47 +0100 Mike Gabriel (29bb12312) + + * Merge branch 'uli42-pr/simplify_xtrans' into 3.6.x + +2017-12-10 21:36:15 +0100 Ulrich Sibiller (0eb1dc67d) + + * Xtranssock.c: simplify code in SocketWritev + (gh-uli42/pr/simplify_xtrans, uli42-pr/simplify_xtrans, + pr/simplify_xtrans) + +2017-12-11 09:41:08 +0100 Mike Gabriel (4988e7c5f) + + * Merge branch + 'sunweaver-pr/drop-NoMachines-own-Xvasprintf-implementation' + into 3.6.x + +2017-12-11 09:22:49 +0100 Mike Gabriel (cf2e07657) + + * Xserver/os/xprintf.c: Drop NoMachine's own implementation of + Xvasprintf(). Use stock implementation instead. + (gh-sunweaver/pr/drop-NoMachines-own-Xvasprintf-implementation, + sunweaver-pr/drop-NoMachines-own-Xvasprintf-implementation, + pr/drop-NoMachines-own-Xvasprintf-implementation) + +2017-12-11 01:05:50 +0100 Mihai Moldovan (c31cd7737) + + * nx-X11/programs/Xserver/os/xprintf.c: remove doubly-defined + Xscnprintf function, add missing header includes. + +2017-12-10 12:17:39 +0100 Mike Gabriel (e54e42af9) + + * Merge branch 'Ionic-feature/backport-asprintf' into 3.6.x + +2017-12-07 12:11:53 +0100 Daniel Kurtz (a6e632aac) + + * os/xprintf: add Xvscnprintf and Xscnprintf + (Ionic-feature/backport-asprintf) + +2017-12-07 10:57:06 +0100 Colin Harrison (c281c6e06) + + * Typo in xserver Xvasprintf() + +2017-12-07 10:48:31 +0100 Alan Coopersmith (1e3a97482) + + * Add asprintf() implementation for platforms without it + +2017-12-09 13:16:37 +0100 Mihai Moldovan (804ff4452) + + * Merge branch 'uli42-pr/fix_memleaks' into 3.6.x + +2017-12-07 22:35:59 +0100 Ulrich Sibiller (4dbee3a3f) + + * nxcomp: use new macro SAFE_FREE(ptr) (gh-uli42/pr/fix_memleaks) + +2017-11-28 21:58:07 +0100 Ulrich Sibiller (2814677a7) + + * Loop.cpp: fix more memory leaks + +2017-11-28 21:18:48 +0100 Ulrich Sibiller (1c09eab70) + + * Loop.cpp: fix two memleaks + +2017-11-28 20:43:44 +0100 Ulrich Sibiller (c4660e109) + + * ChannelEndPoint.cpp: fix two memleaks + +2017-11-27 23:31:35 +0100 Ulrich Sibiller (21c742d25) + + * nxcomp: simplify free calls + +2017-11-27 23:30:50 +0100 Ulrich Sibiller (513aa23a7) + + * nxcomp: fix double free + +2017-12-09 12:54:24 +0100 Mihai Moldovan (6d7536bd4) + + * Merge branch 'uli42-pr/keep_co' into 3.6.x + +2017-12-04 23:44:58 +0100 Ulrich Sibiller (eff0f366d) + + * Reintroduce -co as no-op (gh-uli42/pr/keep_co) + +2017-12-07 08:35:54 +0100 Mihai Moldovan (eb9618739) + + * Merge branch 'uli42-p/xquerytree_leak' into 3.6.x + +2017-12-05 21:25:12 +0100 Ulrich Sibiller (ad53af097) + + * Events.c: add ifdef around nxagentRemoteWindowsTree + (gh-uli42/p/xquerytree_leak) + +2017-12-05 00:29:10 +0100 Ulrich Sibiller (cdaec755d) + + * Make sure XQueryTree results are freed + +2017-12-05 00:28:51 +0100 Ulrich Sibiller (0938cf83d) + + * Events.c: drop unused variable + +2017-12-05 00:28:27 +0100 Ulrich Sibiller (43579a3b9) + + * Events.c: move variable to inner scope + +2017-12-07 07:23:20 +0100 Mihai Moldovan (5487d52fe) + + * Merge branch 'uli42-pr/various_backports' into 3.6.x + +2017-12-05 22:39:34 +0100 Daniel Stone (aac4c5f59) + + * DIX: XKB: Set xkbInfo to NULL as well as freeing it + (gh-uli42/pr/various_backports) + +2017-12-05 22:22:55 +0100 Daniel Stone (e05b90814) + + * Allow options to appear with other components. + +2017-12-05 22:14:22 +0100 Lars Knoll (e073093cc) + + * devPrivates fixes + +2017-12-05 22:09:06 +0100 Adam Jackson (0a010adfc) + + * Coverity # 337: Remove useless NULL check. + +2017-12-05 22:06:11 +0100 Adam Jackson (1771deaf1) + + * Coverity # 491: Check version number correctly. + +2006-03-15 16:33:12 +0000 Adam Jackson (d31f107c6) + + * Coverity # 487: Check version number correctly. + +2006-03-15 16:49:04 +0000 Adam Jackson (43388104d) + + * Coverity # 807: Fix a memory leak in XFixesExpandRegion. + +2017-11-09 10:21:21 +0100 Giuseppe Bilotta (6f9a6aacd) + + * randr: free crtc->outputs on destroy + +2017-11-09 10:21:20 +0100 Giuseppe Bilotta (4e059d579) + + * randr: always realloc crtcs and outputs + +2017-12-07 06:28:19 +0100 Mihai Moldovan (c571aa9ed) + + * Merge branch 'uli42-pr/improve_nxproxy_help' into 3.6.x + +2017-11-29 00:02:01 +0100 Ulrich Sibiller (9e3381cc8) + + * nxproxy/nxcomp: document logging options + (gh-uli42/pr/improve_nxproxy_help) + +2017-11-27 23:37:58 +0100 Ulrich Sibiller (3fcb8e4ee) + + * nxcomp/nxproxy: slightly improve the usage message of nxproxy + +2017-11-27 23:35:04 +0100 Ulrich Sibiller (f51194fb1) + + * nxcomp/nxproxy: add missing hint for keyconv option + +2017-12-06 04:51:59 +0100 Mihai Moldovan (80e590ea1) + + * Merge branch 'sunweaver-pr/drop-bin-wrappers' into 3.6.x + +2017-11-26 23:16:59 +0100 Mike Gabriel (c54558e3c) + + * Makefile: Quote '$@' in make calls with double quotes. + (gh-sunweaver/pr/drop-bin-wrappers) + +2017-11-21 13:45:55 +0100 Mike Gabriel (1539c20e5) + + * Makefile: Don't use DESTDIR in configure. + +2017-11-21 13:28:17 +0100 Mike Gabriel (ca4308781) + + * Drop bin wrappers for nxagent and nxproxy, directly install nxproxy + and nxagent to BINDIR. + +2017-12-05 18:12:11 +0100 Mike Gabriel (05cf54af3) + + * Merge branch 'uli42-pr/fix_global_tcpFD' into 3.6.x + +2017-12-02 01:32:35 +0100 Ulrich Sibiller (b8c929773) + + * nxcomp: use lowercase abbreviations for seconds and milliseconds + (gh-uli42/pr/fix_global_tcpFD, uli42-pr/fix_global_tcpFD) + +2017-12-02 01:07:03 +0100 Ulrich Sibiller (3bd7e03e1) + + * nxcomp: remove unused return values + +2017-12-02 01:03:29 +0100 Ulrich Sibiller (82e893ef2) + + * nxcomp: Fix setting of global tcpFD + +2017-11-26 08:35:55 +0100 Mihai Moldovan (7f777e01e) + + * Merge branch 'uli42-pr/nokeyconv' into 3.6.x + +2017-11-23 15:19:02 +0100 Ulrich Sibiller (66046f138) + + * Keyboard.c: make nxagentKeycodeConversion a Boolean + (gh-uli42/pr/nokeyconv) + +2017-11-19 01:11:05 +0100 Ulrich Sibiller (8fd25cf83) + + * add option keyconv=(auto|on|off) + +2017-11-19 01:07:57 +0100 Ulrich Sibiller (4b71309c3) + + * Keyboard.c: Use booleans for nxagentKeycodeConversion + +2017-11-22 11:09:38 +0100 Mike Gabriel (2e724702e) + + * nxcomp/src/Misc.cpp: Update explanation for the NX_TEMP env + variable. + +2017-11-22 11:08:31 +0100 Mike Gabriel (78661a19a) + + * nxproxy.1 man page: Update explanation for NX_TEMP env variable. + +2017-11-22 10:56:38 +0100 Mike Gabriel (f0f4fdc2b) + + * Merge branch 'Ionic-bugfix/hardcode-socket-paths-in-libX11' into + 3.6.x + +2017-11-22 06:16:01 +0100 Mihai Moldovan (df9b5306e) + + * nx-X11/lib/include/xtrans/Xtranssock.c: drop UNIX path overrides as + well. (gh-Ionic/bugfix/hardcode-socket-paths-in-libX11, + Ionic-bugfix/hardcode-socket-paths-in-libX11) + +2017-11-21 11:47:04 +0100 Mike Gabriel (ce182e88a) + + * Merge branch 'uli42-pr/simplify_free' into 3.6.x + +2017-11-18 23:35:39 +0100 Ulrich Sibiller (dc43f4c98) + + * Error.c: simply nxagentGetClientsPath() (gh-uli42/pr/simplify_free, + uli42-pr/simplify_free) + +2017-11-18 23:33:53 +0100 Ulrich Sibiller (7e975e3cc) + + * simply free() calls + +2017-11-20 10:47:10 +0100 Mike Gabriel (3b640a0f8) + + * Merge branch 'uli42-pr/options_on_reconnect' into 3.6.x + +2017-11-18 22:32:21 +0100 Ulrich Sibiller (4ef4fbf16) + + * Args.c: simplify nxagentProcessOptionsFile() + (uli42-pr/options_on_reconnect) + +2017-11-18 22:18:26 +0100 Ulrich Sibiller (6c9622963) + + * Args.c: Fix compile bug with DEBUG enabled + +2017-11-18 22:15:50 +0100 Ulrich Sibiller (76ce623ab) + + * Fix options parsing on reconnect + +2017-11-17 13:16:39 +0100 Mike Gabriel (39d45a0e8) + + * Merge branch 'uli42-small_fixes' into 3.6.x + +2017-10-18 00:28:23 +0200 Ulrich Sibiller (9a1604372) + + * fix broken path due to missing / (gh-uli42/small_fixes, + uli42-small_fixes, small_fixes) + +2017-10-18 00:22:53 +0200 Ulrich Sibiller (ac66ba349) + + * NXglxext.c: rename and relocate variable + +2017-10-18 00:21:00 +0200 Ulrich Sibiller (fff0d5473) + + * glxext.c/NXglxext.c: merge two functions into one + +2017-10-18 00:08:24 +0200 Ulrich Sibiller (b0b62dde6) + + * keysym.h: fix include path + +2017-11-17 09:30:38 +0100 Mike Gabriel (56569f336) + + * Merge branch 'uli42-pr/fix_manpage' into 3.6.x + +2017-11-17 00:04:57 +0100 Ulrich Sibiller (72c1f83fb) + + * nxagent manpage: some minor formatting improvements and typo fixes + (gh-uli42/pr/fix_manpage, uli42-pr/fix_manpage) + +2017-11-04 09:26:18 +0100 Mike Gabriel (e788a70ce) + + * Merge branch 'Ionic-bugfix/hardcode-some-socket-paths' into 3.6.x + +2017-11-03 12:57:25 +0100 Mihai Moldovan (79257eed0) + + * nxcomp/src/Loop.cpp: hardcode X11 and (legacy/xfs) font UNIX paths. + (gh-Ionic/bugfix/hardcode-some-socket-paths, + Ionic-bugfix/hardcode-some-socket-paths) + +2017-11-03 16:23:41 +0100 Mike Gabriel (e3f498e62) + + * Merge branch 'Ionic-bugfix/fix-X-cookie-on-osx' into 3.6.x + +2017-11-03 12:30:12 +0100 Mihai Moldovan (bd25453bd) + + * nxcomp/src/Auth.cpp: handle launchd sockets in DISPLAY variable + correctly when fetching X cookie. + (gh-Ionic/bugfix/fix-X-cookie-on-osx, + Ionic-bugfix/fix-X-cookie-on-osx) + +2017-10-27 14:14:24 +0200 Mihai Moldovan (1c6c9c04b) + + * nxproxy: use ax_pthread.m4. + +2017-10-27 14:13:26 +0200 Mihai Moldovan (22bb128dc) + + * nxcomp/m4/ax_pthread.m4: move to top-level m4/ directory, use + symlink. + +2017-10-27 11:55:45 +0200 Mike Gabriel (06a6c5829) + + * Regression fix for f855b3b6. Caused FTBFS with Loop.cpp:2669:0: + error: unterminated #ifdef (#ifdef TIME). + +2017-10-27 11:13:08 +0200 Mike Gabriel (2e4f9e7a9) + + * Merge branch 'theqvd-improved-logging-loop' into 3.6.x + +2017-10-27 11:12:00 +0200 Mike Gabriel (de3d9ff4e) + + * Merge branch 'theqvd-improved-logging' into 3.6.x + +2017-09-29 21:05:04 +0200 Mihai Moldovan (ab0c4f842) + + * nxcomp/src/Loop.cpp: fix whitespace errors on continued lines. + (theqvd-improved-logging-loop) + +2017-03-22 16:33:58 +0100 Vadim Troshchinskiy (d202b052e) + + * Remove leading \n in NXTrans* logging + +2017-03-16 12:55:18 +0100 Vadim Troshchinskiy (f855b3b61) + + * Fix whitespace and line splitting issues reported by ionic + +2016-12-22 12:39:40 +0100 Vadim Troshchinskiy (1cf6aa8f2) + + * Conversion of Loop.cpp to the new log system + +2017-09-30 16:58:16 +0200 Mihai Moldovan (ceac07763) + + * nxcomp: add basic logging_test utility in test subdirectory. + (theqvd-improved-logging) + +2017-09-30 16:53:48 +0200 Mihai Moldovan (5efcd39fc) + + * nxcomp/src/Log.h: prepare for logger testing application. + +2017-10-27 08:32:14 +0200 Mihai Moldovan (6c3cf54ba) + + * nxcomp/src/Log.cpp: add PID to thread ID output if requested. + +2017-09-30 15:32:33 +0200 Mihai Moldovan (1829a35cd) + + * nxcomp/src/Log.h: block signals while writing out data. + +2017-09-30 15:30:53 +0200 Mihai Moldovan (09586d760) + + * nxcomp/src/Log.{cpp,h}: port to std::stack as internal buffer + structure. + +2017-06-30 23:32:45 +0200 Mihai Moldovan (fc4a18d33) + + * nxcomp/{configure.ac,Log.cpp}: implement configure-time + std::put_time check and use macro value in Log.cpp. + +2017-06-30 22:42:25 +0200 Mihai Moldovan (67b0a17fa) + + * nxcomp/Log.h: delete stream_ member before class object + destruction. + +2017-06-30 22:37:13 +0200 Mihai Moldovan (ca08512cf) + + * nxcomp/Log.h: also clear the buffer after setting it to an empty + string. + +2016-12-22 12:40:43 +0100 Vadim Troshchinskiy (d960ec2cb) + + * Set default log level to WARNING + +2016-12-22 09:57:47 +0100 Vadim Troshchinskiy (b0521e816) + + * New logging implementation + +2017-07-13 01:10:02 +0200 Mihai Moldovan (381c39b86) + + * nxcomp: add AX_PTHREAD code from autoconf-archive and check for + pthread support. + +2017-09-29 17:19:06 +0200 Mihai Moldovan (1f717c6fd) + + * nx{comp{,shad},proxy}: add configure flag --enable-cxx11 to enable + and setup optional C++11 support. + +2017-10-27 08:42:17 +0200 Mihai Moldovan (39ee56f5d) + + * nxcomp/configure.ac: rename --{en,dis}able-info to + --{en,dis}able-debug, as originally planned. + +2017-10-20 11:30:43 +0200 Mihai Moldovan (dae8551e2) + + * README.md: add short Windows section and mention that using Cygwin + tools is imperative when working with the git repository. + +2017-10-16 10:44:18 +0200 Mihai Moldovan (c6b004578) + + * nx-libs.spec: pass CDEBUGFLAGS and friends directly through via + make command. + +2017-10-16 10:42:51 +0200 Mihai Moldovan (92485be30) + + * nx-libs.spec: handle potentially undefined variables more + gracefully. + +2017-10-16 10:12:36 +0200 Mihai Moldovan (71bda0ed5) + + * nx-libs.spec: drop ugly optsflag sed hack, hopefully obsoleted by + passing CDEBUGFLAGS through. + +2017-10-16 07:24:38 +0200 Mihai Moldovan (bd2a66fec) + + * nx-libs.spec: add -mno-vxs to general C(XX)FLAGS on ppc64le. + +2017-10-10 15:17:40 +0200 Mike Gabriel (13041f5c0) + + * Merge branch 'theqvd-media_argument_bugfix' into 3.6.x + +2017-10-10 13:04:08 +0200 Vadim Troshchinskiy (f2c73bd84) + + * Fix bug #525: PANIC! No port specified for multimedia connections + (theqvd-media_argument_bugfix) + +2017-10-10 10:27:18 +0200 Mike Gabriel (17ae45e0f) + + * Merge branch 'Ionic-add-stray-files-to-gitignore' into 3.6.x + +2017-10-10 07:17:27 +0200 Mihai Moldovan (0336aab79) + + * .gitignore: ignore vim swap files. + (gh-Ionic/add-stray-files-to-gitignore, + Ionic-add-stray-files-to-gitignore) + +2017-10-10 07:16:36 +0200 Mihai Moldovan (5d44c595a) + + * **/.gitignore: add stray files. + +2017-10-09 22:10:57 +0200 Mihai Moldovan (b67be23b1) + + * Merge branch 'sunweaver-pr/nxcomp-tokensize-in-vpn-tunnels' into + 3.6.x + +2017-10-09 11:30:02 +0200 Simon Matter (418db3b5c) + + * nxcomp/src/Loop.cpp: Reduce control->TokenSize slightly again in + order to fix fragmentation of packages when on VPN (or + otherwise encapsulated) connections. + (gh-sunweaver/pr/nxcomp-tokensize-in-vpn-tunnels, + pr/nxcomp-tokensize-in-vpn-tunnels) + +2017-10-09 12:52:01 +0200 Mike Gabriel (27c14b4eb) + + * .gitignore: Improve all .gitignore files, adapt to autotools + build-flow and its build cruft. + +2017-09-29 20:55:36 +0200 Mihai Moldovan (371c71276) + + * nxcomp/src/Loop.cpp: whitespace fixes only. + (pr/gcstruct-type-mismatch) + +2017-09-29 17:58:28 +0200 Mihai Moldovan (b5c714690) + + * nxcomp/configure.ac: prettify AC_ARG_ENABLE() calls, use more + quotes and AS_IF() where appropriate. + +2017-09-29 12:31:01 +0200 Simon Matter (03ebe6f25) + + * nxproxy/src/Main.c: Silence compiler warning. + +2017-09-29 12:22:08 +0200 Vadim Troshchinskiy (b3f2e3006) + + * Merge pull request #519 from theqvd/fix_nxagent_arg_parsing + +2017-09-28 16:42:41 +0200 Vadim Troshchinskiy (5f1eb0dc3) + + * Fix nxagent argument parsing logic + +2017-09-15 15:59:30 +0200 Mike Gabriel (3c95d6040) + + * debian/control: Bump Standards-Version: to 4.1.0. No changes + needed. (pr/autoreconf-nxagent) + +2017-09-15 15:59:03 +0200 Mike Gabriel (4bc1d6ccc) + + * debian/control: Drop non-required B-D libxmltok1-dev. + +2017-09-15 14:57:56 +0200 Mike Gabriel (6557c0043) + + * release 3.5.99.10 (tag: 3.5.99.10, origin/release-builds/3.6.x, + release-builds/3.6.x) 2017-09-14 07:45:45 +0200 Mihai Moldovan (4405c6a6b) * Merge branch 'sunweaver-pr/assure-that-Mesa-includes-headers-from-libNX_X11' - into 3.6.x (origin/HEAD, origin/3.6.x) + into 3.6.x 2017-09-13 13:06:34 +0200 Mike Gabriel (f9c23b51e) @@ -55,8 +776,7 @@ 2017-08-30 19:33:55 +0200 Mike Gabriel (f4afa5a56) - * release 3.5.99.9 (tag: 3.5.99.9, origin/release-builds/3.6.x, - release-builds/3.6.x) + * release 3.5.99.9 (tag: 3.5.99.9) 2017-08-30 19:29:58 +0200 Mike Gabriel (13264ea7f) @@ -170,7 +890,7 @@ 2017-08-10 00:50:27 +0200 Ulrich Sibiller (715fcfe6d) * Set NX_AGENT_VERSION property for root window - (uli42-pr/versionprop) + (gh-uli42/pr/versionprop, uli42-pr/versionprop) 2017-08-09 06:46:30 +0200 Mihai Moldovan (8235925a2) @@ -297,7 +1017,7 @@ 2017-07-24 23:45:48 +0200 Ulrich Sibiller (3f7b30019) * treat options parameter as option string if it starts with nx/nx - (uli42-pr/cmdline) + (gh-uli42/pr/cmdline, uli42-pr/cmdline) 2017-07-24 23:45:24 +0200 Ulrich Sibiller (36e583cf5) @@ -313,7 +1033,8 @@ 2017-07-12 20:01:44 +0200 Ulrich Sibiller (79001dd8a) - * Improve keystroke file handling (uli42-pr/fix_keystroke_files) + * Improve keystroke file handling (gh-uli42/pr/fix_keystroke_files, + uli42-pr/fix_keystroke_files) 2017-07-14 10:42:15 +0200 Mike Gabriel (ccd7c6962) @@ -623,11 +1344,12 @@ 2017-05-25 08:14:49 -0400 Mike DePaulo (c7ce96546) * nx-libs.xpec: Fix FTBFS on F24 due to missing Xfont2 - (mikedep333-f24-ftbfs) + (gh-mikedep333/f24-ftbfs, mikedep333-f24-ftbfs) 2017-05-06 02:01:47 +0200 Mike Gabriel (150cbc23d) * debian/copyright: Update copyright attributions. + (gh-mikedep333/3.6.x) 2017-05-06 00:03:48 +0200 Mike Gabriel (6479ed576) @@ -1160,7 +1882,8 @@ 2017-03-29 21:52:25 -0400 Mike DePaulo (1a2bea981) * Remove EMX (MS-DOS & OS/2) support - (mikedep333-pr/cygwin-nxcomp-ftbfs) + (gh-mikedep333/pr/cygwin-nxcomp-ftbfs, + mikedep333-pr/cygwin-nxcomp-ftbfs) 2017-03-29 07:19:25 -0400 Mike DePaulo (995851206) @@ -6138,7 +6861,7 @@ 2016-01-18 22:37:46 -0500 Mike DePaulo (0239ba72b) - * README.md: Add debuild instructions + * README.md: Add debuild instructions (gh-mikedep333/README.md) 2016-01-18 21:49:03 -0500 Mike DePaulo (474e9c0ba) @@ -6185,6 +6908,7 @@ 2016-01-01 09:52:26 -0500 Mike DePaulo (daace15e2) * Add instructions for building using Mock under Fedora/EPEL + (gh-mikedep333/mock-build-instructions) 2015-12-30 19:25:08 +0100 Mike Gabriel (fa497ac95) @@ -6890,13 +7614,14 @@ * Xv: unvalidated lengths in XVideo extension swapped procs [CVE-2014-8099] (origin/pr/Xext-cve-fixes, + gh-mikedep333/pr/Xext-cve-fixes, gh-Ionic/pr/Xext-cve-fixes) 2015-05-01 13:09:24 +0200 Keith Packard (2db01a9a2) * dix: Allow zero-height PutImage requests (fix for X.Org's CVE-2015-3418). (origin/pr/dix-cve-fixes, - gh-Ionic/pr/dix-cve-fixes) + gh-mikedep333/pr/dix-cve-fixes, gh-Ionic/pr/dix-cve-fixes) 2014-01-22 21:11:16 -0800 Alan Coopersmith (8623faa42) @@ -6940,6 +7665,7 @@ * render: unvalidated lengths in Render extn. swapped procs [CVE-2014-8100 2/2] (origin/pr/render-cve-fixes, + gh-mikedep333/pr/render-cve-fixes, gh-Ionic/pr/render-cve-fixes) 2014-10-28 10:30:04 +0100 Julien Cristau (e469cff02) @@ -7196,7 +7922,9 @@ * library clean-up: Don't build and link libXfont.a anymore. Use system's libXfont shared library and link dynamically. - (origin/pr/libxfont-cleanup, gh-Ionic/pr/libxfont-cleanup) + (origin/pr/libxfont-cleanup, + gh-mikedep333/pr/libxfont-cleanup, + gh-Ionic/pr/libxfont-cleanup) 2015-04-21 15:28:25 +0200 Mike Gabriel (a77ca871c) @@ -9737,7 +10465,8 @@ 2012-05-22 00:49:10 +0200 Mike Gabriel (222a4a222) * Imported nxagent-3.5.0-9.tar.gz (origin/nxagent, - gh-sunweaver/nxagent, gh-Ionic/nxagent) + gh-sunweaver/nxagent, gh-mikedep333/nxagent, + gh-Ionic/nxagent) 2012-05-11 23:57:35 +0200 Mike Gabriel (fe72988fb) @@ -10792,7 +11521,8 @@ 2011-11-13 09:53:38 +0100 Reinhard Tartler (6dc46faed) * Imported nxproxy-3.5.0-1.tar.gz (tag: nxproxy/3.5.0-1, - origin/nxproxy, gh-sunweaver/nxproxy, gh-Ionic/nxproxy) + origin/nxproxy, gh-sunweaver/nxproxy, + gh-mikedep333/nxproxy, gh-Ionic/nxproxy) 2011-11-13 09:53:38 +0100 Reinhard Tartler (d83d9f6be) @@ -10818,7 +11548,7 @@ * Imported nxcompshad-3.5.0-2.tar.gz (tag: nxcompshad/3.5.0-2, origin/nxcompshad, gh-sunweaver/nxcompshad, - gh-Ionic/nxcompshad) + gh-mikedep333/nxcompshad, gh-Ionic/nxcompshad) 2011-11-13 09:53:12 +0100 Reinhard Tartler (c70adf725) @@ -10852,7 +11582,7 @@ * Imported nxcompext-3.5.0-1.tar.gz (tag: nxcompext/3.5.0-1, origin/nxcompext, gh-sunweaver/nxcompext, - gh-Ionic/nxcompext) + gh-mikedep333/nxcompext, gh-Ionic/nxcompext) 2011-11-13 09:52:38 +0100 Reinhard Tartler (9573b5669) @@ -10881,7 +11611,8 @@ 2011-11-13 09:27:53 +0100 Reinhard Tartler (232dfc41d) * Imported nxcomp-3.5.0-2.tar.gz (tag: nxcomp/3.5.0-2, origin/nxcomp, - gh-sunweaver/nxcomp, gh-Ionic/nxcomp) + gh-sunweaver/nxcomp, gh-mikedep333/nxcomp, + gh-Ionic/nxcomp) 2011-11-13 09:27:53 +0100 Reinhard Tartler (233de71fc) @@ -11054,7 +11785,8 @@ 2011-10-10 17:47:59 +0200 Reinhard Tartler (15cee47a4) * Imported nx-X11-3.5.0-2.tar.gz (tag: nx-X11/3.5.0-2, origin/nx-X11, - gh-sunweaver/nx-X11, gh-Ionic/nx-X11) + gh-sunweaver/nx-X11, gh-mikedep333/nx-X11, + gh-Ionic/nx-X11) 2011-10-10 17:47:52 +0200 Reinhard Tartler (964f53964) diff --git a/VERSION b/VERSION index 479da61ea..0246204c4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.99.10 +3.5.99.11 diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index a46974104..ce406af66 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -24,7 +24,7 @@ .\" other dealings in this Software without prior written authorization .\" from The Open Group. .ds q \N'34' -.TH nxagent 1 "Sep 2017" "Version 3.5.99.10" "NX Agent (Xserver)" +.TH nxagent 1 "Dec 2017" "Version 3.5.99.11" "NX Agent (Xserver)" .SH NAME nxagent \- nested Xserver optimized for remote computing .SH SYNOPSIS diff --git a/nx-libs.spec b/nx-libs.spec index 9506cb7a2..dfa556f00 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -10,7 +10,7 @@ %endif Name: nx-libs -Version: 3.5.99.10 +Version: 3.5.99.11 Release: 0.0build1%{?dist} Summary: NX X11 protocol compression libraries diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index 702c7a606..6543bc816 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH nxproxy 1 "Sep 2017" "Version 3.5.99.10" "NX Proxy" +.TH nxproxy 1 "Dec 2017" "Version 3.5.99.11" "NX Proxy" .SH NAME nxproxy \- NX Proxy Tool .SH SYNOPSIS -- cgit v1.2.3 From 2b9025f797ee322e21077e100c2ee27c2e7fa0e0 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 15 Dec 2017 12:40:31 +0100 Subject: release 3.5.99.12 --- ChangeLog | 22 +++++++++++++++++----- VERSION | 2 +- debian/changelog | 7 +++++++ nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 2 +- nx-libs.spec | 2 +- nxproxy/man/nxproxy.1 | 2 +- 6 files changed, 28 insertions(+), 9 deletions(-) (limited to 'nxproxy') diff --git a/ChangeLog b/ChangeLog index b049dc3e8..362d5c479 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,24 @@ -2017-12-15 11:20:52 +0100 Mike Gabriel (5f673977a) +2017-12-15 12:40:31 +0100 Mike Gabriel (c3e284b96) - * release 3.5.99.11 (HEAD -> 3.6.x) + * release 3.5.99.12 (HEAD -> 3.6.x) + +2017-12-15 12:05:16 +0100 Mike Gabriel (4fb495432) + + * Xserver/hw/nxagent/Image.c: Fix regression FTBFS after d4465b71 got + merged in. (origin/HEAD, origin/3.6.x) + +2017-12-15 12:02:36 +0100 Mike Gabriel (cfbb03820) + + * debian/changelog: post-release version bump to 3.5.99.11 + (origin/release-builds/3.6.x, release-builds/3.6.x) + +2017-12-15 11:20:52 +0100 Mike Gabriel (b213c8eba) + + * release 3.5.99.11 (tag: 3.5.99.11) 2017-12-15 11:15:22 +0100 Mike Gabriel (4cca1b4bd) * Merge branch 'sunweaver-pr/more-X-memory-macro-fixes' into 3.6.x - (origin/HEAD, origin/3.6.x) 2017-12-14 11:27:35 +0100 Mike Gabriel (5597f2ea5) @@ -720,8 +733,7 @@ 2017-09-15 14:57:56 +0200 Mike Gabriel (6557c0043) - * release 3.5.99.10 (tag: 3.5.99.10, origin/release-builds/3.6.x, - release-builds/3.6.x) + * release 3.5.99.10 (tag: 3.5.99.10) 2017-09-14 07:45:45 +0200 Mihai Moldovan (4405c6a6b) diff --git a/VERSION b/VERSION index 0246204c4..2129e693c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.5.99.11 +3.5.99.12 diff --git a/debian/changelog b/debian/changelog index 810c28e6e..c37029bae 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +nx-libs (2:3.5.99.12-0) unstable; urgency=medium + + * Upstream-provided Debian package for nx-libs. + See upstream ChangeLog for recent changes. + + -- Mike Gabriel Fri, 15 Dec 2017 12:23:12 +0100 + nx-libs (2:3.5.99.11-0) unstable; urgency=medium * Upstream-provided Debian package for nx-libs. diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index ce406af66..28f397c71 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -24,7 +24,7 @@ .\" other dealings in this Software without prior written authorization .\" from The Open Group. .ds q \N'34' -.TH nxagent 1 "Dec 2017" "Version 3.5.99.11" "NX Agent (Xserver)" +.TH nxagent 1 "Dec 2017" "Version 3.5.99.12" "NX Agent (Xserver)" .SH NAME nxagent \- nested Xserver optimized for remote computing .SH SYNOPSIS diff --git a/nx-libs.spec b/nx-libs.spec index dfa556f00..480d08bcc 100644 --- a/nx-libs.spec +++ b/nx-libs.spec @@ -10,7 +10,7 @@ %endif Name: nx-libs -Version: 3.5.99.11 +Version: 3.5.99.12 Release: 0.0build1%{?dist} Summary: NX X11 protocol compression libraries diff --git a/nxproxy/man/nxproxy.1 b/nxproxy/man/nxproxy.1 index 6543bc816..4c0d563aa 100644 --- a/nxproxy/man/nxproxy.1 +++ b/nxproxy/man/nxproxy.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH nxproxy 1 "Dec 2017" "Version 3.5.99.11" "NX Proxy" +.TH nxproxy 1 "Dec 2017" "Version 3.5.99.12" "NX Proxy" .SH NAME nxproxy \- NX Proxy Tool .SH SYNOPSIS -- cgit v1.2.3