Commit f76c8240 authored by Mike Gabriel's avatar Mike Gabriel

nxcomp: Switch to autoreconf.

parent 9193d11e
......@@ -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
......
usr/lib/*/libXcomp.so
usr/lib/*/libXcomp.a
usr/include/*/nx/NX.h
usr/include/*/nx/NXalert.h
usr/include/*/nx/NXpack.h
......
......@@ -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
......
......@@ -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)
......
......@@ -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 \
......
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
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)
#/**************************************************************************/
#/* */
#/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
#/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
#/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
#/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
#/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
#/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
#/* */
#/* NXCOMP, NX protocol compression and NX extensions to this software */
#/* are copyright of the aforementioned persons and companies. */
#/* */
#/* Redistribution and use of the present software is allowed according */
#/* to terms specified in the file LICENSE.nxcomp which comes in the */
#/* source distribution. */
#/* */
#/* All rights reserved. */
#/* */
#/* NOTE: This software has received contributions from various other */
#/* contributors, only the 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
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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
}
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#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(&timestamp, 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(&timestamp, NULL);
return timestamp;
}
#endif /* Timestamp_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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);
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <zlib.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <vector>
#include <list>
#include <map>
#include <set>
#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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <stdlib.h>
#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
/**************************************************************************/
/* */
/* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <stddef.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#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;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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];
}
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <zlib.h>
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 */
# ***************************************************************************
# *** 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
dnl /**************************************************************************/
dnl /* */
dnl /* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
dnl /* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
dnl /* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
dnl /* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
dnl /* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
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 <netinet/in.h>],[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)
#! /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
../../m4/nx-macros.m4
\ No newline at end of file
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# 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
......@@ -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
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Control.h"
#include "ActionCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Agent.h"
#include "Proxy.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Unpack.h"
#include "Alpha.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Auth.h"
#include "Misc.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Bitmap.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "BlockCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "BlockCacheSet.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ChangeGC.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ChangeProperty.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Channel.h"
#include "List.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ChannelCache.h"
const unsigned int CONFIGUREWINDOW_FIELD_WIDTH[7] =
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "CharCache.h"
int CharCache::lookup(unsigned char value, unsigned int &index)
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ClearArea.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ClientCache.h"
ClientCache::ClientCache() :
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <X11/X.h>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Socket.h"
#include "Agent.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ClientReadBuffer.h"
#include "ClientChannel.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ClientStore.h"
//
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Unpack.h"
#include "Colormap.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ConfigureWindow.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "NX.h"
#include "NXpack.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "CopyArea.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "CreateGC.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "CreatePixmap.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Control.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Control.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "FillPoly.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include "Fork.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/socket.h>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "GenericReadBuffer.h"
#include "GenericChannel.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "GenericReply.h"
#include "ServerCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "GenericRequest.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "GetImage.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "GetImageReply.h"
#include "ServerCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "GetProperty.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "GetPropertyReply.h"
#include "ServerCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ImageText16.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ImageText8.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "Misc.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "InternAtom.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <X11/Xmd.h>
#ifdef ANDROID
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "List.h"
//
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ListFontsReply.h"
#include "ServerCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
......
......@@ -51,6 +51,10 @@
1999-05-03 lpd Original version.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "MD5.h"
#include <string.h>
......
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)
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <cstdio>
#include <unistd.h>
#include <cstring>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <cstdio>
#include <cctype>
#include <cstdlib>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "OpcodeStore.h"
OpcodeStore::OpcodeStore()
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// This file obviously supports PNG
// decompression. It was renamed to
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PolyArc.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PolyFillArc.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PolyFillRectangle.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PolyLine.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PolyPoint.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PolySegment.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PolyText16.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PolyText8.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ProxyReadBuffer.h"
#include "Transport.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PutImage.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "PutPackedImage.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "QueryFontReply.h"
#include "ServerCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ReadBuffer.h"
#include "Transport.h"
......
......@@ -28,6 +28,10 @@
// this message class.
//
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "RenderAddGlyphs.h"
//
......
......@@ -28,6 +28,10 @@
// this message class.
//
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "RenderChangePicture.h"
//
......
......@@ -28,6 +28,10 @@
// this message class.
//
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "RenderComposite.h"
//
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "NXrender.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "NXrender.h"
#include "RenderExtension.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//
// Include the template for
// this message class.
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Rgb.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Rle.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "SendEvent.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "SequenceQueue.h"
static const unsigned int INITIAL_SIZE_ = 16;
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ServerCache.h"
//
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include "NXalert.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ServerReadBuffer.h"
#include "ServerChannel.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ServerStore.h"
//
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "SetClipRectangles.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "SetUnpackAlpha.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "SetUnpackColormap.h"
#include "ClientCache.h"
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "SetUnpackGeometry.h"
#include "ClientCache.h"
......
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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
}
}
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/utsname.h>
......
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include <cstring>
#include <sys/stat.h>
......
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include "Statistics.h"
......
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#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(&timestamp, 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(&timestamp, NULL);
return timestamp;
}
#endif /* Timestamp_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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);
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
......
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <zlib.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <vector>
#include <list>
#include <map>
#include <set>
#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 */
......@@ -23,6 +23,10 @@
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Misc.h"
#include "Unpack.h"
......
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <stdlib.h>
#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
/**************************************************************************/
/* */
/* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 <stddef.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#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;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
......@@ -23,58 +23,29 @@
/* */
/**************************************************************************/
#ifndef StaticCompressor_H
#define StaticCompressor_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "Z.h"
#include "Control.h"
class EncodeBuffer;
class DecodeBuffer;
#include "XidCache.h"
class StaticCompressor
XidCache::XidCache()
{
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)
for (int i = 0; i < 256; i++)
{
return (compressionLevel == Z_DEFAULT_COMPRESSION ||
(compressionLevel >= Z_NO_COMPRESSION &&
compressionLevel <= Z_BEST_COMPRESSION));
base_[i] = new IntCache(8);
}
int fullReset()
slot_ = 0;
last_ = 0;
}
XidCache::~XidCache()
{
for (int i = 0; i < 256; i++)
{
return (deflateReset(&compressionStream_) == Z_OK &&
inflateReset(&decompressionStream_) == Z_OK);
delete base_[i];
}
private:
z_stream compressionStream_;
z_stream decompressionStream_;
unsigned char *buffer_;
unsigned int bufferSize_;
int threshold_;
};
#endif
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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 */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE.nxcomp which comes in the */
/* source distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the 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;
}
......@@ -23,51 +23,15 @@
/* */
/**************************************************************************/
#include "Timestamp.h"
#ifndef Z_H
#define Z_H
//
// Log level.
//
#include <zlib.h>
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
int ZCompress(z_stream *stream, unsigned char *dest, unsigned int *destLen,
const unsigned char *source, unsigned int sourceLen);
//
// Last timestamp taken from the system.
//
int ZDecompress(z_stream *stream, unsigned char *dest, unsigned int *destLen,
const unsigned char *source, unsigned int sourceLen);
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;
}
#endif /* Z_H */
......@@ -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)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment