gg: Remove internal libgadu in favor of always using an external one

Wed, 28 Sep 2016 16:07:11 -0500

author
Mike Ruprecht <cmaiku@gmail.com>
date
Wed, 28 Sep 2016 16:07:11 -0500
changeset 38067
3c2c551feeb9
parent 38066
2e94b6fa06a0
child 38068
fd6805c0df15

gg: Remove internal libgadu in favor of always using an external one

configure.ac file | annotate | diff | comparison | revisions
libpurple/protocols/gg/Makefile.am file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/COPYING file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/common.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/config.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/dcc.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/dcc7.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/debug.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/debug.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/deflate.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/deflate.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/encoding.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/encoding.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/endian.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/events.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/fileio.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/handlers.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/http.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/internal.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/libgadu.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/libgadu.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/message.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/message.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/network.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/network.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/obsolete.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/packets.pb-c.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/packets.pb-c.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/protobuf-c.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/protobuf-c.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/protobuf.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/protobuf.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/protocol.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/pubdir.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/pubdir50.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/resolver.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/resolver.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/session.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/sha1.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/strman.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/tvbuff.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/tvbuff.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/tvbuilder.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/lib/tvbuilder.h file | annotate | diff | comparison | revisions
--- a/configure.ac	Wed Sep 28 09:32:19 2016 -0500
+++ b/configure.ac	Wed Sep 28 16:07:11 2016 -0500
@@ -1181,58 +1181,38 @@
 dnl #######################################################################
 dnl # Check for Gadu-Gadu protocol library (libgadu)
 dnl #######################################################################
-
-PKG_CHECK_MODULES(LIBGADU, [libgadu >= 1.12.0], [have_libgadu=yes], [have_libgadu=no])
+AC_ARG_ENABLE(libgadu,
+	[AS_HELP_STRING([--disable-libgadu],
+		[compile without libgadu (required for GaduGadu support)])],
+	enable_libgadu="$enableval", enable_libgadu="yes")
 
-if test "x$have_libgadu" = "xyes"; then
-	AC_CHECK_LIB(gadu, gg_is_gpl_compliant, , [
-		LIBGADU_LIBS=""
-		LIBGADU_CFLAGS=""
-		have_libgadu=no
-		AC_MSG_WARN([
+if test "x$enable_libgadu" = "xyes"; then
+	PKG_CHECK_MODULES(LIBGADU, [libgadu >= 1.12.0], [
+		have_libgadu=yes
+		AC_CHECK_LIB(gadu, gg_is_gpl_compliant, , [
+			LIBGADU_LIBS=""
+			LIBGADU_CFLAGS=""
+			have_libgadu=no
+			if test "x$force_deps" = "xyes" ; then
+				AC_MSG_WARN([
 libgadu is not compatible with the GPL when compiled with OpenSSL support.
 
 To compile against system libgadu, please recompile libgadu using:
 ./configure --with-openssl=no
 Then rerun this ./configure
-
-Falling back to using our own copy of libgadu.
-		])
-	], [$LIBGADU_LIBS])
-fi
-
-AM_CONDITIONAL(HAVE_LIBGADU, test "x$have_libgadu" = "xyes")
-if test "x$have_libgadu" = "xyes"; then
-	AC_DEFINE(HAVE_LIBGADU, 1, [Linked with external libgadu])
-else
-	AC_CHECK_LIB(gnutls, gnutls_certificate_set_x509_system_trust, [gg_have_gnutls_csxst=yes], [gg_have_gnutls_csxst=no])
+				])
+			fi
+		], [$LIBGADU_LIBS])
+	], [
+		have_libgadu=no
+	])
 
-	gg_gnutls_sts=""
-	if test "x$gg_have_gnutls_csxst" = "xno"; then
-		for i in /etc/ssl/ca-bundle.pem \
-			/etc/ssl/certs/ca-certificates.crt \
-			/etc/pki/tls/cert.pem \
-			/usr/local/share/certs/ca-root-nss.crt \
-			/etc/ssl/cert.pem
-		do
-			if test -e $i; then
-				gg_gnutls_sts="$i"
-				break
-			fi
-		done
+	if test "x$have_libgadu" != "xyes" -a "x$force_deps" = "xyes" ; then
+		AC_MSG_ERROR([
+Libgadu development headers not found.
+Use --disable-libgadu if you do not need GG (GaduGadu) support.
+])
 	fi
-
-	if test "x$gg_have_gnutls_csxst" = "xyes"; then
-		AC_DEFINE(HAVE_GNUTLS_CERTIFICATE_SET_X509_SYSTEM_TRUST, 1, [gnutls contains the gnutls_certificate_set_x509_system_trust function])
-	fi
-	if test "x$gg_gnutls_sts" != "x"; then
-		AC_DEFINE_UNQUOTED(GG_CONFIG_GNUTLS_SYSTEM_TRUST_STORE, ["$gg_gnutls_sts"], [use the given file as GnuTLS default trust store])
-	fi
-
-	dnl # redundant - only here to stay compatible with libgadu upstream
-	PKG_CHECK_MODULES([GNUTLS_2_10], [gnutls >= 2.10.0], [
-		AC_DEFINE([HAVE_GNUTLS_2_10], [], [Defined if GnuTLS >= 2.10.0 is available.])
-	],:)
 fi
 
 AC_SUBST(LIBGADU_LIBS)
@@ -1259,6 +1239,9 @@
 if test "x$silcincludes" != "xyes" -o "x$silcclient" != "xyes"; then
 	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc//'`
 fi
+if test "x$have_libgadu" != "xyes" ; then
+	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/gg//'`
+fi
 if test "x$is_win32" = "xyes" ; then
 	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/zephyr//'`
 fi
@@ -1333,6 +1316,9 @@
 if test "x$silcincludes" != "xyes" -o "x$silcclient" != "xyes"; then
 	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc//'`
 fi
+if test "x$have_libgadu" != "xyes"; then
+	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/gg//'`
+fi
 if test "x$is_win32" = "xyes" ; then
 	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/zephyr//'`
 fi
@@ -2254,7 +2240,6 @@
 echo Build with Cyrus SASL support. : $enable_cyrus_sasl
 echo Use kerberos 4 with zephyr.... : $kerberos
 echo Use external libzephyr........ : $zephyr
-echo Use external libgadu.......... : $have_libgadu
 echo Install pixmaps............... : $enable_pixmaps
 echo Old tray icon compatibility... : $enable_traycompat
 echo Install translations.......... : $enable_i18n
--- a/libpurple/protocols/gg/Makefile.am	Wed Sep 28 09:32:19 2016 -0500
+++ b/libpurple/protocols/gg/Makefile.am	Wed Sep 28 16:07:11 2016 -0500
@@ -3,64 +3,9 @@
 EXTRA_DIST = \
 	account.c \
 	account.h \
-	Makefile.mingw \
-	lib/COPYING
-
-if ! HAVE_LIBGADU
-INTGG_SOURCES = \
-	lib/common.c \
-	lib/config.h \
-	lib/dcc.c \
-	lib/dcc7.c \
-	lib/debug.c \
-	lib/debug.h \
-	lib/deflate.c \
-	lib/deflate.h \
-	lib/encoding.c \
-	lib/encoding.h \
-	lib/endian.c \
-	lib/events.c \
-	lib/fileio.h \
-	lib/handlers.c \
-	lib/http.c \
-	lib/internal.h \
-	lib/libgadu.c \
-	lib/libgadu.h \
-	lib/message.c \
-	lib/message.h \
-	lib/network.c \
-	lib/network.h \
-	lib/obsolete.c \
-	lib/packets.pb-c.c \
-	lib/packets.pb-c.h \
-	lib/protobuf-c.c \
-	lib/protobuf-c.h \
-	lib/protobuf.c \
-	lib/protobuf.h \
-	lib/protocol.h \
-	lib/pubdir.c \
-	lib/pubdir50.c \
-	lib/resolver.c \
-	lib/resolver.h \
-	lib/session.h \
-	lib/strman.h \
-	lib/sha1.c \
-	lib/tvbuff.c \
-	lib/tvbuff.h \
-	lib/tvbuilder.c \
-	lib/tvbuilder.h
-
-INTGG_LIBS = $(ZLIB_LIBS) $(GNUTLS_LIBS)
-INTGG_CFLAGS = \
-	-I$(top_srcdir)/libpurple/protocols/gg/lib \
-	$(ZLIB_CFLAGS) \
-	$(GNUTLS_CFLAGS) \
-	-DGG_IGNORE_DEPRECATED
-
-endif
+	Makefile.mingw
 
 GGSOURCES = \
-	$(INTGG_SOURCES) \
 	avatar.c \
 	avatar.h \
 	blist.c \
@@ -131,13 +76,12 @@
 
 endif
 
-libgg_la_LIBADD  = @PURPLE_LIBS@ $(LIBGADU_LIBS) $(INTGG_LIBS) $(JSON_LIBS)
+libgg_la_LIBADD  = @PURPLE_LIBS@ $(LIBGADU_LIBS) $(JSON_LIBS)
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	$(LIBGADU_CFLAGS) \
-	$(INTGG_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	$(JSON_CFLAGS) \
 	$(GPLUGIN_CFLAGS) \
--- a/libpurple/protocols/gg/lib/COPYING	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,504 +0,0 @@
-		  GNU LESSER GENERAL PUBLIC LICENSE
-		       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-		  GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
--- a/libpurple/protocols/gg/lib/common.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,882 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file common.c
- *
- * \brief Funkcje wykorzystywane przez różne moduły biblioteki
- */
-
-#include "network.h"
-#include "strman.h"
-#include "fileio.h"
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-
-#include "config.h"
-#include "libgadu.h"
-#include "internal.h"
-
-#ifndef GG_CONFIG_HAVE_VA_COPY
-#  ifdef GG_CONFIG_HAVE___VA_COPY
-#    define va_copy(dest, src) __va_copy((dest), (src))
-#  else
-/* Taka wersja va_copy() działa poprawnie tylko na platformach, które
- * va_copy() de facto wcale nie potrzebują, np. MSVC. Definicja tylko dla
- * przejrzystości kodu. */
-#    define va_copy(dest, src) (dest) = (src)
-#  endif
-#endif
-
-/**
- * \internal Odpowiednik funkcji \c vsprintf alokujący miejsce na wynik.
- *
- * Funkcja korzysta z funkcji \c vsnprintf, sprawdzając czy dostępna funkcja
- * systemowa jest zgodna ze standardem C99 czy wcześniejszymi.
- *
- * \param format Format wiadomości (zgodny z \c printf)
- * \param ap Lista argumentów (zgodna z \c printf)
- *
- * \return Zaalokowany bufor lub NULL, jeśli zabrakło pamięci.
- *
- * \ingroup helper
- */
-char *gg_vsaprintf(const char *format, va_list ap)
-{
-	int size;
-	char *buf = NULL;
-	va_list aq;
-
-#if !defined(GG_CONFIG_HAVE_C99_VSNPRINTF) && !defined(HAVE__VSCPRINTF)
-	{
-		int res = 0;
-		char *tmp;
-
-		size = 128;
-		do {
-			if (res > size) {
-				/* Jednak zachowanie zgodne z C99. */
-				size = res + 1;
-			} else {
-				size *= 2;
-			}
-
-			if (!(tmp = realloc(buf, size))) {
-				free(buf);
-				return NULL;
-			}
-
-			buf = tmp;
-			va_copy(aq, ap);
-			res = vsnprintf(buf, size, format, aq);
-			va_end(aq);
-		} while (res >= size || res < 0);
-	}
-#else
-	va_copy(aq, ap);
-
-#  ifdef HAVE__VSCPRINTF
-	size = _vscprintf(format, aq) + 1;
-#  else
-	{
-		char tmp[2];
-
-		/* libce Solarisa przy buforze NULL zawsze zwracają -1, więc
-		 * musimy podać coś istniejącego jako cel printf()owania. */
-		size = vsnprintf(tmp, sizeof(tmp), format, aq) + 1;
-	}
-#  endif
-	va_end(aq);
-	if (!(buf = malloc(size)))
-		return NULL;
-
-	vsnprintf(buf, size, format, ap);
-#endif
-
-	return buf;
-}
-
-/**
- * \internal Odpowiednik funkcji \c sprintf alokujący miejsce na wynik.
- *
- * Funkcja korzysta z funkcji \c vsnprintf, sprawdzając czy dostępna funkcja
- * systemowa jest zgodna ze standardem C99 czy wcześniejszymi.
- *
- * \param format Format wiadomości (zgodny z \c printf)
- *
- * \return Zaalokowany bufor lub NULL, jeśli zabrakło pamięci.
- *
- * \ingroup helper
- */
-char *gg_saprintf(const char *format, ...)
-{
-	va_list ap;
-	char *res;
-
-	va_start(ap, format);
-	res = gg_vsaprintf(format, ap);
-	va_end(ap);
-
-	return res;
-}
-
-/**
- * \internal Pobiera linię tekstu z bufora.
- *
- * Funkcja niszczy bufor źródłowy bezpowrotnie, dzieląc go na kolejne ciągi
- * znaków i obcina znaki końca linii.
- *
- * \param ptr Wskaźnik do zmiennej, która przechowuje aktualne położenie
- *            w analizowanym buforze
- *
- * \note Funkcja nie jest już używana. Pozostała dla zachowania ABI.
- *
- * \return Wskaźnik do kolejnej linii tekstu lub NULL, jeśli to już koniec
- *         bufora.
- */
-char *gg_get_line(char **ptr)
-{
-	char *foo, *res;
-
-	if (!ptr || !*ptr || !strcmp(*ptr, ""))
-		return NULL;
-
-	res = *ptr;
-
-	if (!(foo = strchr(*ptr, '\n')))
-		*ptr += strlen(*ptr);
-	else {
-		size_t len;
-		*ptr = foo + 1;
-		*foo = 0;
-
-		len = strlen(res);
-
-		if (len > 1 && res[len - 1] == '\r')
-			res[len - 1] = 0;
-	}
-
-	return res;
-}
-
-/**
- * \internal Czyta linię tekstu z gniazda.
- *
- * Funkcja czyta tekst znak po znaku, więc nie jest efektywna, ale dzięki
- * brakowi buforowania, nie koliduje z innymi funkcjami odczytu.
- *
- * \note W przypadku zakończenia połączenia przez drugą stronę, ostatnia
- * linia nie jest zwracana.
- *
- * \param sock Deskryptor gniazda
- * \param buf Wskaźnik do bufora
- * \param length Długość bufora
- *
- * \return Zwraca wskaźnik na koniec odebranej linii jeśli się powiodło,
- * lub \c NULL w przypadku błędu.
- */
-char *gg_read_line(int sock, char *buf, int length)
-{
-	int ret;
-
-	if (!buf || length < 0)
-		return NULL;
-
-	for (; length > 1; buf++, length--) {
-		do {
-			if ((ret = recv(sock, buf, 1, 0)) == -1 &&
-				errno != EINTR && errno != EAGAIN)
-			{
-				gg_debug(GG_DEBUG_MISC, "// gg_read_line() "
-					"error on read (errno=%d, %s)\n",
-					errno, strerror(errno));
-				*buf = 0;
-				return NULL;
-			} else if (ret == 0) {
-				gg_debug(GG_DEBUG_MISC, "// gg_read_line() "
-					"eof reached\n");
-				*buf = 0;
-				return NULL;
-			}
-		} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
-
-		if (*buf == '\n') {
-			buf++;
-			break;
-		}
-	}
-
-	*buf = 0;
-	return buf;
-}
-
-/**
- * \internal Nawiązuje połączenie TCP.
- *
- * \param addr Wskaźnik na strukturę \c in_addr z adresem serwera
- * \param port Port serwera
- * \param async Flaga asynchronicznego połączenia
- *
- * \return Deskryptor gniazda lub -1 w przypadku błędu
- *
- * \ingroup helper
- */
-int gg_connect(void *addr, int port, int async)
-{
-	int sock, errno2;
-	struct sockaddr_in sin;
-	struct in_addr *a = addr;
-	struct sockaddr_in myaddr;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_connect(%s, %d, %d);\n",
-		inet_ntoa(*a), port, async);
-
-	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_connect() socket() failed "
-			"(errno=%d, %s)\n", errno, strerror(errno));
-		return -1;
-	}
-
-	memset(&myaddr, 0, sizeof(myaddr));
-	myaddr.sin_family = AF_INET;
-
-	myaddr.sin_addr.s_addr = gg_local_ip;
-
-	if (bind(sock, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_connect() bind() failed "
-			"(errno=%d, %s)\n", errno, strerror(errno));
-		errno2 = errno;
-		close(sock);
-		errno = errno2;
-		return -1;
-	}
-
-	if (async) {
-		if (!gg_fd_set_nonblocking(sock)) {
-			gg_debug(GG_DEBUG_MISC, "// gg_connect() can't set "
-				"nonblocking (errno=%d, %s)\n",
-				errno, strerror(errno));
-			errno2 = errno;
-			close(sock);
-			errno = errno2;
-			return -1;
-		}
-	}
-
-	memset(&sin, 0, sizeof(sin));
-	sin.sin_port = htons(port);
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = a->s_addr;
-
-	if (connect(sock, (struct sockaddr*) &sin, sizeof(sin)) == -1) {
-		if (errno && (!async || errno != EINPROGRESS)) {
-			gg_debug(GG_DEBUG_MISC, "// gg_connect() connect() "
-				"failed (errno=%d, %s)\n",
-				errno, strerror(errno));
-			errno2 = errno;
-			close(sock);
-			errno = errno2;
-			return -1;
-		}
-		gg_debug(GG_DEBUG_MISC,
-			"// gg_connect() connect() in progress\n");
-	}
-
-	return sock;
-}
-
-/**
- * \internal Usuwa znaki końca linii.
- *
- * Funkcja działa bezpośrednio na buforze.
- *
- * \param line Bufor z tekstem
- *
- * \ingroup helper
- */
-void gg_chomp(char *line)
-{
-	int len;
-
-	if (!line)
-		return;
-
-	len = strlen(line);
-
-	if (len > 0 && line[len - 1] == '\n')
-		line[--len] = 0;
-	if (len > 0 && line[len - 1] == '\r')
-		line[--len] = 0;
-}
-
-/**
- * \internal Koduje ciąg znaków do postacji adresu HTTP.
- *
- * Zamienia znaki niedrukowalne, spoza ASCII i mające specjalne znaczenie
- * dla protokołu HTTP na encje postaci \c %XX, gdzie \c XX jest szesnastkową
- * wartością znaku.
- *
- * \param str Ciąg znaków do zakodowania
- *
- * \return Zaalokowany bufor lub \c NULL w przypadku błędu.
- *
- * \ingroup helper
- */
-char *gg_urlencode(const char *str)
-{
-	char *q, *buf;
-	const char hex[] = "0123456789abcdef";
-	const char *p;
-	unsigned int size = 0;
-
-	if (!str)
-		str = "";
-
-	for (p = str; *p; p++, size++) {
-		if (!((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') ||
-			(*p >= '0' && *p <= '9') || *p == ' ') || (*p == '@') ||
-			(*p == '.') || (*p == '-'))
-		{
-			size += 2;
-		}
-	}
-
-	if (!(buf = malloc(size + 1)))
-		return NULL;
-
-	for (p = str, q = buf; *p; p++, q++) {
-		if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') ||
-			(*p >= '0' && *p <= '9') || (*p == '@') ||
-			(*p == '.') || (*p == '-'))
-		{
-			*q = *p;
-		} else {
-			if (*p == ' ')
-				*q = '+';
-			else {
-				*q++ = '%';
-				*q++ = hex[*p >> 4 & 15];
-				*q = hex[*p & 15];
-			}
-		}
-	}
-
-	*q = 0;
-
-	return buf;
-}
-
-/**
- * \internal Wyznacza skrót dla usług HTTP.
- *
- * Funkcja jest wykorzystywana do wyznaczania skrótu adresu e-mail, hasła
- * i innych wartości przekazywanych jako parametry usług HTTP.
- *
- * W parametrze \c format należy umieścić znaki określające postać kolejnych
- * parametrów: \c 's' jeśli parametr jest ciągiem znaków, \c 'u' jeśli jest
- * liczbą.
- *
- * \param format Format kolejnych parametrów (niezgodny z \c printf)
- *
- * \return Wartość skrótu
- */
-int gg_http_hash(const char *format, ...)
-{
-	unsigned int a, c, i, j;
-	va_list ap;
-	int b = -1;
-
-	va_start(ap, format);
-
-	for (j = 0; j < strlen(format); j++) {
-		const char *arg;
-		char buf[16];
-
-		if (format[j] == 'u') {
-			snprintf(buf, sizeof(buf), "%d", va_arg(ap, uin_t));
-			arg = buf;
-		} else {
-			if (!(arg = va_arg(ap, char*)))
-				arg = "";
-		}
-
-		i = 0;
-		while ((c = (unsigned char) arg[i++]) != 0) {
-			a = (c ^ b) + (c << 8);
-			b = (a >> 24) | (a << 8);
-		}
-	}
-
-	va_end(ap);
-
-	return (b < 0 ? -b : b);
-}
-
-/**
- * \internal Zestaw znaków kodowania base64.
- */
-static char gg_base64_charset[] =
-	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-/**
- * \internal Koduje ciąg znaków do base64.
- *
- * Wynik funkcji należy zwolnić za pomocą \c free.
- *
- * \param buf Bufor z danami do zakodowania
- *
- * \return Zaalokowany bufor z zakodowanymi danymi
- *
- * \ingroup helper
- */
-char *gg_base64_encode(const char *buf)
-{
-	char *out, *res;
-	unsigned int i = 0, j = 0, k = 0, len = strlen(buf);
-
-	res = out = malloc((len / 3 + 1) * 4 + 2);
-
-	if (!res)
-		return NULL;
-
-	while (j <= len) {
-		switch (i % 4) {
-			case 0:
-				k = (buf[j] & 252) >> 2;
-				break;
-			case 1:
-				if (j < len)
-					k = ((buf[j] & 3) << 4) | ((buf[j + 1] & 240) >> 4);
-				else
-					k = (buf[j] & 3) << 4;
-
-				j++;
-				break;
-			case 2:
-				if (j < len)
-					k = ((buf[j] & 15) << 2) | ((buf[j + 1] & 192) >> 6);
-				else
-					k = (buf[j] & 15) << 2;
-
-				j++;
-				break;
-			case 3:
-				k = buf[j++] & 63;
-				break;
-		}
-		*out++ = gg_base64_charset[k];
-		i++;
-	}
-
-	if (i % 4)
-		for (j = 0; j < 4 - (i % 4); j++, out++)
-			*out = '=';
-
-	*out = 0;
-
-	return res;
-}
-
-/**
- * \internal Dekoduje ciąg znaków zapisany w base64.
- *
- * Wynik funkcji należy zwolnić za pomocą \c free.
- *
- * \param buf Bufor źródłowy z danymi do zdekodowania
- *
- * \return Zaalokowany bufor ze zdekodowanymi danymi
- *
- * \ingroup helper
- */
-char *gg_base64_decode(const char *buf)
-{
-	char *res, *save, *foo, val;
-	const char *end;
-	unsigned int idx = 0;
-
-	if (!buf)
-		return NULL;
-
-	save = res = calloc(1, (strlen(buf) / 4 + 1) * 3 + 2);
-
-	if (!save)
-		return NULL;
-
-	end = buf + strlen(buf);
-
-	while (*buf && buf < end) {
-		if (*buf == '\r' || *buf == '\n') {
-			buf++;
-			continue;
-		}
-		if (!(foo = memchr(gg_base64_charset, *buf, sizeof(gg_base64_charset))))
-			foo = gg_base64_charset;
-		val = (int)(foo - gg_base64_charset);
-		buf++;
-		switch (idx) {
-			case 0:
-				*res |= val << 2;
-				break;
-			case 1:
-				*res++ |= val >> 4;
-				*res |= val << 4;
-				break;
-			case 2:
-				*res++ |= val >> 2;
-				*res |= val << 6;
-				break;
-			case 3:
-				*res++ |= val;
-				break;
-		}
-		idx++;
-		idx %= 4;
-	}
-	*res = 0;
-
-	return save;
-}
-
-/**
- * \internal Tworzy nagłówek autoryzacji serwera pośredniczącego.
- *
- * Dane pobiera ze zmiennych globalnych \c gg_proxy_username i
- * \c gg_proxy_password.
- *
- * \return Zaalokowany bufor z tekstem lub NULL, jeśli serwer pośredniczący
- *         nie jest używany lub nie wymaga autoryzacji.
- */
-char *gg_proxy_auth(void)
-{
-	char *tmp, *enc, *out;
-	unsigned int tmp_size;
-
-	if (!gg_proxy_enabled || !gg_proxy_username || !gg_proxy_password)
-		return NULL;
-
-	tmp_size = strlen(gg_proxy_username) + strlen(gg_proxy_password) + 2;
-	tmp = malloc(tmp_size);
-	if (!tmp)
-		return NULL;
-
-	snprintf(tmp, tmp_size, "%s:%s", gg_proxy_username, gg_proxy_password);
-
-	enc = gg_base64_encode(tmp);
-	if (!enc) {
-		free(tmp);
-		return NULL;
-	}
-
-	free(tmp);
-
-	out = malloc(strlen(enc) + 40);
-	if (!out) {
-		free(enc);
-		return NULL;
-	}
-
-	snprintf(out, strlen(enc) + 40,  "Proxy-Authorization: Basic %s\r\n", enc);
-
-	free(enc);
-
-	return out;
-}
-
-/**
- * \internal Tablica pomocnicza do wyznaczania sumy kontrolnej.
- */
-static const uint32_t gg_crc32_table[256] =
-{
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
-
-/**
- * Wyznacza sumę kontrolną CRC32.
- *
- * \param crc Suma kontrola poprzedniego bloku danych lub 0 jeśli liczona
- *            jest suma kontrolna pierwszego bloku
- * \param buf Bufor danych
- * \param len Długość bufora danych
- *
- * \return Suma kontrolna.
- */
-uint32_t gg_crc32(uint32_t crc, const unsigned char *buf, int len)
-{
-	if (buf == NULL || len < 0)
-		return crc;
-
-	crc ^= 0xffffffffL;
-
-	while (len--)
-		crc = (crc >> 8) ^ gg_crc32_table[(crc ^ *buf++) & 0xff];
-
-	return crc ^ 0xffffffffL;
-}
-
-/**
- * \internal Parsuje identyfikator użytkownika.
- *
- * \param str Ciąg tekstowy, zawierający identyfikator
- * \param len Długość identyfikatora
- *
- * \return Identyfikator, lub 0, jeżeli nie udało się odczytać
- */
-uin_t gg_str_to_uin(const char *str, int len)
-{
-	char buff[11];
-	char *endptr;
-	uin_t uin;
-
-	if (len < 0)
-		len = strlen(str);
-	if (len > 10)
-		return 0;
-	memcpy(buff, str, len);
-	buff[len] = '\0';
-
-	errno = 0;
-	uin = strtoul(buff, &endptr, 10);
-	if (errno == ERANGE || endptr[0] != '\0')
-		return 0;
-
-	return uin;
-}
-
-/**
- * Szuka informacji o konferencji o podanym identyfikatorze.
- *
- * \param sess Struktura sesji
- * \param id   Identyfikator konferencji
- *
- * \return Struktura z informacjami o konferencji
- */
-gg_chat_list_t *gg_chat_find(struct gg_session *sess, uint64_t id)
-{
-	gg_chat_list_t *chat_list = sess->private_data->chat_list;
-
-	while (chat_list != NULL) {
-		if (chat_list->id == id)
-			return chat_list;
-		chat_list = chat_list->next;
-	}
-
-	return NULL;
-}
-
-/**
- * \internal Aktualizuje informacje o konferencji.
- *
- * \param sess               Struktura sesji
- * \param id                 Identyfikator konferencji
- * \param version            Wersja informacji o konferencji
- * \param participants       Lista uczestników konferencji
- * \param participants_count Ilość uczestników konferencji
- *
- * \return Wartość równa 0, jeżeli zakończono powodzeniem
- */
-int gg_chat_update(struct gg_session *sess, uint64_t id, uint32_t version,
-	const uin_t *participants, unsigned int participants_count)
-{
-	gg_chat_list_t *chat;
-	uin_t *participants_new;
-
-	if (participants_count >= ~(unsigned int)0 / sizeof(uin_t))
-		return -1;
-
-	chat = gg_chat_find(sess, id);
-
-	if (!chat) {
-		chat = malloc(sizeof(gg_chat_list_t));
-
-		if (!chat)
-			return -1;
-
-		memset(chat, 0, sizeof(gg_chat_list_t));
-		chat->id = id;
-		chat->next = sess->private_data->chat_list;
-		sess->private_data->chat_list = chat;
-	}
-
-	participants_new = realloc(chat->participants,
-		sizeof(uin_t) * participants_count);
-
-	if (participants_new == NULL)
-		return -1;
-
-	chat->version = version;
-	chat->participants = participants_new;
-	chat->participants_count = participants_count;
-	memcpy(chat->participants, participants,
-		sizeof(uin_t) * participants_count);
-
-	return 0;
-}
-
-void gg_connection_failure(struct gg_session *gs, struct gg_event *ge,
-	enum gg_failure_t failure)
-{
-	gg_close(gs);
-
-	if (ge != NULL) {
-		ge->type = GG_EVENT_CONN_FAILED;
-		ge->event.failure = failure;
-	}
-	gs->state = GG_STATE_IDLE;
-}
-
-time_t gg_server_time(struct gg_session *gs)
-{
-	time_t now = time(NULL);
-
-	if (gs == NULL || gs->private_data == NULL) {
-		gg_debug_session(gs, GG_DEBUG_ERROR, "time diff data is not "
-			"accessible\n");
-		return now;
-	}
-
-	return now + gs->private_data->time_diff;
-}
-
-void gg_strarr_free(char **strarr)
-{
-	char **it;
-
-	if (strarr == NULL)
-		return;
-
-	for (it = strarr; *it != NULL; it++)
-		free(*it);
-	free(strarr);
-}
-
-char ** gg_strarr_dup(char **strarr)
-{
-	size_t i, len, size;
-	char **it, **out;
-
-	if (strarr == NULL)
-		return NULL;
-
-	len = 0;
-	for (it = strarr; *it != NULL; it++)
-		len++;
-
-	size = (len + 1) * sizeof(char*);
-	out = malloc(size);
-
-	if (out == NULL) {
-		gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_strarr_dup() "
-			"not enough memory for the array\n");
-		return NULL;
-	}
-	memset(out, 0, size);
-
-	for (i = 0; i < len; i++) {
-		out[i] = strdup(strarr[i]);
-		if (out[i] == NULL) {
-			gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR,
-				"// gg_strarr_dup() "
-				"not enough memory for the array element\n");
-			gg_strarr_free(out);
-			return NULL;
-		}
-	}
-
-	return out;
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
--- a/libpurple/protocols/gg/lib/config.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/* Local libgadu configuration file. */
-
-#undef printf
-
-/* libpurple's config */
-#include <config.h>
-
-#define GG_LIBGADU_VERSION "1.12.1"
-
-/* Defined if libgadu was compiled for bigendian machine. */
-#undef GG_CONFIG_BIGENDIAN
-#ifdef WORDS_BIGENDIAN
-#  define GG_CONFIG_BIGENDIAN
-#endif
-
-/* Defined if this machine has gethostbyname_r(). */
-#undef GG_CONFIG_HAVE_GETHOSTBYNAME_R
-
-/* Define to 1 if you have the `_exit' function. */
-#define HAVE__EXIT 1
-
-/* Defined if libgadu was compiled and linked with fork support. */
-#undef GG_CONFIG_HAVE_FORK
-#ifndef _WIN32
-#  define GG_CONFIG_HAVE_FORK
-#endif
-
-/* Defined if libgadu was compiled and linked with pthread support. */
-/* We don't use pthreads - they may not be safe. */
-#undef GG_CONFIG_HAVE_PTHREAD
-
-/* Defined if this machine has C99-compiliant vsnprintf(). */
-#undef HAVE_C99_VSNPRINTF
-#if !defined(_WIN32) || (defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR >= 3)
-#  define HAVE_C99_VSNPRINTF
-#endif
-
-/* Defined if this machine has va_copy(). */
-#define GG_CONFIG_HAVE_VA_COPY
-
-/* Defined if this machine has __va_copy(). */
-#define GG_CONFIG_HAVE___VA_COPY
-
-/* Defined if this machine supports long long. */
-#undef GG_CONFIG_HAVE_LONG_LONG
-#ifdef HAVE_LONG_LONG
-#  define GG_CONFIG_HAVE_LONG_LONG
-#endif
-
-/* Defined if libgadu was compiled and linked with GnuTLS support. */
-#undef GG_CONFIG_HAVE_GNUTLS
-#if defined(HAVE_GNUTLS) && defined(HAVE_GNUTLS_2_10)
-#  define GG_CONFIG_HAVE_GNUTLS
-#endif
-
-/* Defined if libgadu was compiled and linked with OpenSSL support. */
-/* OpenSSL cannot be used with libpurple due to licence type. */
-#undef GG_CONFIG_HAVE_OPENSSL
-
-/* Defined if libgadu was compiled and linked with zlib support. */
-#define GG_CONFIG_HAVE_ZLIB
-
-/* Defined if uintX_t types are defined in <stdint.h>. */
-#undef GG_CONFIG_HAVE_STDINT_H
-#ifdef HAVE_STDINT_H
-#  define GG_CONFIG_HAVE_STDINT_H
-#endif
-
-/* Defined if uintX_t types are defined in <inttypes.h>. */
-#undef GG_CONFIG_HAVE_INTTYPES_H
-#ifdef HAVE_INTTYPES_H
-#  define GG_CONFIG_HAVE_INTTYPES_H
-#endif
-
-/* Defined if uintX_t types are defined in <sys/types.h>. */
-#undef GG_CONFIG_HAVE_SYS_TYPES_H
-#ifdef HAVE_SYS_TYPES_H
-#  define GG_CONFIG_HAVE_SYS_TYPES_H
-#endif
-
-/* Defined if this machine has uint64_t. */
-#define GG_CONFIG_HAVE_UINT64_T
-
-/* Defined if libgadu is GPL compliant (was not linked with OpenSSL or any
- * other non-GPL compliant library support). */
-#define GG_CONFIG_IS_GPL_COMPLIANT
-
-/* Defined if libgadu uses system defalt trusted CAs. */
-#define GG_CONFIG_SSL_SYSTEM_TRUST
-
-/* Defined if libgadu is GPL compliant (was not linked with OpenSSL or any
-   other non-GPL compliant library support). */
-#define GG_CONFIG_IS_GPL_COMPLIANT
--- a/libpurple/protocols/gg/lib/dcc.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1410 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2008 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Tomasz Chiliński <chilek@chilan.com>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file dcc.c
- *
- * \brief Obsługa połączeń bezpośrednich do wersji Gadu-Gadu 6.x
- */
-
-#include "fileio.h"
-#include "network.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "libgadu.h"
-#include "debug.h"
-#include "internal.h"
-
-/**
- * \internal Przekazuje zawartość pakietu do odpluskwiania.
- *
- * \param prefix Prefiks informacji
- * \param fd Deskryptor gniazda
- * \param buf Bufor z danumi
- * \param size Rozmiar bufora z danymi
- */
-static void gg_dcc_debug_data(const char *prefix, int fd, const void *buf, unsigned int size)
-{
-	gg_debug(GG_DEBUG_MISC, "++ gg_dcc %s (fd=%d,len=%d)", prefix, fd, size);
-	gg_debug_dump(NULL, GG_DEBUG_DUMP, buf, size);
-	gg_debug(GG_DEBUG_MISC, "\n");
-}
-
-/**
- * Wysyła żądanie zwrotnego połączenia bezpośredniego.
- *
- * Funkcję wykorzystuje się, jeśli nie ma możliwości połączenia się z odbiorcą
- * pliku lub rozmowy głosowej. Po otrzymaniu żądania druga strona spróbuje
- * nawiązać zwrotne połączenie bezpośrednie z nadawcą.
- * gg_dcc_request()
- *
- * \param sess Struktura sesji
- * \param uin Numer odbiorcy
- *
- * \return Patrz \c gg_send_message_ctcp()
- *
- * \ingroup dcc6
- */
-int gg_dcc_request(struct gg_session *sess, uin_t uin)
-{
-	return gg_send_message_ctcp(sess, GG_CLASS_CTCP, uin, (const unsigned char*) "\002", 1);
-}
-
-/**
- * \internal Zamienia znacznik czasu w postaci uniksowej na format API WIN32.
- *
- * \note Funkcja działa jedynie gdy kompilator obsługuje typ danych
- * \c long \c long.
- *
- * \param ut Czas w postaci uniksowej
- * \param ft Czas w postaci API WIN32
- */
-static void gg_dcc_fill_filetime(uint32_t ut, uint32_t *ft)
-{
-	uint64_t tmp;
-
-	tmp = ut;
-	tmp += 11644473600LL;
-	tmp *= 10000000LL;
-
-	tmp = gg_fix64(tmp);
-
-	memcpy(ft, &tmp, sizeof(tmp));
-}
-
-/**
- * Wypełnia pola struktury \c gg_dcc niezbędne do wysłania pliku.
- *
- * \note Większą funkcjonalność zapewnia funkcja \c gg_dcc_fill_file_info2().
- *
- * \param d Struktura połączenia
- * \param filename Nazwa pliku
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup dcc6
- */
-int gg_dcc_fill_file_info(struct gg_dcc *d, const char *filename)
-{
-	return gg_dcc_fill_file_info2(d, filename, filename);
-}
-
-/**
- * Wypełnia pola struktury \c gg_dcc niezbędne do wysłania pliku.
- *
- * \param d Struktura połączenia
- * \param filename Nazwa pliku zapisywana w strukturze
- * \param local_filename Nazwa pliku w lokalnym systemie plików
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup dcc6
- */
-int gg_dcc_fill_file_info2(struct gg_dcc *d, const char *filename, const char *local_filename)
-{
-	struct stat st;
-	const char *name, *ext, *p;
-	unsigned char *q;
-	int i, j;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_fill_file_info2(%p, \"%s\", \"%s\");\n", d, filename, local_filename);
-
-	if (!d || d->type != GG_SESSION_DCC_SEND) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() invalid arguments\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if ((d->file_fd = open(local_filename, O_RDONLY)) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() open() failed (%s)\n", strerror(errno));
-		return -1;
-	}
-
-	if (fstat(d->file_fd, &st) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() "
-			"fstat() failed (%s)\n", strerror(errno));
-		close(d->file_fd);
-		d->file_fd = -1;
-		return -1;
-	}
-
-	if ((st.st_mode & S_IFDIR)) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() that's a directory\n");
-		errno = EINVAL;
-		close(d->file_fd);
-		d->file_fd = -1;
-		return -1;
-	}
-
-	memset(&d->file_info, 0, sizeof(d->file_info));
-
-	if (!(st.st_mode & S_IWUSR))
-		d->file_info.mode |= gg_fix32(GG_DCC_FILEATTR_READONLY);
-
-	gg_dcc_fill_filetime(st.st_atime, d->file_info.atime);
-	gg_dcc_fill_filetime(st.st_mtime, d->file_info.mtime);
-	gg_dcc_fill_filetime(st.st_ctime, d->file_info.ctime);
-
-	d->file_info.size = gg_fix32(st.st_size);
-	d->file_info.mode = gg_fix32(0x20);	/* FILE_ATTRIBUTE_ARCHIVE */
-
-	if (!(name = strrchr(filename, '/')))
-		name = filename;
-	else
-		name++;
-
-	if (!(ext = strrchr(name, '.')))
-		ext = name + strlen(name);
-
-	for (i = 0, p = name; i < 8 && p < ext; i++, p++)
-		d->file_info.short_filename[i] = toupper(name[i]);
-
-	if (i == 8 && p < ext) {
-		d->file_info.short_filename[6] = '~';
-		d->file_info.short_filename[7] = '1';
-	}
-
-	if (strlen(ext) > 0) {
-		for (j = 0; *ext && j < 4; j++, p++)
-			d->file_info.short_filename[i + j] = toupper(ext[j]);
-	}
-
-	for (q = d->file_info.short_filename; *q; q++) {
-		if (*q == 185) {
-			*q = 165;
-		} else if (*q == 230) {
-			*q = 198;
-		} else if (*q == 234) {
-			*q = 202;
-		} else if (*q == 179) {
-			*q = 163;
-		} else if (*q == 241) {
-			*q = 209;
-		} else if (*q == 243) {
-			*q = 211;
-		} else if (*q == 156) {
-			*q = 140;
-		} else if (*q == 159) {
-			*q = 143;
-		} else if (*q == 191) {
-			*q = 175;
-		}
-	}
-
-	gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() short name \"%s\","
-		" dos name \"%s\"\n", name, d->file_info.short_filename);
-	strncpy((char*) d->file_info.filename, name, sizeof(d->file_info.filename) - 1);
-
-	return 0;
-}
-
-/**
- * \internal Rozpoczyna połączenie bezpośrednie z danym klientem.
- *
- * \param ip Adres IP odbiorcy
- * \param port Port odbiorcy
- * \param my_uin Własny numer
- * \param peer_uin Numer odbiorcy
- * \param type Rodzaj połączenia (\c GG_SESSION_DCC_SEND lub \c GG_SESSION_DCC_GET)
- *
- * \return Struktura \c gg_dcc lub \c NULL w przypadku błędu
- */
-static struct gg_dcc *gg_dcc_transfer(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin, int type)
-{
-	struct gg_dcc *d = NULL;
-	struct in_addr addr;
-
-	addr.s_addr = ip;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_transfer(%s, %d, %u, %u, "
-		"%s);\n", inet_ntoa(addr), port, my_uin, peer_uin,
-		(type == GG_SESSION_DCC_SEND) ? "SEND" : "GET");
-
-	if (!ip || ip == INADDR_NONE || !port || !my_uin || !peer_uin) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_transfer() invalid arguments\n");
-		errno = EINVAL;
-		return NULL;
-	}
-
-	if (!(d = (void*) calloc(1, sizeof(*d)))) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_transfer() not enough memory\n");
-		return NULL;
-	}
-
-	d->check = GG_CHECK_WRITE;
-	d->state = GG_STATE_CONNECTING;
-	d->type = type;
-	d->timeout = GG_DEFAULT_TIMEOUT;
-	d->file_fd = -1;
-	d->active = 1;
-	d->fd = -1;
-	d->uin = my_uin;
-	d->peer_uin = peer_uin;
-
-	if ((d->fd = gg_connect(&addr, port, 1)) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_transfer() connection failed\n");
-		free(d);
-		return NULL;
-	}
-
-	return d;
-}
-
-/**
- * Rozpoczyna odbieranie pliku przez zwrotne połączenie bezpośrednie.
- *
- * \param ip Adres IP nadawcy
- * \param port Port nadawcy
- * \param my_uin Własny numer
- * \param peer_uin Numer nadawcy
- *
- * \return Struktura \c gg_dcc lub \c NULL w przypadku błędu
- *
- * \ingroup dcc6
- */
-struct gg_dcc *gg_dcc_get_file(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_dcc_get_file() handing over to gg_dcc_transfer()\n");
-
-	return gg_dcc_transfer(ip, port, my_uin, peer_uin, GG_SESSION_DCC_GET);
-}
-
-/**
- * Rozpoczyna wysyłanie pliku.
- *
- * \param ip Adres IP odbiorcy
- * \param port Port odbiorcy
- * \param my_uin Własny numer
- * \param peer_uin Numer odbiorcy
- *
- * \return Struktura \c gg_dcc lub \c NULL w przypadku błędu
- *
- * \ingroup dcc6
- */
-struct gg_dcc *gg_dcc_send_file(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_dcc_send_file() handing over to gg_dcc_transfer()\n");
-
-	return gg_dcc_transfer(ip, port, my_uin, peer_uin, GG_SESSION_DCC_SEND);
-}
-
-/**
- * Rozpoczyna połączenie głosowe.
- *
- * \param ip Adres IP odbiorcy
- * \param port Port odbiorcy
- * \param my_uin Własny numer
- * \param peer_uin Numer odbiorcy
- *
- * \return Struktura \c gg_dcc lub \c NULL w przypadku błędu
- *
- * \ingroup dcc6
- */
-struct gg_dcc *gg_dcc_voice_chat(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_chat() handing over to gg_dcc_transfer()\n");
-
-	return gg_dcc_transfer(ip, port, my_uin, peer_uin, GG_SESSION_DCC_VOICE);
-}
-
-/**
- * Ustawia typ przychodzącego połączenia bezpośredniego.
- *
- * Funkcję należy wywołać po otrzymaniu zdarzenia \c GG_EVENT_DCC_CALLBACK.
- *
- * \param d Struktura połączenia
- * \param type Rodzaj połączenia (\c GG_SESSION_DCC_SEND lub
- *             \c GG_SESSION_DCC_VOICE)
- *
- * \ingroup dcc6
- */
-void gg_dcc_set_type(struct gg_dcc *d, int type)
-{
-	d->type = type;
-	d->state = (type == GG_SESSION_DCC_SEND) ? GG_STATE_SENDING_FILE_INFO : GG_STATE_SENDING_VOICE_REQUEST;
-}
-
-/**
- * \internal Funkcja zwrotna połączenia bezpośredniego.
- *
- * Pole \c callback struktury \c gg_dcc zawiera wskaźnik do tej funkcji.
- * Wywołuje ona \c gg_dcc_watch_fd() i zachowuje wynik w polu \c event.
- *
- * \note Funkcjonalność funkcji zwrotnej nie jest już wspierana.
- *
- * \param d Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc_callback(struct gg_dcc *d)
-{
-	struct gg_event *e = gg_dcc_watch_fd(d);
-
-	d->event = e;
-
-	return (e != NULL) ? 0 : -1;
-}
-
-/**
- * Tworzy gniazdo nasłuchujące dla połączeń bezpośrednich.
- *
- * Funkcja przywiązuje gniazdo do pierwszego wolnego portu TCP.
- *
- * \param uin Własny numer
- * \param port Preferowany port (jeśli równy 0 lub -1, próbuje się domyślnego)
- *
- * \note Ze względu na możliwość podania wartości -1 do parametru będącego
- *       16-bitową liczbą bez znaku, port 65535 nie jest dostępny.
- *
- * \return Struktura \c gg_dcc lub \c NULL w przypadku błędu
- *
- * \ingroup dcc6
- */
-struct gg_dcc *gg_dcc_socket_create(uin_t uin, uint16_t port)
-{
-	struct gg_dcc *c;
-	int sock, bound = 0, errno2;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_create_dcc_socket(%d, %d);\n", uin, port);
-
-	if (!uin) {
-		gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() invalid arguments\n");
-		errno = EINVAL;
-		return NULL;
-	}
-
-	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() can't create socket (%s)\n", strerror(errno));
-		return NULL;
-	}
-
-	if (port == 0 || port == (uint16_t)-1)
-		port = GG_DEFAULT_DCC_PORT;
-
-	while (!bound) {
-		struct sockaddr_in sin;
-
-		memset(&sin, 0, sizeof(sin));
-		sin.sin_family = AF_INET;
-		sin.sin_addr.s_addr = INADDR_ANY;
-		sin.sin_port = htons(port);
-
-		gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() trying port %d\n", port);
-		if (!bind(sock, (struct sockaddr*) &sin, sizeof(sin)))
-			bound = 1;
-		else {
-			if (++port == 65535) {
-				gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() no free port found\n");
-				close(sock);
-				return NULL;
-			}
-		}
-	}
-
-	if (listen(sock, 10)) {
-		gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() unable to listen (%s)\n", strerror(errno));
-		errno2 = errno;
-		close(sock);
-		errno = errno2;
-		return NULL;
-	}
-
-	gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() bound to port %d\n", port);
-
-	if (!(c = malloc(sizeof(*c)))) {
-		gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() not enough memory for struct\n");
-		close(sock);
-		return NULL;
-	}
-	memset(c, 0, sizeof(*c));
-
-	c->port = c->id = port;
-	c->fd = sock;
-	c->file_fd = -1;
-	c->type = GG_SESSION_DCC_SOCKET;
-	c->uin = uin;
-	c->timeout = -1;
-	c->state = GG_STATE_LISTENING;
-	c->check = GG_CHECK_READ;
-	c->callback = gg_dcc_callback;
-	c->destroy = gg_dcc_free;
-
-	return c;
-}
-
-/**
- * Wysyła ramkę danych połączenia głosowego.
- *
- * \param d Struktura połączenia
- * \param buf Bufor z danymi
- * \param length Długość bufora z danymi
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup dcc6
- */
-int gg_dcc_voice_send(struct gg_dcc *d, char *buf, int length)
-{
-	struct packet_s {
-		uint8_t type;
-		uint32_t length;
-	} GG_PACKED;
-	struct packet_s packet;
-
-	gg_debug(GG_DEBUG_FUNCTION, "++ gg_dcc_voice_send(%p, %p, %d);\n", d, buf, length);
-	if (!d || !buf || length < 0 || d->type != GG_SESSION_DCC_VOICE) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_send() invalid argument\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	packet.type = 0x03; /* XXX */
-	packet.length = gg_fix32(length);
-
-	if (send(d->fd, &packet, sizeof(packet), 0) < (signed)sizeof(packet)) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_send() send() failed\n");
-		return -1;
-	}
-	gg_dcc_debug_data("write", d->fd, &packet, sizeof(packet));
-
-	if (send(d->fd, buf, length, 0) < length) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_send() send() failed\n");
-		return -1;
-	}
-	gg_dcc_debug_data("write", d->fd, buf, length);
-
-	return 0;
-}
-
-/**
- * \internal Odbiera dane z połączenia bezpośredniego z obsługą błędów.
- *
- * \param fd Deskryptor gniazda
- * \param buf Bufor na dane
- * \param size Rozmiar bufora na dane
- */
-#define gg_dcc_read(fd, buf, size) \
-{ \
-	int _tmp = recv(fd, buf, size, 0); \
-	\
-	if (_tmp < (int) size) { \
-		if (_tmp == -1) { \
-			gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed " \
-				"(errno=%d, %s)\n", errno, strerror(errno)); \
-		} else if (_tmp == 0) { \
-			gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed, " \
-				"connection broken\n"); \
-		} else { \
-			gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed " \
-				"(%d bytes, %" GG_SIZE_FMT " needed)\n", \
-				_tmp, size); \
-		} \
-		e->type = GG_EVENT_DCC_ERROR; \
-		e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; \
-		return e; \
-	} \
-	gg_dcc_debug_data("read", fd, buf, size); \
-}
-
-/**
- * \internal Wysyła dane do połączenia bezpośredniego z obsługą błędów.
- *
- * \param fd Deskryptor gniazda
- * \param buf Bufor z danymi
- * \param size Rozmiar bufora z danymi
- */
-#define gg_dcc_write(fd, buf, size) \
-{ \
-	int write_res; \
-	gg_dcc_debug_data("write", fd, buf, size); \
-	write_res = send(fd, buf, size, 0); \
-	if (write_res < (int) size) { \
-		if (write_res == -1) { \
-			gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() send() " \
-				"failed (errno=%d, %s)\n", errno, strerror(errno)); \
-		} else { \
-			gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() send() " \
-				"failed (%" GG_SIZE_FMT " needed, %d done)\n", \
-				size, write_res); \
-		} \
-		e->type = GG_EVENT_DCC_ERROR; \
-		e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; \
-		return e; \
-	} \
-}
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Funkcja zwraca strukturę zdarzenia \c gg_event. Jeśli rodzaj zdarzenia
- * to \c GG_EVENT_NONE, nie wydarzyło się jeszcze nic wartego odnotowania.
- * Strukturę zdarzenia należy zwolnić funkcja \c gg_event_free.
- *
- * \param h Struktura połączenia
- *
- * \return Struktura zdarzenia lub \c NULL jeśli wystąpił błąd
- *
- * \ingroup dcc6
- */
-struct gg_event *gg_dcc_watch_fd(struct gg_dcc *h)
-{
-	struct gg_event *e;
-	int foo;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_watch_fd(%p);\n", h);
-
-	if (!h || (h->type != GG_SESSION_DCC &&
-		h->type != GG_SESSION_DCC_SOCKET &&
-		h->type != GG_SESSION_DCC_SEND &&
-		h->type != GG_SESSION_DCC_GET &&
-		h->type != GG_SESSION_DCC_VOICE))
-	{
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() invalid argument\n");
-		errno = EINVAL;
-		return NULL;
-	}
-
-	if (!(e = (void*) calloc(1, sizeof(*e)))) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() not enough memory\n");
-		return NULL;
-	}
-
-	e->type = GG_EVENT_NONE;
-
-	if (h->type == GG_SESSION_DCC_SOCKET) {
-		struct sockaddr_in sin;
-		struct gg_dcc *c;
-		int fd;
-		socklen_t sin_len = sizeof(sin);
-
-		if ((fd = accept(h->fd, (struct sockaddr*) &sin, &sin_len)) == -1) {
-			gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't "
-				"accept() new connection (errno=%d, %s)\n",
-				errno, strerror(errno));
-			return e;
-		}
-
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() new direct "
-			"connection from %s:%d\n", inet_ntoa(sin.sin_addr),
-			htons(sin.sin_port));
-
-		if (!gg_fd_set_nonblocking(fd)) {
-			gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't set"
-				" nonblocking (errno=%d, %s)\n",
-				errno, strerror(errno));
-			close(fd);
-			e->type = GG_EVENT_DCC_ERROR;
-			e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
-			return e;
-		}
-
-		if (!(c = (void*) calloc(1, sizeof(*c)))) {
-			gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() not enough memory for client data\n");
-
-			free(e);
-			close(fd);
-			return NULL;
-		}
-
-		c->fd = fd;
-		c->check = GG_CHECK_READ;
-		c->state = GG_STATE_READING_UIN_1;
-		c->type = GG_SESSION_DCC;
-		c->timeout = GG_DEFAULT_TIMEOUT;
-		c->file_fd = -1;
-		c->remote_addr = sin.sin_addr.s_addr;
-		c->remote_port = ntohs(sin.sin_port);
-
-		e->type = GG_EVENT_DCC_NEW;
-		e->event.dcc_new = c;
-
-		return e;
-	} else {
-		struct gg_dcc_tiny_packet tiny_pkt;
-		struct gg_dcc_small_packet small_pkt;
-		struct gg_dcc_big_packet big_pkt;
-		int size, tmp, res;
-		unsigned int utmp;
-		socklen_t res_size = sizeof(res);
-		char buf[1024], ack[] = "UDAG";
-		void *tmp_buf;
-
-		struct gg_dcc_file_info_packet {
-			struct gg_dcc_big_packet big;
-			struct gg_file_info file_info;
-		} GG_PACKED;
-		struct gg_dcc_file_info_packet file_info_packet;
-
-		switch (h->state) {
-			case GG_STATE_READING_UIN_1:
-			case GG_STATE_READING_UIN_2:
-			{
-				uin_t uin;
-
-				gg_debug(GG_DEBUG_MISC,
-					"// gg_dcc_watch_fd() GG_READING_UIN_%d\n",
-					(h->state == GG_STATE_READING_UIN_1) ? 1 : 2);
-
-				gg_dcc_read(h->fd, &uin, sizeof(uin));
-
-				if (h->state == GG_STATE_READING_UIN_1) {
-					h->state = GG_STATE_READING_UIN_2;
-					h->check = GG_CHECK_READ;
-					h->timeout = GG_DEFAULT_TIMEOUT;
-					h->peer_uin = gg_fix32(uin);
-				} else {
-					h->state = GG_STATE_SENDING_ACK;
-					h->check = GG_CHECK_WRITE;
-					h->timeout = GG_DEFAULT_TIMEOUT;
-					h->uin = gg_fix32(uin);
-					e->type = GG_EVENT_DCC_CLIENT_ACCEPT;
-				}
-
-				return e;
-			}
-
-			case GG_STATE_SENDING_ACK:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_SENDING_ACK\n");
-
-				gg_dcc_write(h->fd, ack, (size_t)4);
-
-				h->state = GG_STATE_READING_TYPE;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				return e;
-
-			case GG_STATE_READING_TYPE:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_TYPE\n");
-
-				gg_dcc_read(h->fd, &small_pkt, sizeof(small_pkt));
-
-				small_pkt.type = gg_fix32(small_pkt.type);
-
-				switch (small_pkt.type) {
-					case 0x0003:	/* XXX */
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() callback\n");
-						h->type = GG_SESSION_DCC_SEND;
-						h->state = GG_STATE_SENDING_FILE_INFO;
-						h->check = GG_CHECK_WRITE;
-						h->timeout = GG_DEFAULT_TIMEOUT;
-
-						e->type = GG_EVENT_DCC_CALLBACK;
-
-						break;
-
-					case 0x0002:	/* XXX */
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() dialin\n");
-						h->type = GG_SESSION_DCC_GET;
-						h->state = GG_STATE_READING_REQUEST;
-						h->check = GG_CHECK_READ;
-						h->timeout = GG_DEFAULT_TIMEOUT;
-						h->incoming = 1;
-
-						break;
-
-					default:
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown dcc type "
-							"(%.4x) from %u\n", small_pkt.type, h->peer_uin);
-						e->type = GG_EVENT_DCC_ERROR;
-						e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
-				}
-
-				return e;
-
-			case GG_STATE_READING_REQUEST:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_REQUEST\n");
-
-				gg_dcc_read(h->fd, &small_pkt, sizeof(small_pkt));
-
-				small_pkt.type = gg_fix32(small_pkt.type);
-
-				switch (small_pkt.type) {
-					case 0x0001:	/* XXX */
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() file transfer request\n");
-						h->state = GG_STATE_READING_FILE_INFO;
-						h->check = GG_CHECK_READ;
-						h->timeout = GG_DEFAULT_TIMEOUT;
-						break;
-
-					case 0x0003:	/* XXX */
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() voice chat request\n");
-						h->state = GG_STATE_SENDING_VOICE_ACK;
-						h->check = GG_CHECK_WRITE;
-						h->timeout = GG_DCC_TIMEOUT_VOICE_ACK;
-						h->type = GG_SESSION_DCC_VOICE;
-						e->type = GG_EVENT_DCC_NEED_VOICE_ACK;
-
-						break;
-
-					default:
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown "
-							"dcc request (%.4x) from %u\n",
-							small_pkt.type, h->peer_uin);
-						e->type = GG_EVENT_DCC_ERROR;
-						e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
-				}
-
-				return e;
-
-			case GG_STATE_READING_FILE_INFO:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_FILE_INFO\n");
-
-				gg_dcc_read(h->fd, &file_info_packet, sizeof(file_info_packet));
-
-				memcpy(&h->file_info, &file_info_packet.file_info, sizeof(h->file_info));
-
-				h->file_info.mode = gg_fix32(h->file_info.mode);
-				h->file_info.size = gg_fix32(h->file_info.size);
-
-				h->state = GG_STATE_SENDING_FILE_ACK;
-				h->check = GG_CHECK_WRITE;
-				h->timeout = GG_DCC_TIMEOUT_FILE_ACK;
-
-				e->type = GG_EVENT_DCC_NEED_FILE_ACK;
-
-				return e;
-
-			case GG_STATE_SENDING_FILE_ACK:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_FILE_ACK\n");
-
-				big_pkt.type = gg_fix32(0x0006);	/* XXX */
-				big_pkt.dunno1 = gg_fix32(h->offset);
-				big_pkt.dunno2 = 0;
-
-				gg_dcc_write(h->fd, &big_pkt, sizeof(big_pkt));
-
-				h->state = GG_STATE_READING_FILE_HEADER;
-				h->chunk_size = sizeof(big_pkt);
-				h->chunk_offset = 0;
-				h->chunk_buf = NULL;
-				tmp_buf = malloc(sizeof(big_pkt));
-				if (!tmp_buf) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() out of memory\n");
-					free(e);
-					return NULL;
-				}
-				h->chunk_buf = tmp_buf;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				return e;
-
-			case GG_STATE_SENDING_VOICE_ACK:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_VOICE_ACK\n");
-
-				tiny_pkt.type = 0x01;	/* XXX */
-
-				gg_dcc_write(h->fd, &tiny_pkt, sizeof(tiny_pkt));
-
-				h->state = GG_STATE_READING_VOICE_HEADER;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				h->offset = 0;
-
-				return e;
-
-			case GG_STATE_READING_FILE_HEADER:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_FILE_HEADER\n");
-
-				tmp = recv(h->fd, h->chunk_buf + h->chunk_offset, h->chunk_size - h->chunk_offset, 0);
-
-				if (tmp == -1) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() "
-						"failed (errno=%d, %s)\n", errno, strerror(errno));
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_NET;
-					return e;
-				}
-
-				gg_dcc_debug_data("read", h->fd,
-					h->chunk_buf + h->chunk_offset,
-					h->chunk_size - h->chunk_offset);
-
-				h->chunk_offset += tmp;
-
-				if (h->chunk_offset < h->chunk_size)
-					return e;
-
-				memcpy(&big_pkt, h->chunk_buf, sizeof(big_pkt));
-				free(h->chunk_buf);
-				h->chunk_buf = NULL;
-
-				big_pkt.type = gg_fix32(big_pkt.type);
-				h->chunk_size = gg_fix32(big_pkt.dunno1);
-				h->chunk_offset = 0;
-
-				if (big_pkt.type == 0x0005)	{ /* XXX */
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() transfer refused\n");
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_REFUSED;
-					return e;
-				}
-
-				if (h->chunk_size == 0) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() empty chunk, EOF\n");
-					e->type = GG_EVENT_DCC_DONE;
-					return e;
-				}
-
-				h->state = GG_STATE_GETTING_FILE;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-				h->established = 1;
-
-				return e;
-
-			case GG_STATE_READING_VOICE_HEADER:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_VOICE_HEADER\n");
-
-				gg_dcc_read(h->fd, &tiny_pkt, sizeof(tiny_pkt));
-
-				switch (tiny_pkt.type) {
-					case 0x03:	/* XXX */
-						h->state = GG_STATE_READING_VOICE_SIZE;
-						h->check = GG_CHECK_READ;
-						h->timeout = GG_DEFAULT_TIMEOUT;
-						h->established = 1;
-						break;
-					case 0x04:	/* XXX */
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() "
-							"peer breaking connection\n");
-						/* XXX zwracać odpowiedni event */
-					default:
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() "
-							"unknown request (%.2x)\n", tiny_pkt.type);
-						e->type = GG_EVENT_DCC_ERROR;
-						e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
-				}
-
-				return e;
-
-			case GG_STATE_READING_VOICE_SIZE:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_VOICE_SIZE\n");
-
-				gg_dcc_read(h->fd, &small_pkt, sizeof(small_pkt));
-
-				small_pkt.type = gg_fix32(small_pkt.type);
-
-				if (small_pkt.type < 16 || small_pkt.type > sizeof(buf)) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() "
-						"invalid voice frame size (%d)\n", small_pkt.type);
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_NET;
-
-					return e;
-				}
-
-				h->chunk_size = small_pkt.type;
-				h->chunk_offset = 0;
-
-				if (!(h->voice_buf = malloc(h->chunk_size))) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() out of memory for voice frame\n");
-					free(e);
-					return NULL;
-				}
-
-				h->state = GG_STATE_READING_VOICE_DATA;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				return e;
-
-			case GG_STATE_READING_VOICE_DATA:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_VOICE_DATA\n");
-
-				tmp = recv(h->fd, h->voice_buf + h->chunk_offset, h->chunk_size - h->chunk_offset, 0);
-				if (tmp < 1) {
-					if (tmp == -1) {
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() "
-							"recv() failed (errno=%d, %s)\n",
-							errno, strerror(errno));
-					} else {
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() "
-							"recv() failed, connection broken\n");
-					}
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_NET;
-					return e;
-				}
-
-				gg_dcc_debug_data("read", h->fd, h->voice_buf + h->chunk_offset, tmp);
-
-				h->chunk_offset += tmp;
-
-				if (h->chunk_offset >= h->chunk_size) {
-					e->type = GG_EVENT_DCC_VOICE_DATA;
-					e->event.dcc_voice_data.data = (unsigned char*) h->voice_buf;
-					e->event.dcc_voice_data.length = h->chunk_size;
-					h->state = GG_STATE_READING_VOICE_HEADER;
-					h->voice_buf = NULL;
-				}
-
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				return e;
-
-			case GG_STATE_CONNECTING:
-			{
-				uin_t uins[2];
-
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_CONNECTING\n");
-
-				res = 0;
-				if ((foo = getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &res, &res_size)) || res) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() connection failed "
-						"(fd=%d,errno=%d(%s),foo=%d,res=%d(%s))\n",
-						h->fd, errno, strerror(errno), foo, res, strerror(res));
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
-					return e;
-				}
-
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() connected, sending uins\n");
-
-				uins[0] = gg_fix32(h->uin);
-				uins[1] = gg_fix32(h->peer_uin);
-
-				gg_dcc_write(h->fd, uins, sizeof(uins));
-
-				h->state = GG_STATE_READING_ACK;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				return e;
-			}
-
-			case GG_STATE_READING_ACK:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_ACK\n");
-
-				gg_dcc_read(h->fd, buf, (size_t)4);
-
-				if (strncmp(buf, ack, 4)) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() did't get ack\n");
-
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
-					return e;
-				}
-
-				h->check = GG_CHECK_WRITE;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-				h->state = GG_STATE_SENDING_REQUEST;
-
-				return e;
-
-			case GG_STATE_SENDING_VOICE_REQUEST:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_VOICE_REQUEST\n");
-
-				small_pkt.type = gg_fix32(0x0003);
-
-				gg_dcc_write(h->fd, &small_pkt, sizeof(small_pkt));
-
-				h->state = GG_STATE_READING_VOICE_ACK;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				return e;
-
-			case GG_STATE_SENDING_REQUEST:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_REQUEST\n");
-
-				small_pkt.type = (h->type == GG_SESSION_DCC_GET) ?
-					gg_fix32(0x0003) : gg_fix32(0x0002); /* XXX */
-
-				gg_dcc_write(h->fd, &small_pkt, sizeof(small_pkt));
-
-				switch (h->type) {
-					case GG_SESSION_DCC_GET:
-						h->state = GG_STATE_READING_REQUEST;
-						h->check = GG_CHECK_READ;
-						h->timeout = GG_DEFAULT_TIMEOUT;
-						break;
-
-					case GG_SESSION_DCC_SEND:
-						h->state = GG_STATE_SENDING_FILE_INFO;
-						h->check = GG_CHECK_WRITE;
-						h->timeout = GG_DEFAULT_TIMEOUT;
-
-						if (h->file_fd == -1)
-							e->type = GG_EVENT_DCC_NEED_FILE_INFO;
-						break;
-
-					case GG_SESSION_DCC_VOICE:
-						h->state = GG_STATE_SENDING_VOICE_REQUEST;
-						h->check = GG_CHECK_WRITE;
-						h->timeout = GG_DEFAULT_TIMEOUT;
-						break;
-				}
-
-				return e;
-
-			case GG_STATE_SENDING_FILE_INFO:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_FILE_INFO\n");
-
-				if (h->file_fd == -1) {
-					e->type = GG_EVENT_DCC_NEED_FILE_INFO;
-					return e;
-				}
-
-				small_pkt.type = gg_fix32(0x0001);	/* XXX */
-
-				gg_dcc_write(h->fd, &small_pkt, sizeof(small_pkt));
-
-				file_info_packet.big.type = gg_fix32(0x0003);	/* XXX */
-				file_info_packet.big.dunno1 = 0;
-				file_info_packet.big.dunno2 = 0;
-
-				memcpy(&file_info_packet.file_info, &h->file_info, sizeof(h->file_info));
-
-				/* zostają teraz u nas, więc odwracamy z powrotem */
-				h->file_info.size = gg_fix32(h->file_info.size);
-				h->file_info.mode = gg_fix32(h->file_info.mode);
-
-				gg_dcc_write(h->fd, &file_info_packet, sizeof(file_info_packet));
-
-				h->state = GG_STATE_READING_FILE_ACK;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DCC_TIMEOUT_FILE_ACK;
-
-				return e;
-
-			case GG_STATE_READING_FILE_ACK:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_FILE_ACK\n");
-
-				gg_dcc_read(h->fd, &big_pkt, sizeof(big_pkt));
-
-				/* XXX sprawdzać wynik */
-				h->offset = gg_fix32(big_pkt.dunno1);
-
-				h->state = GG_STATE_SENDING_FILE_HEADER;
-				h->check = GG_CHECK_WRITE;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				e->type = GG_EVENT_DCC_ACK;
-
-				return e;
-
-			case GG_STATE_READING_VOICE_ACK:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_VOICE_ACK\n");
-
-				gg_dcc_read(h->fd, &tiny_pkt, sizeof(tiny_pkt));
-
-				if (tiny_pkt.type != 0x01) {
-					gg_debug(GG_DEBUG_MISC, "// invalid "
-						"reply (%.2x), connection "
-						"refused\n", tiny_pkt.type);
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_REFUSED;
-					return e;
-				}
-
-				h->state = GG_STATE_READING_VOICE_HEADER;
-				h->check = GG_CHECK_READ;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-
-				e->type = GG_EVENT_DCC_ACK;
-
-				return e;
-
-			case GG_STATE_SENDING_FILE_HEADER:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_FILE_HEADER\n");
-
-				h->chunk_offset = 0;
-
-				if ((h->chunk_size = h->file_info.size - h->offset) > 4096) {
-					h->chunk_size = 4096;
-					big_pkt.type = gg_fix32(0x0003);  /* XXX */
-				} else
-					big_pkt.type = gg_fix32(0x0002);  /* XXX */
-
-				big_pkt.dunno1 = gg_fix32(h->chunk_size);
-				big_pkt.dunno2 = 0;
-
-				gg_dcc_write(h->fd, &big_pkt, sizeof(big_pkt));
-
-				h->state = GG_STATE_SENDING_FILE;
-				h->check = GG_CHECK_WRITE;
-				h->timeout = GG_DEFAULT_TIMEOUT;
-				h->established = 1;
-
-				return e;
-
-			case GG_STATE_SENDING_FILE:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_FILE\n");
-
-				if ((utmp = h->chunk_size - h->chunk_offset) > sizeof(buf))
-					utmp = sizeof(buf);
-
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() "
-					"offset=%d, size=%d\n",
-					h->offset, h->file_info.size);
-
-				/* koniec pliku? */
-				if (h->file_info.size == 0) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() read()"
-						"reached eof on empty file\n");
-					e->type = GG_EVENT_DCC_DONE;
-
-					return e;
-				}
-
-				if (h->offset >= h->file_info.size) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() offset >= size, finished\n");
-					e->type = GG_EVENT_DCC_DONE;
-					return e;
-				}
-
-				if (lseek(h->file_fd, h->offset, SEEK_SET) != (off_t)h->offset) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() lseek() "
-						"failed. (errno=%d, %s)\n",
-						errno, strerror(errno));
-
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_FILE;
-
-					return e;
-				}
-
-				size = read(h->file_fd, buf, utmp);
-
-				/* błąd */
-				if (size == -1) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() read() "
-						"failed. (errno=%d, %s)\n",
-						errno, strerror(errno));
-
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_FILE;
-
-					return e;
-				}
-
-				/* koniec pliku? */
-				if (size == 0) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() reached eof\n");
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_EOF;
-
-					return e;
-				}
-
-				/* jeśli wczytaliśmy więcej, utnijmy. */
-				if (h->offset + size > h->file_info.size) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() read() "
-						"too much (read=%d, ofs=%d, "
-						"size=%d)\n", size, h->offset,
-						h->file_info.size);
-					size = h->file_info.size - h->offset;
-
-					if (size < 1) {
-						gg_debug(GG_DEBUG_MISC,
-							"// gg_dcc_watch_fd() "
-							"reached EOF after cutting\n");
-						e->type = GG_EVENT_DCC_DONE;
-						return e;
-					}
-				}
-
-				tmp = send(h->fd, buf, size, 0);
-
-				if (tmp == -1) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() send() "
-						"failed (%s)\n", strerror(errno));
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_NET;
-					return e;
-				}
-
-				if (tmp == 0) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() send() "
-						"failed (connection reset)\n");
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_NET;
-					return e;
-				}
-
-				h->offset += tmp;
-
-				if (h->offset >= h->file_info.size) {
-					e->type = GG_EVENT_DCC_DONE;
-					return e;
-				}
-
-				h->chunk_offset += tmp;
-
-				if (h->chunk_offset >= h->chunk_size) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() chunk finished\n");
-					h->state = GG_STATE_SENDING_FILE_HEADER;
-					h->timeout = GG_DEFAULT_TIMEOUT;
-				} else {
-					h->state = GG_STATE_SENDING_FILE;
-					h->timeout = GG_DCC_TIMEOUT_SEND;
-				}
-
-				h->check = GG_CHECK_WRITE;
-
-				return e;
-
-			case GG_STATE_GETTING_FILE:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_GETTING_FILE\n");
-
-				if ((utmp = h->chunk_size - h->chunk_offset) > sizeof(buf))
-					utmp = sizeof(buf);
-
-				if (h->offset >= h->file_info.size) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() offset >= size, finished\n");
-					e->type = GG_EVENT_DCC_DONE;
-					return e;
-				}
-
-				size = recv(h->fd, buf, utmp, 0);
-
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() "
-					"ofs=%d, size=%d, recv()=%d\n",
-					h->offset, h->file_info.size, size);
-
-				/* błąd */
-				if (size == -1) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() recv() "
-						"failed. (errno=%d, %s)\n",
-						errno, strerror(errno));
-
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_NET;
-
-					return e;
-				}
-
-				/* koniec? */
-				if (size == 0) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() reached eof\n");
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_EOF;
-
-					return e;
-				}
-
-				tmp = write(h->file_fd, buf, size);
-
-				if (tmp == -1 || tmp < size) {
-					gg_debug(GG_DEBUG_MISC,
-						"// gg_dcc_watch_fd() write() "
-						"failed (%d:fd=%d:res=%d:%s)\n",
-						tmp, h->file_fd, size,
-						strerror(errno));
-					e->type = GG_EVENT_DCC_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC_NET;
-					return e;
-				}
-
-				h->offset += size;
-
-				if (h->offset >= h->file_info.size) {
-					e->type = GG_EVENT_DCC_DONE;
-					return e;
-				}
-
-				h->chunk_offset += size;
-
-				if (h->chunk_offset >= h->chunk_size) {
-					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() chunk finished\n");
-					h->state = GG_STATE_READING_FILE_HEADER;
-					h->timeout = GG_DEFAULT_TIMEOUT;
-					h->chunk_offset = 0;
-					h->chunk_size = sizeof(big_pkt);
-					h->chunk_buf = NULL;
-					tmp_buf = malloc(sizeof(big_pkt));
-					if (!tmp_buf) {
-						gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() out of memory\n");
-						free(e);
-						return NULL;
-					}
-					h->chunk_buf = tmp_buf;
-				} else {
-					h->state = GG_STATE_GETTING_FILE;
-					h->timeout = GG_DCC_TIMEOUT_GET;
-				}
-
-				h->check = GG_CHECK_READ;
-
-				return e;
-
-			default:
-				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_???\n");
-				e->type = GG_EVENT_DCC_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
-
-				return e;
-		}
-	}
-
-	return e;
-}
-
-/**
- * Zwalnia zasoby używane przez połączenie bezpośrednie.
- *
- * \param d Struktura połączenia
- *
- * \ingroup dcc6
- */
-void gg_dcc_free(struct gg_dcc *d)
-{
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_free(%p);\n", d);
-
-	if (!d)
-		return;
-
-	if (d->fd != -1)
-		close(d->fd);
-
-	if (d->file_fd != -1)
-		gg_file_close(d->file_fd);
-
-	free(d->chunk_buf);
-	free(d);
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
--- a/libpurple/protocols/gg/lib/dcc7.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1660 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2010 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Tomasz Chiliński <chilek@chilan.com>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *                          Bartłomiej Zimoń <uzi18@o2.pl>
- *
- *  Thanks to Jakub Zawadzki <darkjames@darkjames.ath.cx>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110,
- *  USA.
- */
-
-/**
- * \file dcc7.c
- *
- * \brief Obsługa połączeń bezpośrednich od wersji Gadu-Gadu 7.x
- */
-
-#include "fileio.h"
-#include "network.h"
-#include "strman.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "libgadu.h"
-#include "protocol.h"
-#include "resolver.h"
-#include "internal.h"
-#include "debug.h"
-
-#ifdef _MSC_VER
-#  define gg_debug_dcc(dcc, level, fmt, ...) \
-	gg_debug_session(((dcc) != NULL) ? (dcc)->sess : NULL, level, fmt, __VA_ARGS__)
-#else
-#  define gg_debug_dcc(dcc, level, fmt...) \
-	gg_debug_session(((dcc) != NULL) ? (dcc)->sess : NULL, level, fmt)
-#endif
-
-#define gg_debug_dump_dcc(dcc, level, buf, len) \
-	gg_debug_dump(((dcc) != NULL) ? (dcc)->sess : NULL, level, buf, len)
-
-/**
- * \internal Dodaje połączenie bezpośrednie do sesji.
- *
- * \param sess Struktura sesji
- * \param dcc Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc7_session_add(struct gg_session *sess, struct gg_dcc7 *dcc)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_session_add(%p, %p)\n", sess, dcc);
-
-	if (!sess || !dcc || dcc->next) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_session_add() invalid parameters\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	dcc->next = sess->dcc7_list;
-	sess->dcc7_list = dcc;
-
-	return 0;
-}
-
-/**
- * \internal Usuwa połączenie bezpośrednie z sesji.
- *
- * \param sess Struktura sesji
- * \param dcc Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc7_session_remove(struct gg_session *sess, struct gg_dcc7 *dcc)
-{
-	struct gg_dcc7 *tmp;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_session_remove(%p, %p)\n", sess, dcc);
-
-	if (sess == NULL || dcc == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_session_remove() invalid parameters\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (sess->dcc7_list == dcc) {
-		sess->dcc7_list = dcc->next;
-		dcc->next = NULL;
-		return 0;
-	}
-
-	for (tmp = sess->dcc7_list; tmp != NULL; tmp = tmp->next) {
-		if (tmp->next == dcc) {
-			tmp->next = dcc->next;
-			dcc->next = NULL;
-			return 0;
-		}
-	}
-
-	errno = ENOENT;
-	return -1;
-}
-
-/**
- * \internal Zwraca strukturę połączenia o danym identyfikatorze.
- *
- * \param sess Struktura sesji
- * \param id Identyfikator połączenia
- * \param uin Numer nadawcy lub odbiorcy
- *
- * \return Struktura połączenia lub \c NULL jeśli nie znaleziono
- */
-static struct gg_dcc7 *gg_dcc7_session_find(struct gg_session *sess, gg_dcc7_id_t id, uin_t uin)
-{
-	struct gg_dcc7 *tmp;
-	int empty;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_session_find(%p, ..., %d)\n", sess, (int) uin);
-
-	empty = !memcmp(&id, "\0\0\0\0\0\0\0\0", 8);
-
-	for (tmp = sess->dcc7_list; tmp; tmp = tmp->next) {
-		if (empty) {
-			if (tmp->peer_uin == uin && tmp->state == GG_STATE_WAITING_FOR_ACCEPT)
-				return tmp;
-		} else {
-			if (!memcmp(&tmp->cid, &id, sizeof(id)))
-				return tmp;
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * \internal Rozpoczyna proces pobierania adresu
- *
- * \param dcc Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc7_get_relay_addr(struct gg_dcc7 *dcc)
-{
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_get_relay_addr(%p)\n", dcc);
-
-	if (dcc == NULL || dcc->sess == NULL) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_get_relay_addr() invalid parameters\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (dcc->sess->resolver_start(&dcc->fd, &dcc->resolver, GG_RELAY_HOST) == -1) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_get_relay_addr() "
-			"resolving failed (errno=%d, %s)\n",
-			errno, strerror(errno));
-		return -1;
-	}
-
-	dcc->state = GG_STATE_RESOLVING_RELAY;
-	dcc->check = GG_CHECK_READ;
-	dcc->timeout = GG_DEFAULT_TIMEOUT;
-
-	return 0;
-}
-
-/**
- * \internal Nawiązuje połączenie bezpośrednie
- *
- * \param dcc Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc7_connect(struct gg_dcc7 *dcc)
-{
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_connect(%p)\n", dcc);
-
-	if (dcc == NULL) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_connect() invalid parameters\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if ((dcc->fd = gg_connect(&dcc->remote_addr, dcc->remote_port, 1)) == -1) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_connect() connection failed\n");
-		return -1;
-	}
-
-	dcc->state = GG_STATE_CONNECTING;
-	dcc->check = GG_CHECK_WRITE;
-	dcc->timeout = GG_DCC7_TIMEOUT_CONNECT;
-	dcc->soft_timeout = 1;
-
-	return 0;
-}
-
-/**
- * \internal Tworzy gniazdo nasłuchujące dla połączenia bezpośredniego
- *
- * \param dcc Struktura połączenia
- * \param addr Preferowany adres (jeśli równy 0, nasłuchujemy na wszystkich interfejsach)
- * \param port Preferowany port (jeśli równy 0, nasłuchujemy na losowym)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc7_listen(struct gg_dcc7 *dcc, uint32_t addr, uint16_t port)
-{
-	struct sockaddr_in sin;
-	socklen_t sin_len = sizeof(sin);
-	int errsv;
-	int fd;
-
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_listen(%p, %d)\n", dcc, port);
-
-	if (!dcc) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() invalid parameters\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() can't create socket (%s)\n", strerror(errno));
-		return -1;
-	}
-
-	memset(&sin, 0, sizeof(sin));
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = addr;
-	sin.sin_port = htons(port);
-
-	if (bind(fd, (struct sockaddr*) &sin, sizeof(sin)) == -1) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() unable to"
-			" bind to %s:%d\n", inet_ntoa(sin.sin_addr), port);
-		goto fail;
-	}
-
-	if (port == 0 && getsockname(fd, (struct sockaddr*) &sin, &sin_len) == -1) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() unable to bind to port %d\n", port);
-		goto fail;
-	}
-
-	if (listen(fd, 1)) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() unable to listen (%s)\n", strerror(errno));
-		goto fail;
-	}
-
-	dcc->fd = fd;
-	dcc->local_addr = sin.sin_addr.s_addr;
-	dcc->local_port = ntohs(sin.sin_port);
-
-	dcc->state = GG_STATE_LISTENING;
-	dcc->check = GG_CHECK_READ;
-	dcc->timeout = GG_DCC7_TIMEOUT_FILE_ACK;
-
-	return 0;
-
-fail:
-	errsv = errno;
-	close(fd);
-	errno = errsv;
-	return -1;
-}
-
-/**
- * \internal Tworzy gniazdo nasłuchujące i wysyła jego parametry
- *
- * \param dcc Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc7_listen_and_send_info(struct gg_dcc7 *dcc)
-{
-	struct gg_dcc7_info pkt;
-	uint16_t external_port;
-	uint32_t external_addr;
-	struct in_addr addr;
-
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_listen_and_send_info(%p)\n", dcc);
-
-	if (gg_dcc7_listen(dcc, dcc->sess->client_addr, dcc->sess->client_port) == -1)
-		return -1;
-
-	if (dcc->sess->external_port != 0)
-		external_port = dcc->sess->external_port;
-	else
-		external_port = dcc->local_port;
-
-	if (dcc->sess->external_addr != 0)
-		external_addr = dcc->sess->external_addr;
-	else
-		external_addr = dcc->local_addr;
-
-	addr.s_addr = external_addr;
-
-	gg_debug_dcc(dcc, GG_DEBUG_MISC, "// dcc7_listen_and_send_info() "
-		"sending IP address %s and port %d\n",
-		inet_ntoa(addr), external_port);
-
-	memset(&pkt, 0, sizeof(pkt));
-	pkt.uin = gg_fix32(dcc->peer_uin);
-	pkt.type = GG_DCC7_TYPE_P2P;
-	pkt.id = dcc->cid;
-	snprintf((char*) pkt.info, sizeof(pkt.info), "%s %d", inet_ntoa(addr), external_port);
-	snprintf((char*) pkt.hash, sizeof(pkt.hash), "%u", external_addr + external_port * rand());
-
-	return gg_send_packet(dcc->sess, GG_DCC7_INFO, &pkt, sizeof(pkt), NULL);
-}
-
-/**
- * \internal Odwraca połączenie po nieudanym connect()
- *
- * \param dcc Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc7_reverse_connect(struct gg_dcc7 *dcc)
-{
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_reverse_connect(%p)\n", dcc);
-
-	if (dcc == NULL)
-		return -1;
-
-	if (dcc->reverse) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_reverse_connect() already reverse connection\n");
-		return -1;
-	}
-
-	gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_reverse_connect() timeout, trying reverse connection\n");
-	close(dcc->fd);
-	dcc->fd = -1;
-	dcc->reverse = 1;
-
-	return gg_dcc7_listen_and_send_info(dcc);
-}
-
-/**
- * \internal Wysyła do serwera żądanie nadania identyfikatora sesji
- *
- * \param sess Struktura sesji
- * \param type Rodzaj połączenia (\c GG_DCC7_TYPE_FILE lub \c GG_DCC7_TYPE_VOICE)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_dcc7_request_id(struct gg_session *sess, uint32_t type)
-{
-	struct gg_dcc7_id_request pkt;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_request_id(%p, %d)\n", sess, type);
-
-	if (!sess) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_request_id() invalid parameters\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_request_id() not connected\n");
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	if (type != GG_DCC7_TYPE_VOICE && type != GG_DCC7_TYPE_FILE) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_request_id() invalid transfer type (%d)\n", type);
-		errno = EINVAL;
-		return -1;
-	}
-
-	memset(&pkt, 0, sizeof(pkt));
-	pkt.type = gg_fix32(type);
-
-	return gg_send_packet(sess, GG_DCC7_ID_REQUEST, &pkt, sizeof(pkt), NULL);
-}
-
-/**
- * \internal Rozpoczyna wysyłanie pliku.
- *
- * Funkcja jest wykorzystywana przez \c gg_dcc7_send_file() oraz
- * \c gg_dcc_send_file_fd().
- *
- * \param sess Struktura sesji
- * \param rcpt Numer odbiorcy
- * \param fd Deskryptor pliku
- * \param size Rozmiar pliku
- * \param filename1250 Nazwa pliku w kodowaniu CP-1250
- * \param hash Skrót SHA-1 pliku
- * \param seek Flaga mówiąca, czy można używać lseek()
- *
- * \return Struktura \c gg_dcc7 lub \c NULL w przypadku błędu
- *
- * \ingroup dcc7
- */
-static struct gg_dcc7 *gg_dcc7_send_file_common(struct gg_session *sess,
-	uin_t rcpt, int fd, size_t size, const char *filename1250,
-	const char *hash, int seek)
-{
-	struct gg_dcc7 *dcc = NULL;
-
-	if (!sess || !rcpt || !filename1250 || !hash || fd == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file_common() invalid parameters\n");
-		errno = EINVAL;
-		goto fail;
-	}
-
-	if (!(dcc = malloc(sizeof(struct gg_dcc7)))) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file_common() not enough memory\n");
-		goto fail;
-	}
-
-	if (gg_dcc7_request_id(sess, GG_DCC7_TYPE_FILE) == -1)
-		goto fail;
-
-	memset(dcc, 0, sizeof(struct gg_dcc7));
-	dcc->type = GG_SESSION_DCC7_SEND;
-	dcc->dcc_type = GG_DCC7_TYPE_FILE;
-	dcc->state = GG_STATE_REQUESTING_ID;
-	dcc->timeout = GG_DEFAULT_TIMEOUT;
-	dcc->sess = sess;
-	dcc->fd = -1;
-	dcc->uin = sess->uin;
-	dcc->peer_uin = rcpt;
-	dcc->file_fd = fd;
-	dcc->size = size;
-	dcc->seek = seek;
-
-	strncpy((char*) dcc->filename, filename1250, GG_DCC7_FILENAME_LEN);
-	dcc->filename[GG_DCC7_FILENAME_LEN] = 0;
-
-	memcpy(dcc->hash, hash, GG_DCC7_HASH_LEN);
-
-	if (gg_dcc7_session_add(sess, dcc) == -1)
-		goto fail;
-
-	return dcc;
-
-fail:
-	free(dcc);
-	return NULL;
-}
-
-/**
- * Rozpoczyna wysyłanie pliku o danej nazwie.
- *
- * \param sess Struktura sesji
- * \param rcpt Numer odbiorcy
- * \param filename Nazwa pliku w lokalnym systemie plików
- * \param filename1250 Nazwa pliku w kodowaniu CP-1250
- * \param hash Skrót SHA-1 pliku (lub \c NULL jeśli ma być wyznaczony)
- *
- * \return Struktura \c gg_dcc7 lub \c NULL w przypadku błędu
- *
- * \ingroup dcc7
- */
-struct gg_dcc7 *gg_dcc7_send_file(struct gg_session *sess, uin_t rcpt,
-	const char *filename, const char *filename1250, const char *hash)
-{
-	struct gg_dcc7 *dcc = NULL;
-	const char *tmp;
-	char hash_buf[GG_DCC7_HASH_LEN];
-	struct stat st;
-	int fd = -1;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_send_file(%p, %d,"
-		" \"%s\", %p)\n", sess, rcpt, filename, hash);
-
-	if (!sess || !rcpt || !filename) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file() invalid parameters\n");
-		errno = EINVAL;
-		goto fail;
-	}
-
-	if (!filename1250)
-		filename1250 = filename;
-
-	if ((fd = open(filename, O_RDONLY)) == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file() open() failed (%s)\n", strerror(errno));
-		goto fail;
-	}
-
-	if (fstat(fd, &st) == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file() "
-			"fstat() failed (%s)\n", strerror(errno));
-		goto fail;
-	}
-
-	if ((st.st_mode & S_IFDIR)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file() that's a directory\n");
-		errno = EINVAL;
-		goto fail;
-	}
-
-	if (!hash) {
-		if (gg_file_hash_sha1(fd, (uint8_t*) hash_buf) == -1)
-			goto fail;
-
-		hash = hash_buf;
-	}
-
-	if ((tmp = strrchr(filename1250, '/')))
-		filename1250 = tmp + 1;
-
-	if (!(dcc = gg_dcc7_send_file_common(sess, rcpt, fd, st.st_size, filename1250, hash, 1)))
-		goto fail;
-
-	return dcc;
-
-fail:
-	if (fd != -1) {
-		int errsv = errno;
-		gg_file_close(fd);
-		errno = errsv;
-	}
-
-	free(dcc);
-	return NULL;
-}
-
-/**
- * \internal Rozpoczyna wysyłanie pliku o danym deskryptorze.
- *
- * \note Wysyłanie pliku nie będzie działać poprawnie, jeśli deskryptor
- * źródłowy jest w trybie nieblokującym i w pewnym momencie zabraknie danych.
- *
- * \param sess Struktura sesji
- * \param rcpt Numer odbiorcy
- * \param fd Deskryptor pliku
- * \param size Rozmiar pliku
- * \param filename1250 Nazwa pliku w kodowaniu CP-1250
- * \param hash Skrót SHA-1 pliku
- *
- * \return Struktura \c gg_dcc7 lub \c NULL w przypadku błędu
- *
- * \ingroup dcc7
- */
-struct gg_dcc7 *gg_dcc7_send_file_fd(struct gg_session *sess, uin_t rcpt,
-	int fd, size_t size, const char *filename1250, const char *hash)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_send_file_fd(%p, "
-		"%d, %d, %" GG_SIZE_FMT ", \"%s\", %p)\n",
-		sess, rcpt, fd, size, filename1250, hash);
-
-	return gg_dcc7_send_file_common(sess, rcpt, fd, size, filename1250, hash, 0);
-}
-
-
-/**
- * Potwierdza chęć odebrania pliku.
- *
- * \param dcc Struktura połączenia
- * \param offset Początkowy offset przy wznawianiu przesyłania pliku
- *
- * \note Biblioteka nie zmienia położenia w odbieranych plikach. Jeśli offset
- * początkowy jest różny od zera, należy ustawić go funkcją \c lseek() lub
- * podobną.
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup dcc7
- */
-int gg_dcc7_accept(struct gg_dcc7 *dcc, unsigned int offset)
-{
-	struct gg_dcc7_accept pkt;
-
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_accept(%p, %d)\n", dcc, offset);
-
-	if (!dcc || !dcc->sess) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_accept() invalid parameters\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	memset(&pkt, 0, sizeof(pkt));
-	pkt.uin = gg_fix32(dcc->peer_uin);
-	pkt.id = dcc->cid;
-	pkt.offset = gg_fix32(offset);
-
-	if (gg_send_packet(dcc->sess, GG_DCC7_ACCEPT, &pkt, sizeof(pkt), NULL) == -1)
-		return -1;
-
-	dcc->offset = offset;
-
-	return gg_dcc7_listen_and_send_info(dcc);
-}
-
-/**
- * Odrzuca próbę przesłania pliku.
- *
- * \param dcc Struktura połączenia
- * \param reason Powód odrzucenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup dcc7
- */
-int gg_dcc7_reject(struct gg_dcc7 *dcc, int reason)
-{
-	struct gg_dcc7_reject pkt;
-
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_reject(%p, %d)\n", dcc, reason);
-
-	if (!dcc || !dcc->sess) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_reject() invalid parameters\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	memset(&pkt, 0, sizeof(pkt));
-	pkt.uin = gg_fix32(dcc->peer_uin);
-	pkt.id = dcc->cid;
-	pkt.reason = gg_fix32(reason);
-
-	return gg_send_packet(dcc->sess, GG_DCC7_REJECT, &pkt, sizeof(pkt), NULL);
-}
-
-/**
- * \internal Obsługuje pakiet identyfikatora połączenia bezpośredniego.
- *
- * \param sess Struktura sesji
- * \param e Struktura zdarzenia
- * \param payload Treść pakietu
- * \param len Długość pakietu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_dcc7_handle_id(struct gg_session *sess, struct gg_event *e, const void *payload, int len)
-{
-	const struct gg_dcc7_id_reply *p = payload;
-	struct gg_dcc7 *tmp;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_handle_id(%p, %p, %p, %d)\n", sess, e, payload, len);
-
-	for (tmp = sess->dcc7_list; tmp; tmp = tmp->next) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// checking dcc %p, "
-			"state %d, type %d\n", tmp, tmp->state, tmp->dcc_type);
-
-		if (tmp->state != GG_STATE_REQUESTING_ID || tmp->dcc_type != (int) gg_fix32(p->type))
-			continue;
-
-		tmp->cid = p->id;
-
-		switch (tmp->dcc_type) {
-			case GG_DCC7_TYPE_FILE:
-			{
-				struct gg_dcc7_new s;
-
-				memset(&s, 0, sizeof(s));
-				s.id = tmp->cid;
-				s.type = gg_fix32(GG_DCC7_TYPE_FILE);
-				s.uin_from = gg_fix32(tmp->uin);
-				s.uin_to = gg_fix32(tmp->peer_uin);
-				s.size = gg_fix32(tmp->size);
-
-				/* Uwaga: To nie jest ciąg kończony zerem.
-				 * Note: This is not a null-terminated string. */
-				GG_STATIC_ASSERT(
-					sizeof(s.filename) == sizeof(tmp->filename) - 1,
-					filename_sizes_does_not_match);
-				memcpy((char*)s.filename, (char*)tmp->filename, sizeof(s.filename));
-
-				tmp->state = GG_STATE_WAITING_FOR_ACCEPT;
-				tmp->timeout = GG_DCC7_TIMEOUT_FILE_ACK;
-
-				return gg_send_packet(sess, GG_DCC7_NEW, &s, sizeof(s), NULL);
-			}
-		}
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet akceptacji połączenia bezpośredniego.
- *
- * \param sess Struktura sesji
- * \param e Struktura zdarzenia
- * \param payload Treść pakietu
- * \param len Długość pakietu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_dcc7_handle_accept(struct gg_session *sess, struct gg_event *e, const void *payload, int len)
-{
-	const struct gg_dcc7_accept *p = payload;
-	struct gg_dcc7 *dcc;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_handle_accept(%p, %p, %p, %d)\n", sess, e, payload, len);
-
-	if (!(dcc = gg_dcc7_session_find(sess, p->id, gg_fix32(p->uin)))) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_accept() unknown dcc session\n");
-		/* XXX wysłać reject? */
-		e->type = GG_EVENT_DCC7_ERROR;
-		e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-		return 0;
-	}
-
-	if (dcc->state != GG_STATE_WAITING_FOR_ACCEPT) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_accept() invalid state\n");
-		e->type = GG_EVENT_DCC7_ERROR;
-		e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-		return 0;
-	}
-
-	/* XXX czy dla odwrotnego połączenia powinniśmy wywołać już zdarzenie GG_DCC7_ACCEPT? */
-
-	dcc->offset = gg_fix32(p->offset);
-	dcc->state = GG_STATE_WAITING_FOR_INFO;
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet informacji o połączeniu bezpośrednim.
- *
- * \param sess Struktura sesji
- * \param e Struktura zdarzenia
- * \param payload Treść pakietu
- * \param len Długość pakietu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_dcc7_handle_info(struct gg_session *sess, struct gg_event *e, const void *payload, int len)
-{
-	const struct gg_dcc7_info *p = payload;
-	struct gg_dcc7 *dcc;
-	char *tmp;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_handle_info(%p, %p, %p, %d)\n", sess, e, payload, len);
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "// gg_dcc7_handle_info() "
-		"received address: %s, hash: %s\n", p->info, p->hash);
-
-	if (!(dcc = gg_dcc7_session_find(sess, p->id, gg_fix32(p->uin)))) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() unknown dcc session\n");
-		return 0;
-	}
-
-	if (dcc->state == GG_STATE_CONNECTED) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() state is already connected\n");
-		return 0;
-	}
-
-	switch (p->type)
-	{
-	case GG_DCC7_TYPE_P2P:
-		if ((dcc->remote_addr = inet_addr(p->info)) == INADDR_NONE) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() invalid IP address\n");
-			e->type = GG_EVENT_DCC7_ERROR;
-			e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-			return 0;
-		}
-
-		if (!(tmp = strchr(p->info, ' ')) || !(dcc->remote_port = atoi(tmp + 1))) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() invalid IP port\n");
-			e->type = GG_EVENT_DCC7_ERROR;
-			e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-			return 0;
-		}
-
-		if (dcc->state == GG_STATE_WAITING_FOR_INFO) {
-			gg_debug_session(sess, GG_DEBUG_MISC,
-				"// gg_dcc7_handle_info() waiting for info "
-				"so send one\n");
-			gg_dcc7_listen_and_send_info(dcc);
-			e->type = GG_EVENT_DCC7_PENDING;
-			e->event.dcc7_pending.dcc7 = dcc;
-			return 0;
-		}
-
-		break;
-
-	case GG_DCC7_TYPE_SERVER:
-		if (!(tmp = strstr(p->info, "GG"))) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() unknown info packet\n");
-			e->type = GG_EVENT_DCC7_ERROR;
-			e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-			return 0;
-		}
-
-#if defined(HAVE__STRTOUI64) || defined(HAVE_STRTOULL)
-		{
-			uint64_t cid;
-
-#  ifdef HAVE__STRTOUI64
-			cid = _strtoui64(tmp + 2, NULL, 0);
-#  else
-			cid = strtoull(tmp + 2, NULL, 0);
-#  endif
-
-			gg_debug_session(sess, GG_DEBUG_MISC,
-				"// gg_dcc7_handle_info() info.str=%s, "
-				"info.id=%llu, sess.id=%llu\n", tmp + 2, cid,
-				*((unsigned long long*) &dcc->cid));
-
-			cid = gg_fix64(cid);
-
-			if (memcmp(&dcc->cid, &cid, sizeof(cid)) != 0) {
-				gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() invalid session id\n");
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-				return 0;
-			}
-		}
-#else
-		(void)tmp;
-#endif
-
-		if (gg_dcc7_get_relay_addr(dcc) == -1) {
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_handle_info() unable to retrieve relay address\n");
-			e->type = GG_EVENT_DCC7_ERROR;
-			e->event.dcc7_error = GG_ERROR_DCC7_RELAY;
-			return 0;
-		}
-
-		/* XXX wysyłać dopiero jeśli uda się połączyć z serwerem? */
-
-		gg_send_packet(dcc->sess, GG_DCC7_INFO, payload, len, NULL);
-
-		return 0;
-
-	default:
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info()"
-			" unhandled transfer type (%d)\n", p->type);
-		e->type = GG_EVENT_DCC7_ERROR;
-		e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-		return 0;
-	}
-
-#if 0
-	/* jeśli nadal czekamy na połączenie przychodzące, a druga strona nie
-	 * daje rady i oferuje namiary na siebie, bierzemy co dają.
-	 */
-	if (dcc->state != GG_STATE_WAITING_FOR_INFO && (dcc->state != GG_STATE_LISTENING || dcc->reverse)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() invalid state\n");
-		e->type = GG_EVENT_DCC7_ERROR;
-		e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-		return 0;
-	}
-#endif
-
-	if (dcc->state == GG_STATE_LISTENING) {
-		close(dcc->fd);
-		dcc->fd = -1;
-		dcc->reverse = 1;
-	}
-
-	if (dcc->type == GG_SESSION_DCC7_SEND) {
-		e->type = GG_EVENT_DCC7_ACCEPT;
-		e->event.dcc7_accept.dcc7 = dcc;
-		e->event.dcc7_accept.type = gg_fix32(p->type);
-		e->event.dcc7_accept.remote_ip = dcc->remote_addr;
-		e->event.dcc7_accept.remote_port = dcc->remote_port;
-	} else {
-		e->type = GG_EVENT_DCC7_PENDING;
-		e->event.dcc7_pending.dcc7 = dcc;
-	}
-
-	if (gg_dcc7_connect(dcc) == -1) {
-		if (gg_dcc7_reverse_connect(dcc) == -1) {
-			e->type = GG_EVENT_DCC7_ERROR;
-			e->event.dcc7_error = GG_ERROR_DCC7_NET;
-			return 0;
-		}
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet odrzucenia połączenia bezpośredniego.
- *
- * \param sess Struktura sesji
- * \param e Struktura zdarzenia
- * \param payload Treść pakietu
- * \param len Długość pakietu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_dcc7_handle_reject(struct gg_session *sess, struct gg_event *e, const void *payload, int len)
-{
-	const struct gg_dcc7_reject *p = payload;
-	struct gg_dcc7 *dcc;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_handle_reject(%p, %p, %p, %d)\n", sess, e, payload, len);
-
-	if (!(dcc = gg_dcc7_session_find(sess, p->id, gg_fix32(p->uin)))) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_reject() unknown dcc session\n");
-		return 0;
-	}
-
-	if (dcc->state != GG_STATE_WAITING_FOR_ACCEPT) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_reject() invalid state\n");
-		e->type = GG_EVENT_DCC7_ERROR;
-		e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE;
-		return 0;
-	}
-
-	e->type = GG_EVENT_DCC7_REJECT;
-	e->event.dcc7_reject.dcc7 = dcc;
-	e->event.dcc7_reject.reason = gg_fix32(p->reason);
-
-	/* XXX ustawić state na rejected? */
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet nowego połączenia bezpośredniego.
- *
- * \param sess Struktura sesji
- * \param e Struktura zdarzenia
- * \param payload Treść pakietu
- * \param len Długość pakietu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_dcc7_handle_new(struct gg_session *sess, struct gg_event *e, const void *payload, int len)
-{
-	const struct gg_dcc7_new *p = payload;
-	struct gg_dcc7 *dcc;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_handle_new(%p, %p, %p, %d)\n", sess, e, payload, len);
-
-	switch (gg_fix32(p->type)) {
-		case GG_DCC7_TYPE_FILE:
-			if (!(dcc = malloc(sizeof(struct gg_dcc7)))) {
-				gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_new() not enough memory\n");
-				return -1;
-			}
-
-			memset(dcc, 0, sizeof(struct gg_dcc7));
-			dcc->type = GG_SESSION_DCC7_GET;
-			dcc->dcc_type = GG_DCC7_TYPE_FILE;
-			dcc->fd = -1;
-			dcc->file_fd = -1;
-			dcc->uin = sess->uin;
-			dcc->peer_uin = gg_fix32(p->uin_from);
-			dcc->cid = p->id;
-			dcc->sess = sess;
-
-			if (gg_dcc7_session_add(sess, dcc) == -1) {
-				gg_debug_session(sess, GG_DEBUG_MISC,
-					"// gg_dcc7_handle_new() unable to "
-					"add to session\n");
-				gg_dcc7_free(dcc);
-				return -1;
-			}
-
-			dcc->size = gg_fix32(p->size);
-			strncpy((char*) dcc->filename, (char*) p->filename, GG_DCC7_FILENAME_LEN);
-			dcc->filename[GG_DCC7_FILENAME_LEN] = 0;
-			memcpy(dcc->hash, p->hash, GG_DCC7_HASH_LEN);
-
-			e->type = GG_EVENT_DCC7_NEW;
-			e->event.dcc7_new = dcc;
-
-			break;
-
-		case GG_DCC7_TYPE_VOICE:
-			if (!(dcc = malloc(sizeof(struct gg_dcc7)))) {
-				gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_packet() not enough memory\n");
-				return -1;
-			}
-
-			memset(dcc, 0, sizeof(struct gg_dcc7));
-
-			dcc->type = GG_SESSION_DCC7_VOICE;
-			dcc->dcc_type = GG_DCC7_TYPE_VOICE;
-			dcc->fd = -1;
-			dcc->file_fd = -1;
-			dcc->uin = sess->uin;
-			dcc->peer_uin = gg_fix32(p->uin_from);
-			dcc->cid = p->id;
-			dcc->sess = sess;
-
-			if (gg_dcc7_session_add(sess, dcc) == -1) {
-				gg_debug_session(sess, GG_DEBUG_MISC,
-					"// gg_dcc7_handle_new() unable to add "
-					"to session\n");
-				gg_dcc7_free(dcc);
-				return -1;
-			}
-
-			e->type = GG_EVENT_DCC7_NEW;
-			e->event.dcc7_new = dcc;
-
-			break;
-
-		default:
-			gg_debug_session(sess, GG_DEBUG_MISC,
-				"// gg_dcc7_handle_new() unknown dcc type (%d) "
-				"from %u\n", gg_fix32(p->type),
-				gg_fix32(p->uin_from));
-
-			break;
-	}
-
-	return 0;
-}
-
-/**
- * \internal Ustawia odpowiednie stany wewnętrzne w zależności od rodzaju
- * połączenia.
- *
- * \param dcc Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu.
- */
-static int gg_dcc7_postauth_fixup(struct gg_dcc7 *dcc)
-{
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_postauth_fixup(%p)\n", dcc);
-
-	if (!dcc) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_postauth_fixup() invalid parameters\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	switch (dcc->type) {
-		case GG_SESSION_DCC7_GET:
-			dcc->state = GG_STATE_GETTING_FILE;
-			dcc->check = GG_CHECK_READ;
-			return 0;
-
-		case GG_SESSION_DCC7_SEND:
-			dcc->state = GG_STATE_SENDING_FILE;
-			dcc->check = GG_CHECK_WRITE;
-			return 0;
-
-		case GG_SESSION_DCC7_VOICE:
-			dcc->state = GG_STATE_READING_VOICE_DATA;
-			dcc->check = GG_CHECK_READ;
-			return 0;
-	}
-
-	errno = EINVAL;
-
-	return -1;
-}
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Funkcja zwraca strukturę zdarzenia \c gg_event. Jeśli rodzaj zdarzenia
- * to \c GG_EVENT_NONE, nie wydarzyło się jeszcze nic wartego odnotowania.
- * Strukturę zdarzenia należy zwolnić funkcja \c gg_event_free().
- *
- * \param dcc Struktura połączenia
- *
- * \return Struktura zdarzenia lub \c NULL jeśli wystąpił błąd
- *
- * \ingroup dcc7
- */
-struct gg_event *gg_dcc7_watch_fd(struct gg_dcc7 *dcc)
-{
-	struct gg_event *e;
-
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_watch_fd(%p)\n", dcc);
-
-	if (!dcc || (dcc->type != GG_SESSION_DCC7_SEND &&
-		dcc->type != GG_SESSION_DCC7_GET &&
-		dcc->type != GG_SESSION_DCC7_VOICE))
-	{
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() invalid parameters\n");
-		errno = EINVAL;
-		return NULL;
-	}
-
-	if (!(e = malloc(sizeof(struct gg_event)))) {
-		gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() not enough memory\n");
-		return NULL;
-	}
-
-	memset(e, 0, sizeof(struct gg_event));
-	e->type = GG_EVENT_NONE;
-
-	switch (dcc->state) {
-		case GG_STATE_LISTENING:
-		{
-			struct sockaddr_in sin;
-			int fd;
-			socklen_t sin_len = sizeof(sin);
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_LISTENING\n");
-
-			if ((fd = accept(dcc->fd, (struct sockaddr*) &sin, &sin_len)) == -1) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() accept() failed "
-					"(%s)\n", strerror(errno));
-				return e;
-			}
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd()"
-				" connection from %s:%d\n",
-				inet_ntoa(sin.sin_addr), htons(sin.sin_port));
-
-			if (!gg_fd_set_nonblocking(fd)) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() can't set "
-					"nonblocking (%s)\n", strerror(errno));
-				close(fd);
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_HANDSHAKE;
-				return e;
-			}
-
-			close(dcc->fd);
-			dcc->fd = fd;
-
-			dcc->state = GG_STATE_READING_ID;
-			dcc->check = GG_CHECK_READ;
-			dcc->timeout = GG_DEFAULT_TIMEOUT;
-			dcc->incoming = 1;
-
-			dcc->remote_port = ntohs(sin.sin_port);
-			dcc->remote_addr = sin.sin_addr.s_addr;
-
-			e->type = GG_EVENT_DCC7_CONNECTED;
-			e->event.dcc7_connected.dcc7 = dcc;
-
-			return e;
-		}
-
-		case GG_STATE_CONNECTING:
-		{
-			int res = 0, error = 0;
-			socklen_t error_size = sizeof(error);
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_CONNECTING\n");
-
-			dcc->soft_timeout = 0;
-
-			if (dcc->timeout == 0)
-				error = ETIMEDOUT;
-
-			if (error || (res = getsockopt(dcc->fd, SOL_SOCKET,
-				SO_ERROR, &error, &error_size)) == -1 ||
-				error != 0)
-			{
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() connection "
-					"failed (%s)\n", (res == -1) ?
-					strerror(errno) : strerror(error));
-
-				if (dcc->relay) {
-					for (dcc->relay_index++;
-						dcc->relay_index < dcc->relay_count;
-						dcc->relay_index++)
-					{
-						dcc->remote_addr = dcc->relay_list[dcc->relay_index].addr;
-						dcc->remote_port = dcc->relay_list[dcc->relay_index].port;
-
-						if (gg_dcc7_connect(dcc) == 0)
-							break;
-					}
-
-					if (dcc->relay_index >= dcc->relay_count) {
-						gg_debug_dcc(dcc, GG_DEBUG_MISC,
-							"// gg_dcc7_watch_fd() "
-							"no relay available\n");
-						e->type = GG_EVENT_DCC7_ERROR;
-						e->event.dcc_error = GG_ERROR_DCC7_RELAY;
-						return e;
-					}
-				} else {
-					if (gg_dcc7_reverse_connect(dcc) != -1) {
-						e->type = GG_EVENT_DCC7_PENDING;
-						e->event.dcc7_pending.dcc7 = dcc;
-					} else {
-						e->type = GG_EVENT_DCC7_ERROR;
-						e->event.dcc_error = GG_ERROR_DCC7_NET;
-					}
-
-					return e;
-				}
-			}
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() connected, sending id\n");
-
-			dcc->state = GG_STATE_SENDING_ID;
-			dcc->check = GG_CHECK_WRITE;
-			dcc->timeout = GG_DEFAULT_TIMEOUT;
-			dcc->incoming = 0;
-
-			return e;
-		}
-
-		case GG_STATE_READING_ID:
-		{
-			int res;
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_READING_ID\n");
-
-			if (!dcc->relay) {
-				struct gg_dcc7_welcome_p2p welcome, welcome_ok;
-				welcome_ok.id = dcc->cid;
-
-				if ((res = recv(dcc->fd, &welcome, sizeof(welcome), 0)) != sizeof(welcome)) {
-					gg_debug_dcc(dcc, GG_DEBUG_MISC,
-						"// gg_dcc7_watch_fd() recv() "
-						"failed (%d, %s)\n", res,
-						strerror(errno));
-					e->type = GG_EVENT_DCC7_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC7_HANDSHAKE;
-					return e;
-				}
-
-				if (memcmp(&welcome, &welcome_ok, sizeof(welcome))) {
-					gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() invalid id\n");
-					e->type = GG_EVENT_DCC7_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC7_HANDSHAKE;
-					return e;
-				}
-			} else {
-				struct gg_dcc7_welcome_server welcome, welcome_ok;
-				welcome_ok.magic = GG_DCC7_WELCOME_SERVER;
-				welcome_ok.id = dcc->cid;
-
-				if ((res = recv(dcc->fd, &welcome, sizeof(welcome), 0)) != sizeof(welcome)) {
-					gg_debug_dcc(dcc, GG_DEBUG_MISC,
-						"// gg_dcc7_watch_fd() recv() "
-						"failed (%d, %s)\n",
-						res, strerror(errno));
-					e->type = GG_EVENT_DCC7_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC7_HANDSHAKE;
-					return e;
-				}
-
-				if (memcmp(&welcome, &welcome_ok, sizeof(welcome)) != 0) {
-					gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() invalid id\n");
-					e->type = GG_EVENT_DCC7_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC7_HANDSHAKE;
-					return e;
-				}
-			}
-
-			if (dcc->incoming) {
-				dcc->state = GG_STATE_SENDING_ID;
-				dcc->check = GG_CHECK_WRITE;
-				dcc->timeout = GG_DEFAULT_TIMEOUT;
-			} else {
-				gg_dcc7_postauth_fixup(dcc);
-				dcc->timeout = GG_DEFAULT_TIMEOUT;
-			}
-
-			return e;
-		}
-
-		case GG_STATE_SENDING_ID:
-		{
-			int res;
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_SENDING_ID\n");
-
-			if (!dcc->relay) {
-				struct gg_dcc7_welcome_p2p welcome;
-
-				welcome.id = dcc->cid;
-
-				if ((res = send(dcc->fd, &welcome, sizeof(welcome), 0)) != sizeof(welcome)) {
-					gg_debug_dcc(dcc, GG_DEBUG_MISC,
-						"// gg_dcc7_watch_fd() send() "
-						"failed (%d, %s)\n",
-						res, strerror(errno));
-					e->type = GG_EVENT_DCC7_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC7_HANDSHAKE;
-					return e;
-				}
-			} else {
-				struct gg_dcc7_welcome_server welcome;
-
-				welcome.magic = gg_fix32(GG_DCC7_WELCOME_SERVER);
-				welcome.id = dcc->cid;
-
-				if ((res = send(dcc->fd, &welcome, sizeof(welcome), 0)) != sizeof(welcome)) {
-					gg_debug_dcc(dcc, GG_DEBUG_MISC,
-						"// gg_dcc7_watch_fd() send() "
-						"failed (%d, %s)\n", res,
-						strerror(errno));
-					e->type = GG_EVENT_DCC7_ERROR;
-					e->event.dcc_error = GG_ERROR_DCC7_HANDSHAKE;
-					return e;
-				}
-			}
-
-			if (dcc->incoming) {
-				gg_dcc7_postauth_fixup(dcc);
-				dcc->timeout = GG_DEFAULT_TIMEOUT;
-			} else {
-				dcc->state = GG_STATE_READING_ID;
-				dcc->check = GG_CHECK_READ;
-				dcc->timeout = GG_DEFAULT_TIMEOUT;
-			}
-
-			return e;
-		}
-
-		case GG_STATE_SENDING_FILE:
-		{
-			char buf[1024];
-			size_t chunk;
-			int res;
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd()"
-				" GG_STATE_SENDING_FILE (offset=%d, size=%d)\n",
-				dcc->offset, dcc->size);
-
-			if (dcc->offset >= dcc->size) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() offset >= size, finished\n");
-				e->type = GG_EVENT_DCC7_DONE;
-				e->event.dcc7_done.dcc7 = dcc;
-				return e;
-			}
-
-			if (dcc->seek && lseek(dcc->file_fd, dcc->offset, SEEK_SET) == (off_t) -1) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() lseek() failed "
-					"(%s)\n", strerror(errno));
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_FILE;
-				return e;
-			}
-
-			if ((chunk = dcc->size - dcc->offset) > sizeof(buf))
-				chunk = sizeof(buf);
-
-			if ((res = read(dcc->file_fd, buf, chunk)) < 1) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() read() failed "
-					"(res=%d, %s)\n", res, strerror(errno));
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = (res == -1) ? GG_ERROR_DCC7_FILE : GG_ERROR_DCC7_EOF;
-				return e;
-			}
-
-			if ((res = send(dcc->fd, buf, res, 0)) == -1) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() send() failed "
-					"(%s)\n", strerror(errno));
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_NET;
-				return e;
-			}
-
-			dcc->offset += res;
-
-			if (dcc->offset >= dcc->size) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() finished\n");
-				e->type = GG_EVENT_DCC7_DONE;
-				e->event.dcc7_done.dcc7 = dcc;
-				return e;
-			}
-
-			dcc->state = GG_STATE_SENDING_FILE;
-			dcc->check = GG_CHECK_WRITE;
-			dcc->timeout = GG_DCC7_TIMEOUT_SEND;
-
-			return e;
-		}
-
-		case GG_STATE_GETTING_FILE:
-		{
-			char buf[1024];
-			int res, wres;
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd()"
-				" GG_STATE_GETTING_FILE (offset=%d, size=%d)\n",
-				dcc->offset, dcc->size);
-
-			if (dcc->offset >= dcc->size) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() finished\n");
-				e->type = GG_EVENT_DCC7_DONE;
-				e->event.dcc7_done.dcc7 = dcc;
-				return e;
-			}
-
-			if ((res = recv(dcc->fd, buf, sizeof(buf), 0)) < 1) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() recv() failed "
-					"(fd=%d, res=%d, %s)\n", dcc->fd, res,
-					strerror(errno));
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = (res == -1) ? GG_ERROR_DCC7_NET : GG_ERROR_DCC7_EOF;
-				return e;
-			}
-
-			/* XXX zapisywać do skutku? */
-
-			if ((wres = write(dcc->file_fd, buf, res)) < res) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() write() failed "
-					"(fd=%d, res=%d, %s)\n", dcc->file_fd,
-					wres, strerror(errno));
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_FILE;
-				return e;
-			}
-
-			dcc->offset += res;
-
-			if (dcc->offset >= dcc->size) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() finished\n");
-				e->type = GG_EVENT_DCC7_DONE;
-				e->event.dcc7_done.dcc7 = dcc;
-				return e;
-			}
-
-			dcc->state = GG_STATE_GETTING_FILE;
-			dcc->check = GG_CHECK_READ;
-			dcc->timeout = GG_DCC7_TIMEOUT_GET;
-
-			return e;
-		}
-
-		case GG_STATE_RESOLVING_RELAY:
-		{
-			struct in_addr addr;
-			int res;
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_RESOLVING_RELAY\n");
-
-			do {
-				res = gg_resolver_recv(dcc->fd, &addr, sizeof(addr));
-			} while (res == -1 && errno == EINTR);
-
-			dcc->sess->resolver_cleanup(&dcc->resolver, 0);
-
-			if (res != sizeof(addr) || addr.s_addr == INADDR_NONE) {
-				int errno_save = errno;
-
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() resolving failed\n");
-				close(dcc->fd);
-				dcc->fd = -1;
-				errno = errno_save;
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_RELAY;
-				return e;
-			}
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd()"
-				" resolved, connecting to %s:%d\n",
-				inet_ntoa(addr), GG_RELAY_PORT);
-
-			if ((dcc->fd = gg_connect(&addr, GG_RELAY_PORT, 1)) == -1) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() connection "
-					"failed (errno=%d, %s), critical\n",
-					errno, strerror(errno));
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_RELAY;
-				return e;
-			}
-
-			dcc->state = GG_STATE_CONNECTING_RELAY;
-			dcc->check = GG_CHECK_WRITE;
-			dcc->timeout = GG_DEFAULT_TIMEOUT;
-
-			e->type = GG_EVENT_DCC7_PENDING;
-			e->event.dcc7_pending.dcc7 = dcc;
-
-			return e;
-		}
-
-		case GG_STATE_CONNECTING_RELAY:
-		{
-			int res;
-			socklen_t res_size = sizeof(res);
-			struct gg_dcc7_relay_req pkt;
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_CONNECTING_RELAY\n");
-
-			if (getsockopt(dcc->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) != 0 || res != 0) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() connection "
-					"failed (errno=%d, %s)\n",
-					res, strerror(res));
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_RELAY;
-				return e;
-			}
-
-			memset(&pkt, 0, sizeof(pkt));
-			pkt.magic = gg_fix32(GG_DCC7_RELAY_REQUEST);
-			pkt.len = gg_fix32(sizeof(pkt));
-			pkt.id = dcc->cid;
-			pkt.type = gg_fix16(GG_DCC7_RELAY_TYPE_SERVER);
-			pkt.dunno1 = gg_fix16(GG_DCC7_RELAY_DUNNO1);
-
-			gg_debug_dcc(dcc, GG_DEBUG_DUMP, "// gg_dcc7_watch_fd()"
-				" send pkt(0x%.2x)\n", gg_fix32(pkt.magic));
-			gg_debug_dump_dcc(dcc, GG_DEBUG_DUMP, (const char*) &pkt, sizeof(pkt));
-
-			if ((res = send(dcc->fd, &pkt, sizeof(pkt), 0)) != sizeof(pkt)) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() sending failed\n");
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_RELAY;
-				return e;
-			}
-
-			dcc->state = GG_STATE_READING_RELAY;
-			dcc->check = GG_CHECK_READ;
-			dcc->timeout = GG_DEFAULT_TIMEOUT;
-
-			return e;
-		}
-
-		case GG_STATE_READING_RELAY:
-		{
-			char buf[256];
-			struct gg_dcc7_relay_reply *pkt;
-			struct gg_dcc7_relay_reply_server srv;
-			size_t max_relay_count = (sizeof(buf) - sizeof(*pkt)) / sizeof(srv);
-			int res;
-			int i;
-
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_READING_RELAY\n");
-
-			if ((res = recv(dcc->fd, buf, sizeof(buf), 0)) < (int) sizeof(*pkt)) {
-				if (res == 0)
-					errno = ECONNRESET;
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() recv() failed "
-					"(%d, %s)\n", res, strerror(errno));
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_RELAY;
-				return e;
-			}
-
-			pkt = (struct gg_dcc7_relay_reply*) buf;
-
-			if (gg_fix32(pkt->magic) != GG_DCC7_RELAY_REPLY ||
-				gg_fix32(pkt->rcount) < 1 ||
-				gg_fix32(pkt->rcount) > 256 ||
-				gg_fix32(pkt->len) < sizeof(*pkt) +
-				gg_fix32(pkt->rcount) * sizeof(srv))
-			{
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_wathc_fd() invalid reply\n");
-				errno = EINVAL;
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_RELAY;
-				return e;
-			}
-
-			gg_debug_dcc(dcc, GG_DEBUG_DUMP,
-				"// gg_dcc7_get_relay() read pkt(0x%.2x)\n",
-				gg_fix32(pkt->magic));
-			gg_debug_dump_dcc(dcc, GG_DEBUG_DUMP, buf, res);
-
-			free(dcc->relay_list);
-
-			dcc->relay_index = 0;
-			dcc->relay_count = gg_fix32(pkt->rcount);
-
-			if (dcc->relay_count > 0xffff ||
-				(size_t)dcc->relay_count > max_relay_count)
-			{
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"// gg_dcc7_watch_fd() relay_count out "
-					"of bounds (%d)\n", dcc->relay_count);
-				dcc->relay_count = 0;
-				free(e);
-				return NULL;
-			}
-
-			dcc->relay_list = malloc(dcc->relay_count * sizeof(gg_dcc7_relay_t));
-
-			if (dcc->relay_list == NULL) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() not enough memory\n");
-				dcc->relay_count = 0;
-				free(e);
-				return NULL;
-			}
-
-			for (i = 0; i < dcc->relay_count; i++) {
-				struct in_addr addr;
-
-				memcpy(&srv, buf + sizeof(*pkt) + i * sizeof(srv), sizeof(srv));
-				dcc->relay_list[i].addr = srv.addr;
-				dcc->relay_list[i].port = gg_fix16(srv.port);
-				dcc->relay_list[i].family = srv.family;
-
-				addr.s_addr = srv.addr;
-				gg_debug_dcc(dcc, GG_DEBUG_MISC,
-					"//    %s %d %d\n", inet_ntoa(addr),
-					gg_fix16(srv.port), srv.family);
-			}
-
-			dcc->relay = 1;
-
-			for (; dcc->relay_index < dcc->relay_count; dcc->relay_index++) {
-				dcc->remote_addr = dcc->relay_list[dcc->relay_index].addr;
-				dcc->remote_port = dcc->relay_list[dcc->relay_index].port;
-
-				if (gg_dcc7_connect(dcc) == 0)
-					break;
-			}
-
-			if (dcc->relay_index >= dcc->relay_count) {
-				gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() no relay available\n");
-				e->type = GG_EVENT_DCC7_ERROR;
-				e->event.dcc_error = GG_ERROR_DCC7_RELAY;
-				return e;
-			}
-
-			return e;
-		}
-
-		default:
-		{
-			gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_watch_fd() GG_STATE_???\n");
-			e->type = GG_EVENT_DCC7_ERROR;
-			e->event.dcc_error = GG_ERROR_DCC7_HANDSHAKE;
-
-			return e;
-		}
-	}
-
-	return e;
-}
-
-/**
- * Zwalnia zasoby używane przez połączenie bezpośrednie.
- *
- * \param dcc Struktura połączenia
- *
- * \ingroup dcc7
- */
-void gg_dcc7_free(struct gg_dcc7 *dcc)
-{
-	gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_free(%p)\n", dcc);
-
-	if (!dcc)
-		return;
-
-	if (dcc->fd != -1)
-		close(dcc->fd);
-
-	if (dcc->file_fd != -1)
-		gg_file_close(dcc->file_fd);
-
-	if (dcc->sess)
-		gg_dcc7_session_remove(dcc->sess, dcc);
-
-	free(dcc->relay_list);
-
-	free(dcc);
-}
--- a/libpurple/protocols/gg/lib/debug.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,397 +0,0 @@
-/*
- *  (C) Copyright 2001-2006 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *                          Arkadiusz Miśkiewicz <arekm@pld-linux.org>
- *                          Tomasz Chiliński <chilek@chilan.com>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file debug.c
- *
- * \brief Funkcje odpluskwiania
- */
-#include <sys/types.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libgadu.h"
-#include "debug.h"
-
-/**
- * Poziom rejestracji informacji odpluskwiających. Zmienna jest maską bitową
- * składającą się ze stałych \c GG_DEBUG_...
- *
- * \ingroup debug
- */
-int gg_debug_level = 0;
-
-/**
- * Funkcja, do której są przekazywane informacje odpluskwiające. Jeśli zarówno
- * ten \c gg_debug_handler, jak i \c gg_debug_handler_session, są równe
- * \c NULL, informacje są wysyłane do standardowego wyjścia błędu (\c stderr).
- *
- * \param level Poziom rejestracji
- * \param format Format wiadomości (zgodny z \c printf)
- * \param ap Lista argumentów (zgodna z \c printf)
- *
- * \note Funkcja jest przesłaniana przez \c gg_debug_handler_session.
- *
- * \ingroup debug
- */
-void (*gg_debug_handler)(int level, const char *format, va_list ap) = NULL;
-
-/**
- * Funkcja, do której są przekazywane informacje odpluskwiające. Jeśli zarówno
- * ten \c gg_debug_handler, jak i \c gg_debug_handler_session, są równe
- * \c NULL, informacje są wysyłane do standardowego wyjścia błędu.
- *
- * \param sess Sesja której dotyczy informacja lub \c NULL
- * \param level Poziom rejestracji
- * \param format Format wiadomości (zgodny z \c printf)
- * \param ap Lista argumentów (zgodna z \c printf)
- *
- * \note Funkcja przesłania przez \c gg_debug_handler_session.
- *
- * \ingroup debug
- */
-void (*gg_debug_handler_session)(struct gg_session *sess, int level, const char *format, va_list ap) = NULL;
-
-/**
- * Plik, do którego będą przekazywane informacje odpluskwiania.
- *
- * Funkcja \c gg_debug() i pochodne mogą być przechwytywane przez aplikację
- * korzystającą z biblioteki, by wyświetlić je na żądanie użytkownika lub
- * zapisać do późniejszej analizy. Jeśli nie określono pliku, wybrane
- * informacje będą wysyłane do standardowego wyjścia błędu (\c stderr).
- *
- * \ingroup debug
- */
-FILE *gg_debug_file = NULL;
-
-#ifndef GG_DEBUG_DISABLE
-
-/**
- * \internal Przekazuje informacje odpluskwiania do odpowiedniej funkcji.
- *
- * Jeśli aplikacja ustawiła odpowiednią funkcję obsługi w
- * \c gg_debug_handler_session lub \c gg_debug_handler, jest ona wywoływana.
- * W przeciwnym wypadku wynik jest wysyłany do standardowego wyjścia błędu.
- *
- * \param sess Struktura sesji (może być \c NULL)
- * \param level Poziom informacji
- * \param format Format wiadomości (zgodny z \c printf)
- * \param ap Lista argumentów (zgodna z \c printf)
- */
-void gg_debug_common(struct gg_session *sess, int level, const char *format, va_list ap)
-{
-	if (gg_debug_handler_session != NULL)
-		(*gg_debug_handler_session)(sess, level, format, ap);
-	else if (gg_debug_handler != NULL)
-		(*gg_debug_handler)(level, format, ap);
-	else if ((gg_debug_level & level) != 0)
-		vfprintf((gg_debug_file) ? gg_debug_file : stderr, format, ap);
-}
-
-
-/**
- * \internal Przekazuje informację odpluskawiania.
- *
- * \param level Poziom wiadomości
- * \param format Format wiadomości (zgodny z \c printf)
- *
- * \ingroup debug
- */
-void gg_debug(int level, const char *format, ...)
-{
-	va_list ap;
-	int old_errno = errno;
-
-	va_start(ap, format);
-	gg_debug_common(NULL, level, format, ap);
-	va_end(ap);
-	errno = old_errno;
-}
-
-/**
- * \internal Przekazuje informację odpluskwiania związaną z sesją.
- *
- * \param gs Struktura sesji
- * \param level Poziom wiadomości
- * \param format Format wiadomości (zgodny z \c printf)
- *
- * \ingroup debug
- */
-void gg_debug_session(struct gg_session *gs, int level, const char *format, ...)
-{
-	va_list ap;
-	int old_errno = errno;
-
-	va_start(ap, format);
-	gg_debug_common(gs, level, format, ap);
-	va_end(ap);
-	errno = old_errno;
-}
-
-/**
- * \internal Przekazuje zrzut bufora do odpluskwiania.
- *
- * \param gs Struktura sesji
- * \param level Poziom wiadomości
- * \param buf Bufor danych
- * \param len Długość bufora danych
- *
- * \ingroup debug
- */
-void gg_debug_dump(struct gg_session *gs, int level, const char *buf, size_t len)
-{
-	char line[80];
-	unsigned int i, j;
-
-	for (i = 0; i < len; i += 16) {
-		int ofs;
-
-		sprintf(line, "%.4x: ", i);
-		ofs = 6;
-
-		for (j = 0; j < 16; j++) {
-			if (i + j < len)
-				sprintf(line + ofs, " %02x", (unsigned char) buf[i + j]);
-			else
-				sprintf(line + ofs, "   ");
-
-			ofs += 3;
-		}
-
-		sprintf(line + ofs, "  ");
-		ofs += 2;
-
-		for (j = 0; j < 16; j++) {
-			unsigned char ch;
-
-			if (i + j < len) {
-				ch = buf[i + j];
-
-				if (ch < 32 || ch > 126)
-					ch = '.';
-			} else {
-				ch = ' ';
-			}
-
-			line[ofs++] = ch;
-		}
-
-		line[ofs++] = '\n';
-		line[ofs++] = 0;
-
-		gg_debug_session(gs, level, "%s", line);
-	}
-}
-
-/**
- * \internal Zwraca ciąg z nazwą podanego stanu sesji.
- *
- * \param state Stan sesji.
- *
- * \return Ciąg z nazwą stanu
- *
- * \ingroup debug
- */
-const char *gg_debug_state(enum gg_state_t state)
-{
-	switch (state) {
-#define GG_DEBUG_STATE(x) case x: return #x;
-	GG_DEBUG_STATE(GG_STATE_IDLE)
-	GG_DEBUG_STATE(GG_STATE_RESOLVING)
-	GG_DEBUG_STATE(GG_STATE_CONNECTING)
-	GG_DEBUG_STATE(GG_STATE_READING_DATA)
-	GG_DEBUG_STATE(GG_STATE_ERROR)
-	GG_DEBUG_STATE(GG_STATE_CONNECTING_HUB)
-	GG_DEBUG_STATE(GG_STATE_CONNECTING_GG)
-	GG_DEBUG_STATE(GG_STATE_READING_KEY)
-	GG_DEBUG_STATE(GG_STATE_READING_REPLY)
-	GG_DEBUG_STATE(GG_STATE_CONNECTED)
-	GG_DEBUG_STATE(GG_STATE_SENDING_QUERY)
-	GG_DEBUG_STATE(GG_STATE_READING_HEADER)
-	GG_DEBUG_STATE(GG_STATE_PARSING)
-	GG_DEBUG_STATE(GG_STATE_DONE)
-	GG_DEBUG_STATE(GG_STATE_LISTENING)
-	GG_DEBUG_STATE(GG_STATE_READING_UIN_1)
-	GG_DEBUG_STATE(GG_STATE_READING_UIN_2)
-	GG_DEBUG_STATE(GG_STATE_SENDING_ACK)
-	GG_DEBUG_STATE(GG_STATE_READING_ACK)
-	GG_DEBUG_STATE(GG_STATE_READING_REQUEST)
-	GG_DEBUG_STATE(GG_STATE_SENDING_REQUEST)
-	GG_DEBUG_STATE(GG_STATE_SENDING_FILE_INFO)
-	GG_DEBUG_STATE(GG_STATE_READING_PRE_FILE_INFO)
-	GG_DEBUG_STATE(GG_STATE_READING_FILE_INFO)
-	GG_DEBUG_STATE(GG_STATE_SENDING_FILE_ACK)
-	GG_DEBUG_STATE(GG_STATE_READING_FILE_ACK)
-	GG_DEBUG_STATE(GG_STATE_SENDING_FILE_HEADER)
-	GG_DEBUG_STATE(GG_STATE_READING_FILE_HEADER)
-	GG_DEBUG_STATE(GG_STATE_GETTING_FILE)
-	GG_DEBUG_STATE(GG_STATE_SENDING_FILE)
-	GG_DEBUG_STATE(GG_STATE_READING_VOICE_ACK)
-	GG_DEBUG_STATE(GG_STATE_READING_VOICE_HEADER)
-	GG_DEBUG_STATE(GG_STATE_READING_VOICE_SIZE)
-	GG_DEBUG_STATE(GG_STATE_READING_VOICE_DATA)
-	GG_DEBUG_STATE(GG_STATE_SENDING_VOICE_ACK)
-	GG_DEBUG_STATE(GG_STATE_SENDING_VOICE_REQUEST)
-	GG_DEBUG_STATE(GG_STATE_READING_TYPE)
-	GG_DEBUG_STATE(GG_STATE_TLS_NEGOTIATION)
-	GG_DEBUG_STATE(GG_STATE_REQUESTING_ID)
-	GG_DEBUG_STATE(GG_STATE_WAITING_FOR_ACCEPT)
-	GG_DEBUG_STATE(GG_STATE_WAITING_FOR_INFO)
-	GG_DEBUG_STATE(GG_STATE_READING_ID)
-	GG_DEBUG_STATE(GG_STATE_SENDING_ID)
-	GG_DEBUG_STATE(GG_STATE_RESOLVING_GG)
-	GG_DEBUG_STATE(GG_STATE_RESOLVING_RELAY)
-	GG_DEBUG_STATE(GG_STATE_CONNECTING_RELAY)
-	GG_DEBUG_STATE(GG_STATE_READING_RELAY)
-	GG_DEBUG_STATE(GG_STATE_DISCONNECTING)
-	GG_DEBUG_STATE(GG_STATE_CONNECT_HUB)
-	GG_DEBUG_STATE(GG_STATE_CONNECT_PROXY_HUB)
-	GG_DEBUG_STATE(GG_STATE_CONNECT_GG)
-	GG_DEBUG_STATE(GG_STATE_CONNECT_PROXY_GG)
-	GG_DEBUG_STATE(GG_STATE_CONNECTING_PROXY_HUB)
-	GG_DEBUG_STATE(GG_STATE_CONNECTING_PROXY_GG)
-	GG_DEBUG_STATE(GG_STATE_RESOLVE_HUB_SYNC)
-	GG_DEBUG_STATE(GG_STATE_RESOLVE_HUB_ASYNC)
-	GG_DEBUG_STATE(GG_STATE_RESOLVE_PROXY_HUB_SYNC)
-	GG_DEBUG_STATE(GG_STATE_RESOLVE_PROXY_HUB_ASYNC)
-	GG_DEBUG_STATE(GG_STATE_RESOLVE_PROXY_GG_SYNC)
-	GG_DEBUG_STATE(GG_STATE_RESOLVE_PROXY_GG_ASYNC)
-	GG_DEBUG_STATE(GG_STATE_RESOLVE_GG_SYNC)
-	GG_DEBUG_STATE(GG_STATE_RESOLVE_GG_ASYNC)
-	GG_DEBUG_STATE(GG_STATE_RESOLVING_HUB)
-	GG_DEBUG_STATE(GG_STATE_RESOLVING_PROXY_HUB)
-	GG_DEBUG_STATE(GG_STATE_RESOLVING_PROXY_GG)
-	GG_DEBUG_STATE(GG_STATE_SEND_HUB)
-	GG_DEBUG_STATE(GG_STATE_SEND_PROXY_HUB)
-	GG_DEBUG_STATE(GG_STATE_SEND_PROXY_GG)
-	GG_DEBUG_STATE(GG_STATE_SENDING_HUB)
-	GG_DEBUG_STATE(GG_STATE_SENDING_PROXY_HUB)
-	GG_DEBUG_STATE(GG_STATE_SENDING_PROXY_GG)
-	GG_DEBUG_STATE(GG_STATE_READING_HUB)
-	GG_DEBUG_STATE(GG_STATE_READING_PROXY_HUB)
-	GG_DEBUG_STATE(GG_STATE_READING_PROXY_GG)
-#undef GG_DEBUG_STATE
-
-	/* Celowo nie ma default, żeby kompilator wyłapał brakujące stany */
-	}
-
-	return NULL;
-}
-
-/**
- * \internal Zwraca ciąg z nazwą podanego zdarzenia.
- *
- * \param event Zdarzenie.
- *
- * \return Ciąg z nazwą zdarzenia
- *
- * \ingroup debug
- */
-const char *gg_debug_event(enum gg_event_t event)
-{
-	switch (event) {
-#define GG_DEBUG_EVENT(x) case x: return #x;
-	GG_DEBUG_EVENT(GG_EVENT_NONE)
-	GG_DEBUG_EVENT(GG_EVENT_MSG)
-	GG_DEBUG_EVENT(GG_EVENT_NOTIFY)
-	GG_DEBUG_EVENT(GG_EVENT_NOTIFY_DESCR)
-	GG_DEBUG_EVENT(GG_EVENT_STATUS)
-	GG_DEBUG_EVENT(GG_EVENT_ACK)
-	GG_DEBUG_EVENT(GG_EVENT_PONG)
-	GG_DEBUG_EVENT(GG_EVENT_CONN_FAILED)
-	GG_DEBUG_EVENT(GG_EVENT_CONN_SUCCESS)
-	GG_DEBUG_EVENT(GG_EVENT_DISCONNECT)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_NEW)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_ERROR)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_DONE)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_CLIENT_ACCEPT)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_CALLBACK)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_NEED_FILE_INFO)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_NEED_FILE_ACK)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_NEED_VOICE_ACK)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_VOICE_DATA)
-	GG_DEBUG_EVENT(GG_EVENT_PUBDIR50_SEARCH_REPLY)
-	GG_DEBUG_EVENT(GG_EVENT_PUBDIR50_READ)
-	GG_DEBUG_EVENT(GG_EVENT_PUBDIR50_WRITE)
-	GG_DEBUG_EVENT(GG_EVENT_STATUS60)
-	GG_DEBUG_EVENT(GG_EVENT_NOTIFY60)
-	GG_DEBUG_EVENT(GG_EVENT_USERLIST)
-	GG_DEBUG_EVENT(GG_EVENT_IMAGE_REQUEST)
-	GG_DEBUG_EVENT(GG_EVENT_IMAGE_REPLY)
-	GG_DEBUG_EVENT(GG_EVENT_DCC_ACK)
-	GG_DEBUG_EVENT(GG_EVENT_DCC7_NEW)
-	GG_DEBUG_EVENT(GG_EVENT_DCC7_ACCEPT)
-	GG_DEBUG_EVENT(GG_EVENT_DCC7_REJECT)
-	GG_DEBUG_EVENT(GG_EVENT_DCC7_CONNECTED)
-	GG_DEBUG_EVENT(GG_EVENT_DCC7_ERROR)
-	GG_DEBUG_EVENT(GG_EVENT_DCC7_DONE)
-	GG_DEBUG_EVENT(GG_EVENT_DCC7_PENDING)
-	GG_DEBUG_EVENT(GG_EVENT_XML_EVENT)
-	GG_DEBUG_EVENT(GG_EVENT_JSON_EVENT)
-	GG_DEBUG_EVENT(GG_EVENT_ACK110)
-	GG_DEBUG_EVENT(GG_EVENT_DISCONNECT_ACK)
-	GG_DEBUG_EVENT(GG_EVENT_TYPING_NOTIFICATION)
-	GG_DEBUG_EVENT(GG_EVENT_USER_DATA)
-	GG_DEBUG_EVENT(GG_EVENT_MULTILOGON_MSG)
-	GG_DEBUG_EVENT(GG_EVENT_MULTILOGON_INFO)
-	GG_DEBUG_EVENT(GG_EVENT_USERLIST100_VERSION)
-	GG_DEBUG_EVENT(GG_EVENT_USERLIST100_REPLY)
-	GG_DEBUG_EVENT(GG_EVENT_IMTOKEN)
-	GG_DEBUG_EVENT(GG_EVENT_PONG110)
-	GG_DEBUG_EVENT(GG_EVENT_CHAT_INFO)
-	GG_DEBUG_EVENT(GG_EVENT_CHAT_INFO_GOT_ALL)
-	GG_DEBUG_EVENT(GG_EVENT_CHAT_INFO_UPDATE)
-	GG_DEBUG_EVENT(GG_EVENT_CHAT_CREATED)
-	GG_DEBUG_EVENT(GG_EVENT_CHAT_INVITE_ACK)
-#undef GG_DEBUG_EVENT
-
-	/* Celowo nie ma default, żeby kompilator wyłapał brakujące zdarzenia */
-	}
-
-	return NULL;
-}
-
-#else
-
-#undef gg_debug_common
-void gg_debug_common(struct gg_session *sess, int level, const char *format, va_list ap)
-{
-}
-
-#undef gg_debug
-void gg_debug(int level, const char *format, ...)
-{
-}
-
-#undef gg_debug_session
-void gg_debug_session(struct gg_session *gs, int level, const char *format, ...)
-{
-}
-
-#undef gg_debug_dump
-void gg_debug_dump(struct gg_session *gs, int level, const char *buf, size_t len)
-{
-}
-
-#endif
--- a/libpurple/protocols/gg/lib/debug.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- *  (C) Copyright 2009 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_DEBUG_H
-#define LIBGADU_DEBUG_H
-
-#include "libgadu.h"
-
-void gg_debug_dump(struct gg_session *sess, int level, const char *buf, size_t len);
-void gg_debug_common(struct gg_session *sess, int level, const char *format, va_list ap);
-
-#endif /* LIBGADU_DEBUG_H */
--- a/libpurple/protocols/gg/lib/deflate.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2011 Bartosz Brachaczek <b.brachaczek@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file deflate.c
- *
- * \brief Funkcje kompresji Deflate
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "libgadu.h"
-#include "internal.h"
-#include "deflate.h"
-
-#ifdef GG_CONFIG_HAVE_ZLIB
-#include <zlib.h>
-#endif
-
-/**
- * \internal Kompresuje dane wejściowe algorytmem Deflate z najwyższym
- * stopniem kompresji, tak samo jak oryginalny klient.
- *
- * Wynik funkcji należy zwolnić za pomocą \c free.
- *
- * \param in Ciąg znaków do skompresowania, zakończony \c \\0
- * \param out_lenp Wskaźnik na zmienną, do której zostanie zapisana
- *                 długość bufora wynikowego
- *
- * \return Skompresowany ciąg znaków lub \c NULL w przypadku niepowodzenia.
- */
-unsigned char *gg_deflate(const char *in, size_t *out_lenp)
-{
-#ifdef GG_CONFIG_HAVE_ZLIB
-	int ret;
-	z_stream strm;
-	unsigned char *out, *out2;
-	size_t out_len;
-
-	if (in == NULL || out_lenp == NULL)
-		return NULL;
-
-	strm.zalloc = Z_NULL;
-	strm.zfree = Z_NULL;
-	strm.opaque = Z_NULL;
-	strm.avail_in = strlen(in);
-	strm.next_in = (unsigned char*) in;
-
-	ret = deflateInit(&strm, Z_BEST_COMPRESSION);
-	if (ret != Z_OK) {
-		gg_debug(GG_DEBUG_MISC, "// gg_deflate() deflateInit() failed (%d)\n", ret);
-		return NULL;
-	}
-
-	out_len = deflateBound(&strm, strm.avail_in);
-	out = malloc(out_len);
-
-	if (out == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_deflate() not enough memory for "
-			"output data (%" GG_SIZE_FMT ")\n", out_len);
-		goto fail;
-	}
-
-	strm.avail_out = out_len;
-	strm.next_out = out;
-
-	for (;;) {
-		ret = deflate(&strm, Z_FINISH);
-
-		if (ret == Z_STREAM_END)
-			break;
-
-		/* raczej nie powinno się zdarzyć przy Z_FINISH i out_len == deflateBound(),
-		 * ale dokumentacja zlib nie wyklucza takiej możliwości */
-		if (ret == Z_OK) {
-			out_len *= 2;
-			out2 = realloc(out, out_len);
-
-			if (out2 == NULL) {
-				gg_debug(GG_DEBUG_MISC, "// gg_deflate() not "
-					"enough memory for output data (%"
-					GG_SIZE_FMT ")\n", out_len);
-				goto fail;
-			}
-
-			out = out2;
-
-			strm.avail_out = out_len / 2;
-			strm.next_out = out + out_len / 2;
-		} else {
-			gg_debug(GG_DEBUG_MISC, "// gg_deflate() deflate() "
-				"failed (ret=%d, msg=%s)\n", ret,
-				strm.msg != NULL ? strm.msg :
-				"no error message provided");
-			goto fail;
-		}
-	}
-
-	out_len = strm.total_out;
-	out2 = realloc(out, out_len);
-
-	if (out2 == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_deflate() not enough memory for "
-			"output data (%" GG_SIZE_FMT ")\n", out_len);
-		goto fail;
-	}
-
-	*out_lenp = out_len;
-	deflateEnd(&strm);
-
-	return out2;
-
-fail:
-	*out_lenp = 0;
-	deflateEnd(&strm);
-	free(out);
-#endif
-	return NULL;
-}
-
-/**
- * \internal Dekompresuje dane wejściowe w formacie Deflate.
- *
- * Wynik funkcji należy zwolnić za pomocą \c free.
- *
- * \param in Bufor danych skompresowanych algorytmem Deflate
- * \param length Długość bufora wejściowego
- *
- * \note Dokleja \c \\0 na końcu bufora wynikowego.
- *
- * \return Zdekompresowany ciąg znaków, zakończony \c \\0,
- *         lub \c NULL w przypadku niepowodzenia.
- */
-char *gg_inflate(const unsigned char *in, size_t length)
-{
-#ifdef GG_CONFIG_HAVE_ZLIB
-	int ret;
-	z_stream strm;
-	char *out = NULL, *out2;
-	size_t out_len = 1024;
-	int first = 1;
-
-	if (in == NULL)
-		return NULL;
-
-	strm.zalloc = Z_NULL;
-	strm.zfree = Z_NULL;
-	strm.opaque = Z_NULL;
-	strm.avail_in = length;
-	strm.next_in = (unsigned char*) in;
-
-	ret = inflateInit(&strm);
-	if (ret != Z_OK) {
-		gg_debug(GG_DEBUG_MISC, "// gg_inflate() inflateInit() failed (%d)\n", ret);
-		return NULL;
-	}
-
-	do {
-		out_len *= 2;
-		out2 = realloc(out, out_len);
-
-		if (out2 == NULL) {
-			gg_debug(GG_DEBUG_MISC, "// gg_inflate() not enough "
-				"memory for output data (%" GG_SIZE_FMT ")\n", out_len);
-			goto fail;
-		}
-
-		out = out2;
-
-		if (first) {
-			strm.avail_out = out_len;
-			strm.next_out = (unsigned char*) out;
-		} else {
-			strm.avail_out = out_len / 2;
-			strm.next_out = (unsigned char*) out + out_len / 2;
-		}
-
-		ret = inflate(&strm, Z_NO_FLUSH);
-
-		if (ret != Z_OK && ret != Z_STREAM_END) {
-			gg_debug(GG_DEBUG_MISC, "// gg_inflate() inflate() "
-				"failed (ret=%d, msg=%s)\n", ret,
-				strm.msg != NULL ? strm.msg :
-				"no error message provided");
-			goto fail;
-		}
-
-		first = 0;
-	} while (ret != Z_STREAM_END);
-
-	/* rezerwujemy ostatni znak na NULL-a */
-	out_len = strm.total_out + 1;
-	out2 = realloc(out, out_len);
-
-	if (out2 == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_inflate() not enough memory for "
-			"output data (%" GG_SIZE_FMT ")\n", out_len);
-		goto fail;
-	}
-
-	out = out2;
-	out[out_len - 1] = '\0';
-
-	inflateEnd(&strm);
-
-	return out;
-
-fail:
-	inflateEnd(&strm);
-	free(out);
-#endif
-	return NULL;
-}
--- a/libpurple/protocols/gg/lib/deflate.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2011 Bartosz Brachaczek <b.brachaczek@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_DEFLATE_H
-#define LIBGADU_DEFLATE_H
-
-#include "libgadu.h"
-
-unsigned char *gg_deflate(const char *in, size_t *out_lenp);
-char *gg_inflate(const unsigned char *in, size_t length);
-
-#endif /* LIBGADU_DEFLATE_H */
--- a/libpurple/protocols/gg/lib/encoding.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-/*
- *  (C) Copyright 2008-2009 Jakub Zawadzki <darkjames@darkjames.ath.cx>
- *                          Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#include "strman.h"
-#include <stdlib.h>
-#include <errno.h>
-
-#include "libgadu.h"
-#include "encoding.h"
-
-/**
- * \file encoding.c
- *
- * \brief Funkcje konwersji kodowania tekstu
- */
-
-/**
- * \internal Tablica konwersji CP1250 na Unikod.
- */
-static const uint16_t table_cp1250[] =
-{
-	0x20ac, '?',    0x201a, '?',    0x201e, 0x2026, 0x2020, 0x2021,
-	'?',    0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,
-	'?',    0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
-	'?',    0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,
-	0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7,
-	0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b,
-	0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
-	0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c,
-	0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7,
-	0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
-	0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7,
-	0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
-	0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7,
-	0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
-	0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7,
-	0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9,
-};
-
-/**
- * \internal Zamienia tekst kodowany CP1250 na UTF-8.
- *
- * \param src Tekst źródłowy w CP1250.
- * \param src_length Długość ciągu źródłowego (nigdy ujemna).
- * \param dst_length Długość ciągu docelowego (jeśli -1, nieograniczona).
- *
- * \return Zaalokowany bufor z tekstem w UTF-8.
- */
-static char *gg_encoding_convert_cp1250_utf8(const char *src, int src_length, int dst_length)
-{
-	int i, j, len;
-	char *result = NULL;
-
-	for (i = 0, len = 0; (src[i] != 0) && (i < src_length); i++) {
-		uint16_t uc;
-
-		if ((unsigned char) src[i] < 0x80)
-			uc = (unsigned char) src[i];
-		else
-			uc = table_cp1250[(unsigned char) src[i] - 128];
-
-		if (uc < 0x80)
-			len += 1;
-		else if (uc < 0x800)
-			len += 2;
-		else
-			len += 3;
-	}
-
-	if ((dst_length != -1) && (len > dst_length))
-		len = dst_length;
-
-	result = malloc(len + 1);
-
-	if (result == NULL)
-		return NULL;
-
-	for (i = 0, j = 0; (src[i] != 0) && (i < src_length) && (j < len); i++) {
-		uint16_t uc;
-
-		if ((unsigned char) src[i] < 0x80)
-			uc = (unsigned char) src[i];
-		else
-			uc = table_cp1250[(unsigned char) src[i] - 128];
-
-		if (uc < 0x80)
-			result[j++] = (char) uc;
-		else if (uc < 0x800) {
-			if (j + 1 > len)
-				break;
-			result[j++] = 0xc0 | ((uc >> 6) & 0x1f);
-			result[j++] = 0x80 | (uc & 0x3f);
-		} else {
-			if (j + 2 > len)
-				break;
-			result[j++] = 0xe0 | ((uc >> 12) & 0x1f);
-			result[j++] = 0x80 | ((uc >> 6) & 0x3f);
-			result[j++] = 0x80 | (uc & 0x3f);
-		}
-	}
-
-	result[j] = 0;
-
-	return result;
-}
-
-/**
- * \internal Zamienia tekst kodowany UTF-8 na CP1250.
- *
- * \param src Tekst źródłowy w UTF-8.
- * \param src_length Długość ciągu źródłowego (nigdy ujemna).
- * \param dst_length Długość ciągu docelowego (jeśli -1, nieograniczona).
- *
- * \return Zaalokowany bufor z tekstem w CP1250.
- */
-static char *gg_encoding_convert_utf8_cp1250(const char *src, int src_length, int dst_length)
-{
-	char *result;
-	int i, j, len, uc_left = 0;
-	uint32_t uc = 0, uc_min = 0;
-
-	for (i = 0, len = 0; (src[i] != 0) && (i < src_length); i++) {
-		if ((src[i] & 0xc0) != 0x80)
-			len++;
-	}
-
-	if ((dst_length != -1) && (len > dst_length))
-		len = dst_length;
-
-	result = malloc(len + 1);
-
-	if (result == NULL)
-		return NULL;
-
-	for (i = 0, j = 0; (src[i] != 0) && (i < src_length) && (j < len); i++) {
-		if ((unsigned char) src[i] >= 0xf5) {
-			if (uc_left != 0)
-				result[j++] = '?';
-			/* Restricted sequences */
-			result[j++] = '?';
-			uc_left = 0;
-		} else if ((src[i] & 0xf8) == 0xf0) {
-			if (uc_left != 0)
-				result[j++] = '?';
-			uc = src[i] & 0x07;
-			uc_left = 3;
-			uc_min = 0x10000;
-		} else if ((src[i] & 0xf0) == 0xe0) {
-			if (uc_left != 0)
-				result[j++] = '?';
-			uc = src[i] & 0x0f;
-			uc_left = 2;
-			uc_min = 0x800;
-		} else if ((src[i] & 0xe0) == 0xc0) {
-			if (uc_left != 0)
-				result[j++] = '?';
-			uc = src[i] & 0x1f;
-			uc_left = 1;
-			uc_min = 0x80;
-		} else if ((src[i] & 0xc0) == 0x80) {
-			if (uc_left > 0) {
-				uc <<= 6;
-				uc |= src[i] & 0x3f;
-				uc_left--;
-
-				if (uc_left == 0) {
-					int valid = 0;
-					int k;
-
-					if (uc >= uc_min) {
-						for (k = 0; k < 128; k++) {
-							if (uc == table_cp1250[k]) {
-								result[j++] = k + 128;
-								valid = 1;
-								break;
-							}
-						}
-					}
-
-					if (!valid && uc != 0xfeff)	/* Byte Order Mark */
-						result[j++] = '?';
-				}
-			}
-		} else {
-			if (uc_left != 0) {
-				result[j++] = '?';
-				uc_left = 0;
-			}
-			result[j++] = src[i];
-		}
-	}
-
-	if ((uc_left != 0) && (src[i] == 0))
-		result[j++] = '?';
-
-	result[j] = 0;
-
-	return result;
-}
-
-/**
- * \internal Zamienia kodowanie tekstu.
- *
- * \param src Tekst źródłowy.
- * \param src_encoding Kodowanie tekstu źródłowego.
- * \param dst_encoding Kodowanie tekstu docelowego.
- * \param src_length Długość ciągu źródłowego w bajtach (jeśli -1, zostanie obliczona na podstawie zawartości \p src).
- * \param dst_length Długość ciągu docelowego w bajtach (jeśli -1, nieograniczona).
- *
- * \return Zaalokowany bufor z tekstem w kodowaniu docelowym.
- */
-char *gg_encoding_convert(const char *src, gg_encoding_t src_encoding,
-	gg_encoding_t dst_encoding, int src_length, int dst_length)
-{
-	char *result;
-
-	if (src == NULL) {
-		errno = EINVAL;
-		return NULL;
-	}
-
-	/* specjalny przypadek obsługiwany ekspresowo */
-	if ((dst_encoding == src_encoding) && (dst_length == -1) && (src_length == -1))
-		return strdup(src);
-
-	if (src_length == -1)
-		src_length = strlen(src);
-
-	if (dst_encoding == src_encoding) {
-		int len;
-
-		if (dst_length == -1)
-			len = src_length;
-		else
-			len = (src_length < dst_length) ? src_length : dst_length;
-
-		result = malloc(len + 1);
-
-		if (result == NULL)
-			return NULL;
-
-		strncpy(result, src, len);
-		result[len] = 0;
-
-		return result;
-	}
-
-	if (dst_encoding == GG_ENCODING_CP1250 && src_encoding == GG_ENCODING_UTF8)
-		return gg_encoding_convert_utf8_cp1250(src, src_length, dst_length);
-
-	if (dst_encoding == GG_ENCODING_UTF8 && src_encoding == GG_ENCODING_CP1250)
-		return gg_encoding_convert_cp1250_utf8(src, src_length, dst_length);
-
-	errno = EINVAL;
-	return NULL;
-}
--- a/libpurple/protocols/gg/lib/encoding.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- *  (C) Copyright 2008-2009 Jakub Zawadzki <darkjames@darkjames.ath.cx>
- *                          Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_ENCODING_H
-#define LIBGADU_ENCODING_H
-
-#include "libgadu.h"
-
-char *gg_encoding_convert(const char *src, gg_encoding_t src_encoding,
-	gg_encoding_t dst_encoding, int src_length, int dst_length);
-
-#endif /* LIBGADU_SESSION_H */
--- a/libpurple/protocols/gg/lib/endian.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2010 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *                          Arkadiusz Miśkiewicz <arekm@pld-linux.org>
- *                          Tomasz Chiliński <chilek@chilan.com>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file endian.c
- *
- * \brief Konwersja między różnymi kolejnościami bajtów
- */
-
-#include "libgadu.h"
-#include "internal.h"
-
-/**
- * \internal Zamienia kolejność bajtów w 64-bitowym słowie.
- *
- * Ze względu na little-endianowość protokołu Gadu-Gadu, na maszynach
- * big-endianowych odwraca kolejność bajtów w słowie.
- *
- * \param x Liczba do zamiany
- *
- * \return Liczba z odpowiednią kolejnością bajtów
- *
- * \ingroup helper
- */
-uint64_t gg_fix64(uint64_t x)
-{
-#ifndef GG_CONFIG_BIGENDIAN
-	return x;
-#else
-	return (uint64_t)
-		(((x & (uint64_t) 0x00000000000000ffULL) << 56) |
-		((x & (uint64_t) 0x000000000000ff00ULL) << 40) |
-		((x & (uint64_t) 0x0000000000ff0000ULL) << 24) |
-		((x & (uint64_t) 0x00000000ff000000ULL) << 8) |
-		((x & (uint64_t) 0x000000ff00000000ULL) >> 8) |
-		((x & (uint64_t) 0x0000ff0000000000ULL) >> 24) |
-		((x & (uint64_t) 0x00ff000000000000ULL) >> 40) |
-		((x & (uint64_t) 0xff00000000000000ULL) >> 56));
-#endif
-}
-
-/**
- * \internal Zamienia kolejność bajtów w 32-bitowym słowie.
- *
- * Ze względu na little-endianowość protokołu Gadu-Gadu, na maszynach
- * big-endianowych odwraca kolejność bajtów w słowie.
- *
- * \param x Liczba do zamiany
- *
- * \return Liczba z odpowiednią kolejnością bajtów
- *
- * \ingroup helper
- */
-uint32_t gg_fix32(uint32_t x)
-{
-#ifndef GG_CONFIG_BIGENDIAN
-	return x;
-#else
-	return (uint32_t)
-		(((x & (uint32_t) 0x000000ffU) << 24) |
-		((x & (uint32_t) 0x0000ff00U) << 8) |
-		((x & (uint32_t) 0x00ff0000U) >> 8) |
-		((x & (uint32_t) 0xff000000U) >> 24));
-#endif
-}
-
-/**
- * \internal Zamienia kolejność bajtów w 16-bitowym słowie.
- *
- * Ze względu na little-endianowość protokołu Gadu-Gadu, na maszynach
- * big-endianowych zamienia kolejność bajtów w słowie.
- *
- * \param x Liczba do zamiany
- *
- * \return Liczba z odpowiednią kolejnością bajtów
- *
- * \ingroup helper
- */
-uint16_t gg_fix16(uint16_t x)
-{
-#ifndef GG_CONFIG_BIGENDIAN
-	return x;
-#else
-	return (uint16_t)
-		(((x & (uint16_t) 0x00ffU) << 8) |
-		((x & (uint16_t) 0xff00U) >> 8));
-#endif
-}
--- a/libpurple/protocols/gg/lib/events.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1901 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2006 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *                          Arkadiusz Miśkiewicz <arekm@pld-linux.org>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file events.c
- *
- * \brief Obsługa zdarzeń
- *
- * \todo Poprawna obsługa gg_proxy_http_only
- */
-
-#include "strman.h"
-#include "network.h"
-
-#include "libgadu.h"
-#include "protocol.h"
-#include "internal.h"
-#include "encoding.h"
-#include "debug.h"
-#include "session.h"
-#include "resolver.h"
-#include "config.h"
-
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <ctype.h>
-#ifdef GG_CONFIG_HAVE_GNUTLS
-#  include <gnutls/gnutls.h>
-#  include <gnutls/x509.h>
-#endif
-#ifdef GG_CONFIG_HAVE_OPENSSL
-#  include <openssl/err.h>
-#  include <openssl/x509.h>
-#  include <openssl/rand.h>
-#endif
-
-/**
- * Zwalnia pamięć zajmowaną przez informację o zdarzeniu.
- *
- * Funkcję należy wywoływać za każdym razem gdy funkcja biblioteki zwróci
- * strukturę \c gg_event.
- *
- * \param e Struktura zdarzenia
- *
- * \ingroup events
- */
-void gg_event_free(struct gg_event *e)
-{
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_event_free(%p);\n", e);
-
-	if (!e)
-		return;
-
-	switch (e->type) {
-		case GG_EVENT_MSG:
-		case GG_EVENT_MULTILOGON_MSG:
-			free(e->event.msg.message);
-			free(e->event.msg.formats);
-			free(e->event.msg.recipients);
-			free(e->event.msg.xhtml_message);
-			break;
-
-		case GG_EVENT_NOTIFY:
-			free(e->event.notify);
-			break;
-
-		case GG_EVENT_NOTIFY60:
-		{
-			int i;
-
-			for (i = 0; e->event.notify60[i].uin; i++)
-				free(e->event.notify60[i].descr);
-
-			free(e->event.notify60);
-
-			break;
-		}
-
-		case GG_EVENT_STATUS60:
-			free(e->event.status60.descr);
-			break;
-
-		case GG_EVENT_STATUS:
-			free(e->event.status.descr);
-			break;
-
-		case GG_EVENT_NOTIFY_DESCR:
-			free(e->event.notify_descr.notify);
-			free(e->event.notify_descr.descr);
-			break;
-
-		case GG_EVENT_DCC_VOICE_DATA:
-			free(e->event.dcc_voice_data.data);
-			break;
-
-		case GG_EVENT_PUBDIR50_SEARCH_REPLY:
-		case GG_EVENT_PUBDIR50_READ:
-		case GG_EVENT_PUBDIR50_WRITE:
-			gg_pubdir50_free(e->event.pubdir50);
-			break;
-
-		case GG_EVENT_USERLIST:
-			free(e->event.userlist.reply);
-			break;
-
-		case GG_EVENT_IMAGE_REPLY:
-			free(e->event.image_reply.filename);
-			free(e->event.image_reply.image);
-			break;
-
-		case GG_EVENT_XML_EVENT:
-			free(e->event.xml_event.data);
-			break;
-
-		case GG_EVENT_JSON_EVENT:
-			free(e->event.json_event.data);
-			free(e->event.json_event.type);
-			break;
-
-		case GG_EVENT_USER_DATA:
-		{
-			unsigned int i, j;
-
-			for (i = 0; i < e->event.user_data.user_count; i++) {
-				for (j = 0; j < e->event.user_data.users[i].attr_count; j++) {
-					free(e->event.user_data.users[i].attrs[j].key);
-					free(e->event.user_data.users[i].attrs[j].value);
-				}
-
-				free(e->event.user_data.users[i].attrs);
-			}
-
-			free(e->event.user_data.users);
-
-			break;
-		}
-
-		case GG_EVENT_MULTILOGON_INFO:
-		{
-			int i;
-
-			for (i = 0; i < e->event.multilogon_info.count; i++)
-				free(e->event.multilogon_info.sessions[i].name);
-
-			free(e->event.multilogon_info.sessions);
-
-			break;
-		}
-
-		case GG_EVENT_USERLIST100_REPLY:
-			free(e->event.userlist100_reply.reply);
-			break;
-
-		case GG_EVENT_IMTOKEN:
-			free(e->event.imtoken.imtoken);
-			break;
-
-		case GG_EVENT_CHAT_INFO:
-			free(e->event.chat_info.participants);
-			break;
-	}
-
-	free(e);
-}
-
-/** \cond internal */
-
-/**
- * \internal Usuwa obrazek z kolejki do wysłania.
- *
- * \param s Struktura sesji
- * \param q Struktura obrazka
- * \param freeq Flaga zwolnienia elementu kolejki
- *
- * \return 0 jeśli się powiodło, -1 jeśli wystąpił błąd
- */
-int gg_image_queue_remove(struct gg_session *s, struct gg_image_queue *q, int freeq)
-{
-	if (!s || !q) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (s->images == q)
-		s->images = q->next;
-	else {
-		struct gg_image_queue *qq;
-
-		for (qq = s->images; qq; qq = qq->next) {
-			if (qq->next == q) {
-				qq->next = q->next;
-				break;
-			}
-		}
-	}
-
-	if (freeq) {
-		free(q->image);
-		free(q->filename);
-		free(q);
-	}
-
-	return 0;
-}
-
-/** \endcond */
-
-/**
- * \internal Inicjalizuje struktury SSL.
- *
- * \param gs Struktura sesji
- *
- * \return 0 jeśli się powiodło, -1 jeśli wystąpił błąd
- */
-int gg_session_init_ssl(struct gg_session *gs)
-{
-#ifdef GG_CONFIG_HAVE_GNUTLS
-	gg_session_gnutls_t *tmp;
-
-	tmp = (gg_session_gnutls_t*) gs->ssl;
-
-	if (tmp == NULL) {
-		tmp = malloc(sizeof(gg_session_gnutls_t));
-
-		if (tmp == NULL) {
-			gg_debug(GG_DEBUG_MISC, "// gg_session_connect() out of memory for GnuTLS session\n");
-			return -1;
-		}
-
-		memset(tmp, 0, sizeof(gg_session_gnutls_t));
-
-		gs->ssl = tmp;
-
-		gnutls_global_init();
-		gnutls_certificate_allocate_credentials(&tmp->xcred);
-#ifdef GG_CONFIG_SSL_SYSTEM_TRUST
-#ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_SYSTEM_TRUST
-		gnutls_certificate_set_x509_system_trust(tmp->xcred);
-#else
-		gnutls_certificate_set_x509_trust_file(tmp->xcred,
-			GG_CONFIG_GNUTLS_SYSTEM_TRUST_STORE,
-			GNUTLS_X509_FMT_PEM);
-#endif
-#endif
-	} else {
-		gnutls_deinit(tmp->session);
-	}
-
-	gnutls_init(&tmp->session, GNUTLS_CLIENT);
-	gnutls_set_default_priority(tmp->session);
-	gnutls_credentials_set(tmp->session, GNUTLS_CRD_CERTIFICATE, tmp->xcred);
-	gnutls_transport_set_ptr(tmp->session, (gnutls_transport_ptr_t) (intptr_t) gs->fd);
-#endif
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-	char buf[1024];
-
-	OpenSSL_add_ssl_algorithms();
-
-	if (!RAND_status()) {
-		char rdata[1024];
-		struct {
-			time_t time;
-			void *ptr;
-		} rstruct;
-
-		time(&rstruct.time);
-		rstruct.ptr = (void *) &rstruct;
-
-		RAND_seed((void *) rdata, sizeof(rdata));
-		RAND_seed((void *) &rstruct, sizeof(rstruct));
-	}
-
-	if (gs->ssl_ctx == NULL) {
-		gs->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
-
-		if (gs->ssl_ctx == NULL) {
-			ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
-			gg_debug(GG_DEBUG_MISC, "// gg_session_connect() SSL_CTX_new() failed: %s\n", buf);
-			return -1;
-		}
-
-		SSL_CTX_set_verify(gs->ssl_ctx, SSL_VERIFY_NONE, NULL);
-#ifdef GG_CONFIG_SSL_SYSTEM_TRUST
-		SSL_CTX_set_default_verify_paths(gs->ssl_ctx);
-#endif
-	}
-
-	if (gs->ssl != NULL)
-		SSL_free(gs->ssl);
-
-	gs->ssl = SSL_new(gs->ssl_ctx);
-
-	if (gs->ssl == NULL) {
-		ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
-		gg_debug(GG_DEBUG_MISC, "// gg_session_connect() SSL_new() failed: %s\n", buf);
-		return -1;
-	}
-
-	SSL_set_fd(gs->ssl, gs->fd);
-#endif
-
-	return 0;
-}
-
-/**
- * \internal Funkcja próbuje wysłać dane zakolejkowane do wysyłki.
- *
- * \param sess Struktura sesji
- *
- * \return 0 jeśli się powiodło, -1 jeśli wystąpił błąd
- */
-static int gg_send_queued_data(struct gg_session *sess)
-{
-	int res;
-
-	if (sess->send_buf == NULL || sess->send_left == 0)
-		return 0;
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() sending %d bytes of queued data\n", sess->send_left);
-
-	res = send(sess->fd, sess->send_buf, sess->send_left, 0);
-
-	if (res == -1) {
-		if (errno == EAGAIN || errno == EINTR) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd()"
-				" non-critical send error (errno=%d, %s)\n",
-				errno, strerror(errno));
-
-			return 0;
-		}
-
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() send() "
-			"failed (errno=%d, %s)\n", errno, strerror(errno));
-
-		return -1;
-	}
-
-	if (res == sess->send_left) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() sent all queued data\n");
-		free(sess->send_buf);
-		sess->send_buf = NULL;
-		sess->send_left = 0;
-	} else if (res > 0) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() sent %d"
-			" bytes of queued data, %d bytes left\n",
-			res, sess->send_left - res);
-
-		memmove(sess->send_buf, sess->send_buf + res, sess->send_left - res);
-		sess->send_left -= res;
-	}
-
-	return 0;
-}
-
-/**
- * \internal Sprawdza wynik połączenia asynchronicznego.
- * \param gs Struktura sesji
- * \param res_ptr Wskaźnik na kod błędu
- * \return 0 jeśli się powiodło, -1 jeśli wystąpił błąd
- */
-static int gg_async_connect_failed(struct gg_session *gs, int *res_ptr)
-{
-	int res = 0;
-	socklen_t res_size = sizeof(res);
-
-	if (!gs->async)
-		return 0;
-
-	if (gs->timeout == 0) {
-		*res_ptr = ETIMEDOUT;
-		return 1;
-	}
-
-	if (getsockopt(gs->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) == -1) {
-		*res_ptr = errno;
-		return 1;
-	}
-
-	if (res != 0) {
-		*res_ptr = res;
-		return 1;
-	}
-
-	*res_ptr = 0;
-
-	return 0;
-}
-
-typedef enum
-{
-	GG_ACTION_WAIT,
-	GG_ACTION_NEXT,
-	GG_ACTION_FAIL
-} gg_action_t;
-
-typedef gg_action_t (*gg_state_handler_t)(struct gg_session *gs,
-	struct gg_event *ge, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state);
-
-typedef struct
-{
-	enum gg_state_t state;
-	gg_state_handler_t handler;
-	enum gg_state_t next_state;
-	enum gg_state_t alt_state;
-	enum gg_state_t alt2_state;
-} gg_state_transition_t;
-
-/* zwraca:
- * -1 w przypadku błędu
- * 0 jeżeli nie ma ustawionego specjalnego managera gniazdek
- * 1 w przypadku powodzenia
- */
-static int gg_handle_resolve_custom(struct gg_session *sess, enum gg_state_t next_state)
-{
-	struct gg_session_private *p = sess->private_data;
-	int is_tls = 0;
-	int port;
-
-	if (p->socket_manager_type == GG_SOCKET_MANAGER_TYPE_INTERNAL)
-		return 0;
-
-	if (p->socket_manager.connect_cb == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"// gg_handle_resolve_custom() socket_manager.connect "
-			"callback is empty\n");
-		return -1;
-	}
-
-	if (p->socket_handle != NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"// gg_handle_resolve_custom() socket_handle is not "
-			"NULL\n");
-		return -1;
-	}
-
-	port = sess->connect_port[sess->connect_index];
-	if (next_state == GG_STATE_SEND_HUB)
-		port = GG_APPMSG_PORT;
-
-	if (sess->ssl_flag != GG_SSL_DISABLED &&
-		next_state == GG_STATE_READING_KEY)
-	{
-		/* XXX: w tej chwili nie ma możliwości łączenia się do HUBa po
-		 * SSL, ale może będzie w przyszłości */
-		is_tls = 1;
-	}
-
-	if (is_tls && p->socket_manager_type == GG_SOCKET_MANAGER_TYPE_TCP) {
-		is_tls = 0;
-		next_state = GG_STATE_TLS_NEGOTIATION;
-	}
-
-	if (port <= 0) {
-		gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"// gg_handle_resolve_custom() port <= 0\n");
-		return -1;
-	}
-
-	p->socket_failure = 0;
-	p->socket_next_state = next_state;
-	p->socket_handle = p->socket_manager.connect_cb(
-		p->socket_manager.cb_data, sess->resolver_host, port, is_tls,
-		sess->async, sess);
-
-	if (p->socket_failure != 0) {
-		if (p->socket_handle != NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_WARNING,
-				"// gg_handle_resolve_custom() handle should be"
-				" empty on error\n");
-		}
-		return -1;
-	}
-
-	if (p->socket_handle == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"// gg_handle_resolve_custom() returned empty "
-			"handle\n");
-		return -1;
-	}
-
-	return 1;
-}
-
-static gg_action_t gg_handle_resolve_sync(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	struct in_addr addr;
-	int res;
-
-	res = gg_handle_resolve_custom(sess, alt_state);
-	if (res == 1)
-		return GG_ACTION_NEXT;
-	else if (res == -1)
-		return GG_ACTION_FAIL;
-
-	addr.s_addr = inet_addr(sess->resolver_host);
-
-	if (addr.s_addr == INADDR_NONE) {
-		struct in_addr *addr_list = NULL;
-		unsigned int addr_count;
-
-		if (gg_gethostbyname_real(sess->resolver_host, &addr_list, &addr_count, 0) == -1) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd()"
-				" host %s not found\n", sess->resolver_host);
-			e->event.failure = GG_FAILURE_RESOLVING;
-			free(addr_list);
-			return GG_ACTION_FAIL;
-		}
-
-		sess->resolver_result = addr_list;
-		sess->resolver_count = addr_count;
-		sess->resolver_index = 0;
-	} else {
-		sess->resolver_result = malloc(sizeof(struct in_addr));
-
-		if (sess->resolver_result == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() out of memory\n");
-			return GG_ACTION_FAIL;
-		}
-
-		sess->resolver_result[0].s_addr = addr.s_addr;
-		sess->resolver_count = 1;
-		sess->resolver_index = 0;
-	}
-
-	sess->state = next_state;
-
-	return GG_ACTION_NEXT;
-}
-
-static gg_action_t gg_handle_resolve_async(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	int res;
-
-	res = gg_handle_resolve_custom(sess, alt_state);
-	if (res == 1)
-		return GG_ACTION_WAIT;
-	else if (res == -1)
-		return GG_ACTION_FAIL;
-
-	if (sess->resolver_start(&sess->fd, &sess->resolver, sess->resolver_host) == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"resolving failed (errno=%d, %s)\n",
-			errno, strerror(errno));
-		e->event.failure = GG_FAILURE_RESOLVING;
-		return GG_ACTION_FAIL;
-	}
-
-	sess->state = next_state;
-	sess->check = GG_CHECK_READ;
-	sess->timeout = GG_DEFAULT_TIMEOUT;
-
-	return GG_ACTION_WAIT;
-}
-
-static gg_action_t gg_handle_resolving(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	char buf[256];
-	int count = -1;
-	int res;
-	unsigned int i;
-	struct in_addr *addrs;
-
-	res = gg_resolver_recv(sess->fd, buf, sizeof(buf));
-
-	if (res == -1 && (errno == EAGAIN || errno == EINTR)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"non-critical error (errno=%d, %s)\n",
-			errno, strerror(errno));
-		return GG_ACTION_WAIT;
-	}
-
-	sess->resolver_cleanup(&sess->resolver, 0);
-
-	if (res == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() read "
-			"error (errno=%d, %s)\n", errno, strerror(errno));
-		e->event.failure = GG_FAILURE_RESOLVING;
-		return GG_ACTION_FAIL;
-	}
-
-	if (res > 0) {
-		char *tmp;
-
-		tmp = realloc(sess->recv_buf, sess->recv_done + res);
-
-		if (tmp == NULL)
-			return GG_ACTION_FAIL;
-
-		sess->recv_buf = tmp;
-		memcpy(sess->recv_buf + sess->recv_done, buf, res);
-		sess->recv_done += res;
-	}
-
-	/* Sprawdź, czy mamy listę zakończoną INADDR_NONE */
-
-	addrs = (struct in_addr *)(void *)sess->recv_buf;
-
-	for (i = 0; i < sess->recv_done / sizeof(struct in_addr); i++) {
-		if (addrs[i].s_addr == INADDR_NONE) {
-			count = i;
-			break;
-		}
-	}
-
-	/* Nie znaleziono hosta */
-
-	if (count == 0) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() host not found\n");
-		e->event.failure = GG_FAILURE_RESOLVING;
-		return GG_ACTION_FAIL;
-	}
-
-	/* Nie mamy pełnej listy, ale połączenie zerwane */
-
-	if (res == 0 && count == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection broken\n");
-		e->event.failure = GG_FAILURE_RESOLVING;
-		return GG_ACTION_FAIL;
-	}
-
-	/* Nie mamy pełnej listy, normalna sytuacja */
-
-	if (count == -1)
-		return GG_ACTION_WAIT;
-
-#ifndef GG_DEBUG_DISABLE
-	if ((gg_debug_level & GG_DEBUG_DUMP) && (count > 0)) {
-		char *list;
-		size_t len;
-
-		len = 0;
-
-		for (i = 0; i < (unsigned int) count; i++) {
-			if (i > 0)
-				len += 2;
-
-			len += strlen(inet_ntoa(addrs[i]));
-		}
-
-		list = malloc(len + 1);
-
-		if (list == NULL)
-			return GG_ACTION_FAIL;
-
-		list[0] = 0;
-
-		for (i = 0; i < (unsigned int) count; i++) {
-			if (i > 0)
-				strcat(list, ", ");
-
-			strcat(list, inet_ntoa(addrs[i]));
-		}
-
-		gg_debug_session(sess, GG_DEBUG_DUMP, "// gg_watch_fd() resolved: %s\n", list);
-
-		free(list);
-	}
-#endif
-
-	gg_close(sess);
-
-	sess->state = next_state;
-	sess->resolver_result = addrs;
-	sess->resolver_count = count;
-	sess->resolver_index = 0;
-	sess->recv_buf = NULL;
-	sess->recv_done = 0;
-
-	return GG_ACTION_NEXT;
-}
-
-static gg_action_t gg_handle_connect(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	struct in_addr addr;
-	int port;
-
-	if (sess->resolver_index >= sess->resolver_count) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() out of addresses to connect to\n");
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	addr = sess->resolver_result[sess->resolver_index];
-
-	if (sess->state == GG_STATE_CONNECT_HUB) {
-		sess->hub_addr = addr.s_addr;
-		port = GG_APPMSG_PORT;
-	} else {
-		sess->proxy_addr = addr.s_addr;
-		port = sess->proxy_port;
-	}
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connecting to %s:%d\n", inet_ntoa(addr), port);
-
-	sess->fd = gg_connect(&addr, port, sess->async);
-
-	if (sess->fd == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"connection failed (errno=%d, %s)\n",
-			errno, strerror(errno));
-		sess->resolver_index++;
-		return GG_ACTION_NEXT;
-	}
-
-	sess->state = next_state;
-	sess->check = GG_CHECK_WRITE;
-	sess->timeout = GG_DEFAULT_TIMEOUT;
-	sess->soft_timeout = 1;
-
-	return GG_ACTION_WAIT;
-}
-
-static gg_action_t gg_handle_connecting(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	int res;
-
-	sess->soft_timeout = 0;
-
-	if (gg_async_connect_failed(sess, &res)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"connection failed (errno=%d, %s)\n",
-			res, strerror(res));
-		gg_close(sess);
-		sess->resolver_index++;
-		sess->state = alt_state;
-	} else {
-		/* Z proxy zwykle łączymy się dwa razy, więc nie zwalniamy
-		 * adresów IP po pierwszym połączeniu. */
-		if (sess->state != GG_STATE_CONNECTING_PROXY_HUB) {
-			free(sess->resolver_result);
-			sess->resolver_result = NULL;
-		}
-
-		sess->state = next_state;
-	}
-
-	return GG_ACTION_NEXT;
-}
-
-static gg_action_t gg_handle_connect_gg(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	struct in_addr addr;
-	uint16_t port;
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "resolver_index=%d, "
-		"connect_index=%d, connect_port={%d,%d}\n",
-		sess->resolver_index, sess->connect_index,
-		sess->connect_port[0], sess->connect_port[1]);
-
-	if ((unsigned int) sess->connect_index >=
-		sizeof(sess->connect_port) / sizeof(sess->connect_port[0]) ||
-		sess->connect_port[sess->connect_index] == 0)
-	{
-		sess->connect_index = 0;
-		sess->resolver_index++;
-		if (sess->resolver_index >= sess->resolver_count) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() out of addresses to connect to\n");
-			e->event.failure = GG_FAILURE_CONNECTING;
-			return GG_ACTION_FAIL;
-		}
-	}
-
-	addr = sess->resolver_result[sess->resolver_index];
-	port = sess->connect_port[sess->connect_index];
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connecting to %s:%d\n", inet_ntoa(addr), port);
-
-	sess->server_addr = addr.s_addr;
-	sess->fd = gg_connect(&addr, port, sess->async);
-
-	if (sess->fd == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"connection failed (errno=%d, %s)\n",
-			errno, strerror(errno));
-		sess->connect_index++;
-		return GG_ACTION_NEXT;
-	}
-
-	sess->state = next_state;
-	sess->check = GG_CHECK_WRITE;
-	sess->timeout = GG_DEFAULT_TIMEOUT;
-	sess->soft_timeout = 1;
-
-	return GG_ACTION_WAIT;
-}
-
-static gg_action_t gg_handle_connecting_gg(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	int res;
-
-	sess->soft_timeout = 0;
-
-	/* jeśli wystąpił błąd podczas łączenia się... */
-	if (gg_async_connect_failed(sess, &res)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"connection failed (errno=%d, %s)\n",
-			res, strerror(res));
-		gg_close(sess);
-		sess->connect_index++;
-		sess->state = alt_state;
-		return GG_ACTION_NEXT;
-	}
-
-	free(sess->resolver_result);
-	sess->resolver_result = NULL;
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connected\n");
-
-	if (sess->ssl_flag != GG_SSL_DISABLED) {
-		if (gg_session_init_ssl(sess) == -1) {
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-
-		sess->state = alt2_state;
-		sess->check = GG_CHECK_WRITE;
-		sess->timeout = GG_DEFAULT_TIMEOUT;
-
-		return GG_ACTION_NEXT;
-	} else {
-		sess->state = next_state;
-		sess->check = GG_CHECK_READ;
-		sess->timeout = GG_DEFAULT_TIMEOUT;
-
-		return GG_ACTION_WAIT;
-	}
-}
-
-static gg_action_t gg_handle_send_hub(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	char *req, *client, *auth;
-	const char *host;
-	int res;
-	int proxy;
-	size_t req_len;
-
-	if (sess->client_version != NULL && isdigit(sess->client_version[0]))
-		client = gg_urlencode(sess->client_version);
-	else if (sess->protocol_version <= GG_PROTOCOL_VERSION_100)
-		client = gg_urlencode(GG_DEFAULT_CLIENT_VERSION_100);
-	else /* sess->protocol_version >= GG_PROTOCOL_VERSION_110 */
-		client = gg_urlencode(GG_DEFAULT_CLIENT_VERSION_110);
-
-	if (client == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() out of memory for client version\n");
-		return GG_ACTION_FAIL;
-	}
-
-	if (sess->proxy_addr && sess->proxy_port) {
-		host = "http://" GG_APPMSG_HOST;
-		proxy = 1;
-	} else {
-		host = "";
-		proxy = 0;
-	}
-
-	auth = gg_proxy_auth();
-
-	if (sess->ssl_flag != GG_SSL_DISABLED) {
-		req = gg_saprintf
-			("GET %s/appsvc/appmsg_ver10.asp?fmnumber=%u&fmt=2&"
-			"lastmsg=%d&version=%s&age=2&gender=1 HTTP/1.0\r\n"
-			"Connection: close\r\n"
-			"Host: " GG_APPMSG_HOST "\r\n"
-			"%s"
-			"\r\n", host, sess->uin, sess->last_sysmsg, client, (auth) ? auth : "");
-	} else {
-		req = gg_saprintf
-			("GET %s/appsvc/appmsg_ver8.asp?fmnumber=%u&fmt=2&lastmsg=%d&version=%s HTTP/1.0\r\n"
-			"Host: " GG_APPMSG_HOST "\r\n"
-			"%s"
-			"\r\n", host, sess->uin, sess->last_sysmsg, client, (auth) ? auth : "");
-	}
-
-	free(auth);
-	free(client);
-
-	if (req == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() out of memory\n");
-		e->event.failure = GG_FAILURE_PROXY;
-		return GG_ACTION_FAIL;
-	}
-
-	req_len = strlen(req);
-
-	gg_debug_session(sess, GG_DEBUG_TRAFFIC, "// sending http query:\n%s", req);
-
-	res = send(sess->fd, req, req_len, 0);
-
-	free(req);
-
-	if (res == -1 && errno != EINTR && errno != EAGAIN) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() sending query failed\n");
-		e->event.failure = (!proxy) ? GG_FAILURE_HUB : GG_FAILURE_PROXY;
-		return GG_ACTION_FAIL;
-	}
-
-	if ((size_t) res < req_len) {
-		sess->state = alt_state;
-		sess->check = GG_CHECK_WRITE;
-		sess->timeout = GG_DEFAULT_TIMEOUT;
-	} else {
-		sess->state = next_state;
-		sess->check = GG_CHECK_READ;
-		sess->timeout = GG_DEFAULT_TIMEOUT;
-	}
-
-	return GG_ACTION_WAIT;
-}
-
-static gg_action_t gg_handle_sending_hub_proxy(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	if (gg_send_queued_data(sess) == -1) {
-		e->event.failure = GG_FAILURE_WRITING;
-		return GG_ACTION_FAIL;
-	}
-
-	if (sess->send_left > 0)
-		return GG_ACTION_WAIT;
-
-	sess->state = next_state;
-	sess->check = GG_CHECK_READ;
-	sess->timeout = GG_DEFAULT_TIMEOUT;
-
-	return GG_ACTION_WAIT;
-}
-
-static gg_action_t gg_handle_reading_hub_proxy(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	char buf[1024], *tmp, host[129];
-	int port = GG_DEFAULT_PORT;
-	int reply;
-	const char *body;
-	struct in_addr addr;
-	int res;
-	char **host_white;
-	char *host_white_default[] = GG_DEFAULT_HOST_WHITE_LIST;
-
-	res = recv(sess->fd, buf, sizeof(buf), 0);
-
-	if (res == -1 && (errno == EAGAIN || errno == EINTR)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"non-critical recv error (errno=%d, %s)\n",
-			errno, strerror(errno));
-		return GG_ACTION_WAIT;
-	}
-
-	if (res == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() recv "
-			"error (errno=%d, %s)\n", errno, strerror(errno));
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	if (res != 0) {
-		tmp = realloc(sess->recv_buf, sess->recv_done + res + 1);
-
-		if (tmp == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() not enough memory for http reply\n");
-			return GG_ACTION_FAIL;
-		}
-
-		sess->recv_buf = tmp;
-		memcpy(sess->recv_buf + sess->recv_done, buf, res);
-		sess->recv_done += res;
-		sess->recv_buf[sess->recv_done] = 0;
-	}
-
-	if (res == 0 && sess->recv_buf == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection closed\n");
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	if (res != 0)
-		return GG_ACTION_WAIT;
-
-	gg_debug_session(sess, GG_DEBUG_TRAFFIC, "// received http reply:\n%s", sess->recv_buf);
-
-	res = sscanf(sess->recv_buf, "HTTP/1.%*d %3d ", &reply);
-
-	/* sprawdzamy, czy wszystko w porządku. */
-	if (res != 1 || reply != 200) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() invalid http reply, connection failed\n");
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	/* szukamy początku treści */
-	body = strstr(sess->recv_buf, "\r\n\r\n");
-
-	if (body == NULL) {
-		body = strstr(sess->recv_buf, "\n\n");
-
-		if (body == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() can't find body\n");
-			e->event.failure = GG_FAILURE_CONNECTING;
-			return GG_ACTION_FAIL;
-		} else {
-			body += 2;
-		}
-	} else {
-		body += 4;
-	}
-
-	/* 17591 0 91.197.13.71:8074 91.197.13.71 */
-	res = sscanf(body, "%d %*d %128s", &reply, host);
-
-	if (res != 2) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() invalid hub reply, connection failed\n");
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "reply=%d, host=\"%s\"\n", reply, host);
-
-	/* jeśli pierwsza liczba w linii nie jest równa zeru,
-	 * oznacza to, że mamy wiadomość systemową. */
-	if (reply != 0) {
-		tmp = strchr(body, '\n');
-
-		if (tmp != NULL) {
-			e->type = GG_EVENT_MSG;
-			e->event.msg.msgclass = reply;
-			e->event.msg.sender = 0;
-			e->event.msg.message = (unsigned char*) strdup(tmp + 1);
-
-			if (e->event.msg.message == NULL) {
-				gg_debug_session(sess, GG_DEBUG_MISC,
-					"// gg_watch_fd() not enough memory "
-					"for system message\n");
-				return GG_ACTION_FAIL;
-			}
-		}
-	}
-
-	gg_close(sess);
-
-	tmp = strchr(host, ':');
-
-	if (tmp != NULL) {
-		*tmp = 0;
-		port = atoi(tmp + 1);
-	}
-
-	if (strcmp(host, "notoperating") == 0) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() service unavailable\n");
-		e->event.failure = GG_FAILURE_UNAVAILABLE;
-		return GG_ACTION_FAIL;
-	}
-
-	addr.s_addr = inet_addr(host);
-	if (addr.s_addr == INADDR_NONE)
-		addr.s_addr = 0;
-	sess->server_addr = addr.s_addr;
-
-	free(sess->recv_buf);
-	sess->recv_buf = NULL;
-	sess->recv_done = 0;
-
-	if (sess->state != GG_STATE_READING_PROXY_HUB) {
-		if (sess->port == 0) {
-			sess->connect_port[0] = port;
-			sess->connect_port[1] = (port != GG_HTTPS_PORT) ? GG_HTTPS_PORT : 0;
-		} else {
-			sess->connect_port[0] = sess->port;
-			sess->connect_port[1] = 0;
-		}
-	} else {
-		sess->connect_port[0] = (sess->port == 0) ? GG_HTTPS_PORT : sess->port;
-		sess->connect_port[1] = 0;
-	}
-
-	free(sess->connect_host);
-	sess->connect_host = strdup(host);
-
-	if (sess->connect_host == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() not enough memory\n");
-		return GG_ACTION_FAIL;
-	}
-
-	host_white = sess->private_data->host_white_list;
-	if (!host_white)
-		host_white = host_white_default;
-
-	if (sess->ssl_flag == GG_SSL_REQUIRED && host_white[0] != NULL) {
-		int host_ok = 0;
-		char **it;
-		int host_len;
-
-		host_len = strlen(sess->connect_host);
-
-		for (it = host_white; *it != NULL; it++) {
-			const char *white = *it;
-			int white_len, dom_offset;
-
-			white_len = strlen(white);
-			if (white_len > host_len)
-				continue;
-
-			dom_offset = host_len - white_len;
-			if (strncasecmp(sess->connect_host + dom_offset, white,
-				white_len) != 0)
-			{
-				continue;
-			}
-
-			if (white_len < host_len) {
-				if (sess->connect_host[dom_offset - 1] != '.')
-					continue;
-			}
-
-			host_ok = 1;
-			break;
-		}
-
-		if (!host_ok) {
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-				"// gg_watch_fd() the HUB server returned "
-				"a host that is not trusted (%s)\n",
-				sess->connect_host);
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-	}
-
-	if (sess->state == GG_STATE_READING_HUB)
-		sess->resolver_host = sess->connect_host;
-
-	/* Jeśli łączymy się przez proxy, zacznijmy od początku listy */
-	sess->resolver_index = 0;
-
-	sess->state = (sess->async) ? next_state : alt_state;
-
-	return GG_ACTION_NEXT;
-}
-
-static gg_action_t gg_handle_send_proxy_gg(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	char *req, *auth;
-	size_t req_len;
-	int res;
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() %s\n", gg_debug_state(sess->state));
-
-	if (sess->connect_index > 1 || sess->connect_port[sess->connect_index] == 0) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() out of connection candidates\n");
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	auth = gg_proxy_auth();
-
-	req = gg_saprintf("CONNECT %s:%d HTTP/1.0\r\n%s\r\n",
-		sess->connect_host, sess->connect_port[sess->connect_index],
-		(auth) ? auth : "");
-
-	free(auth);
-
-	sess->connect_index++;
-
-	if (req == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() out of memory\n");
-		e->event.failure = GG_FAILURE_PROXY;
-		return GG_ACTION_FAIL;
-	}
-
-	req_len = strlen(req);
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() proxy request:\n%s", req);
-
-	res = send(sess->fd, req, req_len, 0);
-
-	free(req);
-
-	if (res == -1 && errno != EINTR && errno != EAGAIN) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() sending query failed\n");
-		e->event.failure = GG_FAILURE_PROXY;
-		return GG_ACTION_FAIL;
-	}
-
-	if ((size_t) res < req_len) {
-		sess->state = alt_state;
-		sess->check = GG_CHECK_WRITE;
-		sess->timeout = GG_DEFAULT_TIMEOUT;
-	} else {
-		sess->state = next_state;
-		sess->check = GG_CHECK_READ;
-		sess->timeout = GG_DEFAULT_TIMEOUT;
-	}
-
-	return GG_ACTION_WAIT;
-}
-
-static gg_action_t gg_handle_tls_negotiation(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-#if defined(GG_CONFIG_HAVE_GNUTLS) || defined(GG_CONFIG_HAVE_OPENSSL)
-	int valid_hostname = 0;
-#endif
-
-#ifdef GG_CONFIG_HAVE_GNUTLS
-	unsigned int status;
-	int res;
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_TLS_NEGOTIATION\n");
-
-	for (;;) {
-		res = gnutls_handshake(GG_SESSION_GNUTLS(sess));
-
-		if (res == GNUTLS_E_AGAIN) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() TLS handshake GNUTLS_E_AGAIN\n");
-
-			if (gnutls_record_get_direction(GG_SESSION_GNUTLS(sess)) == 0)
-				sess->check = GG_CHECK_READ;
-			else
-				sess->check = GG_CHECK_WRITE;
-			sess->timeout = GG_DEFAULT_TIMEOUT;
-			return GG_ACTION_WAIT;
-		}
-
-		if (res == GNUTLS_E_INTERRUPTED) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() TLS handshake GNUTLS_E_INTERRUPTED\n");
-			continue;
-		}
-
-		if (res != GNUTLS_E_SUCCESS) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd()"
-				" TLS handshake error: %d, %s\n",
-				res, gnutls_strerror(res));
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-
-		break;
-	}
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() TLS negotiation succeded:\n");
-	gg_debug_session(sess, GG_DEBUG_MISC, "//   cipher: VERS-%s:%s:%s:%s:COMP-%s\n",
-		gnutls_protocol_get_name(gnutls_protocol_get_version(GG_SESSION_GNUTLS(sess))),
-		gnutls_cipher_get_name(gnutls_cipher_get(GG_SESSION_GNUTLS(sess))),
-		gnutls_kx_get_name(gnutls_kx_get(GG_SESSION_GNUTLS(sess))),
-		gnutls_mac_get_name(gnutls_mac_get(GG_SESSION_GNUTLS(sess))),
-		gnutls_compression_get_name(gnutls_compression_get(GG_SESSION_GNUTLS(sess))));
-
-	if (gnutls_certificate_type_get(GG_SESSION_GNUTLS(sess)) == GNUTLS_CRT_X509) {
-		unsigned int peer_count;
-		const gnutls_datum_t *peers;
-		gnutls_x509_crt_t cert;
-
-		if (gnutls_x509_crt_init(&cert) == 0) {
-			peers = gnutls_certificate_get_peers(GG_SESSION_GNUTLS(sess), &peer_count);
-
-			if (peers != NULL) {
-				char buf[256];
-				size_t size;
-
-				if (gnutls_x509_crt_import(cert, &peers[0], GNUTLS_X509_FMT_DER) == 0) {
-					size = sizeof(buf);
-					gnutls_x509_crt_get_dn(cert, buf, &size);
-					gg_debug_session(sess, GG_DEBUG_MISC, "//   cert subject: %s\n", buf);
-					size = sizeof(buf);
-					gnutls_x509_crt_get_issuer_dn(cert, buf, &size);
-					gg_debug_session(sess, GG_DEBUG_MISC, "//   cert issuer: %s\n", buf);
-
-					if (gnutls_x509_crt_check_hostname(cert, sess->connect_host) != 0)
-						valid_hostname = 1;
-				}
-			}
-
-			gnutls_x509_crt_deinit(cert);
-		}
-	}
-
-	res = gnutls_certificate_verify_peers2(GG_SESSION_GNUTLS(sess), &status);
-
-	if (res != 0 || status != 0) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "//   WARNING!  unable to"
-			" verify peer certificate: 0x%x, %d, %s\n", status, res,
-			gnutls_strerror(res));
-
-		if (sess->ssl_flag == GG_SSL_REQUIRED) {
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-	} else {
-		gg_debug_session(sess, GG_DEBUG_MISC, "//   verified peer certificate\n");
-	}
-
-
-#elif defined GG_CONFIG_HAVE_OPENSSL
-
-	X509 *peer;
-	int res;
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() %s\n", gg_debug_state(sess->state));
-
-	res = SSL_connect(GG_SESSION_OPENSSL(sess));
-
-	if (res <= 0) {
-		int err;
-
-		err = SSL_get_error(GG_SESSION_OPENSSL(sess), res);
-
-		if (res == 0) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() disconnected during TLS negotiation\n");
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-
-		if (err == SSL_ERROR_WANT_READ) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() SSL_connect() wants to read\n");
-
-			sess->check = GG_CHECK_READ;
-			sess->timeout = GG_DEFAULT_TIMEOUT;
-			return GG_ACTION_WAIT;
-		} else if (err == SSL_ERROR_WANT_WRITE) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() SSL_connect() wants to write\n");
-
-			sess->check = GG_CHECK_WRITE;
-			sess->timeout = GG_DEFAULT_TIMEOUT;
-			return GG_ACTION_WAIT;
-		} else {
-			char buf[256];
-
-			ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
-
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() SSL_connect() bailed out: %s\n", buf);
-
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-	}
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() TLS negotiation"
-		" succeded:\n//   cipher: %s\n",
-		SSL_get_cipher_name(GG_SESSION_OPENSSL(sess)));
-
-	peer = SSL_get_peer_certificate(GG_SESSION_OPENSSL(sess));
-
-	if (peer == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "//   WARNING! unable to get peer certificate!\n");
-
-		if (sess->ssl_flag == GG_SSL_REQUIRED) {
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-	} else {
-		char buf[256];
-		long res;
-
-		X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof(buf));
-		gg_debug_session(sess, GG_DEBUG_MISC, "//   cert subject: %s\n", buf);
-
-		X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof(buf));
-		gg_debug_session(sess, GG_DEBUG_MISC, "//   cert issuer: %s\n", buf);
-
-		res = SSL_get_verify_result(GG_SESSION_OPENSSL(sess));
-
-		if (res != X509_V_OK) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "//   WARNING!  "
-				"unable to verify peer certificate! "
-				"res=%ld\n", res);
-
-			if (sess->ssl_flag == GG_SSL_REQUIRED) {
-				e->event.failure = GG_FAILURE_TLS;
-				return GG_ACTION_FAIL;
-			}
-		} else {
-			gg_debug_session(sess, GG_DEBUG_MISC, "//   verified peer certificate\n");
-		}
-
-		if (X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, buf, sizeof(buf)) == -1)
-			buf[0] = 0;
-
-		/* Obsługa certyfikatów z wieloznacznikiem */
-		if (strchr(buf, '*') == buf && strchr(buf + 1, '*') == NULL) {
-			char *tmp;
-
-			tmp = strchr(sess->connect_host, '.');
-
-			if (tmp != NULL)
-				valid_hostname = (strcasecmp(tmp, buf + 1) == 0);
-		} else {
-			valid_hostname = (strcasecmp(sess->connect_host, buf) == 0);
-		}
-	}
-
-#else
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() no SSL support\n");
-	e->event.failure = GG_FAILURE_TLS;
-	return GG_ACTION_FAIL;
-
-#endif
-
-#if defined(GG_CONFIG_HAVE_GNUTLS) || defined(GG_CONFIG_HAVE_OPENSSL)
-	if (!valid_hostname) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "//   WARNING!  unable to verify hostname\n");
-
-		if (sess->ssl_flag == GG_SSL_REQUIRED) {
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-	}
-
-	sess->state = next_state;
-	sess->check = GG_CHECK_READ;
-	sess->timeout = GG_DEFAULT_TIMEOUT;
-
-	return GG_ACTION_WAIT;
-#endif
-}
-
-static gg_action_t gg_handle_reading_proxy_gg(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-	char buf[256];
-	int res;
-	int reply;
-	char *body;
-
-	res = recv(sess->fd, buf, sizeof(buf), 0);
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "recv() = %d\n", res);
-
-	if (res == -1 && (errno == EAGAIN || errno == EINTR)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"non-critical recv error (errno=%d, %s)\n",
-			errno, strerror(errno));
-		return GG_ACTION_WAIT;
-	}
-
-	if (res == -1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() recv "
-			"error (errno=%d, %s)\n", errno, strerror(errno));
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	if (res != 0) {
-		char *tmp;
-
-		tmp = realloc(sess->recv_buf, sess->recv_done + res + 1);
-
-		if (tmp == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() not enough memory for http reply\n");
-			return GG_ACTION_FAIL;
-		}
-
-		sess->recv_buf = tmp;
-		memcpy(sess->recv_buf + sess->recv_done, buf, res);
-		sess->recv_done += res;
-		sess->recv_buf[sess->recv_done] = 0;
-	}
-
-	if (res == 0 && sess->recv_buf == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection closed\n");
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	/* szukamy początku treści */
-	body = strstr(sess->recv_buf, "\r\n\r\n");
-
-	if (body == NULL) {
-		body = strstr(sess->recv_buf, "\n\n");
-
-		if (body == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() can't find body\n");
-			e->event.failure = GG_FAILURE_CONNECTING;
-			return GG_ACTION_FAIL;
-		} else {
-			body += 2;
-		}
-	} else {
-		body += 4;
-	}
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// found body!\n");
-
-	gg_debug_session(sess, GG_DEBUG_TRAFFIC, "// received proxy reply:\n%s\n", sess->recv_buf);
-
-	res = sscanf(sess->recv_buf, "HTTP/1.%*d %3d ", &reply);
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "res = %d, reply = %d\n", res, reply);
-
-	/* sprawdzamy, czy wszystko w porządku. */
-	if (res != 1 || reply != 200) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() invalid http reply, connection failed\n");
-		e->event.failure = GG_FAILURE_CONNECTING;
-		return GG_ACTION_FAIL;
-	}
-
-	if (sess->ssl_flag != GG_SSL_DISABLED) {
-		if (gg_session_init_ssl(sess) == -1) {
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-
-		/* Teoretycznie SSL jest inicjowany przez klienta, więc serwer
-		 * nie powinien niczego wysłać. */
-		if (sess->recv_buf + sess->recv_done > body) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() unexpected SSL data\n");
-			e->event.failure = GG_FAILURE_TLS;
-			return GG_ACTION_FAIL;
-		}
-
-		free(sess->recv_buf);
-		sess->recv_buf = NULL;
-		sess->recv_done = 0;
-
-		sess->state = alt_state;
-		sess->check = GG_CHECK_WRITE;
-		sess->timeout = GG_DEFAULT_TIMEOUT;
-
-		return GG_ACTION_WAIT;
-	}
-
-	sess->state = next_state;
-	sess->check = GG_CHECK_READ;
-	sess->timeout = GG_DEFAULT_TIMEOUT;	/* Pierwszy pakiet musi przyjść */
-
-	/* Jeśli zbuforowaliśmy za dużo, przeanalizuj */
-
-	if (sess->recv_buf + sess->recv_done > body) {
-		sess->recv_done = sess->recv_done - (body - sess->recv_buf);
-		memmove(sess->recv_buf, body, sess->recv_done);
-		sess->state = alt2_state;
-		return GG_ACTION_NEXT;
-	} else {
-		free(sess->recv_buf);
-		sess->recv_buf = NULL;
-		sess->recv_done = 0;
-	}
-
-	return GG_ACTION_WAIT;
-}
-
-static gg_action_t gg_handle_connected(struct gg_session *sess,
-	struct gg_event *e, enum gg_state_t next_state,
-	enum gg_state_t alt_state, enum gg_state_t alt2_state)
-{
-#if 0
-	char buf[1024];
-	int res;
-
-	if (gg_send_queued_data(sess) == -1)
-		return GG_ACTION_FAIL;
-
-	res = gg_read(sess, buf, sizeof(buf));
-
-	if (res == -1 && (errno == EAGAIN || errno == EINTR)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"non-critical read error (errno=%d, %s)\n",
-			errno, strerror(errno));
-		return GG_ACTION_WAIT;
-	}
-
-	if (res == -1 || res == 0) {
-		if (res == -1) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd()"
-				" read error (errno=%d, %s)\n",
-				errno, strerror(errno));
-		} else {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd()"
-				" connection closed\n");
-		}
-
-		if (sess->state == GG_STATE_DISCONNECTING && res == 0) {
-			e->type = GG_EVENT_DISCONNECT_ACK;
-		} else if (sess->state == GG_STATE_READING_KEY) {
-			e->event.failure = GG_FAILURE_INVALID;
-			return GG_ACTION_FAIL;
-		}
-
-		return GG_ACTION_FAIL;
-	}
-
-	gg_debug_dump(sess, GG_DEBUG_DUMP, buf, res);
-
-	if (gg_session_handle_data(sess, buf, res, e) == -1)
-		return GG_ACTION_FAIL;
-
-	if (sess->send_buf != NULL)
-		sess->check |= GG_CHECK_WRITE;
-
-	return GG_ACTION_WAIT;
-#else
-	struct gg_header *gh;
-
-	if (gg_send_queued_data(sess) == -1)
-		return GG_ACTION_FAIL;
-
-	gh = gg_recv_packet(sess);
-
-	if (gh == NULL) {
-		if (sess->state == GG_STATE_DISCONNECTING) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection broken expectedly\n");
-			e->type = GG_EVENT_DISCONNECT_ACK;
-			return GG_ACTION_WAIT;
-		}
-
-		if (errno != EAGAIN) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd()"
-				" gg_recv_packet failed (errno=%d, %s)\n",
-				errno, strerror(errno));
-			return GG_ACTION_FAIL;
-		}
-	} else {
-		if (gg_session_handle_packet(sess, gh->type,
-			(const char *) gh + sizeof(struct gg_header),
-			gh->length, e) == -1)
-		{
-			free(gh);
-			return GG_ACTION_FAIL;
-		}
-
-		free(gh);
-	}
-
-	sess->check = GG_CHECK_READ;
-
-	if (sess->send_buf != NULL)
-		sess->check |= GG_CHECK_WRITE;
-
-	return GG_ACTION_WAIT;
-#endif
-}
-
-static gg_action_t gg_handle_error(struct gg_session *sess, struct gg_event *e,
-	enum gg_state_t next_state, enum gg_state_t alt_state,
-	enum gg_state_t alt2_state)
-{
-	struct gg_session_private *p = sess->private_data;
-
-	gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_handle_error() failure=%d\n", p->socket_failure);
-
-	e->event.failure = p->socket_failure;
-
-	return GG_ACTION_FAIL;
-}
-
-static const gg_state_transition_t handlers[] =
-{
-	/* style:maxlinelength:start-ignore */
-	{ GG_STATE_RESOLVE_HUB_SYNC, gg_handle_resolve_sync, GG_STATE_CONNECT_HUB, GG_STATE_SEND_HUB, 0 },
-	{ GG_STATE_RESOLVE_GG_SYNC, gg_handle_resolve_sync, GG_STATE_CONNECT_GG, GG_STATE_READING_KEY, 0 },
-	{ GG_STATE_RESOLVE_PROXY_HUB_SYNC, gg_handle_resolve_sync, GG_STATE_CONNECT_PROXY_HUB, GG_STATE_SEND_PROXY_HUB, 0 },
-	{ GG_STATE_RESOLVE_PROXY_GG_SYNC, gg_handle_resolve_sync, GG_STATE_CONNECT_PROXY_GG, GG_STATE_SEND_PROXY_GG, 0 },
-
-	{ GG_STATE_RESOLVE_HUB_ASYNC, gg_handle_resolve_async, GG_STATE_RESOLVING_HUB, GG_STATE_SEND_HUB, 0 },
-	{ GG_STATE_RESOLVE_GG_ASYNC, gg_handle_resolve_async, GG_STATE_RESOLVING_GG, GG_STATE_READING_KEY, 0 },
-	{ GG_STATE_RESOLVE_PROXY_HUB_ASYNC, gg_handle_resolve_async, GG_STATE_RESOLVING_PROXY_HUB, GG_STATE_SEND_PROXY_HUB, 0 },
-	{ GG_STATE_RESOLVE_PROXY_GG_ASYNC, gg_handle_resolve_async, GG_STATE_RESOLVING_PROXY_GG, GG_STATE_SEND_PROXY_GG, 0 },
-
-	{ GG_STATE_RESOLVING_HUB, gg_handle_resolving, GG_STATE_CONNECT_HUB, 0, 0 },
-	{ GG_STATE_RESOLVING_GG, gg_handle_resolving, GG_STATE_CONNECT_GG, 0, 0 },
-	{ GG_STATE_RESOLVING_PROXY_HUB, gg_handle_resolving, GG_STATE_CONNECT_PROXY_HUB, 0, 0 },
-	{ GG_STATE_RESOLVING_PROXY_GG, gg_handle_resolving, GG_STATE_CONNECT_PROXY_GG, 0, 0 },
-
-	{ GG_STATE_CONNECT_HUB, gg_handle_connect, GG_STATE_CONNECTING_HUB, 0, 0 },
-	{ GG_STATE_CONNECT_PROXY_HUB, gg_handle_connect, GG_STATE_CONNECTING_PROXY_HUB, 0, 0 },
-	{ GG_STATE_CONNECT_PROXY_GG, gg_handle_connect, GG_STATE_CONNECTING_PROXY_GG, 0, 0 },
-
-	{ GG_STATE_CONNECT_GG, gg_handle_connect_gg, GG_STATE_CONNECTING_GG, 0, 0 },
-
-	{ GG_STATE_CONNECTING_HUB, gg_handle_connecting, GG_STATE_SEND_HUB, GG_STATE_CONNECT_HUB, 0 },
-	{ GG_STATE_CONNECTING_PROXY_HUB, gg_handle_connecting, GG_STATE_SEND_PROXY_HUB, GG_STATE_CONNECT_PROXY_HUB, 0 },
-	{ GG_STATE_CONNECTING_PROXY_GG, gg_handle_connecting, GG_STATE_SEND_PROXY_GG, GG_STATE_CONNECT_PROXY_GG, 0 },
-
-	{ GG_STATE_CONNECTING_GG, gg_handle_connecting_gg, GG_STATE_READING_KEY, GG_STATE_CONNECT_GG, GG_STATE_TLS_NEGOTIATION },
-
-	{ GG_STATE_SEND_HUB, gg_handle_send_hub, GG_STATE_READING_HUB, GG_STATE_SENDING_HUB, 0 },
-	{ GG_STATE_SEND_PROXY_HUB, gg_handle_send_hub, GG_STATE_READING_PROXY_HUB, GG_STATE_SENDING_PROXY_HUB, 0 },
-
-	{ GG_STATE_SEND_PROXY_GG, gg_handle_send_proxy_gg, GG_STATE_READING_PROXY_GG, GG_STATE_SENDING_PROXY_GG, 0 },
-
-	{ GG_STATE_SENDING_HUB, gg_handle_sending_hub_proxy, GG_STATE_READING_HUB, 0, 0 },
-	{ GG_STATE_SENDING_PROXY_HUB, gg_handle_sending_hub_proxy, GG_STATE_READING_PROXY_HUB, 0, 0 },
-	{ GG_STATE_SENDING_PROXY_GG, gg_handle_sending_hub_proxy, GG_STATE_READING_PROXY_GG, 0, 0 },
-
-	{ GG_STATE_READING_HUB, gg_handle_reading_hub_proxy, GG_STATE_RESOLVE_GG_ASYNC, GG_STATE_RESOLVE_GG_SYNC, 0 },
-	{ GG_STATE_READING_PROXY_HUB, gg_handle_reading_hub_proxy, GG_STATE_CONNECT_PROXY_GG, GG_STATE_CONNECT_PROXY_GG, 0 },
-
-	{ GG_STATE_READING_PROXY_GG, gg_handle_reading_proxy_gg, GG_STATE_READING_KEY, GG_STATE_TLS_NEGOTIATION, GG_STATE_READING_KEY },
-
-	{ GG_STATE_TLS_NEGOTIATION, gg_handle_tls_negotiation, GG_STATE_READING_KEY, 0, 0 },
-
-	{ GG_STATE_READING_KEY, gg_handle_connected, 0, 0, 0 },
-	{ GG_STATE_READING_REPLY, gg_handle_connected, 0, 0, 0 },
-	{ GG_STATE_CONNECTED, gg_handle_connected, 0, 0, 0 },
-	{ GG_STATE_DISCONNECTING, gg_handle_connected, 0, 0, 0 },
-	{ GG_STATE_ERROR, gg_handle_error, 0, 0, 0 },
-	/* style:maxlinelength:end-ignore */
-};
-
-struct gg_event *gg_eventqueue_add(struct gg_session *sess)
-{
-	struct gg_event *ge;
-	gg_eventqueue_t *queue_el, *it;
-
-	queue_el = gg_new0(sizeof(gg_eventqueue_t));
-	ge = gg_new0(sizeof(struct gg_event));
-
-	if (queue_el == NULL || ge == NULL) {
-		free(queue_el);
-		free(ge);
-		return NULL;
-	}
-
-	ge->type = GG_EVENT_NONE;
-
-	queue_el->event = ge;
-	if (sess->private_data->event_queue == NULL)
-		sess->private_data->event_queue = queue_el;
-	else {
-		it = sess->private_data->event_queue;
-		while (it->next != NULL)
-			it = it->next;
-		it->next = queue_el;
-	}
-
-	return ge;
-}
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze sesji.
- *
- * Funkcja zwraca strukturę zdarzenia \c gg_event. Jeśli rodzaj zdarzenia
- * to \c GG_EVENT_NONE, nie wydarzyło się jeszcze nic wartego odnotowania.
- * Strukturę zdarzenia należy zwolnić funkcja \c gg_event_free().
- *
- * \param sess Struktura sesji
- *
- * \return Struktura zdarzenia lub \c NULL jeśli wystąpił błąd
- *
- * \ingroup events
- */
-struct gg_event *gg_watch_fd(struct gg_session *sess)
-{
-	struct gg_event *ge;
-	struct gg_session_private *priv;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_watch_fd(%p);\n", sess);
-
-	if (sess == NULL) {
-		errno = EFAULT;
-		return NULL;
-	}
-
-	priv = sess->private_data;
-
-	if (priv->event_queue != NULL) {
-		gg_eventqueue_t *next;
-
-		ge = priv->event_queue->event;
-		next = priv->event_queue->next;
-		free(priv->event_queue);
-		priv->event_queue = next;
-
-		if (next == NULL) {
-			sess->check = priv->check_after_queue;
-			sess->fd = priv->fd_after_queue;
-		}
-		return ge;
-	}
-
-	ge = malloc(sizeof(struct gg_event));
-
-	if (ge == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() not enough memory for event data\n");
-		return NULL;
-	}
-
-	memset(ge, 0, sizeof(struct gg_event));
-
-	ge->type = GG_EVENT_NONE;
-
-	for (;;) {
-		unsigned int i, found = 0;
-		gg_action_t res;
-
-		res = GG_ACTION_FAIL;
-
-		for (i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++) {
-			if (handlers[i].state == (enum gg_state_t) sess->state) {
-				gg_debug_session(sess, GG_DEBUG_MISC,
-					"// gg_watch_fd() %s\n",
-					gg_debug_state(sess->state));
-				res = (*handlers[i].handler)(sess, ge,
-					handlers[i].next_state,
-					handlers[i].alt_state,
-					handlers[i].alt2_state);
-				found = 1;
-				break;
-			}
-		}
-
-		if (!found) {
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-				"// gg_watch_fd() invalid state %s\n",
-				gg_debug_state(sess->state));
-			ge->event.failure = GG_FAILURE_INTERNAL;
-		}
-
-		if (!sess->async && ge->type == GG_EVENT_NONE && res == GG_ACTION_WAIT)
-			res = GG_ACTION_NEXT;
-
-		switch (res) {
-			case GG_ACTION_WAIT:
-				if (priv->event_queue != NULL) {
-					priv->fd_after_queue = sess->fd;
-					priv->check_after_queue = sess->check;
-					/* wymuszamy ponowne wywołanie gg_watch_fd */
-					sess->fd = gg_get_dummy_fd(sess);
-					if (sess->fd < 0)
-						sess->fd = priv->fd_after_queue;
-					sess->check = GG_CHECK_READ | GG_CHECK_WRITE;
-				}
-				return ge;
-
-			case GG_ACTION_NEXT:
-				continue;
-
-			case GG_ACTION_FAIL:
-				sess->state = GG_STATE_IDLE;
-
-				gg_close(sess);
-
-				if (ge->event.failure != 0) {
-					ge->type = GG_EVENT_CONN_FAILED;
-				} else {
-					free(ge);
-					ge = NULL;
-				}
-
-				return ge;
-
-			/* Celowo nie ma default */
-		}
-	}
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
--- a/libpurple/protocols/gg/lib/fileio.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2011 Bartosz Brachaczek <b.brachaczek@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file fileio.h
- *
- * \brief Makra zapewniające kompatybilność API do obsługi operacji na plikach na różnych systemach
- */
-
-#ifndef LIBGADU_FILEIO_H
-#define LIBGADU_FILEIO_H
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#ifdef _WIN32
-#  include <io.h>
-#  define gg_file_close _close
-#  undef lseek
-#  define lseek _lseek
-#  undef open
-#  define open _open
-#  undef read
-#  define read _read
-#  undef stat
-#  define stat _stat
-#  undef fstat
-#  define fstat _fstat
-#  undef write
-#  define write _write
-#  define S_IRWXO 0
-#  define S_IRWXG 0
-#else
-#  ifdef sun
-#    include <sys/filio.h>
-#  endif
-#  include <unistd.h>
-#  define gg_file_close close
-#endif
-
-#ifndef S_IWUSR
-#  define S_IWUSR S_IWRITE
-#endif
-
-#endif /* LIBGADU_FILEIO_H */
--- a/libpurple/protocols/gg/lib/handlers.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2881 +0,0 @@
-/*
- *  (C) Copyright 2001-2011 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *                          Arkadiusz Miśkiewicz <arekm@pld-linux.org>
- *                          Tomasz Chiliński <chilek@chilan.com>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file handlers.c
- *
- * \brief Funkcje obsługi przychodzących pakietów
- */
-
-#include <ctype.h>
-
-#include "fileio.h"
-#include "network.h"
-#include "strman.h"
-#include "libgadu.h"
-#include "resolver.h"
-#include "session.h"
-#include "protocol.h"
-#include "encoding.h"
-#include "message.h"
-#include "internal.h"
-#include "deflate.h"
-#include "tvbuff.h"
-#include "protobuf.h"
-#include "packets.pb-c.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* Ograniczenie długości listy kontaktów
- * z pakietów GG_USERLIST_REPLY do 10MB. */
-#define GG_USERLIST_REPLY_MAX_LENGTH 10485760
-
-/**
- * \internal Struktura opisująca funkcję obsługi pakietu.
- */
-typedef struct {
-	/* Typ pakietu */
-	uint32_t type;
-	/* Stan w którym pakiet jest obsługiwany */
-	enum gg_state_t state;
-	/* Minimalny rozmiar danych pakietu */
-	size_t min_length;
-	/* Funkcja obsługująca pakiet. Patrz gg_session_handle_packet(). */
-	int (*handler)(struct gg_session *, uint32_t, const char *, size_t, struct gg_event *);
-} gg_packet_handler_t;
-
-static int gg_ack_110(struct gg_session *gs, GG110Ack__Type type, uint32_t seq, struct gg_event *ge)
-{
-	GG110Ack msg = GG110_ACK__INIT;
-
-	msg.type = type;
-	msg.seq = seq;
-
-	if (!GG_PROTOBUF_SEND(gs, ge, GG_ACK110, gg110_ack, msg))
-		return -1;
-	return 0;
-}
-
-static void gg_sync_time(struct gg_session *gs, time_t server_time)
-{
-	time_t local_time = time(NULL);
-	int time_diff = server_time - local_time;
-
-	if (gs->private_data->time_diff == time_diff)
-		return;
-
-	gs->private_data->time_diff = time_diff;
-	gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_VERBOSE,
-		"// time synchronized (diff = %d)\n", time_diff);
-}
-
-static int gg_session_handle_welcome_110(struct gg_session *gs, uint32_t seed,
-	struct gg_event *ge)
-{
-	GG105Login msg = GG105_LOGIN__INIT;
-	char client_str[1000];
-	uint8_t hash[64];
-	const char *client_name = GG11_VERSION;
-	const char *client_version = GG_DEFAULT_CLIENT_VERSION_110;
-	const char *client_target = GG11_TARGET;
-	uint8_t dummy4[4] = {0, 0, 0, 0};
-
-	if (gs->hash_type != GG_LOGIN_HASH_SHA1) {
-		gg_debug_session(gs, GG_DEBUG_ERROR, "// Unsupported hash type "
-			"for this protocol version\n");
-		gg_connection_failure(gs, ge, GG_FAILURE_INTERNAL);
-		return -1;
-	}
-
-	if (gg_login_hash_sha1_2(gs->password, seed, hash) == -1) {
-		gg_debug_session(gs, GG_DEBUG_ERROR, "// gg_watch_fd() "
-			"gg_login_hash_sha1_2() failed, "
-			"probably out of memory\n");
-		gg_connection_failure(gs, ge, GG_FAILURE_INTERNAL);
-		return -1;
-	}
-
-	if (gs->client_version != NULL && !isdigit(gs->client_version[0])) {
-		client_name = "";
-		client_target = "";
-	}
-	if (gs->client_version != NULL)
-		client_version = gs->client_version;
-	snprintf(client_str, sizeof(client_str), "%s%s%s",
-		client_name, client_version, client_target);
-	client_str[sizeof(client_str) - 1] = '\0';
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() "
-		"sending GG_LOGIN105 packet\n");
-
-	msg.lang = GG8_LANG;
-	gg_protobuf_set_uin(&msg.uin, gs->uin, NULL);
-	msg.hash.len = 20;
-	msg.hash.data = hash;
-	msg.client = client_str;
-
-	/* flagi gg8 są różne od tych dla gg11 */
-	msg.initial_status = gs->initial_status ?
-		(gs->initial_status & 0xFF) : GG_STATUS_AVAIL;
-
-	if (gs->initial_descr != NULL) {
-		msg.initial_descr = gs->initial_descr;
-	}
-
-	/* GG11.0
-	msg.supported_features = "avatar,StatusComments,gg_account_sdp,"
-		"edisc,bot,fanpage,pubdir,botCaps"; */
-	/* GG11.2 */
-	msg.supported_features = "avatar,StatusComments,ggaccount,edisc,"
-		"music_shared,bot,fanpage,pubdir,botCaps,gifts,Gift";
-
-	msg.dummy4.len = sizeof(dummy4);
-	msg.dummy4.data = dummy4;
-
-	msg.has_dummy7 = 1;
-	msg.has_dummy8 = 1;
-	msg.has_dummy10 = 1;
-
-	if (!GG_PROTOBUF_SEND(gs, ge, GG_LOGIN105, gg105_login, msg))
-		return -1;
-
-	gs->state = GG_STATE_READING_REPLY;
-	gs->check = GG_CHECK_READ;
-	return 0;
-}
-
-static int gg_session_handle_login110_ok(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110LoginOK *msg = gg110_login_ok__unpack(NULL, len, (uint8_t*)ptr);
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110LoginOK", msg))
-		return -1;
-
-	gg_protobuf_expected(gs, "GG110LoginOK.dummy1", msg->dummy1, 1);
-	gg_sync_time(gs, msg->server_time);
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// login110_ok: "
-		"uin=%u, dummyhash=%s\n", msg->uin, msg->dummyhash);
-
-	gg110_login_ok__free_unpacked(msg, NULL);
-
-	ge->type = GG_EVENT_CONN_SUCCESS;
-	gs->state = GG_STATE_CONNECTED;
-	gs->check = GG_CHECK_READ;
-	gs->timeout = -1;
-	gs->status = (gs->initial_status) ? gs->initial_status : GG_STATUS_AVAIL;
-#if 0
-	free(gs->status_descr);
-	gs->status_descr = gs->initial_descr;
-#else
-	free(gs->initial_descr);
-#endif
-	gs->initial_descr = NULL;
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_WELCOME.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_welcome(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_welcome *w;
-	int ret;
-	uint8_t hash_buf[64];
-	uint32_t local_ip;
-	struct sockaddr_in sin;
-	socklen_t sin_len = sizeof(sin);
-	uint32_t seed;
-
-	struct gg_login80 l80;
-	const char *client_name, *version, *descr;
-	uint32_t client_name_len, version_len, descr_len;
-
-	if (len < sizeof(struct gg_welcome)) {
-		ge->type = GG_EVENT_CONN_FAILED;
-		ge->event.failure = GG_FAILURE_INVALID;
-		gs->state = GG_STATE_IDLE;
-		gg_close(gs);
-		return 0;
-	}
-
-	w = (const struct gg_welcome*) ptr;
-	seed = gg_fix32(w->key);
-
-	if (gs->protocol_version >= GG_PROTOCOL_VERSION_110)
-		return gg_session_handle_welcome_110(gs, seed, ge);
-
-	memset(hash_buf, 0, sizeof(hash_buf));
-
-	switch (gs->hash_type) {
-		case GG_LOGIN_HASH_GG32:
-		{
-			uint32_t hash;
-
-			hash = gg_fix32(gg_login_hash((unsigned char*) gs->password, seed));
-			gg_debug_session(gs, GG_DEBUG_DUMP, "// gg_watch_fd() "
-				"challenge %.4x --> GG32 hash %.8x\n",
-				seed, hash);
-			memcpy(hash_buf, &hash, sizeof(hash));
-
-			break;
-		}
-
-		case GG_LOGIN_HASH_SHA1:
-		{
-#ifndef GG_DEBUG_DISABLE
-			char tmp[41];
-			int i;
-#endif
-
-			if (gg_login_hash_sha1_2(gs->password, seed, hash_buf) == -1) {
-				gg_debug_session(gs, GG_DEBUG_MISC,
-					"// gg_watch_fd() gg_login_hash_sha1_2()"
-					" failed, probably out of memory\n");
-				gg_close(gs);
-				ge->type = GG_EVENT_CONN_FAILED;
-				ge->event.failure = GG_FAILURE_INTERNAL;
-				gs->state = GG_STATE_IDLE;
-				return -1;
-			}
-
-#ifndef GG_DEBUG_DISABLE
-			for (i = 0; i < 40; i += 2)
-				snprintf(tmp + i, sizeof(tmp) - i, "%02x", hash_buf[i / 2]);
-
-			gg_debug_session(gs, GG_DEBUG_DUMP, "// gg_watch_fd() "
-				"challenge %.4x --> SHA1 hash: %s\n",
-				seed, tmp);
-#endif
-
-			break;
-		}
-
-		default:
-			break;
-	}
-
-#if 0
-	if (gs->password != NULL && (gs->flags & (1 << GG_SESSION_FLAG_CLEAR_PASSWORD))) {
-		memset(gs->password, 0, strlen(gs->password));
-		free(gs->password);
-		gs->password = NULL;
-	}
-#endif
-
-	if (!getsockname(gs->fd, (struct sockaddr*) &sin, &sin_len)) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"detected address to %s\n", inet_ntoa(sin.sin_addr));
-		local_ip = sin.sin_addr.s_addr;
-	} else {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() unable to detect address\n");
-		local_ip = 0;
-	}
-
-	if (gs->external_addr == 0)
-		gs->external_addr = local_ip;
-
-	memset(&l80, 0, sizeof(l80));
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() sending GG_LOGIN80 packet\n");
-	l80.uin = gg_fix32(gs->uin);
-	memcpy(l80.language, GG8_LANG, sizeof(l80.language));
-	l80.hash_type = gs->hash_type;
-	memcpy(l80.hash, hash_buf, sizeof(l80.hash));
-	l80.status = gg_fix32(gs->initial_status ? gs->initial_status : GG_STATUS_AVAIL);
-	l80.flags = gg_fix32(gs->status_flags);
-	l80.features = gg_fix32(gs->protocol_features);
-	l80.image_size = gs->image_size;
-	l80.dunno2 = 0x64;
-
-	if (gs->client_version != NULL && !isdigit(gs->client_version[0])) {
-		client_name = "";
-		client_name_len = 0;
-	} else {
-		client_name = GG8_VERSION;
-		client_name_len = strlen(GG8_VERSION);
-	}
-
-	version = (gs->client_version != NULL) ? gs->client_version : GG_DEFAULT_CLIENT_VERSION_100;
-	version_len = gg_fix32(client_name_len + strlen(version));
-
-	descr = (gs->initial_descr != NULL) ? gs->initial_descr : "";
-	descr_len = (gs->initial_descr != NULL) ? gg_fix32(strlen(gs->initial_descr)) : 0;
-
-	ret = gg_send_packet(gs,
-			GG_LOGIN80,
-			&l80, sizeof(l80),
-			&version_len, sizeof(version_len),
-			client_name, client_name_len,
-			version, strlen(version),
-			&descr_len, sizeof(descr_len),
-			descr, strlen(descr),
-			NULL);
-
-	if (ret == -1) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() "
-			"sending packet failed. (errno=%d, %s)\n",
-			errno, strerror(errno));
-		gg_close(gs);
-		ge->type = GG_EVENT_CONN_FAILED;
-		ge->event.failure = GG_FAILURE_WRITING;
-		gs->state = GG_STATE_IDLE;
-		return -1;
-	}
-
-	gs->state = GG_STATE_READING_REPLY;
-	gs->check = GG_CHECK_READ;
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_LOGIN_OK.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_login_ok(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() login succeded\n");
-	ge->type = GG_EVENT_CONN_SUCCESS;
-	gs->state = GG_STATE_CONNECTED;
-	gs->check = GG_CHECK_READ;
-	gs->timeout = -1;
-	gs->status = (gs->initial_status) ? gs->initial_status : GG_STATUS_AVAIL;
-#if 0
-	free(gs->status_descr);
-	gs->status_descr = gs->initial_descr;
-#else
-	free(gs->initial_descr);
-#endif
-	gs->initial_descr = NULL;
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_LOGIN_FAILED.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_login_failed(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	if (type != GG_DISCONNECTING)
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() login failed\n");
-	else
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() too many incorrect password attempts\n");
-	ge->type = GG_EVENT_CONN_FAILED;
-	ge->event.failure = (type != GG_DISCONNECTING) ? GG_FAILURE_PASSWORD : GG_FAILURE_INTRUDER;
-	gs->state = GG_STATE_IDLE;
-	gg_close(gs);
-	errno = EACCES;
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_SEND_MSG_ACK.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_send_msg_ack(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	struct gg_session_private *p = gs->private_data;
-	const struct gg_send_msg_ack *s = (const struct gg_send_msg_ack*) ptr;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a message ack\n");
-
-	ge->type = GG_EVENT_ACK;
-	ge->event.ack.status = gg_fix32(s->status);
-	ge->event.ack.recipient = gg_fix32(s->recipient);
-	ge->event.ack.seq = gg_fix32(s->seq);
-
-	if (ge->event.ack.seq == 0 && p->imgout_waiting_ack > 0)
-		p->imgout_waiting_ack--;
-	gg_image_sendout(gs);
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_SEND_MSG_ACK110.
- */
-static int gg_session_handle_send_msg_ack_110(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	struct gg_session_private *p = gs->private_data;
-	GG110MessageAck *msg = gg110_message_ack__unpack(NULL, len, (uint8_t*)ptr);
-	size_t i;
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110MessageAck", msg))
-		return -1;
-
-	if (msg->dummy1 == 0x4000) {
-		/* zaobserwowane w EKG rev2856, po wywołaniu check_conn, czyli
-		 * gg_image_request(sess, uin, 0, time(NULL));
-		 */
-		gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_WARNING,
-			"// gg_session_handle_send_msg_ack_110() magic dummy1 "
-			"value 0x4000\n");
-	} else if (msg->dummy1 != 0) {
-		gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_WARNING,
-			"// gg_session_handle_send_msg_ack_110() unknown dummy1 "
-			"value: %x\n", msg->dummy1);
-	}
-
-	gg_debug_session(gs, GG_DEBUG_VERBOSE,
-		"// gg_session_handle_send_msg_ack_110() "
-		"%s=%016" PRIx64 " %s=%016" PRIx64 "\n",
-		msg->has_msg_id ? "msg_id" : "0", msg->msg_id,
-		msg->has_conv_id ? "conv_id" : "0", msg->conv_id);
-
-	for (i = 0; i < msg->n_links; i++) {
-		GG110MessageAckLink *link = msg->links[i];
-		if (!GG_PROTOBUF_VALID(gs, "GG110MessageAckLink", link))
-			continue;
-		gg_debug_session(gs, GG_DEBUG_MISC,
-			"// gg_session_handle_send_msg_ack_110() "
-			"got link (id=%" PRIx64 ") \"%s\"\n", link->id, link->url);
-	}
-
-	ge->type = GG_EVENT_ACK110;
-	ge->event.ack110.msg_type = msg->msg_type;
-	ge->event.ack110.seq = msg->seq;
-	ge->event.ack110.time = msg->time;
-
-	gg_compat_message_ack(gs, msg->seq);
-
-	gg110_message_ack__free_unpacked(msg, NULL);
-
-	if (msg->seq == 0 && p->imgout_waiting_ack > 0)
-		p->imgout_waiting_ack--;
-	gg_image_sendout(gs);
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_PONG.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_pong(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a pong\n");
-
-	ge->type = GG_EVENT_PONG;
-
-	gs->last_pong = time(NULL);
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_DISCONNECTING.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_disconnecting(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received disconnection warning\n");
-
-	ge->type = GG_EVENT_DISCONNECT;
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_DISCONNECT_ACK.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_disconnect_ack(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received logoff acknowledge\n");
-
-	ge->type = GG_EVENT_DISCONNECT_ACK;
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiety GG_XML_EVENT i GG_XML_ACTION.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_xml_event(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received XML event\n");
-
-	ge->type = GG_EVENT_XML_EVENT;
-	ge->event.xml_event.data = malloc(len + 1);
-
-	if (ge->event.xml_event.data == NULL) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-		return -1;
-	}
-
-	memcpy(ge->event.xml_event.data, ptr, len);
-	ge->event.xml_event.data[len] = 0;
-
-	return 0;
-}
-
-static int gg_session_handle_event_110(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110Event *msg = gg110_event__unpack(NULL, len, (uint8_t*)ptr);
-	int succ = 1;
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110Event", msg))
-		return -1;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_session_handle_event_110: "
-		"received GG11 event (type=%d, id=%" PRIx64 ")\n", msg->type, msg->id);
-
-	if (msg->type == GG110_EVENT__TYPE__XML) {
-		ge->type = GG_EVENT_XML_EVENT;
-		ge->event.xml_event.data = strdup(msg->data);
-		succ = succ && (ge->event.xml_event.data != NULL);
-	} else if (msg->type == GG110_EVENT__TYPE__JSON) {
-		ge->type = GG_EVENT_JSON_EVENT;
-		ge->event.json_event.data = strdup(msg->data);
-		succ = succ && (ge->event.json_event.data != NULL);
-		ge->event.json_event.type = strdup(msg->subtype);
-		succ = succ && (ge->event.json_event.type != NULL);
-	} else {
-		gg_debug_session(gs, GG_DEBUG_WARNING,
-			"// gg_session_handle_event_110: "
-			"unsupported GG11 event type: %d\n", msg->type);
-		succ = 0;
-	}
-
-	if (gg_ack_110(gs, GG110_ACK__TYPE__MPA, msg->seq, ge) != 0) {
-		succ = 0;
-	}
-
-	gg110_event__free_unpacked(msg, NULL);
-
-	return succ ? 0 : -1;
-}
-
-/**
- * \internal Obsługuje pakiet GG_PUBDIR50_REPLY.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_pubdir50_reply(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received pubdir/search reply\n");
-
-	return gg_pubdir50_handle_reply_sess(gs, ge, ptr, len);
-}
-
-/**
- * \internal Obsługuje pakiet GG_USERLIST_REPLY.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_userlist_reply(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	char reply_type;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received userlist reply\n");
-
-	reply_type = ptr[0];
-
-	/* jeśli odpowiedź na eksport, wywołaj zdarzenie tylko
-	 * gdy otrzymano wszystkie odpowiedzi */
-	if (reply_type == GG_USERLIST_PUT_REPLY || reply_type == GG_USERLIST_PUT_MORE_REPLY) {
-		if (--gs->userlist_blocks)
-			return 0;
-
-		reply_type = GG_USERLIST_PUT_REPLY;
-	}
-
-	if (len > 1) {
-		unsigned int reply_len = (gs->userlist_reply != NULL) ? strlen(gs->userlist_reply) : 0;
-		char *tmp;
-
-		gg_debug_session(gs, GG_DEBUG_MISC, "userlist_reply=%p, len=%"
-			GG_SIZE_FMT "\n", gs->userlist_reply, len);
-
-		if (reply_len + len > GG_USERLIST_REPLY_MAX_LENGTH) {
-			gg_debug_session(gs, GG_DEBUG_MISC,
-				"// gg_session_handle_userlist_reply() "
-				"too many userlist replies\n");
-			return -1;
-		}
-
-		tmp = realloc(gs->userlist_reply, reply_len + len);
-
-		if (tmp == NULL) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			return -1;
-		}
-
-		gs->userlist_reply = tmp;
-		memcpy(gs->userlist_reply + reply_len, ptr + 1, len - 1);
-		gs->userlist_reply[reply_len + len - 1] = 0;
-	}
-
-	if (reply_type == GG_USERLIST_GET_MORE_REPLY)
-		return 0;
-
-	ge->type = GG_EVENT_USERLIST;
-	ge->event.userlist.type = reply_type;
-	ge->event.userlist.reply = gs->userlist_reply;
-
-	gs->userlist_reply = NULL;
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_DCC7_ID_REPLY.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_dcc7_id_reply(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received dcc7 id packet\n");
-
-	return gg_dcc7_handle_id(gs, ge, ptr, len);
-}
-
-/**
- * \internal Obsługuje pakiet GG_DCC7_ACCEPT.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_dcc7_accept(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received dcc7 accept\n");
-
-	return gg_dcc7_handle_accept(gs, ge, ptr, len);
-}
-
-/**
- * \internal Obsługuje pakiet GG_DCC7_NEW.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_dcc7_new(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received dcc7 request\n");
-
-	return gg_dcc7_handle_new(gs, ge, ptr, len);
-}
-
-/**
- * \internal Obsługuje pakiet GG_DCC7_REJECT.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_dcc7_reject(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received dcc7 reject\n");
-
-	return gg_dcc7_handle_reject(gs, ge, ptr, len);
-}
-
-/**
- * \internal Obsługuje pakiet GG_DCC7_INFO.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_dcc7_info(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received dcc7 info\n");
-
-	return gg_dcc7_handle_info(gs, ge, ptr, len);
-}
-
-/**
- * \internal Analizuje przychodzący pakiet z obrazkiem.
- *
- * \param e Struktura zdarzenia
- * \param p Bufor z danymi
- * \param len Długość bufora
- * \param sess Struktura sesji
- * \param sender Numer nadawcy
- * \param type Typ pakietu (NIE typ GG_MSG_OPTION_IMAGE_*)
- */
-static void gg_image_queue_parse(struct gg_event *e, const char *p,
-	unsigned int len, struct gg_session *sess, uin_t sender,
-	uint32_t type)
-{
-	const struct gg_msg_image_reply *i = (const void*) p;
-	struct gg_image_queue *q, *qq;
-
-	gg_debug_session(sess, GG_DEBUG_VERBOSE,
-		"// gg_image_queue_parse(%p, %p, %d, %p, %u, %d)\n",
-		e, p, len, sess, sender, type);
-
-	if (!p || !sess || !e) {
-		errno = EFAULT;
-		return;
-	}
-
-	if (i->flag == GG_MSG_OPTION_IMAGE_REQUEST) {
-		e->type = GG_EVENT_IMAGE_REQUEST;
-		e->event.image_request.sender = sender;
-		e->event.image_reply.size = i->size;
-		e->event.image_request.crc32 = i->crc32;
-		return;
-	}
-
-	/* znajdź dany obrazek w kolejce danej sesji */
-
-	for (qq = sess->images, q = NULL; qq; qq = qq->next) {
-		if (sender == qq->sender && i->size == qq->size && i->crc32 == qq->crc32) {
-			q = qq;
-			break;
-		}
-	}
-
-	if (!q) {
-		gg_debug_session(sess, GG_DEBUG_WARNING,
-			"// gg_image_queue_parse() unknown image from %d, "
-			"size=%d, crc32=%.8x\n", sender, i->size, i->crc32);
-		return;
-	}
-
-	if (q->packet_type == 0)
-		q->packet_type = type;
-	if (q->packet_type != type)
-		return;
-
-	if (i->flag == GG_MSG_OPTION_IMAGE_REPLY) {
-		q->done = 0;
-
-		len -= sizeof(struct gg_msg_image_reply);
-		p += sizeof(struct gg_msg_image_reply);
-
-		if (memchr(p, 0, len) == NULL) {
-			gg_debug_session(sess, GG_DEBUG_ERROR,
-				"// gg_image_queue_parse() malformed packet "
-				"from %d, unlimited filename\n", sender);
-			return;
-		}
-
-		if (!(q->filename = strdup(p))) {
-			gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_image_queue_parse() out of memory\n");
-			return;
-		}
-
-		len -= strlen(p) + 1;
-		p += strlen(p) + 1;
-	} else if (i->flag == GG_MSG_OPTION_IMAGE_REPLY_MORE) {
-		len -= sizeof(struct gg_msg_image_reply);
-		p += sizeof(struct gg_msg_image_reply);
-	} else {
-		gg_debug_session(sess, GG_DEBUG_WARNING, "// gg_image_queue_parse() unexpected flag\n");
-		return;
-	}
-
-	if (q->done + len > q->size) {
-		gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_image_queue_parse() got too much\n");
-		len = q->size - q->done;
-	}
-
-	memcpy(q->image + q->done, p, len);
-	q->done += len;
-
-	gg_debug_session(sess, GG_DEBUG_VERBOSE,
-		"// gg_image_queue_parse() got image part (done: %d of %d)\n",
-		q->done, q->size);
-
-	/* jeśli skończono odbierać obrazek, wygeneruj zdarzenie */
-
-	if (q->done >= q->size) {
-		gg_debug_session(sess, GG_DEBUG_VERBOSE,
-			"// gg_image_queue_parse() image ready\n");
-
-		e->type = GG_EVENT_IMAGE_REPLY;
-		e->event.image_reply.sender = sender;
-		e->event.image_reply.size = q->size;
-		e->event.image_reply.crc32 = q->crc32;
-		e->event.image_reply.filename = q->filename;
-		e->event.image_reply.image = q->image;
-
-		gg_image_queue_remove(sess, q, 0);
-
-		free(q);
-	}
-}
-
-/**
- * \internal Analizuje informacje rozszerzone wiadomości.
- *
- * \param sess Struktura sesji.
- * \param e Struktura zdarzenia.
- * \param sender Numer nadawcy.
- * \param p Wskaźnik na dane rozszerzone.
- * \param packet_end Wskaźnik na koniec pakietu.
- * \param packet_type Typ pakietu, w którym otrzymaliśmy wiadomość.
- *
- * \return 0 jeśli się powiodło, -1 jeśli wiadomość obsłużono i wynik ma
- * zostać przekazany aplikacji, -2 jeśli wystąpił błąd ogólny, -3 jeśli
- * wiadomość jest niepoprawna.
- */
-static int gg_handle_recv_msg_options(struct gg_session *sess,
-	struct gg_event *e, uin_t sender, const char *p, const char *packet_end,
-	uint32_t packet_type)
-{
-	while (p < packet_end) {
-		switch (*p) {
-			case GG_MSG_OPTION_CONFERENCE:
-			{
-				const struct gg_msg_recipients *m = (const void*) p;
-				uint32_t i, count;
-
-				p += sizeof(*m);
-
-				if (p > packet_end) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" packet out of bounds (1)\n");
-					goto malformed;
-				}
-
-				count = gg_fix32(m->count);
-
-				if (p + count * sizeof(uin_t) > packet_end ||
-					p + count * sizeof(uin_t) < p ||
-					count > 0xffff)
-				{
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" packet out of bounds (1.5)\n");
-					goto malformed;
-				}
-
-				if (e->event.msg.recipients != NULL) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" e->event.msg.recipients already exist\n");
-					goto malformed;
-				}
-
-				e->event.msg.recipients = malloc(count * sizeof(uin_t));
-
-				if (e->event.msg.recipients == NULL) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" not enough memory for recipients data\n");
-					goto fail;
-				}
-
-				memcpy(e->event.msg.recipients, p, count * sizeof(uin_t));
-				p += count * sizeof(uin_t);
-
-				for (i = 0; i < count; i++)
-					e->event.msg.recipients[i] = gg_fix32(e->event.msg.recipients[i]);
-
-				e->event.msg.recipients_count = count;
-
-				break;
-			}
-
-			case GG_MSG_OPTION_ATTRIBUTES:
-			{
-				uint16_t len;
-				char *buf;
-
-				if (p + 3 > packet_end) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" packet out of bounds (2)\n");
-					goto malformed;
-				}
-
-				memcpy(&len, p + 1, sizeof(uint16_t));
-				len = gg_fix16(len);
-
-				if (e->event.msg.formats != NULL) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" e->event.msg.formats already exist\n");
-					goto malformed;
-				}
-
-				buf = malloc(len);
-
-				if (buf == NULL) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" not enough memory for richtext data\n");
-					goto fail;
-				}
-
-				p += 3;
-
-				if (p + len > packet_end) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" packet out of bounds (3)\n");
-					free(buf);
-					goto malformed;
-				}
-
-				memcpy(buf, p, len);
-
-				e->event.msg.formats = buf;
-				e->event.msg.formats_length = len;
-
-				p += len;
-
-				break;
-			}
-
-			case GG_MSG_OPTION_IMAGE_REQUEST:
-			{
-				const struct gg_msg_image_request *i = (const void*) p;
-
-				if (p + sizeof(*i) > packet_end) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg() "
-						"packet out of bounds (3)\n");
-					goto malformed;
-				}
-
-				if (e->event.msg.formats != NULL || e->event.msg.recipients != NULL) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options()"
-						" mixed options (1)\n");
-					goto malformed;
-				}
-
-				e->event.image_request.sender = sender;
-				e->event.image_request.size = gg_fix32(i->size);
-				e->event.image_request.crc32 = gg_fix32(i->crc32);
-
-				e->type = GG_EVENT_IMAGE_REQUEST;
-
-				goto handled;
-			}
-
-			case GG_MSG_OPTION_IMAGE_REPLY:
-			case GG_MSG_OPTION_IMAGE_REPLY_MORE:
-			{
-				struct gg_msg_image_reply *rep = (void*) p;
-
-				if (e->event.msg.formats != NULL || e->event.msg.recipients != NULL) {
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg_options() "
-						"mixed options (2)\n");
-					goto malformed;
-				}
-
-				if (p + sizeof(struct gg_msg_image_reply) == packet_end) {
-
-					/* pusta odpowiedź - klient po drugiej stronie nie ma żądanego obrazka */
-
-					e->type = GG_EVENT_IMAGE_REPLY;
-					e->event.image_reply.sender = sender;
-					e->event.image_reply.size = 0;
-					e->event.image_reply.crc32 = gg_fix32(rep->crc32);
-					e->event.image_reply.filename = NULL;
-					e->event.image_reply.image = NULL;
-					goto handled;
-
-				} else if (p + sizeof(struct gg_msg_image_reply) + 1 > packet_end) {
-
-					gg_debug_session(sess, GG_DEBUG_MISC,
-						"// gg_handle_recv_msg() "
-						"packet out of bounds (4)\n");
-					goto malformed;
-				}
-
-				rep->size = gg_fix32(rep->size);
-				rep->crc32 = gg_fix32(rep->crc32);
-				gg_image_queue_parse(e, p, (unsigned int)(packet_end - p), sess, sender, packet_type);
-
-				goto handled;
-			}
-
-			default:
-			{
-				gg_debug_session(sess, GG_DEBUG_MISC,
-					"// gg_handle_recv_msg() "
-					"unknown payload 0x%.2x\n", *p);
-				p = packet_end;
-			}
-		}
-	}
-
-	return 0;
-
-handled:
-	return -1;
-
-fail:
-	return -2;
-
-malformed:
-	return -3;
-}
-
-/**
- * \internal Wysyła potwierdzenie odebrania wiadomości.
- *
- * \param gs Struktura sesji
- * \param seq Numer sekwencyjny odebranej wiadomości
- *
- * \return 0 jeśli się powiodło, -1 jeśli wystąpił błąd
- */
-static int gg_session_send_msg_ack(struct gg_session *gs, uint32_t seq)
-{
-	struct gg_recv_msg_ack pkt;
-
-	gg_debug_session(gs, GG_DEBUG_FUNCTION, "** gg_session_send_msg_ack(%p);\n", gs);
-
-	if ((gs->protocol_features & GG_FEATURE_MSG_ACK) == 0)
-		return 0;
-
-	/* Kiedyś zdawało nam się, że mamy wysyłać liczbę odebranych
-	 * wiadomości, ale okazało się, że numer sekwencyjny. */
-	gs->recv_msg_count++;
-
-	pkt.seq = gg_fix32(seq);
-
-	return gg_send_packet(gs, GG_RECV_MSG_ACK, &pkt, sizeof(pkt), NULL);
-}
-
-/**
- * \internal Obsługuje pakiet GG_RECV_MSG.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_recv_msg(struct gg_session *sess, uint32_t type,
-	const char *packet, size_t length, struct gg_event *e)
-{
-	const struct gg_recv_msg *r = (const struct gg_recv_msg*) packet;
-	const char *payload = packet + sizeof(struct gg_recv_msg);
-	const char *payload_end = packet + length;
-	size_t len;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_handle_recv_msg(%p, %"
-		GG_SIZE_FMT ", %p);\n", packet, length, e);
-
-	if (sess == NULL)
-		goto fail;
-
-	if ((r->seq == 0) && (r->msgclass == 0)) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_recv_msg() oops, silently ignoring the bait\n");
-		goto malformed;
-	}
-
-	/* jednobajtowa wiadomość o treści \x02 to żądanie połączenia DCC */
-	if (*payload == GG_MSG_CALLBACK && payload == payload_end - 1) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_recv_msg() received ctcp packet\n");
-		length = 1;
-	} else {
-		const char *options;
-
-		options = memchr(payload, 0, (size_t) (payload_end - payload));
-
-		if (options == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC,
-				"// gg_handle_recv_msg() malformed packet, "
-				"message out of bounds (0)\n");
-			goto malformed;
-		}
-
-		length = (size_t) (options - payload);
-
-		switch (gg_handle_recv_msg_options(sess, e, gg_fix32(r->sender), options + 1, payload_end, type)) {
-			case -1:	/* handled */
-				gg_session_send_msg_ack(sess, gg_fix32(r->seq));
-				return 0;
-
-			case -2:	/* failed */
-				goto fail;
-
-			case -3:	/* malformed */
-				goto malformed;
-		}
-	}
-
-	e->type = GG_EVENT_MSG;
-	e->event.msg.msgclass = gg_fix32(r->msgclass);
-	e->event.msg.sender = gg_fix32(r->sender);
-	e->event.msg.time = gg_fix32(r->time);
-	e->event.msg.seq = gg_fix32(r->seq);
-
-	e->event.msg.message = (unsigned char*)gg_encoding_convert(payload,
-		GG_ENCODING_CP1250, sess->encoding, length, -1);
-	if (e->event.msg.message == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_session_handle_recv_msg() out of memory\n");
-		goto fail;
-	}
-
-	len = gg_message_text_to_html(NULL, (char*)e->event.msg.message,
-		sess->encoding, e->event.msg.formats,
-		e->event.msg.formats_length);
-	e->event.msg.xhtml_message = malloc(len + 1);
-
-	if (e->event.msg.xhtml_message == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_session_handle_recv_msg() out of memory\n");
-		goto fail;
-	}
-
-	gg_message_text_to_html(e->event.msg.xhtml_message,
-		(char*)e->event.msg.message, sess->encoding,
-		e->event.msg.formats, e->event.msg.formats_length);
-
-	gg_session_send_msg_ack(sess, gg_fix32(r->seq));
-	return 0;
-
-fail:
-	free(e->event.msg.message);
-	free(e->event.msg.xhtml_message);
-	free(e->event.msg.recipients);
-	free(e->event.msg.formats);
-	return -1;
-
-malformed:
-	e->type = GG_EVENT_NONE;
-	free(e->event.msg.message);
-	free(e->event.msg.xhtml_message);
-	free(e->event.msg.recipients);
-	free(e->event.msg.formats);
-	gg_session_send_msg_ack(sess, gg_fix32(r->seq));
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_RECV_MSG80.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_recv_msg_80(struct gg_session *sess, uint32_t type,
-	const char *packet, size_t length, struct gg_event *e)
-{
-	const struct gg_recv_msg80 *r = (const struct gg_recv_msg80*) packet;
-	uint32_t offset_plain;
-	uint32_t offset_attr;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION,
-		"** gg_handle_recv_msg80(%p, %" GG_SIZE_FMT ", %p);\n",
-		packet, length, e);
-
-	if (sess == NULL)
-		goto fail;
-
-	if (r->seq == 0 && r->msgclass == 0) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_recv_msg80() oops, silently ignoring the bait\n");
-		goto malformed;
-	}
-
-	offset_plain = gg_fix32(r->offset_plain);
-	offset_attr = gg_fix32(r->offset_attr);
-
-	if (offset_plain < sizeof(struct gg_recv_msg80) || offset_plain >= length) {
-		gg_debug_session(sess, GG_DEBUG_MISC,
-			"// gg_handle_recv_msg80() malformed packet, "
-			"message out of bounds (0)\n");
-		goto malformed;
-	}
-
-	if (offset_attr < sizeof(struct gg_recv_msg80) || offset_attr > length) {
-		gg_debug_session(sess, GG_DEBUG_MISC,
-			"// gg_handle_recv_msg80() malformed packet, "
-			"attr out of bounds (1)\n");
-		offset_attr = 0; /* nie parsuj attr. */
-	}
-
-	/* Normalna sytuacja, więc nie podpada pod powyższy warunek. */
-	if (offset_attr == length)
-		offset_attr = 0;
-
-	if (memchr(packet + offset_plain, 0, length - offset_plain) == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC,
-			"// gg_handle_recv_msg80() malformed packet, "
-			"message out of bounds (2)\n");
-		goto malformed;
-	}
-
-	if (offset_plain > sizeof(struct gg_recv_msg80) && memchr(packet +
-		sizeof(struct gg_recv_msg80), 0, offset_plain -
-		sizeof(struct gg_recv_msg80)) == NULL)
-	{
-		gg_debug_session(sess, GG_DEBUG_MISC,
-			"// gg_handle_recv_msg80() malformed packet, "
-			"message out of bounds (3)\n");
-		goto malformed;
-	}
-
-	e->type = (type != GG_RECV_OWN_MSG) ? GG_EVENT_MSG : GG_EVENT_MULTILOGON_MSG;
-	e->event.msg.msgclass = gg_fix32(r->msgclass);
-	e->event.msg.sender = gg_fix32(r->sender);
-	e->event.msg.time = gg_fix32(r->time);
-	e->event.msg.seq = gg_fix32(r->seq);
-
-	if (offset_attr != 0) {
-		switch (gg_handle_recv_msg_options(sess, e, gg_fix32(r->sender),
-			packet + offset_attr, packet + length, type))
-		{
-			case -1:	/* handled */
-				gg_session_send_msg_ack(sess, gg_fix32(r->seq));
-				return 0;
-
-			case -2:	/* failed */
-				goto fail;
-
-			case -3:	/* malformed */
-				goto malformed;
-		}
-	}
-
-	if (sess->encoding == GG_ENCODING_CP1250) {
-		e->event.msg.message = (unsigned char*) strdup(packet + offset_plain);
-
-		if (e->event.msg.message == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_session_handle_recv_msg_80() out of memory\n");
-			goto fail;
-		}
-	} else {
-		if (offset_plain > sizeof(struct gg_recv_msg80)) {
-			size_t len, fmt_len;
-
-			len = gg_message_html_to_text(NULL, NULL, &fmt_len,
-				packet + sizeof(struct gg_recv_msg80),
-				GG_ENCODING_UTF8);
-			e->event.msg.message = malloc(len + 1);
-
-			if (e->event.msg.message == NULL) {
-				gg_debug_session(sess, GG_DEBUG_MISC,
-					"// gg_session_handle_recv_msg_80() "
-					"out of memory\n");
-				goto fail;
-			}
-
-			free(e->event.msg.formats);
-			e->event.msg.formats_length = fmt_len;
-			e->event.msg.formats = malloc(fmt_len);
-
-			if (e->event.msg.formats == NULL) {
-				gg_debug_session(sess, GG_DEBUG_MISC,
-					"// gg_session_handle_recv_msg_80() "
-					"out of memory\n");
-				goto fail;
-			}
-
-			gg_message_html_to_text((char*)e->event.msg.message,
-				e->event.msg.formats, NULL,
-				packet + sizeof(struct gg_recv_msg80),
-				GG_ENCODING_UTF8);
-		} else {
-			e->event.msg.message = (unsigned char*)gg_encoding_convert(
-				packet + offset_plain, GG_ENCODING_CP1250,
-				sess->encoding, -1, -1);
-
-			if (e->event.msg.message == NULL) {
-				gg_debug_session(sess, GG_DEBUG_MISC,
-					"// gg_session_handle_recv_msg_80() "
-					"out of memory\n");
-				goto fail;
-			}
-		}
-	}
-
-	if (offset_plain > sizeof(struct gg_recv_msg80)) {
-		e->event.msg.xhtml_message = gg_encoding_convert(
-			packet + sizeof(struct gg_recv_msg80), GG_ENCODING_UTF8,
-			sess->encoding, -1, -1);
-
-		if (e->event.msg.xhtml_message == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_session_handle_recv_msg_80() out of memory\n");
-			goto fail;
-		}
-	} else {
-		size_t len;
-
-		len = gg_message_text_to_html(NULL,
-			(char*)e->event.msg.message, sess->encoding,
-			e->event.msg.formats, e->event.msg.formats_length);
-		e->event.msg.xhtml_message = malloc(len + 1);
-
-		if (e->event.msg.xhtml_message == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_session_handle_recv_msg_80() out of memory\n");
-			goto fail;
-		}
-
-		gg_message_text_to_html(e->event.msg.xhtml_message,
-			(char*)e->event.msg.message, sess->encoding,
-			e->event.msg.formats, e->event.msg.formats_length);
-	}
-
-	gg_session_send_msg_ack(sess, gg_fix32(r->seq));
-	return 0;
-
-fail:
-	free(e->event.msg.message);
-	free(e->event.msg.xhtml_message);
-	free(e->event.msg.recipients);
-	free(e->event.msg.formats);
-	return -1;
-
-malformed:
-	e->type = GG_EVENT_NONE;
-	free(e->event.msg.message);
-	free(e->event.msg.xhtml_message);
-	free(e->event.msg.recipients);
-	free(e->event.msg.formats);
-	gg_session_send_msg_ack(sess, gg_fix32(r->seq));
-	return 0;
-}
-
-static int gg_session_handle_recv_msg_110(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110RecvMessage *msg = gg110_recv_message__unpack(NULL, len, (uint8_t*)ptr);
-	uint8_t ack_type;
-	uin_t sender = 0;
-	uint32_t seq;
-	int succ = 1;
-	struct gg_event_msg *ev = &ge->event.msg;
-
-	gg_debug_session(gs, GG_DEBUG_FUNCTION,
-		"** gg_session_handle_recv_msg_110(%p, %" GG_SIZE_FMT
-		", %p);\n", ptr, len, ge);
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110RecvMessage", msg))
-		return -1;
-
-	seq = msg->seq;
-	if (type == GG_CHAT_RECV_MSG || type == GG_CHAT_RECV_OWN_MSG)
-		ack_type = GG110_ACK__TYPE__CHAT;
-	else
-		ack_type = GG110_ACK__TYPE__MSG;
-
-	if (msg->has_msg_id || msg->has_conv_id) {
-		msg->msg_id = msg->has_msg_id ? msg->msg_id : 0;
-		msg->conv_id = msg->has_conv_id ? msg->conv_id : 0;
-		gg_debug_session(gs, GG_DEBUG_VERBOSE,
-			"// gg_session_handle_recv_msg_110() "
-			"msg_id=%016" PRIx64 " conv_id=%016" PRIx64 "\n",
-			msg->msg_id, msg->conv_id);
-	}
-
-	if (msg->has_sender)
-		sender = gg_protobuf_get_uin(msg->sender);
-	else if (type == GG_CHAT_RECV_OWN_MSG)
-		sender = gs->uin;
-
-	if (msg->has_data && msg->msg_plain[0] == '\0') {
-		if (msg->data.len < sizeof(struct gg_msg_image_reply)) {
-			gg_debug_session(gs, GG_DEBUG_ERROR,
-				"// gg_session_handle_recv_msg_110() "
-				"packet too small (%" GG_SIZE_FMT " < %"
-				GG_SIZE_FMT ")\n", msg->data.len,
-				sizeof(struct gg_msg_image_reply));
-		} else {
-			gg_image_queue_parse(ge, (char *)msg->data.data,
-				msg->data.len, gs, sender, type);
-		}
-		gg110_recv_message__free_unpacked(msg, NULL);
-		return gg_ack_110(gs, GG110_ACK__TYPE__MSG, seq, ge);
-	}
-
-	if (type == GG_RECV_OWN_MSG110 || type == GG_CHAT_RECV_OWN_MSG)
-		ge->type = GG_EVENT_MULTILOGON_MSG;
-	else
-		ge->type = GG_EVENT_MSG;
-	ev->msgclass = GG_CLASS_CHAT;
-	ev->seq = seq;
-	ev->sender = sender;
-	ev->flags = msg->flags;
-	ev->seq = seq;
-	ev->time = msg->time;
-
-	if (abs(msg->time - gg_server_time(gs)) > 2)
-		ev->msgclass |= GG_CLASS_QUEUED;
-
-	ev->message = NULL;
-	if (msg->msg_plain[0] != '\0') {
-		ev->message = (unsigned char*)gg_encoding_convert(
-			msg->msg_plain, GG_ENCODING_UTF8, gs->encoding, -1, -1);
-		succ = succ && (ev->message != NULL);
-	}
-	ev->xhtml_message = NULL;
-	if (msg->msg_xhtml != NULL) {
-		ev->xhtml_message = gg_encoding_convert(
-			msg->msg_xhtml, GG_ENCODING_UTF8, gs->encoding, -1, -1);
-		succ = succ && (ev->xhtml_message != NULL);
-	}
-
-	/* wiadomości wysłane z mobilnego gg nie posiadają wersji xhtml */
-	if (ev->message == NULL && ev->xhtml_message == NULL) {
-		ev->message = (unsigned char*)strdup("");
-		succ = succ && (ev->message != NULL);
-	} else if (ev->message == NULL) {
-		ev->message = (unsigned char*)gg_message_html_to_text_110(
-			ev->xhtml_message);
-		succ = succ && (ev->message != NULL);
-	} else if (ev->xhtml_message == NULL) {
-		ev->xhtml_message = gg_message_text_to_html_110(
-			(char*)ev->message, -1);
-		succ = succ && (ev->xhtml_message != NULL);
-	}
-
-	/* otrzymywane tylko od gg <= 10.5 */
-	ev->formats = NULL;
-	ev->formats_length = 0;
-	if (msg->has_data && succ) {
-		ev->formats_length = msg->data.len;
-		ev->formats = malloc(msg->data.len);
-		if (ev->formats == NULL)
-			succ = 0;
-		else
-			memcpy(ev->formats, msg->data.data, msg->data.len);
-	}
-
-	if (msg->has_chat_id && succ) {
-		gg_chat_list_t *chat;
-
-		ev->chat_id = msg->chat_id;
-
-		chat = gg_chat_find(gs, msg->chat_id);
-		if (chat) {
-			size_t rcpt_size = chat->participants_count *
-				sizeof(uin_t);
-			ev->recipients = malloc(rcpt_size);
-			ev->recipients_count = chat->participants_count;
-			if (ev->recipients == NULL)
-				succ = 0;
-			else {
-				memcpy(ev->recipients, chat->participants,
-					rcpt_size);
-			}
-		}
-	}
-
-	gg110_recv_message__free_unpacked(msg, NULL);
-
-	if (gg_ack_110(gs, ack_type, seq, ge) != 0)
-		succ = 0;
-
-	if (succ)
-		return 0;
-	else {
-		free(ev->message);
-		free(ev->xhtml_message);
-		free(ev->formats);
-		free(ev->recipients);
-		return -1;
-	}
-}
-
-/**
- * \internal Obsługuje pakiet GG_STATUS.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_status(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_status *s = (const void*) ptr;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a status change\n");
-
-	ge->type = GG_EVENT_STATUS;
-	ge->event.status.uin = gg_fix32(s->uin);
-	ge->event.status.status = gg_fix32(s->status);
-	ge->event.status.descr = NULL;
-
-	if (len > sizeof(*s)) {
-		ge->event.status.descr = gg_encoding_convert(ptr + sizeof(*s),
-			GG_ENCODING_CP1250, gs->encoding, len - sizeof(*s), -1);
-
-		if (ge->event.status.descr == NULL) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiety GG_STATUS60, GG_STATUS77 i GG_STATUS80BETA.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_status_60_77_80beta(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_status60 *s60 = (const void*) ptr;
-	const struct gg_status77 *s77 = (const void*) ptr;
-	size_t struct_len;
-	uint32_t uin;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a status change\n");
-
-	ge->type = GG_EVENT_STATUS60;
-	ge->event.status60.descr = NULL;
-	ge->event.status60.time = 0;
-
-	if (type == GG_STATUS60) {
-		uin = gg_fix32(s60->uin);
-		ge->event.status60.status = s60->status;
-		ge->event.status60.remote_ip = s60->remote_ip;
-		ge->event.status60.remote_port = gg_fix16(s60->remote_port);
-		ge->event.status60.version = s60->version;
-		ge->event.status60.image_size = s60->image_size;
-		struct_len = sizeof(*s60);
-	} else {
-		uin = gg_fix32(s77->uin);
-		ge->event.status60.status = s77->status;
-		ge->event.status60.remote_ip = s77->remote_ip;
-		ge->event.status60.remote_port = gg_fix16(s77->remote_port);
-		ge->event.status60.version = s77->version;
-		ge->event.status60.image_size = s77->image_size;
-		struct_len = sizeof(*s77);
-	}
-
-	ge->event.status60.uin = uin & 0x00ffffff;
-
-	if (uin & 0x40000000)
-		ge->event.status60.version |= GG_HAS_AUDIO_MASK;
-	if (uin & 0x20000000)
-		ge->event.status60.version |= GG_HAS_AUDIO7_MASK;
-	if (uin & 0x08000000)
-		ge->event.status60.version |= GG_ERA_OMNIX_MASK;
-
-	if (len > struct_len) {
-		size_t descr_len;
-
-		descr_len = len - struct_len;
-
-		ge->event.status60.descr = gg_encoding_convert(ptr + struct_len,
-			(type == GG_STATUS80BETA) ? GG_ENCODING_UTF8 : GG_ENCODING_CP1250,
-			gs->encoding, descr_len, -1);
-
-		if (ge->event.status60.descr == NULL) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			return -1;
-		}
-
-		if (descr_len > 4 && ptr[len - 5] == 0) {
-			uint32_t t;
-			memcpy(&t, ptr + len - 4, sizeof(uint32_t));
-			ge->event.status60.time = gg_fix32(t);
-		}
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_NOTIFY_REPLY.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_notify_reply(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_notify_reply *n = (const void*) ptr;
-	char *descr;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n");
-
-	if (gg_fix32(n->status) == GG_STATUS_BUSY_DESCR ||
-		gg_fix32(n->status) == GG_STATUS_NOT_AVAIL_DESCR ||
-		gg_fix32(n->status) == GG_STATUS_AVAIL_DESCR)
-	{
-		size_t descr_len;
-
-		ge->type = GG_EVENT_NOTIFY_DESCR;
-
-		if (!(ge->event.notify_descr.notify = (void*) malloc(sizeof(*n) * 2))) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			return -1;
-		}
-		ge->event.notify_descr.notify[1].uin = 0;
-		memcpy(ge->event.notify_descr.notify, ptr, sizeof(*n));
-		ge->event.notify_descr.notify[0].uin = gg_fix32(ge->event.notify_descr.notify[0].uin);
-		ge->event.notify_descr.notify[0].status = gg_fix32(ge->event.notify_descr.notify[0].status);
-		ge->event.notify_descr.notify[0].remote_port = gg_fix16(ge->event.notify_descr.notify[0].remote_port);
-		ge->event.notify_descr.notify[0].version = gg_fix32(ge->event.notify_descr.notify[0].version);
-
-		descr_len = len - sizeof(*n);
-
-		descr = gg_encoding_convert(ptr + sizeof(*n), GG_ENCODING_CP1250, gs->encoding, descr_len, -1);
-
-		if (descr == NULL) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			return -1;
-		}
-
-		ge->event.notify_descr.descr = descr;
-
-	} else {
-		unsigned int i, count;
-
-		ge->type = GG_EVENT_NOTIFY;
-
-		if (!(ge->event.notify = (void*) malloc(len + 2 * sizeof(*n)))) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			return -1;
-		}
-
-		memcpy(ge->event.notify, ptr, len);
-		count = len / sizeof(*n);
-		ge->event.notify[count].uin = 0;
-
-		for (i = 0; i < count; i++) {
-			ge->event.notify[i].uin = gg_fix32(ge->event.notify[i].uin);
-			ge->event.notify[i].status = gg_fix32(ge->event.notify[i].status);
-			ge->event.notify[i].remote_port = gg_fix16(ge->event.notify[i].remote_port);
-			ge->event.notify[i].version = gg_fix32(ge->event.notify[i].version);
-		}
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_STATUS80.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_status_80(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_notify_reply80 *n = (const void*) ptr;
-	size_t descr_len;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a status change\n");
-
-	ge->type = GG_EVENT_STATUS60;
-	ge->event.status60.uin = gg_fix32(n->uin);
-	ge->event.status60.status = gg_fix32(n->status);
-	ge->event.status60.remote_ip = n->remote_ip;
-	ge->event.status60.remote_port = gg_fix16(n->remote_port);
-	ge->event.status60.version = 0;
-	ge->event.status60.image_size = n->image_size;
-	ge->event.status60.descr = NULL;
-	ge->event.status60.time = 0;
-
-	descr_len = gg_fix32(n->descr_len);
-
-	if (descr_len != 0 && sizeof(struct gg_notify_reply80) + descr_len <= len) {
-		ge->event.status60.descr = gg_encoding_convert(
-			(const char*) n + sizeof(struct gg_notify_reply80),
-			GG_ENCODING_UTF8, gs->encoding, descr_len, -1);
-
-		if (ge->event.status60.descr == NULL) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			return -1;
-		}
-
-		/* XXX czas */
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_NOTIFY_REPLY80.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_notify_reply_80(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_notify_reply80 *n = (const void*) ptr;
-	unsigned int length = len, i = 0;
-
-	/* TODO: najpierw przeanalizować strukturę i określić
-	 * liczbę rekordów, żeby obyć się bez realloc()
-	 */
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n");
-
-	ge->type = GG_EVENT_NOTIFY60;
-	ge->event.notify60 = malloc(sizeof(*ge->event.notify60));
-
-	if (!ge->event.notify60) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-		return -1;
-	}
-
-	ge->event.notify60[0].uin = 0;
-
-	while (length >= sizeof(struct gg_notify_reply80)) {
-		uin_t uin = gg_fix32(n->uin);
-		int descr_len;
-		void *tmp;
-
-		ge->event.notify60[i].uin = uin;
-		ge->event.notify60[i].status = gg_fix32(n->status);
-		ge->event.notify60[i].remote_ip = n->remote_ip;
-		ge->event.notify60[i].remote_port = gg_fix16(n->remote_port);
-		ge->event.notify60[i].version = 0;
-		ge->event.notify60[i].image_size = n->image_size;
-		ge->event.notify60[i].descr = NULL;
-		ge->event.notify60[i].time = 0;
-
-		descr_len = gg_fix32(n->descr_len);
-
-		if (descr_len != 0) {
-			if (sizeof(struct gg_notify_reply80) + descr_len <= length) {
-				ge->event.notify60[i].descr = gg_encoding_convert(
-					(const char*) n + sizeof(struct gg_notify_reply80),
-					GG_ENCODING_UTF8, gs->encoding, descr_len, -1);
-
-				if (ge->event.notify60[i].descr == NULL) {
-					gg_debug_session(gs, GG_DEBUG_MISC,
-						"// gg_watch_fd_connected() "
-						"out of memory\n");
-					return -1;
-				}
-
-				/* XXX czas */
-
-				length -= sizeof(struct gg_notify_reply80) + descr_len;
-				n = (const void*) ((const char*) n + sizeof(struct gg_notify_reply80) + descr_len);
-			} else {
-				length = 0;
-			}
-
-		} else {
-			length -= sizeof(struct gg_notify_reply80);
-			n = (const void*) ((const char*) n + sizeof(struct gg_notify_reply80));
-		}
-
-		if (!(tmp = realloc(ge->event.notify60, (i + 2) * sizeof(*ge->event.notify60)))) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			free(ge->event.notify60);
-			return -1;
-		}
-
-		ge->event.notify60 = tmp;
-		ge->event.notify60[++i].uin = 0;
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiety GG_NOTIFY_REPLY77 i GG_NOTIFY_REPLY80BETA.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_notify_reply_77_80beta(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_notify_reply77 *n = (const void*) ptr;
-	unsigned int length = len, i = 0;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n");
-
-	ge->type = GG_EVENT_NOTIFY60;
-	ge->event.notify60 = malloc(sizeof(*ge->event.notify60));
-
-	if (ge->event.notify60 == NULL) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-		return -1;
-	}
-
-	ge->event.notify60[0].uin = 0;
-
-	while (length >= sizeof(struct gg_notify_reply77)) {
-		uin_t uin = gg_fix32(n->uin);
-		void *tmp;
-
-		ge->event.notify60[i].uin = uin & 0x00ffffff;
-		ge->event.notify60[i].status = n->status;
-		ge->event.notify60[i].remote_ip = n->remote_ip;
-		ge->event.notify60[i].remote_port = gg_fix16(n->remote_port);
-		ge->event.notify60[i].version = n->version;
-		ge->event.notify60[i].image_size = n->image_size;
-		ge->event.notify60[i].descr = NULL;
-		ge->event.notify60[i].time = 0;
-
-		if (uin & 0x40000000)
-			ge->event.notify60[i].version |= GG_HAS_AUDIO_MASK;
-		if (uin & 0x20000000)
-			ge->event.notify60[i].version |= GG_HAS_AUDIO7_MASK;
-		if (uin & 0x08000000)
-			ge->event.notify60[i].version |= GG_ERA_OMNIX_MASK;
-
-		if (GG_S_D(n->status)) {
-			unsigned char descr_len = *((const char*) n + sizeof(struct gg_notify_reply77));
-
-			if (sizeof(struct gg_notify_reply77) + descr_len <= length) {
-				ge->event.notify60[i].descr = gg_encoding_convert(
-					(const char*) n + sizeof(struct gg_notify_reply77) + 1,
-					(type == GG_NOTIFY_REPLY80BETA) ? GG_ENCODING_UTF8 : GG_ENCODING_CP1250,
-					gs->encoding, descr_len, -1);
-
-				if (ge->event.notify60[i].descr == NULL) {
-					gg_debug_session(gs, GG_DEBUG_MISC,
-						"// gg_watch_fd_connected() "
-						"out of memory\n");
-					return -1;
-				}
-
-				/* XXX czas */
-
-				length -= sizeof(struct gg_notify_reply77) + descr_len + 1;
-				n = (const void*) ((const char*) n + sizeof(struct gg_notify_reply77) + descr_len + 1);
-			} else {
-				length = 0;
-			}
-
-		} else {
-			length -= sizeof(struct gg_notify_reply77);
-			n = (const void*) ((const char*) n + sizeof(struct gg_notify_reply77));
-		}
-
-		if (!(tmp = realloc(ge->event.notify60, (i + 2) * sizeof(*ge->event.notify60)))) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			free(ge->event.notify60);
-			return -1;
-		}
-
-		ge->event.notify60 = tmp;
-		ge->event.notify60[++i].uin = 0;
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_NOTIFY_REPLY60.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_notify_reply_60(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_notify_reply60 *n = (const void*) ptr;
-	unsigned int length = len, i = 0;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n");
-
-	ge->type = GG_EVENT_NOTIFY60;
-	ge->event.notify60 = malloc(sizeof(*ge->event.notify60));
-
-	if (ge->event.notify60 == NULL) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-		return -1;
-	}
-
-	ge->event.notify60[0].uin = 0;
-
-	while (length >= sizeof(struct gg_notify_reply60)) {
-		uin_t uin = gg_fix32(n->uin);
-		void *tmp;
-
-		ge->event.notify60[i].uin = uin & 0x00ffffff;
-		ge->event.notify60[i].status = n->status;
-		ge->event.notify60[i].remote_ip = n->remote_ip;
-		ge->event.notify60[i].remote_port = gg_fix16(n->remote_port);
-		ge->event.notify60[i].version = n->version;
-		ge->event.notify60[i].image_size = n->image_size;
-		ge->event.notify60[i].descr = NULL;
-		ge->event.notify60[i].time = 0;
-
-		if (uin & 0x40000000)
-			ge->event.notify60[i].version |= GG_HAS_AUDIO_MASK;
-		if (uin & 0x08000000)
-			ge->event.notify60[i].version |= GG_ERA_OMNIX_MASK;
-
-		if (GG_S_D(n->status)) {
-			unsigned char descr_len = *((const char*) n + sizeof(struct gg_notify_reply60));
-
-			if (sizeof(struct gg_notify_reply60) + descr_len <= length) {
-				char *descr;
-
-				descr = gg_encoding_convert((const char*) n +
-					sizeof(struct gg_notify_reply60) + 1,
-					GG_ENCODING_CP1250, gs->encoding,
-					descr_len, -1);
-
-				if (descr == NULL) {
-					gg_debug_session(gs, GG_DEBUG_MISC,
-						"// gg_watch_fd_connected() "
-						"out of memory\n");
-					return -1;
-				}
-
-				ge->event.notify60[i].descr = descr;
-
-				/* XXX czas */
-
-				length -= sizeof(struct gg_notify_reply60) + descr_len + 1;
-				n = (const void*) ((const char*) n + sizeof(struct gg_notify_reply60) + descr_len + 1);
-			} else {
-				length = 0;
-			}
-
-		} else {
-			length -= sizeof(struct gg_notify_reply60);
-			n = (const void*) ((const char*) n + sizeof(struct gg_notify_reply60));
-		}
-
-		if (!(tmp = realloc(ge->event.notify60, (i + 2) * sizeof(*ge->event.notify60)))) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() out of memory\n");
-			free(ge->event.notify60);
-			return -1;
-		}
-
-		ge->event.notify60 = tmp;
-		ge->event.notify60[++i].uin = 0;
-	}
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_USER_DATA.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_user_data(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	struct gg_user_data d;
-	const char *p = (const char*) ptr;
-	const char *packet_end = (const char*) ptr + len;
-	struct gg_event_user_data_user *users;
-	unsigned int i, j;
-	int res = 0;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received user data\n");
-
-	ge->event.user_data.user_count = 0;
-	ge->event.user_data.users = NULL;
-
-	if (ptr + sizeof(d) > packet_end)
-		goto malformed;
-
-	memcpy(&d, p, sizeof(d));
-	p += sizeof(d);
-
-	d.type = gg_fix32(d.type);
-	d.user_count = gg_fix32(d.user_count);
-
-	if (d.user_count > 0xffff) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_session_handle_user_data() malformed packet (1)\n");
-		goto malformed;
-	}
-
-	if (d.user_count > 0) {
-		users = calloc(d.user_count, sizeof(struct gg_event_user_data_user));
-
-		if (users == NULL) {
-			gg_debug_session(gs, GG_DEBUG_MISC,
-				"// gg_session_handle_user_data() out of memory"
-				" (%d*%" GG_SIZE_FMT ")\n", d.user_count,
-				sizeof(struct gg_event_user_data_user));
-			goto fail;
-		}
-	} else {
-		users = NULL;
-	}
-
-	ge->type = GG_EVENT_USER_DATA;
-	ge->event.user_data.type = d.type;
-	ge->event.user_data.user_count = d.user_count;
-	ge->event.user_data.users = users;
-
-	gg_debug_session(gs, GG_DEBUG_DUMP, "type=%d, count=%d\n", d.type, d.user_count);
-
-	for (i = 0; i < d.user_count; i++) {
-		struct gg_user_data_user u;
-		struct gg_event_user_data_attr *attrs;
-
-		if (p + sizeof(u) > packet_end) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_session_handle_user_data() malformed packet (2)\n");
-			goto malformed;
-		}
-
-		memcpy(&u, p, sizeof(u));
-		p += sizeof(u);
-
-		u.uin = gg_fix32(u.uin);
-		u.attr_count = gg_fix32(u.attr_count);
-
-		if (u.attr_count > 0xffff) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_session_handle_user_data() malformed packet (2)\n");
-			goto malformed;
-		}
-
-		if (u.attr_count > 0) {
-			attrs = calloc(u.attr_count, sizeof(struct gg_event_user_data_attr));
-
-			if (attrs == NULL) {
-				gg_debug_session(gs, GG_DEBUG_MISC,
-					"// gg_session_handle_user_data() "
-					"out of memory (%d*%" GG_SIZE_FMT
-					")\n", u.attr_count,
-					sizeof(struct gg_event_user_data_attr));
-				goto fail;
-			}
-		} else {
-			attrs = NULL;
-		}
-
-		users[i].uin = u.uin;
-		users[i].attr_count = u.attr_count;
-		users[i].attrs = attrs;
-
-		gg_debug_session(gs, GG_DEBUG_DUMP, "    uin=%d, count=%d\n", u.uin, u.attr_count);
-
-		for (j = 0; j < u.attr_count; j++) {
-			uint32_t key_size;
-			uint32_t attr_type;
-			uint32_t value_size;
-			char *key;
-			char *value;
-
-			if (p + sizeof(key_size) > packet_end) {
-				gg_debug_session(gs, GG_DEBUG_MISC,
-					"// gg_session_handle_user_data()"
-					"malformed packet (3)\n");
-				goto malformed;
-			}
-
-			memcpy(&key_size, p, sizeof(key_size));
-			p += sizeof(key_size);
-
-			key_size = gg_fix32(key_size);
-
-			if (key_size > 0xffff || p + key_size > packet_end) {
-				gg_debug_session(gs, GG_DEBUG_MISC,
-					"// gg_session_handle_user_data() "
-					"malformed packet (3)\n");
-				goto malformed;
-			}
-
-			key = malloc(key_size + 1);
-
-			if (key == NULL) {
-				gg_debug_session(gs, GG_DEBUG_MISC,
-					"// gg_session_handle_user_data() "
-					"out of memory (%d)\n", key_size + 1);
-				goto fail;
-			}
-
-			memcpy(key, p, key_size);
-			p += key_size;
-
-			key[key_size] = 0;
-
-			attrs[j].key = key;
-
-			if (p + sizeof(attr_type) + sizeof(value_size) > packet_end) {
-				gg_debug_session(gs, GG_DEBUG_MISC,
-					"// gg_session_handle_user_data() "
-					"malformed packet (4)\n");
-				goto malformed;
-			}
-
-			memcpy(&attr_type, p, sizeof(attr_type));
-			p += sizeof(attr_type);
-			memcpy(&value_size, p, sizeof(value_size));
-			p += sizeof(value_size);
-
-			attrs[j].type = gg_fix32(attr_type);
-			value_size = gg_fix32(value_size);
-
-			if (value_size > 0xffff || p + value_size > packet_end) {
-				gg_debug_session(gs, GG_DEBUG_MISC,
-					"// gg_session_handle_user_data() "
-					"malformed packet (5)\n");
-				goto malformed;
-			}
-
-			value = malloc(value_size + 1);
-
-			if (value == NULL) {
-				gg_debug_session(gs, GG_DEBUG_MISC,
-					"// gg_session_handle_user_data() "
-					"out of memory (%d)\n", value_size + 1);
-				goto fail;
-			}
-
-			memcpy(value, p, value_size);
-			p += value_size;
-
-			value[value_size] = 0;
-
-			attrs[j].value = value;
-
-			gg_debug_session(gs, GG_DEBUG_DUMP, "	key=\"%s\", "
-				"type=%d, value=\"%s\"\n", key, attr_type, value);
-		}
-	}
-
-	return 0;
-
-fail:
-	res = -1;
-
-malformed:
-	ge->type = GG_EVENT_NONE;
-
-	for (i = 0; i < ge->event.user_data.user_count; i++) {
-		for (j = 0; j < ge->event.user_data.users[i].attr_count; j++) {
-			free(ge->event.user_data.users[i].attrs[j].key);
-			free(ge->event.user_data.users[i].attrs[j].value);
-		}
-
-		free(ge->event.user_data.users[i].attrs);
-	}
-
-	free(ge->event.user_data.users);
-
-	return res;
-}
-
-/**
- * \internal Obsługuje pakiet GG_TYPING_NOTIFICATION.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_typing_notification(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_typing_notification *n = (const void*) ptr;
-	uin_t uin;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received typing notification\n");
-
-	memcpy(&uin, &n->uin, sizeof(uin_t));
-
-	ge->type = GG_EVENT_TYPING_NOTIFICATION;
-	ge->event.typing_notification.uin = gg_fix32(uin);
-	ge->event.typing_notification.length = gg_fix16(n->length);
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_MULTILOGON_INFO.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_multilogon_info(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const char *packet_end = (const char*) ptr + len;
-	const struct gg_multilogon_info *info = (const struct gg_multilogon_info*) ptr;
-	const char *p = (const char*) ptr + sizeof(*info);
-	struct gg_multilogon_session *sessions = NULL;
-	size_t count;
-	size_t i;
-	int res = 0;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received multilogon info\n");
-
-	count = gg_fix32(info->count);
-
-	if (count > 0xffff) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// gg_handle_multilogon_info() malformed packet (1)\n");
-		goto malformed;
-	}
-
-	sessions = calloc(count, sizeof(struct gg_multilogon_session));
-
-	if (sessions == NULL) {
-		gg_debug_session(gs, GG_DEBUG_MISC, "// "
-			"gg_handle_multilogon_info() out of memory (%"
-			GG_SIZE_FMT "*%" GG_SIZE_FMT ")\n",
-			count, sizeof(struct gg_multilogon_session));
-		return -1;
-	}
-
-	ge->type = GG_EVENT_MULTILOGON_INFO;
-	ge->event.multilogon_info.count = count;
-	ge->event.multilogon_info.sessions = sessions;
-
-	for (i = 0; i < count; i++) {
-		struct gg_multilogon_info_item item;
-		size_t name_size;
-
-		if (p + sizeof(item) > packet_end) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_handle_multilogon_info() malformed packet (2)\n");
-			goto malformed;
-		}
-
-		memcpy(&item, p, sizeof(item));
-
-		sessions[i].id = item.conn_id;
-		sessions[i].remote_addr = item.addr;
-		sessions[i].status_flags = gg_fix32(item.flags);
-		sessions[i].protocol_features = gg_fix32(item.features);
-		sessions[i].logon_time = gg_fix32(item.logon_time);
-
-		p += sizeof(item);
-
-		name_size = gg_fix32(item.name_size);
-
-		if (name_size > 0xffff || p + name_size > packet_end) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_handle_multilogon_info() malformed packet (3)\n");
-			goto malformed;
-		}
-
-		sessions[i].name = malloc(name_size + 1);
-
-		if (sessions[i].name == NULL) {
-			gg_debug_session(gs, GG_DEBUG_MISC,
-				"// gg_handle_multilogon_info() out of "
-				"memory (%" GG_SIZE_FMT ")\n", name_size);
-			goto fail;
-		}
-
-		memcpy(sessions[i].name, p, name_size);
-		sessions[i].name[name_size] = 0;
-
-		p += name_size;
-	}
-
-	return 0;
-
-fail:
-	res = -1;
-
-malformed:
-	ge->type = GG_EVENT_NONE;
-
-	for (i = 0; (int) i < ge->event.multilogon_info.count; i++)
-		free(ge->event.multilogon_info.sessions[i].name);
-
-	free(ge->event.multilogon_info.sessions);
-
-	return res;
-}
-
-/**
- * \internal Obsługuje pakiet GG_USERLIST100_VERSION.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_userlist_100_version(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_userlist100_version *version = (const struct gg_userlist100_version*) ptr;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received userlist 100 version\n");
-
-	ge->type = GG_EVENT_USERLIST100_VERSION;
-	ge->event.userlist100_version.version = gg_fix32(version->version);
-
-	return 0;
-}
-
-/**
- * \internal Obsługuje pakiet GG_USERLIST100_REPLY.
- *
- * Patrz gg_packet_handler_t
- */
-static int gg_session_handle_userlist_100_reply(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_userlist100_reply *reply = (const struct gg_userlist100_reply*) ptr;
-	char *data = NULL;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received userlist 100 reply\n");
-
-	if (len > sizeof(*reply)) {
-		data = gg_inflate((const unsigned char*) ptr + sizeof(*reply), len - sizeof(*reply));
-
-		if (data == NULL) {
-			gg_debug_session(gs, GG_DEBUG_MISC, "// gg_handle_userlist_100_reply() gg_inflate() failed\n");
-			return -1;
-		}
-	}
-
-	ge->type = GG_EVENT_USERLIST100_REPLY;
-	ge->event.userlist100_reply.type = reply->type;
-	ge->event.userlist100_reply.version = gg_fix32(reply->version);
-	ge->event.userlist100_reply.format_type = reply->format_type;
-	ge->event.userlist100_reply.reply = data;
-
-	return 0;
-}
-
-static int gg_session_handle_imtoken(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110Imtoken *msg = gg110_imtoken__unpack(NULL, len, (uint8_t*)ptr);
-	char *imtoken = NULL;
-	int succ = 1;
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110Imtoken", msg))
-		return -1;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() "
-		"received imtoken\n");
-
-	if (msg->imtoken[0] != '\0') {
-		imtoken = strdup(msg->imtoken);
-		succ = succ && (imtoken != NULL);
-	}
-
-	gg110_imtoken__free_unpacked(msg, NULL);
-
-	ge->type = GG_EVENT_IMTOKEN;
-	ge->event.imtoken.imtoken = imtoken;
-
-	return succ ? 0 : -1;
-}
-
-static int gg_session_handle_pong_110(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110Pong *msg = gg110_pong__unpack(NULL, len, (uint8_t*)ptr);
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110Pong", msg))
-		return -1;
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() "
-		"received pong110\n");
-
-	ge->type = GG_EVENT_PONG110;
-	ge->event.pong110.time = msg->server_time;
-
-	gg_sync_time(gs, msg->server_time);
-
-	gg110_pong__free_unpacked(msg, NULL);
-
-	return 0;
-}
-
-static int gg_session_handle_chat_info(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_tvbuff_t *tvb;
-	uint32_t i;
-
-	uint64_t id;
-	uint32_t version;
-	uint32_t dummy1;
-	uint32_t participants_count;
-	uin_t *participants = NULL;
-
-	tvb = gg_tvbuff_new(ptr, len);
-
-	id = gg_tvbuff_read_uint64(tvb);
-	gg_tvbuff_expected_uint32(tvb, 0); /* unknown */
-	version = gg_tvbuff_read_uint32(tvb);
-	dummy1 = gg_tvbuff_read_uint32(tvb);
-	if (gg_tvbuff_is_valid(tvb) && dummy1 == 1) {
-		uint32_t name_length;
-
-		name_length = gg_tvbuff_read_uint32(tvb);
-		gg_tvbuff_skip(tvb, name_length);
-
-		gg_tvbuff_expected_uint32(tvb, 0); /* unknown */
-		gg_tvbuff_expected_uint32(tvb, 2); /* unknown */
-	}
-	participants_count = gg_tvbuff_read_uint32(tvb);
-	if (id == 0 && participants_count > 0) {
-		gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_WARNING,
-			"// gg_session_handle_chat_info() terminating packet "
-			"shouldn't contain participants\n");
-		participants_count = 0;
-	}
-
-	if (participants_count > 0) {
-		participants = malloc(sizeof(uin_t) * participants_count);
-		if (participants == NULL) {
-			gg_tvbuff_close(tvb);
-			return -1;
-		}
-	}
-
-	for (i = 0; i < participants_count && gg_tvbuff_is_valid(tvb); i++) {
-		participants[i] = gg_tvbuff_read_uint32(tvb);
-		gg_tvbuff_read_uint32(tvb); /* 0x1e lub 0x18 */
-	}
-
-	if (!gg_tvbuff_close(tvb)) {
-		free(participants);
-		return -1;
-	}
-
-	if (id == 0) {
-		ge->type = GG_EVENT_CHAT_INFO_GOT_ALL;
-		return 0;
-	}
-
-	if (0 != gg_chat_update(gs, id, version, participants,
-		participants_count))
-	{
-		free(participants);
-		return -1;
-	}
-
-	ge->type = GG_EVENT_CHAT_INFO;
-	ge->event.chat_info.id = id;
-	ge->event.chat_info.version = version;
-	ge->event.chat_info.participants_count = participants_count;
-	ge->event.chat_info.participants = participants;
-
-	return 0;
-}
-
-static int gg_session_handle_chat_info_update(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110ChatInfoUpdate *msg = gg110_chat_info_update__unpack(NULL, len, (uint8_t*)ptr);
-	gg_chat_list_t *chat;
-	uin_t participant;
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110ChatInfoUpdate", msg))
-		return -1;
-
-	gg_debug_session(gs, GG_DEBUG_VERBOSE,
-		"// gg_session_handle_chat_info_update() "
-		"msg_id=%016" PRIx64 " conv_id=%016" PRIx64 "\n",
-		msg->msg_id, msg->conv_id);
-
-	ge->type = GG_EVENT_CHAT_INFO_UPDATE;
-	ge->event.chat_info_update.id = msg->chat_id;
-	ge->event.chat_info_update.type = msg->update_type;
-	ge->event.chat_info_update.participant = participant = gg_protobuf_get_uin(msg->participant);
-	ge->event.chat_info_update.inviter = gg_protobuf_get_uin(msg->inviter);
-	ge->event.chat_info_update.version = msg->version;
-	ge->event.chat_info_update.time = msg->time;
-
-	chat = gg_chat_find(gs, msg->chat_id);
-	if (!chat) {
-		gg110_chat_info_update__free_unpacked(msg, NULL);
-		return 0;
-	}
-
-	chat->version = msg->version;
-	if (msg->update_type == GG_CHAT_INFO_UPDATE_ENTERED) {
-		uin_t *old_part = chat->participants;
-		chat->participants = realloc(chat->participants,
-			sizeof(uin_t) * chat->participants_count);
-		if (chat->participants == NULL) {
-			chat->participants = old_part;
-			gg_debug_session(gs, GG_DEBUG_ERROR,
-				"// gg_session_handle_chat_info_update() "
-				"out of memory (count=%u)\n",
-				chat->participants_count);
-			return -1;
-		}
-		chat->participants_count++;
-		chat->participants[chat->participants_count - 1] = participant;
-	} else if (msg->update_type == GG_CHAT_INFO_UPDATE_EXITED) {
-		uint32_t idx;
-		for (idx = 0; idx < chat->participants_count; idx++)
-			if (chat->participants[idx] == participant)
-				break;
-		if (chat->participants_count > 1 &&
-			idx < chat->participants_count)
-			chat->participants[idx] = chat->participants[chat->participants_count - 1];
-		if (idx < chat->participants_count) {
-			chat->participants_count--;
-			if (chat->participants_count == 0) {
-				free(chat->participants);
-				chat->participants = NULL;
-			} else {
-				chat->participants = realloc(chat->participants,
-					sizeof(uin_t)*chat->participants_count);
-			}
-		}
-	}
-
-	gg110_chat_info_update__free_unpacked(msg, NULL);
-	return 0;
-}
-
-static int gg_session_handle_chat_created(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_chat_created *p = (const struct gg_chat_created *)ptr;
-
-	if (0 != gg_chat_update(gs, gg_fix64(p->id), 0, &gs->uin, 1))
-		return -1;
-
-	ge->type = GG_EVENT_CHAT_CREATED;
-	ge->event.chat_created.id = gg_fix64(p->id);
-	ge->event.chat_created.seq = gg_fix32(p->seq);
-	return 0;
-}
-
-static int gg_session_handle_chat_invite_ack(struct gg_session *gs,
-	uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_chat_invite_ack *p =
-		(const struct gg_chat_invite_ack *)ptr;
-
-	ge->type = GG_EVENT_CHAT_INVITE_ACK;
-	ge->event.chat_invite_ack.id = gg_fix64(p->id);
-	ge->event.chat_invite_ack.seq = gg_fix32(p->seq);
-
-	return 0;
-}
-
-static int gg_session_handle_chat_left(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	const struct gg_chat_left *p = (const struct gg_chat_left *)ptr;
-
-	ge->type = GG_EVENT_CHAT_INFO_UPDATE;
-	ge->event.chat_info_update.id = gg_fix64(p->id);
-	ge->event.chat_info_update.type = GG_CHAT_INFO_UPDATE_EXITED;
-	/* Właściwie, to nie wiadomo, czy to jest "osoba wychodząca", czy
-	 * "osoba wyrzucająca nas" z konferencji. */
-	ge->event.chat_info_update.participant = gg_fix32(p->uin);
-	ge->event.chat_info_update.inviter = gg_fix32(p->uin);
-	ge->event.chat_info_update.version = 0;
-	ge->event.chat_info_update.time = time(NULL);
-
-	return 0;
-}
-
-static int gg_session_handle_options(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110Options *msg = gg110_options__unpack(NULL, len, (uint8_t*)ptr);
-	size_t i;
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110Options", msg))
-		return -1;
-
-	gg_protobuf_expected(gs, "GG110Options.dummy1", msg->dummy1, 0);
-
-	for (i = 0; i < msg->n_options; i++) {
-		ProtobufKVP *kvp = msg->options[i];
-		if (!GG_PROTOBUF_VALID(gs, "ProtobufKVP", kvp))
-			continue;
-		gg_debug_session(gs, GG_DEBUG_MISC,
-			"// gg_session_handle_options[%s] = \"%s\"\n",
-			kvp->key, kvp->value);
-	}
-
-	gg110_options__free_unpacked(msg, NULL);
-
-	return 0;
-}
-
-static int gg_session_handle_access_info(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110AccessInfo *msg = gg110_access_info__unpack(NULL, len, (uint8_t*)ptr);
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110AccessInfo", msg))
-		return -1;
-
-	gg_debug_session(gs, GG_DEBUG_MISC,
-		"// gg_session_handle_access_info: dummy[%02x, %02x], "
-		"last[message=%u, file_transfer=%u, conference_ch=%u]\n",
-		msg->dummy1, msg->dummy2, msg->last_message,
-		msg->last_file_transfer, msg->last_conference_ch);
-
-	gg110_access_info__free_unpacked(msg, NULL);
-
-	return 0;
-}
-
-/* ten pakiet jest odbierany tylko, jeżeli przy logowaniu użyliśmy identyfikatora typu 0x01 */
-static int gg_session_handle_uin_info(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	gg_tvbuff_t *tvb;
-	char *uin1 = NULL, *uin2 = NULL;
-
-	tvb = gg_tvbuff_new(ptr, len);
-
-	gg_tvbuff_expected_uint32(tvb, 1); /* unknown */
-	gg_tvbuff_expected_uint32(tvb, 2); /* unknown */
-
-	/* podstawowy identyfikator (numer GG) */
-	gg_tvbuff_expected_uint8(tvb, 0);
-	gg_tvbuff_read_str_dup(tvb, &uin1);
-
-	/* identyfikator użyty przy logowaniu (numer GG lub email) */
-	gg_tvbuff_expected_uint8(tvb, 1);
-	gg_tvbuff_read_str_dup(tvb, &uin2);
-
-	if (!gg_tvbuff_close(tvb)) {
-		free(uin1);
-		free(uin2);
-		return -1;
-	}
-
-	gg_debug_session(gs, GG_DEBUG_MISC, "// gg_session_handle_uin_info: "
-		"uin1=\"%s\", uin2=\"%s\"\n", uin1, uin2);
-
-	free(uin1);
-	free(uin2);
-
-	return 0;
-}
-
-static int gg_session_handle_transfer_info(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG112TransferInfo *msg = gg112_transfer_info__unpack(NULL, len, (uint8_t*)ptr);
-	int succ = 1;
-	size_t i;
-	uin_t peer = 0, sender = 0;
-
-	if (!GG_PROTOBUF_VALID(gs, "GG112TransferInfo", msg))
-		return -1;
-
-	/* see packets.proto */
-	if (msg->dummy1 != 5 && msg->dummy1 != 6) {
-		gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_WARNING,
-			"// gg_session_handle_transfer_info: "
-			"unknown dummy1 value: %d\n", msg->dummy1);
-	}
-
-	if (GG_PROTOBUF_VALID(gs, "GG112TransferInfoUin", msg->peer)) {
-		gg_protobuf_expected(gs, "GG112TransferInfoUin.dummy1",
-			msg->peer->dummy1, 1);
-		peer = gg_protobuf_get_uin(msg->peer->uin);
-	}
-	if (GG_PROTOBUF_VALID(gs, "GG112TransferInfoUin", msg->sender)) {
-		gg_protobuf_expected(gs, "GG112TransferInfoUin.dummy1",
-			msg->sender->dummy1, 1);
-		sender = gg_protobuf_get_uin(msg->sender->uin);
-	}
-
-	gg_debug_session(gs, GG_DEBUG_MISC,
-		"// gg_session_handle_transfer_info: dummy1=%#x, time=%u, "
-			"sender=%u, peer=%u, msg_id=%#016" PRIx64 ", "
-			"conv_id=%#016" PRIx64 "\n",
-		msg->dummy1, msg->time, sender, peer, msg->msg_id,
-		msg->conv_id);
-
-	for (i = 0; i < msg->n_data; i++) {
-		ProtobufKVP *kvp = msg->data[i];
-		if (!GG_PROTOBUF_VALID(gs, "ProtobufKVP", kvp))
-			continue;
-		gg_debug_session(gs, GG_DEBUG_MISC,
-			"// gg_session_handle_transfer_info[%s] = \"%s\"\n",
-			kvp->key, kvp->value);
-	}
-
-	if (msg->file && GG_PROTOBUF_VALID(gs, "GG112TransferInfoFile", msg->file)) {
-		GG112TransferInfoFile *file = msg->file;
-		gg_debug_session(gs, GG_DEBUG_MISC,
-			"// gg_session_handle_transfer_info file: "
-			"type=\"%s\", content_type=\"%s\", filename=\"%s\", "
-			"filesize=%u, msg_id=%#016" PRIx64 " url=\"%s\"\n",
-			file->type, file->content_type, file->filename,
-			file->filesize, file->msg_id, file->url);
-	}
-
-	succ = (gg_ack_110(gs, GG110_ACK__TYPE__TRANSFER_INFO,
-		msg->seq, ge) == 0);
-
-	gg112_transfer_info__free_unpacked(msg, NULL);
-
-	return succ ? 0 : -1;
-}
-
-static int gg_session_handle_magic_notification(struct gg_session *gs, uint32_t type,
-	const char *ptr, size_t len, struct gg_event *ge)
-{
-	GG110MagicNotification *msg = gg110_magic_notification__unpack(NULL, len, (uint8_t*)ptr);
-	int succ = 1;
-
-	if (!GG_PROTOBUF_VALID(gs, "GG110MagicNotification", msg))
-		return -1;
-
-	gg_debug_session(gs, GG_DEBUG_MISC,
-		"// gg_session_handle_magic_notification \n");
-
-	gg_protobuf_expected(gs, "GG110MagicNotification.dummy1", msg->dummy1, 2);
-	gg_protobuf_expected(gs, "GG110MagicNotification.dummy2", msg->dummy2, 1);
-	gg_protobuf_expected(gs, "GG110MagicNotification.dummy3", msg->dummy3, 1);
-
-	succ = (gg_ack_110(gs, GG110_ACK__TYPE__MAGIC_NOTIFICATION, msg->seq, ge) == 0);
-
-	gg110_magic_notification__free_unpacked(msg, NULL);
-
-	return succ ? 0 : -1;
-}
-
-/**
- * \internal Tablica obsługiwanych pakietów
- */
-static const gg_packet_handler_t handlers[] =
-{
-	/* style:maxlinelength:start-ignore */
-	{ GG_WELCOME, GG_STATE_READING_KEY, 0, gg_session_handle_welcome },
-	{ GG_LOGIN_OK, GG_STATE_READING_REPLY, 0, gg_session_handle_login_ok },
-	{ GG_LOGIN80_OK, GG_STATE_READING_REPLY, 0, gg_session_handle_login_ok },
-	{ GG_LOGIN110_OK, GG_STATE_READING_REPLY, 0, gg_session_handle_login110_ok },
-	{ GG_NEED_EMAIL, GG_STATE_READING_REPLY, 0, gg_session_handle_login_ok },
-	{ GG_LOGIN_FAILED, GG_STATE_READING_REPLY, 0, gg_session_handle_login_failed },
-	{ GG_LOGIN80_FAILED, GG_STATE_READING_REPLY, 0, gg_session_handle_login_failed },
-	{ GG_SEND_MSG_ACK, GG_STATE_CONNECTED, sizeof(struct gg_send_msg_ack), gg_session_handle_send_msg_ack },
-	{ GG_SEND_MSG_ACK110, GG_STATE_CONNECTED, 0, gg_session_handle_send_msg_ack_110 },
-	{ GG_PONG, GG_STATE_CONNECTED, 0, gg_session_handle_pong },
-	{ GG_DISCONNECTING, GG_STATE_CONNECTED, 0, gg_session_handle_disconnecting },
-	{ GG_DISCONNECT_ACK, GG_STATE_DISCONNECTING, 0, gg_session_handle_disconnect_ack },
-	{ GG_XML_EVENT, GG_STATE_CONNECTED, 0, gg_session_handle_xml_event },
-	{ GG_EVENT110, GG_STATE_CONNECTED, 0, gg_session_handle_event_110 },
-	{ GG_PUBDIR50_REPLY, GG_STATE_CONNECTED, 0, gg_session_handle_pubdir50_reply },
-	{ GG_USERLIST_REPLY, GG_STATE_CONNECTED, sizeof(char), gg_session_handle_userlist_reply },
-	{ GG_DCC7_ID_REPLY, GG_STATE_CONNECTED, sizeof(struct gg_dcc7_id_reply), gg_session_handle_dcc7_id_reply },
-	{ GG_DCC7_ACCEPT, GG_STATE_CONNECTED, sizeof(struct gg_dcc7_accept), gg_session_handle_dcc7_accept },
-	{ GG_DCC7_NEW, GG_STATE_CONNECTED, sizeof(struct gg_dcc7_new), gg_session_handle_dcc7_new },
-	{ GG_DCC7_REJECT, GG_STATE_CONNECTED, sizeof(struct gg_dcc7_reject), gg_session_handle_dcc7_reject },
-	{ GG_DCC7_INFO, GG_STATE_CONNECTED, sizeof(struct gg_dcc7_info), gg_session_handle_dcc7_info },
-	{ GG_RECV_MSG, GG_STATE_CONNECTED, sizeof(struct gg_recv_msg), gg_session_handle_recv_msg },
-	{ GG_RECV_MSG80, GG_STATE_CONNECTED, sizeof(struct gg_recv_msg80), gg_session_handle_recv_msg_80 },
-	{ GG_RECV_MSG110, GG_STATE_CONNECTED, 0, gg_session_handle_recv_msg_110 },
-	{ GG_RECV_OWN_MSG110, GG_STATE_CONNECTED, 0, gg_session_handle_recv_msg_110 },
-	{ GG_STATUS, GG_STATE_CONNECTED, sizeof(struct gg_status), gg_session_handle_status },
-	{ GG_STATUS60, GG_STATE_CONNECTED, sizeof(struct gg_status60), gg_session_handle_status_60_77_80beta },
-	{ GG_STATUS77, GG_STATE_CONNECTED, sizeof(struct gg_status77), gg_session_handle_status_60_77_80beta },
-	{ GG_STATUS80BETA, GG_STATE_CONNECTED, sizeof(struct gg_status77), gg_session_handle_status_60_77_80beta },
-	{ GG_STATUS80, GG_STATE_CONNECTED, sizeof(struct gg_notify_reply80), gg_session_handle_status_80 },
-	{ GG_NOTIFY_REPLY, GG_STATE_CONNECTED, sizeof(struct gg_notify_reply), gg_session_handle_notify_reply },
-	{ GG_NOTIFY_REPLY60, GG_STATE_CONNECTED, sizeof(struct gg_notify_reply60), gg_session_handle_notify_reply_60 },
-	{ GG_NOTIFY_REPLY77, GG_STATE_CONNECTED, sizeof(struct gg_notify_reply77), gg_session_handle_notify_reply_77_80beta },
-	{ GG_NOTIFY_REPLY80BETA, GG_STATE_CONNECTED, sizeof(struct gg_notify_reply77), gg_session_handle_notify_reply_77_80beta },
-	{ GG_NOTIFY_REPLY80, GG_STATE_CONNECTED, sizeof(struct gg_notify_reply80), gg_session_handle_notify_reply_80 },
-	{ GG_USER_DATA, GG_STATE_CONNECTED, sizeof(struct gg_user_data), gg_session_handle_user_data },
-	{ GG_TYPING_NOTIFICATION, GG_STATE_CONNECTED, sizeof(struct gg_typing_notification), gg_session_handle_typing_notification },
-	{ GG_MULTILOGON_INFO, GG_STATE_CONNECTED, sizeof(struct gg_multilogon_info), gg_session_handle_multilogon_info },
-	{ GG_XML_ACTION, GG_STATE_CONNECTED, 0, gg_session_handle_xml_event },
-	{ GG_RECV_OWN_MSG, GG_STATE_CONNECTED, sizeof(struct gg_recv_msg80), gg_session_handle_recv_msg_80 },
-	{ GG_USERLIST100_VERSION, GG_STATE_CONNECTED, sizeof(struct gg_userlist100_version), gg_session_handle_userlist_100_version },
-	{ GG_USERLIST100_REPLY, GG_STATE_CONNECTED, sizeof(struct gg_userlist100_reply), gg_session_handle_userlist_100_reply },
-	{ GG_IMTOKEN, GG_STATE_CONNECTED, 0, gg_session_handle_imtoken },
-	{ GG_PONG110, GG_STATE_CONNECTED, 0, gg_session_handle_pong_110 },
-	{ GG_CHAT_INFO, GG_STATE_CONNECTED, 0, gg_session_handle_chat_info },
-	{ GG_CHAT_INFO_UPDATE, GG_STATE_CONNECTED, 0, gg_session_handle_chat_info_update },
-	{ GG_CHAT_CREATED, GG_STATE_CONNECTED, sizeof(struct gg_chat_created), gg_session_handle_chat_created },
-	{ GG_CHAT_INVITE_ACK, GG_STATE_CONNECTED, sizeof(struct gg_chat_invite_ack), gg_session_handle_chat_invite_ack },
-	{ GG_CHAT_RECV_MSG, GG_STATE_CONNECTED, 0, gg_session_handle_recv_msg_110 },
-	{ GG_CHAT_RECV_OWN_MSG, GG_STATE_CONNECTED, 0, gg_session_handle_recv_msg_110 },
-	{ GG_CHAT_LEFT, GG_STATE_CONNECTED, sizeof(struct gg_chat_left), gg_session_handle_chat_left },
-	{ GG_OPTIONS, GG_STATE_CONNECTED, 0, gg_session_handle_options },
-	{ GG_ACCESS_INFO, GG_STATE_CONNECTED, 0, gg_session_handle_access_info },
-	{ GG_UIN_INFO, GG_STATE_CONNECTED, 0, gg_session_handle_uin_info },
-	{ GG_TRANSFER_INFO, GG_STATE_CONNECTED, 0, gg_session_handle_transfer_info },
-	{ GG_MAGIC_NOTIFICATION, GG_STATE_CONNECTED, 0, gg_session_handle_magic_notification }
-	/* style:maxlinelength:end-ignore */
-};
-
-/**
- * \internal Obsługuje przychodzący pakiet danych.
- *
- * \param gs Struktura sesji
- * \param type Typ pakietu
- * \param ptr Wskaźnik do bufora pakietu
- * \param len Długość bufora pakietu
- * \param[out] ge Struktura zdarzenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_session_handle_packet(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
-{
-	unsigned int i;
-
-	gg_debug_session(gs, GG_DEBUG_FUNCTION,
-		"// gg_session_handle_packet(%d, %p, %" GG_SIZE_FMT ")\n",
-		type, ptr, len);
-
-	gs->last_event = time(NULL);
-
-#if 0
-	if ((gs->flags & (1 << GG_SESSION_FLAG_RAW_PACKET)) != 0) {
-		char *tmp;
-
-		tmp = malloc(len);
-
-		if (tmp == NULL) {
-			gg_debug_session(gs, GG_DEBUG_ERROR,
-				"// gg_session_handle_packet() out of memory "
-				"(%d bytes)\n", len);
-			return -1;
-		}
-
-		memcpy(tmp, ptr, len);
-
-		ge->type = GG_EVENT_RAW_PACKET;
-		ge->event.raw_packet.type = type;
-		ge->event.raw_packet.length = len;
-		ge->event.raw_packet.data = tmp;
-
-		return 0;
-	}
-#endif
-
-	for (i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++) {
-		if (handlers[i].type != 0 && handlers[i].type != type)
-			continue;
-
-		if (handlers[i].state != 0 && handlers[i].state != (enum gg_state_t) gs->state) {
-			gg_debug_session(gs, GG_DEBUG_WARNING,
-				"// gg_session_handle_packet() packet 0x%02x "
-				"unexpected in state %d\n", type, gs->state);
-			continue;
-		}
-
-		if (len < handlers[i].min_length) {
-			gg_debug_session(gs, GG_DEBUG_ERROR,
-				"// gg_session_handle_packet() packet 0x%02x "
-				"too short (%" GG_SIZE_FMT " bytes)\n",
-				type, len);
-			continue;
-		}
-
-		return (*handlers[i].handler)(gs, type, ptr, len, ge);
-	}
-
-	gg_debug_session(gs, GG_DEBUG_WARNING, "// gg_session_handle_packet() "
-		"unhandled packet 0x%02x, len %" GG_SIZE_FMT ", state %d\n",
-		type, len, gs->state);
-
-	return 0;
-}
--- a/libpurple/protocols/gg/lib/http.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,592 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file http.c
- *
- * \brief Obsługa połączeń HTTP
- */
-
-#include "strman.h"
-#include "network.h"
-#include "libgadu.h"
-#include "resolver.h"
-#include "internal.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define GG_HTTP_MAX_LENGTH 1000000000
-
-/**
- * Rozpoczyna połączenie HTTP.
- *
- * Funkcja przeprowadza połączenie HTTP przy połączeniu synchronicznym,
- * zwracając wynik w polach struktury \c gg_http, lub błąd, gdy sesja się
- * nie powiedzie.
- *
- * Przy połączeniu asynchronicznym, funkcja rozpoczyna połączenie, a dalsze
- * etapy będą przeprowadzane po wykryciu zmian (\c watch) na obserwowanym
- * deskryptorze (\c fd) i wywołaniu funkcji \c gg_http_watch_fd().
- *
- * Po zakończeniu, należy zwolnić strukturę za pomocą funkcji
- * \c gg_http_free(). Połączenie asynchroniczne można zatrzymać w każdej
- * chwili za pomocą \c gg_http_stop().
- *
- * \param hostname Adres serwera
- * \param port Port serwera
- * \param async Flaga asynchronicznego połączenia
- * \param method Metoda HTTP
- * \param path Ścieżka do zasobu (musi być poprzedzona znakiem '/')
- * \param header Nagłówek zapytania plus ewentualne dane dla POST
- *
- * \return Zaalokowana struktura \c gg_http lub NULL, jeśli wystąpił błąd.
- *
- * \ingroup http
- */
-struct gg_http *gg_http_connect(const char *hostname, int port, int async,
-	const char *method, const char *path, const char *header)
-{
-	struct gg_http *h;
-
-	if (!hostname || !port || !method || !path || !header) {
-		gg_debug(GG_DEBUG_MISC, "// gg_http_connect() invalid arguments\n");
-		errno = EFAULT;
-		return NULL;
-	}
-
-	if (!(h = malloc(sizeof(*h))))
-		return NULL;
-	memset(h, 0, sizeof(*h));
-
-	h->async = async;
-	h->port = port;
-	h->fd = -1;
-	h->type = GG_SESSION_HTTP;
-
-	gg_http_set_resolver(h, GG_RESOLVER_DEFAULT);
-
-	if (gg_proxy_enabled) {
-		char *auth = gg_proxy_auth();
-
-		h->query = gg_saprintf("%s http://%s:%d%s HTTP/1.0\r\n%s%s",
-				method, hostname, port, path, (auth) ? auth :
-				"", header);
-		hostname = gg_proxy_host;
-		h->port = port = gg_proxy_port;
-		free(auth);
-
-	} else {
-		h->query = gg_saprintf("%s %s HTTP/1.0\r\n%s",
-				method, path, header);
-	}
-
-	if (h->query == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_http_connect() not enough memory for query\n");
-		free(h);
-		errno = ENOMEM;
-		return NULL;
-	}
-
-	gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", h->query);
-
-	if (async) {
-		if (h->resolver_start(&h->fd, &h->resolver, hostname) == -1) {
-			gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver failed\n");
-			gg_http_free(h);
-			errno = ENOENT;
-			return NULL;
-		}
-
-		gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver = %p\n", h->resolver);
-
-		h->state = GG_STATE_RESOLVING;
-		h->check = GG_CHECK_READ;
-		h->timeout = GG_DEFAULT_TIMEOUT;
-	} else {
-		struct in_addr *addr_list = NULL;
-		unsigned int addr_count;
-
-		if (gg_gethostbyname_real(hostname, &addr_list, &addr_count, 0) == -1 || addr_count == 0) {
-			gg_debug(GG_DEBUG_MISC, "// gg_http_connect() host not found\n");
-			gg_http_free(h);
-			free(addr_list);
-			errno = ENOENT;
-			return NULL;
-		}
-
-		h->fd = gg_connect(&addr_list[0], port, 0);
-
-		if (h->fd == -1) {
-			gg_debug(GG_DEBUG_MISC, "// gg_http_connect() "
-				"connection failed (errno=%d, %s)\n",
-				errno, strerror(errno));
-			gg_http_free(h);
-			free(addr_list);
-			return NULL;
-		}
-
-		free(addr_list);
-
-		h->state = GG_STATE_CONNECTING;
-
-		while (h->state != GG_STATE_ERROR && h->state != GG_STATE_PARSING) {
-			if (gg_http_watch_fd(h) == -1)
-				break;
-		}
-
-		if (h->state != GG_STATE_PARSING) {
-			gg_debug(GG_DEBUG_MISC, "// gg_http_connect() some strange error\n");
-			gg_http_free(h);
-			return NULL;
-		}
-	}
-
-	h->callback = gg_http_watch_fd;
-	h->destroy = gg_http_free;
-
-	return h;
-}
-
-#ifndef DOXYGEN
-
-#define gg_http_error(x) \
-	if (h->fd > -1) \
-		close(h->fd); \
-	h->fd = -1; \
-	h->state = GG_STATE_ERROR; \
-	h->error = x; \
-	return 0;
-
-#endif /* DOXYGEN */
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Operacja będzie zakończona, gdy pole \c state będzie równe
- * \c GG_STATE_PARSING. W tym miejscu działanie przejmuje zwykle funkcja
- * korzystająca z \c gg_http_watch_fd(). W przypadku błędu połączenia,
- * pole \c state będzie równe \c GG_STATE_ERROR, a kod błędu znajdzie się
- * w polu \c error.
- *
- * \param h Struktura połączenia
- *
- * \return \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup http
- */
-int gg_http_watch_fd(struct gg_http *h)
-{
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_http_watch_fd(%p);\n", h);
-
-	if (h == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_http_watch_fd() invalid arguments\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (h->state == GG_STATE_RESOLVING) {
-		struct in_addr addr;
-		int res;
-
-		gg_debug(GG_DEBUG_MISC, "=> http, resolving done\n");
-
-		do {
-			res = gg_resolver_recv(h->fd, &addr, sizeof(addr));
-		} while (res == -1 && errno == EINTR);
-
-		h->resolver_cleanup(&h->resolver, 0);
-
-		if (res != sizeof(addr) || addr.s_addr == INADDR_NONE) {
-			gg_debug(GG_DEBUG_MISC, "=> http, resolver thread failed\n");
-			gg_http_error(GG_ERROR_RESOLVING);
-		}
-
-		close(h->fd);
-		h->fd = -1;
-
-		gg_debug(GG_DEBUG_MISC, "=> http, connecting to %s:%d\n", inet_ntoa(addr), h->port);
-
-		h->fd = gg_connect(&addr, h->port, h->async);
-
-		if (h->fd == -1) {
-			gg_debug(GG_DEBUG_MISC, "=> http, connection failed (errno=%d, %s)\n", errno, strerror(errno));
-			gg_http_error(GG_ERROR_CONNECTING);
-		}
-
-		h->state = GG_STATE_CONNECTING;
-		h->check = GG_CHECK_WRITE;
-		h->timeout = GG_DEFAULT_TIMEOUT;
-
-		return 0;
-	}
-
-	if (h->state == GG_STATE_CONNECTING) {
-		int res = 0;
-		socklen_t res_size = sizeof(res);
-
-		if (h->async && (getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) {
-			gg_debug(GG_DEBUG_MISC, "=> http, async connection "
-				"failed (errno=%d, %s)\n", (res) ? res : errno,
-				strerror((res) ? res : errno));
-			close(h->fd);
-			h->fd = -1;
-			h->state = GG_STATE_ERROR;
-			h->error = GG_ERROR_CONNECTING;
-			if (res)
-				errno = res;
-			return 0;
-		}
-
-		gg_debug(GG_DEBUG_MISC, "=> http, connected, sending request\n");
-
-		h->state = GG_STATE_SENDING_QUERY;
-	}
-
-	if (h->state == GG_STATE_SENDING_QUERY) {
-		int res;
-
-		res = send(h->fd, h->query, strlen(h->query), 0);
-
-		if (res == -1 && errno != EINTR && errno != EAGAIN) {
-			gg_debug(GG_DEBUG_MISC, "=> http, send() failed "
-				"(len=%" GG_SIZE_FMT ", res=%d, errno=%d)\n",
-				strlen(h->query), res, errno);
-			gg_http_error(GG_ERROR_WRITING);
-		}
-
-		if (res == -1) {
-			gg_debug(GG_DEBUG_MISC, "=> http, non-critical send "
-				"error (errno=%d, %s)\n",
-				errno, strerror(errno));
-			return 0;
-		}
-
-		if ((size_t) res < strlen(h->query)) {
-			gg_debug(GG_DEBUG_MISC, "=> http, partial header sent "
-				"(led=%" GG_SIZE_FMT ", sent=%d)\n",
-				strlen(h->query), res);
-
-			memmove(h->query, h->query + res, strlen(h->query) - res + 1);
-			h->state = GG_STATE_SENDING_QUERY;
-			h->check = GG_CHECK_WRITE;
-			h->timeout = GG_DEFAULT_TIMEOUT;
-		} else {
-			gg_debug(GG_DEBUG_MISC, "=> http, request sent (len=%"
-				GG_SIZE_FMT ")\n", strlen(h->query));
-			free(h->query);
-			h->query = NULL;
-
-			h->state = GG_STATE_READING_HEADER;
-			h->check = GG_CHECK_READ;
-			h->timeout = GG_DEFAULT_TIMEOUT;
-		}
-
-		return 0;
-	}
-
-	if (h->state == GG_STATE_READING_HEADER) {
-		char buf[1024], *tmp;
-		int res;
-
-		res = recv(h->fd, buf, sizeof(buf), 0);
-
-		if (res == -1 && errno != EINTR && errno != EAGAIN) {
-			gg_debug(GG_DEBUG_MISC, "=> http, reading header failed (errno=%d)\n", errno);
-			free(h->header);
-			h->header = NULL;
-			gg_http_error(GG_ERROR_READING);
-		}
-
-		if (res == -1) {
-			gg_debug(GG_DEBUG_MISC, "=> http, non-critical recv "
-				"error (errno=%d, %s)\n",
-				errno, strerror(errno));
-			return 0;
-		}
-
-		if (res == 0) {
-			gg_debug(GG_DEBUG_MISC, "=> http, connection reset by peer\n");
-			free(h->header);
-			h->header = NULL;
-			gg_http_error(GG_ERROR_READING);
-		}
-
-		gg_debug(GG_DEBUG_MISC, "=> http, read %d bytes of header\n", res);
-
-		tmp = realloc(h->header, h->header_size + res + 1);
-
-		if (tmp == NULL) {
-			gg_debug(GG_DEBUG_MISC, "=> http, not enough memory for header\n");
-			free(h->header);
-			h->header = NULL;
-			gg_http_error(GG_ERROR_READING);
-		}
-
-		h->header = tmp;
-
-		memcpy(h->header + h->header_size, buf, res);
-		h->header_size += res;
-
-		gg_debug(GG_DEBUG_MISC, "=> http, header_buf=%p, header_size=%d\n", h->header, h->header_size);
-
-		h->header[h->header_size] = 0;
-
-		if ((tmp = strstr(h->header, "\r\n\r\n")) || (tmp = strstr(h->header, "\n\n"))) {
-			int sep_len = (*tmp == '\r') ? 4 : 2;
-			unsigned int left;
-			char *line;
-
-			left = h->header_size - ((size_t)(tmp) - (size_t)(h->header) + sep_len);
-
-			gg_debug(GG_DEBUG_MISC, "=> http, got all header "
-				"(%d bytes, %d left)\n",
-				h->header_size - left, left);
-
-			/* HTTP/1.1 200 OK */
-			if (strlen(h->header) < 16 || strncmp(h->header + 9, "200", 3)) {
-				gg_debug(GG_DEBUG_MISC,
-					"=> -----BEGIN-HTTP-HEADER-----\n%s\n"
-					"=> -----END-HTTP-HEADER-----\n",
-					h->header);
-
-				gg_debug(GG_DEBUG_MISC, "=> http, didn't get 200 OK -- no results\n");
-				free(h->header);
-				h->header = NULL;
-				gg_http_error(GG_ERROR_CONNECTING);
-			}
-
-			h->body_size = 0;
-			line = h->header;
-			*tmp = 0;
-
-			gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----"
-				"\n%s\n=> -----END-HTTP-HEADER-----\n",
-				h->header);
-
-			while (line) {
-				if (!strncasecmp(line, "Content-length: ", 16)) {
-					h->body_size = atoi(line + 16);
-				}
-				line = strchr(line, '\n');
-				if (line)
-					line++;
-			}
-
-			if (h->body_size <= 0) {
-				gg_debug(GG_DEBUG_MISC, "=> http, content-length not found\n");
-				h->body_size = left;
-			}
-
-			if (h->body_size > GG_HTTP_MAX_LENGTH) {
-				gg_debug(GG_DEBUG_MISC, "=> http, content-length too big\n");
-				h->body_size = GG_HTTP_MAX_LENGTH;
-			}
-
-			if (left > h->body_size) {
-				gg_debug(GG_DEBUG_MISC, "=> http, oversized "
-					"reply (%d bytes needed, "
-					"%d bytes left)\n", h->body_size, left);
-				h->body_size = left;
-			}
-
-			gg_debug(GG_DEBUG_MISC, "=> http, body_size=%d\n", h->body_size);
-
-			if (!(h->body = malloc(h->body_size + 1))) {
-				gg_debug(GG_DEBUG_MISC, "=> http, not enough "
-					"memory (%d bytes for body_buf)\n",
-					h->body_size + 1);
-				free(h->header);
-				h->header = NULL;
-				gg_http_error(GG_ERROR_READING);
-			}
-
-			if (left) {
-				memcpy(h->body, tmp + sep_len, left);
-				h->body_done = left;
-			}
-
-			h->body[left] = 0;
-
-			h->state = GG_STATE_READING_DATA;
-			h->check = GG_CHECK_READ;
-			h->timeout = GG_DEFAULT_TIMEOUT;
-		}
-
-		return 0;
-	}
-
-	if (h->state == GG_STATE_READING_DATA) {
-		char buf[1024];
-		int res;
-
-		res = recv(h->fd, buf, sizeof(buf), 0);
-
-		if (res == -1 && errno != EINTR && errno != EAGAIN) {
-			gg_debug(GG_DEBUG_MISC, "=> http, reading body failed (errno=%d)\n", errno);
-			free(h->body);
-			h->body = NULL;
-			gg_http_error(GG_ERROR_READING);
-		}
-
-		if (res == -1) {
-			gg_debug(GG_DEBUG_MISC, "=> http, non-critical "
-				"recv error (errno=%d, %s)\n",
-				errno, strerror(errno));
-			return 0;
-		}
-
-		if (res == 0) {
-			if (h->body_done >= h->body_size) {
-				gg_debug(GG_DEBUG_MISC, "=> http, we're done, closing socket\n");
-				h->state = GG_STATE_PARSING;
-				close(h->fd);
-				h->fd = -1;
-			} else {
-				gg_debug(GG_DEBUG_MISC, "=> http, "
-					"connection closed while reading "
-					"(have %d, need %d)\n",
-					h->body_done, h->body_size);
-				free(h->body);
-				h->body = NULL;
-				gg_http_error(GG_ERROR_READING);
-			}
-
-			return 0;
-		}
-
-		gg_debug(GG_DEBUG_MISC, "=> http, read %d bytes of body\n", res);
-
-		if (h->body_done + res > h->body_size) {
-			char *tmp;
-
-			gg_debug(GG_DEBUG_MISC, "=> http, too much data "
-				"(%d bytes, %d needed), enlarging buffer\n",
-				h->body_done + res, h->body_size);
-
-			if (!(tmp = realloc(h->body, h->body_done + res + 1))) {
-				gg_debug(GG_DEBUG_MISC, "=> http, not enough "
-					"memory for data (%d needed)\n",
-					h->body_done + res + 1);
-				free(h->body);
-				h->body = NULL;
-				gg_http_error(GG_ERROR_READING);
-			}
-
-			h->body = tmp;
-			h->body_size = h->body_done + res;
-		}
-
-		h->body[h->body_done + res] = 0;
-		memcpy(h->body + h->body_done, buf, res);
-		h->body_done += res;
-
-		gg_debug(GG_DEBUG_MISC, "=> body_done=%d, body_size=%d\n", h->body_done, h->body_size);
-
-		return 0;
-	}
-
-	if (h->fd != -1)
-		close(h->fd);
-
-	h->fd = -1;
-	h->state = GG_STATE_ERROR;
-	h->error = 0;
-
-	return -1;
-}
-
-/**
- * Kończy asynchroniczne połączenie HTTP.
- *
- * Po zatrzymaniu należy zwolnić zasoby funkcją \c gg_http_free().
- *
- * \param h Struktura połączenia
- *
- * \ingroup http
- */
-void gg_http_stop(struct gg_http *h)
-{
-	if (!h)
-		return;
-
-	if (h->state == GG_STATE_ERROR || h->state == GG_STATE_DONE)
-		return;
-
-	h->resolver_cleanup(&h->resolver, 1);
-
-	if (h->fd != -1) {
-		close(h->fd);
-		h->fd = -1;
-	}
-}
-
-/**
- * \internal Zwalnia pola struktury \c gg_http.
- *
- * Funkcja zwalnia same pola, nie zwalnia struktury.
- *
- * \param h Struktura połączenia
- */
-void gg_http_free_fields(struct gg_http *h)
-{
-	if (h == NULL)
-		return;
-
-	free(h->body);
-	h->body = NULL;
-
-	free(h->query);
-	h->query = NULL;
-
-	free(h->header);
-	h->header = NULL;
-}
-
-/**
- * Zwalnia zasoby po połączeniu HTTP.
- *
- * Jeśli połączenie nie zostało jeszcze zakończone, jest przerywane.
- *
- * \param h Struktura połączenia
- *
- * \ingroup http
- */
-void gg_http_free(struct gg_http *h)
-{
-	if (h == NULL)
-		return;
-
-	gg_http_stop(h);
-	gg_http_free_fields(h);
-	free(h);
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
--- a/libpurple/protocols/gg/lib/internal.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,266 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2009 Jakub Zawadzki <darkjames@darkjames.ath.cx>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_INTERNAL_H
-#define LIBGADU_INTERNAL_H
-
-#include "libgadu.h"
-
-#define GG_DEFAULT_CLIENT_VERSION_100 "10.1.0.11070"
-#define GG_DEFAULT_CLIENT_VERSION_110 "11.3.45.10771"
-
-#ifdef _WIN32
-#  ifdef __COVERITY__
-#    define GG_SIZE_FMT "lu"
-#    define _GG_INT64_MODIFIER "ll"
-#    undef PRIu64
-#    undef PRIx64
-#    undef PRId64
-#  else
-#    define GG_SIZE_FMT "Iu"
-#    define _GG_INT64_MODIFIER "I64"
-#  endif
-#elif defined(_LP64)
-#  define GG_SIZE_FMT "zu"
-#  define _GG_INT64_MODIFIER "l"
-#else
-#  define GG_SIZE_FMT "zu"
-#  define _GG_INT64_MODIFIER "ll"
-#endif
-
-#ifndef PRIu64
-#  define PRIu64 _GG_INT64_MODIFIER "u"
-#endif
-#ifndef PRIx64
-#  define PRIx64 _GG_INT64_MODIFIER "x"
-#endif
-#ifndef PRId64
-#  define PRId64 _GG_INT64_MODIFIER "d"
-#endif
-
-#define GG_LOGIN_PARAMS_HAS_FIELD(glp, member) \
-	(offsetof(struct gg_login_params, member) < (glp)->struct_size || \
-	offsetof(struct gg_login_params, member) <= offsetof(struct gg_login_params, struct_size))
-
-#ifdef __GNUC__
-#  define GG_UNUSED __attribute__ ((unused))
-#  define GG_NORETURN __attribute__ ((noreturn))
-#  define GG_CDECL __attribute__ ((__cdecl__))
-#else
-#  define GG_UNUSED
-#  define GG_NORETURN
-#  define GG_CDECL
-#endif
-
-#define GG_STATIC_ASSERT(condition, message) \
-	{ typedef char static_assertion_failed_ ## message \
-	[(condition) ? 1 : -1]; static_assertion_failed_ ## message dummy; \
-	(void)dummy; }
-
-#define GG_IMGOUT_WAITING_MAX 4
-
-struct gg_dcc7_relay {
-	uint32_t addr;
-	uint16_t port;
-	uint8_t family;
-};
-
-typedef struct _gg_chat_list gg_chat_list_t;
-struct _gg_chat_list {
-	uint64_t id;
-	uint32_t version;
-	uint32_t participants_count;
-	uin_t *participants;
-
-	gg_chat_list_t *next;
-};
-
-typedef struct _gg_msg_list gg_msg_list_t;
-struct _gg_msg_list {
-	int seq;
-	uin_t *recipients;
-	size_t recipients_count;
-
-	gg_msg_list_t *next;
-};
-
-typedef struct _gg_eventqueue gg_eventqueue_t;
-struct _gg_eventqueue {
-	struct gg_event *event;
-
-	gg_eventqueue_t *next;
-};
-
-typedef struct _gg_imgout_queue_t gg_imgout_queue_t;
-struct _gg_imgout_queue_t {
-	struct gg_send_msg msg_hdr;
-	char buf[1910];
-	size_t buf_len;
-
-	gg_imgout_queue_t *next;
-};
-
-struct gg_session_private {
-	gg_compat_t compatibility;
-
-	gg_chat_list_t *chat_list;
-	gg_msg_list_t *sent_messages;
-
-	gg_eventqueue_t *event_queue;
-	int check_after_queue;
-	int fd_after_queue;
-
-	gg_imgout_queue_t *imgout_queue;
-	int imgout_waiting_ack;
-
-	gg_socket_manager_type_t socket_manager_type;
-	gg_socket_manager_t socket_manager;
-	void *socket_handle;
-	int socket_next_state;
-	int socket_is_external;
-	enum gg_failure_t socket_failure;
-
-	int time_diff;
-
-	int dummyfds_created;
-	int dummyfds[2];
-
-	char **host_white_list;
-};
-
-typedef enum
-{
-	GG_COMPAT_FEATURE_ACK_EVENT,
-	GG_COMPAT_FEATURE_LEGACY_CONFER
-} gg_compat_feature_t;
-
-typedef struct gg_dcc7_relay gg_dcc7_relay_t;
-
-void * gg_new0(size_t size);
-int gg_required_proto(struct gg_session *gs, int protocol_version);
-int gg_get_dummy_fd(struct gg_session *sess);
-
-int gg_compat_feature_is_enabled(struct gg_session *sess, gg_compat_feature_t feature);
-
-int gg_pubdir50_handle_reply_sess(struct gg_session *sess, struct gg_event *e, const char *packet, int length);
-
-int gg_resolve(int *fd, int *pid, const char *hostname);
-int gg_resolve_pthread(int *fd, void **resolver, const char *hostname);
-void gg_resolve_pthread_cleanup(void *resolver, int kill);
-
-int gg_login_hash_sha1_2(const char *password, uint32_t seed, uint8_t *result);
-
-int gg_chat_update(struct gg_session *sess, uint64_t id, uint32_t version,
-	const uin_t *participants, unsigned int participants_count);
-gg_chat_list_t *gg_chat_find(struct gg_session *sess, uint64_t id);
-
-uin_t gg_str_to_uin(const char *str, int len);
-
-uint64_t gg_fix64(uint64_t x);
-void gg_connection_failure(struct gg_session *gs, struct gg_event *ge,
-	enum gg_failure_t failure);
-
-time_t gg_server_time(struct gg_session *gs);
-
-int gg_session_init_ssl(struct gg_session *gs);
-void gg_close(struct gg_session *gs);
-
-struct gg_event *gg_eventqueue_add(struct gg_session *sess);
-
-void gg_compat_message_ack(struct gg_session *sess, int seq);
-
-void gg_image_sendout(struct gg_session *sess);
-
-void gg_strarr_free(char **strarr);
-char ** gg_strarr_dup(char **strarr);
-
-#ifdef _WIN32
-
-#include <windows.h>
-
-typedef struct {
-	void (*fnc)();
-#ifdef _WIN64
-	uint8_t trap[12];
-	uint8_t original[12];
-#else
-	uint8_t trap[7];
-	uint8_t original[7];
-#endif
-} gg_win32_hook_data_t;
-
-#define gg_win32_hook(orig_func, hook_func, data) \
-	gg_win32_hook_f((void (*)())(orig_func), (void (*)())(hook_func), (data))
-
-static inline void
-gg_win32_hook_f(void (*orig_func)(), void (*hook_func)(), gg_win32_hook_data_t *data)
-{
-	DWORD dPermission;
-	uint8_t trap[] = {
-#ifdef _WIN64
-		0x48, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, /* mov rax, uint64_t */
-		0xff, 0xe0 /* jmp rax */
-#else
-		0xB8, 0, 0, 0, 0, /* mov eax, uint32_t */
-		0xff, 0xe0 /* jmp eax */
-#endif
-	};
-
-#ifdef _WIN64
-	uint64_t addr = (uint64_t)hook_func;
-	memcpy(&trap[2], &addr, sizeof(addr));
-#else
-	uint32_t addr = (uint32_t)hook_func;
-	memcpy(&trap[1], &addr, sizeof(addr));
-#endif
-
-	VirtualProtect(orig_func, sizeof(trap),
-		PAGE_EXECUTE_READWRITE, &dPermission);
-	if (data != NULL) {
-		data->fnc = orig_func;
-		memcpy(data->trap, trap, sizeof(trap));
-		memcpy(data->original, orig_func, sizeof(trap));
-	}
-	memcpy(orig_func, trap, sizeof(trap));
-	VirtualProtect(orig_func, sizeof(trap),
-		dPermission, &dPermission);
-}
-
-static inline void
-gg_win32_hook_set_enabled(gg_win32_hook_data_t *data, int enabled)
-{
-	DWORD dPermission;
-	uint8_t *src;
-
-	if (enabled)
-		src = data->trap;
-	else
-		src = data->original;
-
-	VirtualProtect(data->fnc, sizeof(data->trap),
-		PAGE_EXECUTE_READWRITE, &dPermission);
-	memcpy(data->fnc, src, sizeof(data->trap));
-	VirtualProtect(data->fnc, sizeof(data->trap),
-		dPermission, &dPermission);
-}
-
-#endif /* _WIN32 */
-
-#endif /* LIBGADU_INTERNAL_H */
--- a/libpurple/protocols/gg/lib/libgadu.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3082 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2010 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *                          Arkadiusz Miśkiewicz <arekm@pld-linux.org>
- *                          Tomasz Chiliński <chilek@chilan.com>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file libgadu.c
- *
- * \brief Główny moduł biblioteki
- */
-
-#include "strman.h"
-#include "network.h"
-#include "fileio.h"
-
-#include "libgadu.h"
-#include "protocol.h"
-#include "resolver.h"
-#include "internal.h"
-#include "encoding.h"
-#include "debug.h"
-#include "session.h"
-#include "message.h"
-#include "deflate.h"
-#include "tvbuilder.h"
-#include "protobuf.h"
-#include "packets.pb-c.h"
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#ifdef GG_CONFIG_HAVE_GNUTLS
-#  include <gnutls/gnutls.h>
-#endif
-#ifdef GG_CONFIG_HAVE_OPENSSL
-#  include <openssl/err.h>
-#  include <openssl/rand.h>
-#endif
-
-/**
- * Port gniazda nasłuchującego dla połączeń bezpośrednich.
- *
- * \ingroup ip
- */
-int gg_dcc_port = 0;
-
-/**
- * Adres IP gniazda nasłuchującego dla połączeń bezpośrednich.
- *
- * \ingroup ip
- */
-unsigned long gg_dcc_ip = 0;
-
-/**
- * Adres lokalnego interfejsu IP, z którego wywoływane są wszystkie połączenia.
- *
- * \ingroup ip
- */
-unsigned long gg_local_ip = 0;
-
-/**
- * Flaga włączenia połączeń przez serwer pośredniczący.
- *
- * \ingroup proxy
- */
-int gg_proxy_enabled = 0;
-
-/**
- * Adres serwera pośredniczącego.
- *
- * \ingroup proxy
- */
-char *gg_proxy_host = NULL;
-
-/**
- * Port serwera pośredniczącego.
- *
- * \ingroup proxy
- */
-int gg_proxy_port = 0;
-
-/**
- * Flaga używania serwera pośredniczącego jedynie dla usług HTTP.
- *
- * \ingroup proxy
- */
-int gg_proxy_http_only = 0;
-
-/**
- * Nazwa użytkownika do autoryzacji serwera pośredniczącego.
- *
- * \ingroup proxy
- */
-char *gg_proxy_username = NULL;
-
-/**
- * Hasło użytkownika do autoryzacji serwera pośredniczącego.
- *
- * \ingroup proxy
- */
-char *gg_proxy_password = NULL;
-
-#ifndef DOXYGEN
-
-#ifndef lint
-static char rcsid[] GG_UNUSED = "$Id$";
-#endif
-
-#endif /* DOXYGEN */
-
-static void gg_compat_message_sent(struct gg_session *sess, int seq, size_t recipients_count, uin_t *recipients);
-static void gg_compat_message_cleanup(struct gg_session *sess);
-
-#ifdef GG_CONFIG_IS_GPL_COMPLIANT
-/**
- * Symbol zdefiniowany tylko dla libgadu zgodnego z licencją GPL.
- *
- * Zwracana wartość nie jest istotna, a ponadto może się zmienić w przyszłych
- * wersjach biblioteki. Istotne jest tylko wywołanie tej funkcji w kodzie, który
- * ma być zgodny z GPL, aby wymusić jej istnienie.
- *
- * \return Wartość 1.
- *
- * \ingroup version
- */
-int gg_is_gpl_compliant(void)
-{
-	return 1;
-}
-#endif
-
-/**
- * Zwraca wersję biblioteki.
- *
- * \return Wskaźnik na statyczny bufor z wersją biblioteki.
- *
- * \ingroup version
- */
-const char *gg_libgadu_version(void)
-{
-	return GG_LIBGADU_VERSION;
-}
-
-void * gg_new0(size_t size)
-{
-	void *ptr;
-
-	ptr = malloc(size);
-	if (ptr == NULL) {
-		gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"//gg_new0(%" GG_SIZE_FMT
-			") not enough memory\n", size);
-		return NULL;
-	}
-
-	memset(ptr, 0, size);
-	return ptr;
-}
-
-int
-gg_required_proto(struct gg_session *gs, int protocol_version)
-{
-	if (gs->protocol_version >= protocol_version)
-		return 1;
-
-	gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_ERROR, "// requested "
-		"feature requires protocol %#02x, but %#02x is selected\n",
-		protocol_version, gs->protocol_version);
-	return 0;
-}
-
-int gg_get_dummy_fd(struct gg_session *sess)
-{
-	struct gg_session_private *p = sess->private_data;
-
-	if (p->dummyfds_created)
-		return p->dummyfds[0];
-
-	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, p->dummyfds) == -1) {
-		gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_get_dummy_fd() "
-			"unable to create pipes (errno=%d, %s)\n",
-			errno, strerror(errno));
-		return -1;
-	}
-
-	p->dummyfds_created = 1;
-	return p->dummyfds[0];
-}
-
-/**
- * \internal Liczy skrót z hasła i ziarna.
- *
- * \param password Hasło
- * \param seed Ziarno podane przez serwer
- *
- * \return Wartość skrótu
- */
-unsigned int gg_login_hash(const unsigned char *password, unsigned int seed)
-{
-	unsigned int x, y, z;
-
-	y = seed;
-
-	for (x = 0; *password; password++) {
-		x = (x & 0xffffff00) | *password;
-		y ^= x;
-		y += x;
-		x <<= 8;
-		y ^= x;
-		x <<= 8;
-		y -= x;
-		x <<= 8;
-		y ^= x;
-
-		z = y & 0x1F;
-		y = (y << z) | (y >> (32 - z));
-	}
-
-	return y;
-}
-
-/**
- * \internal Odbiera od serwera dane binarne.
- *
- * Funkcja odbiera dane od serwera zajmując się SSL/TLS w razie konieczności.
- * Obsługuje EINTR, więc użytkownik nie musi się przejmować przerwanymi
- * wywołaniami systemowymi.
- *
- * \param sess Struktura sesji
- * \param buf Bufor na danymi
- * \param length Długość bufora
- *
- * \return To samo co funkcja systemowa \c read
- */
-int gg_read(struct gg_session *sess, char *buf, int length)
-{
-	struct gg_session_private *p = sess->private_data;
-	int res;
-
-#ifdef GG_CONFIG_HAVE_GNUTLS
-	if (sess->ssl != NULL) {
-		for (;;) {
-			res = gnutls_record_recv(GG_SESSION_GNUTLS(sess), buf, length);
-
-			if (res < 0) {
-				if (res == GNUTLS_E_AGAIN)
-					errno = EAGAIN;
-				else if (!gnutls_error_is_fatal(res) || res == GNUTLS_E_INTERRUPTED)
-					continue;
-				else
-					errno = EINVAL;
-
-				return -1;
-			}
-
-			return res;
-		}
-	}
-#endif
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-	if (sess->ssl != NULL) {
-		for (;;) {
-			int err;
-
-			res = SSL_read(sess->ssl, buf, length);
-
-			if (res < 0) {
-				err = SSL_get_error(sess->ssl, res);
-
-				if (err == SSL_ERROR_SYSCALL && errno == EINTR)
-					continue;
-
-				if (err == SSL_ERROR_WANT_READ)
-					errno = EAGAIN;
-				else if (err != SSL_ERROR_SYSCALL)
-					errno = EINVAL;
-
-				return -1;
-			}
-
-			return res;
-		}
-	}
-#endif
-
-	if (p->socket_handle != NULL) {
-		if (p->socket_manager.read_cb == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-				"// gg_read() socket_manager.read callback is "
-				"empty\n");
-			errno = EINVAL;
-			return -1;
-		}
-
-		do {
-			res = p->socket_manager.read_cb(
-				p->socket_manager.cb_data, p->socket_handle,
-				(unsigned char*)buf, length);
-		} while (res < 0 && errno == EINTR);
-
-		if (res < 0) {
-			if (errno == EAGAIN)
-				return -1;
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-				"// gg_read() unexpected errno=%d\n", errno);
-			errno = EINVAL;
-		}
-		return res;
-	}
-
-	for (;;) {
-		res = recv(sess->fd, buf, length, 0);
-
-		if (res == -1 && errno == EINTR)
-			continue;
-
-		return res;
-	}
-}
-
-/**
- * \internal Wysyła do serwera dane binarne.
- *
- * Funkcja wysyła dane do serwera zajmując się SSL/TLS w razie konieczności.
- * Obsługuje EINTR, więc użytkownik nie musi się przejmować przerwanymi
- * wywołaniami systemowymi.
- *
- * \note Funkcja nie zajmuje się buforowaniem wysyłanych danych (patrz
- * gg_write()).
- *
- * \param sess Struktura sesji
- * \param buf Bufor z danymi
- * \param length Długość bufora
- *
- * \return To samo co funkcja systemowa \c write
- */
-static int gg_write_common(struct gg_session *sess, const char *buf, int length)
-{
-	struct gg_session_private *p = sess->private_data;
-	int res;
-
-#ifdef GG_CONFIG_HAVE_GNUTLS
-	if (sess->ssl != NULL) {
-		for (;;) {
-			res = gnutls_record_send(GG_SESSION_GNUTLS(sess), buf, length);
-
-			if (res < 0) {
-				if (!gnutls_error_is_fatal(res) || res == GNUTLS_E_INTERRUPTED)
-					continue;
-
-				if (res == GNUTLS_E_AGAIN)
-					errno = EAGAIN;
-				else
-					errno = EINVAL;
-
-				return -1;
-			}
-
-			return res;
-		}
-	}
-#endif
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-	if (sess->ssl != NULL) {
-		for (;;) {
-			int err;
-
-			res = SSL_write(sess->ssl, buf, length);
-
-			if (res < 0) {
-				err = SSL_get_error(sess->ssl, res);
-
-				if (err == SSL_ERROR_SYSCALL && errno == EINTR)
-					continue;
-
-				if (err == SSL_ERROR_WANT_WRITE)
-					errno = EAGAIN;
-				else if (err != SSL_ERROR_SYSCALL)
-					errno = EINVAL;
-
-				return -1;
-			}
-
-			return res;
-		}
-	}
-#endif
-
-	if (p->socket_handle != NULL) {
-		if (p->socket_manager.write_cb == NULL) {
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-				"// gg_write_common() socket_manager.write "
-				"callback is empty\n");
-			errno = EINVAL;
-			return -1;
-		}
-
-		do {
-			res = p->socket_manager.write_cb(
-				p->socket_manager.cb_data, p->socket_handle,
-				(const unsigned char*)buf, length);
-		} while (res < 0 && errno == EINTR);
-
-		if (res < 0) {
-			if (errno == EAGAIN)
-				return -1;
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-				"// gg_read() unexpected errno=%d\n", errno);
-			errno = EINVAL;
-		}
-
-		return res;
-	}
-
-	for (;;) {
-		res = send(sess->fd, buf, length, 0);
-
-		if (res == -1 && errno == EINTR)
-			continue;
-
-		return res;
-	}
-}
-
-/**
- * \internal Wysyła do serwera dane binarne.
- *
- * Funkcja wysyła dane do serwera zajmując się TLS w razie konieczności.
- *
- * \param sess Struktura sesji
- * \param buf Bufor z danymi
- * \param length Długość bufora
- *
- * \return To samo co funkcja systemowa \c write
- */
-int gg_write(struct gg_session *sess, const char *buf, int length)
-{
-	int res = 0;
-
-	if (!sess->async) {
-		int written = 0;
-
-		while (written < length) {
-			res = gg_write_common(sess, buf + written, length - written);
-
-			if (res == -1)
-				return -1;
-
-			written += res;
-			res = written;
-		}
-	} else {
-		if (sess->send_buf == NULL) {
-			res = gg_write_common(sess, buf, length);
-
-			if (res == -1 && errno == EAGAIN)
-				res = 0;
-			if (res == -1)
-				return -1;
-		}
-
-		if (res < length) {
-			char *tmp;
-
-			if (!(tmp = realloc(sess->send_buf, sess->send_left + length - res))) {
-				errno = ENOMEM;
-				return -1;
-			}
-
-			sess->send_buf = tmp;
-
-			memcpy(sess->send_buf + sess->send_left, buf + res, length - res);
-
-			sess->send_left += length - res;
-		}
-	}
-
-	return res;
-}
-
-void gg_close(struct gg_session *sess)
-{
-	struct gg_session_private *p = sess->private_data;
-	int errno_copy;
-
-	errno_copy = errno;
-
-	if (!p->socket_is_external) {
-		if (sess->fd != -1)
-			close(sess->fd);
-	} else {
-		assert(p->socket_manager_type !=
-			GG_SOCKET_MANAGER_TYPE_INTERNAL);
-		if (p->socket_handle != NULL) {
-			p->socket_manager.close_cb(p->socket_manager.cb_data,
-				p->socket_handle);
-		}
-		p->socket_is_external = 0;
-	}
-	sess->fd = -1;
-	p->socket_handle = NULL;
-
-	while (p->event_queue) {
-		gg_eventqueue_t *next = p->event_queue->next;
-		gg_event_free(p->event_queue->event);
-		free(p->event_queue);
-		p->event_queue = next;
-	}
-
-	while (p->imgout_queue) {
-		gg_imgout_queue_t *next = p->imgout_queue->next;
-		free(p->imgout_queue);
-		p->imgout_queue = next;
-	}
-
-	if (p->dummyfds_created) {
-		close(p->dummyfds[0]);
-		close(p->dummyfds[1]);
-		p->dummyfds_created = 0;
-	}
-
-	gg_compat_message_cleanup(sess);
-
-	errno = errno_copy;
-}
-
-/**
- * \internal Odbiera pakiet od serwera.
- *
- * Funkcja odczytuje nagłówek pakietu, a następnie jego zawartość i zwraca
- * w zaalokowanym buforze.
- *
- * Przy połączeniach asynchronicznych, funkcja może nie być w stanie
- * skompletować całego pakietu -- w takim przypadku zwróci \c NULL, a kodem błędu
- * będzie \c EAGAIN.
- *
- * \param sess Struktura sesji
- *
- * \return Wskaźnik do zaalokowanego bufora
- */
-void *gg_recv_packet(struct gg_session *sess)
-{
-	struct gg_header *gh;
-	char *packet;
-	int res;
-	size_t len;
-	uint32_t ghlen = 0;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_recv_packet(%p);\n", sess);
-
-	if (sess == NULL) {
-		errno = EFAULT;
-		return NULL;
-	}
-
-	for (;;) {
-		if (sess->recv_buf == NULL && sess->recv_done == 0) {
-			sess->recv_buf = malloc(sizeof(struct gg_header) + 1);
-
-			if (sess->recv_buf == NULL) {
-				gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_recv_packet() out of memory\n");
-				return NULL;
-			}
-		}
-
-		gh = (struct gg_header*) sess->recv_buf;
-
-		if ((size_t) sess->recv_done < sizeof(struct gg_header)) {
-			len = sizeof(struct gg_header) - sess->recv_done;
-			gg_debug_session(sess, GG_DEBUG_NET,
-				"// gg_recv_packet() header: %d done, "
-				"%" GG_SIZE_FMT " to go\n",
-				sess->recv_done, len);
-		} else {
-			ghlen = gh ? gg_fix32(gh->length) : 0;
-
-			if (ghlen > 65535) {
-				gg_debug_session(sess, GG_DEBUG_ERROR,
-					"// gg_recv_packet() invalid packet "
-					"length (%d)\n", ghlen);
-				errno = ERANGE;
-				goto fail;
-			}
-
-			if ((size_t) sess->recv_done >= sizeof(struct gg_header) + ghlen) {
-				gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() and that's it\n");
-				break;
-			}
-
-			len = sizeof(struct gg_header) + ghlen - sess->recv_done;
-
-			gg_debug_session(sess, GG_DEBUG_NET,
-				"// gg_recv_packet() payload: %d done, "
-				"%u length, %" GG_SIZE_FMT " to go\n",
-				sess->recv_done, ghlen, len);
-		}
-
-		res = gg_read(sess, sess->recv_buf + sess->recv_done, len);
-
-		if (res == 0) {
-			errno = ECONNRESET;
-			gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_recv_packet() connection broken\n");
-			goto fail;
-		}
-
-		if (res == -1 && errno == EAGAIN) {
-			gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() resource temporarily unavailable\n");
-			goto eagain;
-		}
-
-		if (res == -1) {
-			gg_debug_session(sess, GG_DEBUG_ERROR,
-				"// gg_recv_packet() read failed: errno=%d, "
-				"%s\n", errno, strerror(errno));
-			goto fail;
-		}
-
-		gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() read %d bytes\n", res);
-
-		if (sess->recv_done + res == sizeof(struct gg_header)) {
-			char *tmp;
-			ghlen = gh ? gg_fix32(gh->length) : 0;
-
-			gg_debug_session(sess, GG_DEBUG_NET,
-				"// gg_recv_packet() header complete, "
-				"payload %d bytes\n", ghlen);
-
-			if (ghlen == 0)
-				break;
-
-			if (ghlen > 65535) {
-				gg_debug_session(sess, GG_DEBUG_ERROR,
-					"// gg_recv_packet() invalid packet "
-					"length (%d)\n", ghlen);
-				errno = ERANGE;
-				goto fail;
-			}
-
-			tmp = realloc(sess->recv_buf, sizeof(struct gg_header) + ghlen + 1);
-
-			if (tmp == NULL) {
-				gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_recv_packet() out of memory\n");
-				goto fail;
-			}
-
-			sess->recv_buf = tmp;
-		}
-
-		sess->recv_done += res;
-	}
-
-	packet = sess->recv_buf;
-	sess->recv_buf = NULL;
-	sess->recv_done = 0;
-
-	if (gh == NULL)
-		goto fail;
-
-	/* Czasami zakładamy, że teksty w pakietach są zakończone zerem */
-	packet[sizeof(struct gg_header) + ghlen] = 0;
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet(type=0x%.2x, "
-		"length=%d)\n", gg_fix32(gh->type), ghlen);
-	gg_debug_dump(sess, GG_DEBUG_DUMP, packet, sizeof(struct gg_header) + ghlen);
-
-	gh->type = gg_fix32(gh->type);
-	gh->length = ghlen;
-
-	return packet;
-
-fail:
-	free(sess->recv_buf);
-	sess->recv_buf = NULL;
-	sess->recv_done = 0;
-
-eagain:
-	return NULL;
-}
-
-/**
- * \internal Wysyła pakiet do serwera.
- *
- * Funkcja konstruuje pakiet do wysłania z dowolnej liczby fragmentów. Jeśli
- * rozmiar pakietu jest za duży, by móc go wysłać za jednym razem, pozostała
- * część zostanie zakolejkowana i wysłana, gdy będzie to możliwe.
- *
- * \param sess Struktura sesji
- * \param type Rodzaj pakietu
- * \param ... Lista kolejnych części pakietu (wskaźnik na bufor i długość
- *            typu \c int) zakończona \c NULL
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_send_packet(struct gg_session *sess, int type, ...)
-{
-	struct gg_header *h;
-	char *tmp;
-	unsigned int tmp_length;
-	void *payload;
-	unsigned int payload_length;
-	va_list ap;
-	int res;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_packet(%p, 0x%.2x, ...);\n", sess, type);
-
-	tmp_length = sizeof(struct gg_header);
-
-	if (!(tmp = malloc(tmp_length))) {
-		gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_send_packet() not enough memory for packet header\n");
-		return -1;
-	}
-
-	va_start(ap, type);
-
-	payload = va_arg(ap, void *);
-
-	while (payload) {
-		char *tmp2;
-
-		payload_length = va_arg(ap, unsigned int);
-
-		if (!(tmp2 = realloc(tmp, tmp_length + payload_length))) {
-			gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_send_packet() not enough memory for payload\n");
-			free(tmp);
-			va_end(ap);
-			return -1;
-		}
-
-		tmp = tmp2;
-
-		memcpy(tmp + tmp_length, payload, payload_length);
-		tmp_length += payload_length;
-
-		payload = va_arg(ap, void *);
-	}
-
-	va_end(ap);
-
-	h = (struct gg_header*) tmp;
-	h->type = gg_fix32(type);
-	h->length = gg_fix32(tmp_length - sizeof(struct gg_header));
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet(type=0x%.2x, "
-		"length=%d)\n", gg_fix32(h->type), gg_fix32(h->length));
-	gg_debug_dump(sess, GG_DEBUG_DUMP, tmp, tmp_length);
-
-	res = gg_write(sess, tmp, tmp_length);
-
-	free(tmp);
-
-	if (res == -1) {
-		gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_send_packet() "
-			"write() failed. res = %d, errno = %d (%s)\n",
-			res, errno, strerror(errno));
-		return -1;
-	}
-
-	if (sess->async) {
-		gg_debug_session(sess, GG_DEBUG_NET, "// gg_send_packet() "
-			"partial write(), %d sent, %d left, %d total left\n",
-			res, tmp_length - res, sess->send_left);
-	}
-
-	if (sess->send_buf)
-		sess->check |= GG_CHECK_WRITE;
-
-	return 0;
-}
-
-/**
- * \internal Funkcja zwrotna sesji.
- *
- * Pole \c callback struktury \c gg_session zawiera wskaźnik do tej funkcji.
- * Wywołuje ona \c gg_watch_fd i zachowuje wynik w polu \c event.
- *
- * \note Korzystanie z tej funkcjonalności nie jest już zalecane.
- *
- * \param sess Struktura sesji
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_session_callback(struct gg_session *sess)
-{
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	return ((sess->event = gg_watch_fd(sess)) != NULL) ? 0 : -1;
-}
-
-/**
- * Łączy się z serwerem Gadu-Gadu.
- *
- * Przy połączeniu synchronicznym funkcja zakończy działanie po nawiązaniu
- * połączenia lub gdy wystąpi błąd. Po udanym połączeniu należy wywoływać
- * funkcję \c gg_watch_fd(), która odbiera informacje od serwera i zwraca
- * informacje o zdarzeniach.
- *
- * Przy połączeniu asynchronicznym funkcja rozpocznie procedurę połączenia
- * i zwróci zaalokowaną strukturę. Pole \c fd struktury \c gg_session zawiera
- * deskryptor, który należy obserwować funkcją \c select, \c poll lub za
- * pomocą mechanizmów użytej pętli zdarzeń (Glib, Qt itp.). Pole \c check
- * jest maską bitową mówiącą, czy biblioteka chce być informowana o możliwości
- * odczytu danych (\c GG_CHECK_READ) czy zapisu danych (\c GG_CHECK_WRITE).
- * Po zaobserwowaniu zmian na deskryptorze należy wywołać funkcję
- * \c gg_watch_fd(). Podczas korzystania z połączeń asynchronicznych, w trakcie
- * połączenia może zostać stworzony dodatkowy proces rozwiązujący nazwę
- * serwera -- z tego powodu program musi poprawnie obsłużyć sygnał SIGCHLD.
- *
- * \note Po nawiązaniu połączenia z serwerem należy wysłać listę kontaktów
- *       za pomocą funkcji \c gg_notify() lub \c gg_notify_ex().
- *
- * \note Funkcja zwróci błąd ENOSYS jeśli połączenie SSL było wymagane, ale
- *       obsługa SSL nie jest wkompilowana.
- *
- * \param p Struktura opisująca parametry połączenia. Wymagane pola: uin,
- *          password, async.
- *
- * \return Wskaźnik do zaalokowanej struktury sesji \c gg_session lub NULL
- *         w przypadku błędu.
- *
- * \ingroup login
- */
-struct gg_session *gg_login(const struct gg_login_params *p)
-{
-	struct gg_session *sess = NULL;
-	struct gg_session_private *sess_private = NULL;
-
-	if (p == NULL) {
-		gg_debug(GG_DEBUG_FUNCTION, "** gg_login(%p);\n", p);
-		errno = EFAULT;
-		return NULL;
-	}
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_login(%p: [uin=%u, async=%d, ...]);\n", p, p->uin, p->async);
-
-	sess = malloc(sizeof(struct gg_session));
-
-	if (sess == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for session data\n");
-		goto fail;
-	}
-
-	memset(sess, 0, sizeof(struct gg_session));
-	sess->fd = -1;
-
-	sess_private = malloc(sizeof(struct gg_session_private));
-
-	if (sess_private == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for session private data\n");
-		goto fail;
-	}
-
-	memset(sess_private, 0, sizeof(struct gg_session_private));
-	sess->private_data = sess_private;
-
-	if (p->password == NULL || p->uin == 0) {
-		gg_debug(GG_DEBUG_MISC, "// gg_login() invalid arguments. uin and password needed\n");
-		errno = EFAULT;
-		goto fail;
-	}
-
-	if (!(sess->password = strdup(p->password))) {
-		gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for password\n");
-		goto fail;
-	}
-
-	if (p->hash_type < 0 || p->hash_type > GG_LOGIN_HASH_SHA1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_login() invalid arguments. unknown hash type (%d)\n", p->hash_type);
-		errno = EFAULT;
-		goto fail;
-	}
-
-	sess->uin = p->uin;
-	sess->state = GG_STATE_RESOLVING;
-	sess->check = GG_CHECK_READ;
-	sess->timeout = GG_DEFAULT_TIMEOUT;
-	sess->async = p->async;
-	sess->type = GG_SESSION_GG;
-	sess->initial_status = p->status;
-	sess->callback = gg_session_callback;
-	sess->destroy = gg_free_session;
-	sess->port = p->server_port;
-	sess->server_addr = p->server_addr;
-	sess->external_port = p->external_port;
-	sess->external_addr = p->external_addr;
-	sess->client_addr = p->client_addr;
-	sess->client_port = p->client_port;
-
-	if (GG_LOGIN_PARAMS_HAS_FIELD(p, compatibility))
-		sess_private->compatibility = p->compatibility;
-
-	if (GG_LOGIN_PARAMS_HAS_FIELD(p, connect_host) && p->connect_host != NULL) {
-		int port = 0;
-		char *colon;
-
-		sess->connect_host = strdup(p->connect_host);
-		if (sess->connect_host == NULL)
-			goto fail;
-
-		colon = strchr(sess->connect_host, ':');
-		if (colon != NULL) {
-			colon[0] = '\0';
-			port = atoi(colon + 1);
-		}
-		if (port > 0)
-			sess->port = port;
-	}
-
-	if (GG_LOGIN_PARAMS_HAS_FIELD(p, socket_manager_type) &&
-		GG_LOGIN_PARAMS_HAS_FIELD(p, socket_manager) &&
-		p->socket_manager_type != GG_SOCKET_MANAGER_TYPE_INTERNAL)
-	{
-		if ((unsigned int)p->socket_manager_type >
-			GG_SOCKET_MANAGER_TYPE_TLS)
-		{
-			gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_login()"
-				" invalid arguments. unknown socket manager "
-				"type (%d)\n", p->socket_manager_type);
-			errno = EFAULT;
-			goto fail;
-		} else {
-			sess_private->socket_manager_type =
-				p->socket_manager_type;
-			memcpy(&sess_private->socket_manager,
-				&p->socket_manager,
-				sizeof(gg_socket_manager_t));
-		}
-	} else {
-		sess_private->socket_manager_type =
-			GG_SOCKET_MANAGER_TYPE_INTERNAL;
-	}
-
-	if (GG_LOGIN_PARAMS_HAS_FIELD(p, host_white_list) &&
-		p->host_white_list != NULL)
-	{
-		sess_private->host_white_list =
-			gg_strarr_dup(p->host_white_list);
-		if (sess_private->host_white_list == NULL)
-			goto fail;
-	}
-
-	if (p->protocol_features == 0) {
-		sess->protocol_features = GG_FEATURE_MSG80 |
-			GG_FEATURE_STATUS80 | GG_FEATURE_DND_FFC |
-			GG_FEATURE_IMAGE_DESCR | GG_FEATURE_UNKNOWN_100 |
-			GG_FEATURE_USER_DATA | GG_FEATURE_MSG_ACK |
-			GG_FEATURE_TYPING_NOTIFICATION;
-	} else {
-		sess->protocol_features = (p->protocol_features & ~(GG_FEATURE_STATUS77 | GG_FEATURE_MSG77));
-
-		if (!(p->protocol_features & GG_FEATURE_STATUS77))
-			sess->protocol_features |= GG_FEATURE_STATUS80;
-
-		if (!(p->protocol_features & GG_FEATURE_MSG77))
-			sess->protocol_features |= GG_FEATURE_MSG80;
-	}
-
-	if (!(sess->status_flags = p->status_flags))
-		sess->status_flags = GG_STATUS_FLAG_UNKNOWN | GG_STATUS_FLAG_SPAM;
-
-	if (!p->protocol_version)
-		sess->protocol_version = GG_DEFAULT_PROTOCOL_VERSION;
-	else if (p->protocol_version < 0x2e) {
-		gg_debug(GG_DEBUG_MISC, "// gg_login() libgadu no longer support protocol < 0x2e\n");
-		sess->protocol_version = 0x2e;
-	} else
-		sess->protocol_version = p->protocol_version;
-
-	if (p->client_version && strcmp(p->client_version, "-") != 0)
-		sess->client_version = strdup(p->client_version);
-	sess->last_sysmsg = p->last_sysmsg;
-	sess->image_size = p->image_size;
-	sess->pid = -1;
-	sess->encoding = p->encoding;
-
-	if (gg_session_set_resolver(sess, p->resolver) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_login() invalid arguments. "
-			"unsupported resolver type (%d)\n", p->resolver);
-		errno = EFAULT;
-		goto fail;
-	}
-
-	if (p->status_descr) {
-		sess->initial_descr = gg_encoding_convert(p->status_descr, p->encoding, GG_ENCODING_UTF8, -1, -1);
-
-		if (!sess->initial_descr) {
-			gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for status\n");
-			goto fail;
-		}
-
-		/* XXX pamiętać, żeby nie ciąć w środku znaku utf-8 */
-
-		if (strlen(sess->initial_descr) > GG_STATUS_DESCR_MAXSIZE)
-			sess->initial_descr[GG_STATUS_DESCR_MAXSIZE] = 0;
-	}
-
-	if (p->tls != GG_SSL_DISABLED) {
-#if !defined(GG_CONFIG_HAVE_GNUTLS) && !defined(GG_CONFIG_HAVE_OPENSSL)
-		gg_debug(GG_DEBUG_MISC, "// gg_login() client requested TLS but no support compiled in\n");
-
-		if (p->tls == GG_SSL_REQUIRED) {
-			errno = ENOSYS;
-			goto fail;
-		}
-#else
-		sess->ssl_flag = p->tls;
-#endif
-	}
-
-	if (p->hash_type)
-		sess->hash_type = p->hash_type;
-	else
-		sess->hash_type = GG_LOGIN_HASH_SHA1;
-
-	if (sess->server_addr == 0 && sess->connect_host == NULL) {
-		if (gg_proxy_enabled) {
-			sess->resolver_host = gg_proxy_host;
-			sess->proxy_port = gg_proxy_port;
-			sess->state = (sess->async) ?
-				GG_STATE_RESOLVE_PROXY_HUB_ASYNC :
-				GG_STATE_RESOLVE_PROXY_HUB_SYNC;
-		} else {
-			sess->resolver_host = GG_APPMSG_HOST;
-			sess->proxy_port = 0;
-			sess->state = (sess->async) ? GG_STATE_RESOLVE_HUB_ASYNC : GG_STATE_RESOLVE_HUB_SYNC;
-		}
-	} else {
-		if (sess->connect_host != NULL)
-			sess->server_addr = 0;
-		else {
-			/* XXX inet_ntoa i wielowątkowość */
-			sess->connect_host = strdup(inet_ntoa(*(struct in_addr*) &sess->server_addr));
-			if (sess->connect_host == NULL)
-				goto fail;
-		}
-		sess->connect_index = 0;
-
-		if (gg_proxy_enabled) {
-			sess->resolver_host = gg_proxy_host;
-			sess->proxy_port = gg_proxy_port;
-			if (sess->port == 0)
-				sess->connect_port[0] = GG_HTTPS_PORT;
-			else
-				sess->connect_port[0] = sess->port;
-			sess->connect_port[1] = 0;
-			sess->state = (sess->async) ? GG_STATE_RESOLVE_PROXY_GG_ASYNC : GG_STATE_RESOLVE_PROXY_GG_SYNC;
-		} else {
-			sess->resolver_host = sess->connect_host;
-			if (sess->port == 0) {
-				if (sess->ssl_flag == GG_SSL_DISABLED) {
-					sess->connect_port[0] = GG_DEFAULT_PORT;
-					sess->connect_port[1] = GG_HTTPS_PORT;
-				} else {
-					sess->connect_port[0] = GG_HTTPS_PORT;
-					sess->connect_port[1] = 0;
-				}
-			} else {
-				sess->connect_port[0] = sess->port;
-				sess->connect_port[1] = 0;
-			}
-			sess->state = (sess->async) ? GG_STATE_RESOLVE_GG_ASYNC : GG_STATE_RESOLVE_GG_SYNC;
-		}
-	}
-
-	/* XXX inaczej gg_watch_fd() wyjdzie z timeoutem */
-	sess->timeout = GG_DEFAULT_TIMEOUT;
-
-	if (!sess->async) {
-		while (!GG_SESSION_IS_CONNECTED(sess)) {
-			struct gg_event *ge;
-
-			ge = gg_watch_fd(sess);
-
-			if (ge == NULL) {
-				gg_debug(GG_DEBUG_MISC, "// gg_session_connect() critical error in gg_watch_fd()\n");
-				goto fail;
-			}
-
-			if (ge->type == GG_EVENT_CONN_FAILED) {
-				errno = EACCES;
-				gg_debug(GG_DEBUG_MISC, "// gg_session_connect() could not login\n");
-				gg_event_free(ge);
-				goto fail;
-			}
-
-			gg_event_free(ge);
-		}
-	} else {
-		struct gg_event *ge;
-
-		ge = gg_watch_fd(sess);
-
-		if (ge == NULL) {
-			gg_debug(GG_DEBUG_MISC, "// gg_session_connect() critical error in gg_watch_fd()\n");
-			goto fail;
-		}
-
-		gg_event_free(ge);
-	}
-
-	return sess;
-
-fail:
-	gg_free_session(sess);
-
-	return NULL;
-}
-
-/**
- * Wysyła do serwera pakiet utrzymania połączenia.
- *
- * Klient powinien regularnie co minutę wysyłać pakiet utrzymania połączenia,
- * inaczej serwer uzna, że klient stracił łączność z siecią i zerwie
- * połączenie.
- *
- * \param sess Struktura sesji
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup login
- */
-int gg_ping(struct gg_session *sess)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_ping(%p);\n", sess);
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	return gg_send_packet(sess, GG_PING, NULL);
-}
-
-/**
- * Kończy połączenie z serwerem.
- *
- * Funkcja nie zwalnia zasobów, więc po jej wywołaniu należy użyć
- * \c gg_free_session(). Jeśli chce się ustawić opis niedostępności, należy
- * wcześniej wywołać funkcję \c gg_change_status_descr() lub
- * \c gg_change_status_descr_time().
- *
- * \note Jeśli w buforze nadawczym połączenia z serwerem znajdują się jeszcze
- * dane (np. z powodu strat pakietów na łączu), prawdopodobnie zostaną one
- * utracone przy zrywaniu połączenia. Aby mieć pewność, że opis statusu
- * zostanie zachowany, należy ustawić stan \c GG_STATUS_NOT_AVAIL_DESCR
- * za pomocą funkcji \c gg_change_status_descr() i poczekać na zdarzenie
- * \c GG_EVENT_DISCONNECT_ACK.
- *
- * \param sess Struktura sesji
- *
- * \ingroup login
- */
-void gg_logoff(struct gg_session *sess)
-{
-	if (!sess)
-		return;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_logoff(%p);\n", sess);
-
-#ifdef GG_CONFIG_HAVE_GNUTLS
-	if (sess->ssl != NULL)
-		gnutls_bye(GG_SESSION_GNUTLS(sess), GNUTLS_SHUT_RDWR);
-#endif
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-	if (sess->ssl != NULL)
-		SSL_shutdown(sess->ssl);
-#endif
-
-	sess->resolver_cleanup(&sess->resolver, 1);
-
-	gg_close(sess);
-
-	if (sess->send_buf) {
-		free(sess->send_buf);
-		sess->send_buf = NULL;
-		sess->send_left = 0;
-	}
-}
-
-/**
- * Zwalnia zasoby używane przez połączenie z serwerem. Funkcję należy wywołać
- * po zamknięciu połączenia z serwerem, by nie doprowadzić do wycieku zasobów
- * systemowych.
- *
- * \param sess Struktura sesji
- *
- * \ingroup login
- */
-void gg_free_session(struct gg_session *sess)
-{
-	struct gg_dcc7 *dcc;
-	gg_chat_list_t *chat;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_free_session(%p);\n", sess);
-
-	if (sess == NULL)
-		return;
-
-	/* XXX dopisać zwalnianie i zamykanie wszystkiego, co mogło zostać */
-
-	free(sess->resolver_result);
-	free(sess->connect_host);
-	free(sess->password);
-	free(sess->initial_descr);
-	free(sess->client_version);
-	free(sess->header_buf);
-	free(sess->recv_buf);
-
-#ifdef GG_CONFIG_HAVE_GNUTLS
-	if (sess->ssl != NULL) {
-		gg_session_gnutls_t *tmp;
-
-		tmp = (gg_session_gnutls_t*) sess->ssl;
-		gnutls_deinit(tmp->session);
-		gnutls_certificate_free_credentials(tmp->xcred);
-		gnutls_global_deinit();
-		free(sess->ssl);
-	}
-#endif
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-	if (sess->ssl)
-		SSL_free(sess->ssl);
-
-	if (sess->ssl_ctx)
-		SSL_CTX_free(sess->ssl_ctx);
-#endif
-
-	if (sess->resolver_cleanup != NULL)
-		sess->resolver_cleanup(&sess->resolver, 1);
-
-	gg_close(sess);
-
-	while (sess->images) {
-		struct gg_image_queue *next = sess->images->next;
-
-		gg_image_queue_remove(sess, sess->images, 1);
-
-		/* a fix for false-positive NULL-dereference */
-		sess->images = next;
-	}
-
-	free(sess->send_buf);
-
-	for (dcc = sess->dcc7_list; dcc; dcc = dcc->next)
-		dcc->sess = NULL;
-
-	chat = sess->private_data->chat_list;
-	while (chat != NULL) {
-		gg_chat_list_t *next = chat->next;
-		free(chat->participants);
-		free(chat);
-		chat = next;
-	}
-
-	gg_strarr_free(sess->private_data->host_white_list);
-
-	free(sess->private_data);
-
-	free(sess);
-}
-
-/**
- * Zmienia status użytkownika.
- *
- * \param sess Struktura sesji
- * \param status Nowy status użytkownika
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup status
- */
-int gg_change_status(struct gg_session *sess, int status)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_change_status(%p, %d);\n", sess, status);
-
-	return gg_change_status_descr(sess, status, NULL);
-}
-
-/**
- * Zmienia status użytkownika na status opisowy.
- *
- * \param sess Struktura sesji
- * \param status Nowy status użytkownika
- * \param descr Opis statusu użytkownika (lub \c NULL)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup status
- */
-int gg_change_status_descr(struct gg_session *sess, int status, const char *descr)
-{
-	struct gg_new_status80 p;
-	char *gen_descr = NULL;
-	int descr_len = 0;
-	int descr_null_len = 0;
-	int res;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_change_status_descr(%p, %d, \"%s\");\n", sess, status, descr);
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	sess->status = status;
-
-	if (descr != NULL && sess->encoding != GG_ENCODING_UTF8) {
-		descr = gen_descr = gg_encoding_convert(descr, GG_ENCODING_CP1250, GG_ENCODING_UTF8, -1, -1);
-
-		if (!gen_descr)
-			return -1;
-	}
-
-	if (descr) {
-		descr_len = strlen(descr);
-
-		if (descr_len > GG_STATUS_DESCR_MAXSIZE)
-			descr_len = GG_STATUS_DESCR_MAXSIZE;
-
-		/* XXX pamiętać o tym, żeby nie ucinać w środku znaku utf-8 */
-	} else {
-		descr = "";
-	}
-
-	p.status		= gg_fix32(status);
-	p.flags			= gg_fix32(sess->status_flags);
-	p.description_size	= gg_fix32(descr_len);
-
-	if (sess->protocol_version >= GG_PROTOCOL_VERSION_110) {
-		p.flags = gg_fix32(0x00000014);
-		descr_null_len = 1;
-	}
-
-	res = gg_send_packet(sess, GG_NEW_STATUS80,
-		&p, sizeof(p), descr, descr_len,
-		"\x00", descr_null_len, NULL);
-
-	free(gen_descr);
-
-	if (GG_S_NA(status)) {
-		sess->state = GG_STATE_DISCONNECTING;
-		sess->timeout = GG_TIMEOUT_DISCONNECT;
-	}
-
-	return res;
-}
-
-/**
- * Zmienia status użytkownika na status opisowy z podanym czasem powrotu.
- *
- * \param sess Struktura sesji
- * \param status Nowy status użytkownika
- * \param descr Opis statusu użytkownika
- * \param ts Czas powrotu w postaci uniksowego znacznika czasu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup status
- */
-int gg_change_status_descr_time(struct gg_session *sess, int status, const char *descr, int ts)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION,
-		"** gg_change_status_descr_time(%p, %d, \"%s\", %d);\n",
-		sess, status, descr, ts);
-
-	return gg_change_status_descr(sess, status, descr);
-}
-
-/**
- * Funkcja zmieniająca flagi statusu.
- *
- * \param sess Struktura sesji
- * \param flags Nowe flagi statusu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \note Aby zmiany weszły w życie, należy ponownie ustawić status za pomocą
- * funkcji z rodziny \c gg_change_status().
- *
- * \ingroup status
- */
-int gg_change_status_flags(struct gg_session *sess, int flags)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_change_status_flags(%p, 0x%08x);\n", sess, flags);
-
-	if (sess == NULL) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	sess->status_flags = flags;
-
-	return 0;
-}
-
-#ifndef DOXYGEN
-
-static int gg_send_message_110(struct gg_session *sess,
-	uin_t recipient, uint64_t chat_id,
-	const char *message, int is_html)
-{
-	GG110SendMessage msg = GG110_SEND_MESSAGE__INIT;
-	int packet_type = recipient ? GG_SEND_MSG110 : GG_CHAT_SEND_MSG;
-	int seq;
-	char *html_message_gen = NULL, *plain_message_gen = NULL;
-	const char *html_message, *plain_message;
-	int succ = 1;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION,
-		"** gg_send_message_110(%p, %u, %" PRIu64 ", %p, %d);\n",
-		sess, recipient, chat_id, message, is_html);
-
-	if (message == NULL)
-		return -1;
-
-	if ((recipient == 0) == (chat_id == 0))
-		return -1;
-
-	if (is_html) {
-		html_message = message;
-
-		if (sess->encoding != GG_ENCODING_UTF8) {
-			html_message = html_message_gen = gg_encoding_convert(
-				html_message, sess->encoding, GG_ENCODING_UTF8,
-				-1, -1);
-			if (html_message_gen == NULL)
-				return -1;
-		}
-
-		plain_message = plain_message_gen =
-			gg_message_html_to_text_110(html_message);
-		if (plain_message_gen == NULL) {
-			free(html_message_gen);
-			return -1;
-		}
-	} else {
-		plain_message = message;
-
-		if (sess->encoding != GG_ENCODING_UTF8) {
-			plain_message = plain_message_gen = gg_encoding_convert(
-				plain_message, sess->encoding, GG_ENCODING_UTF8,
-				-1, -1);
-			if (plain_message_gen == NULL)
-				return -1;
-		}
-
-		html_message = html_message_gen =
-			gg_message_text_to_html_110(plain_message, -1);
-		if (html_message_gen == NULL) {
-			free(plain_message_gen);
-			return -1;
-		}
-	}
-
-	seq = ++sess->seq;
-
-	if (recipient) {
-		msg.has_recipient = 1;
-		gg_protobuf_set_uin(&msg.recipient, recipient, NULL);
-	}
-
-	msg.seq = seq;
-
-	/* rzutujemy z const, ale msg i tak nie będzie modyfikowany */
-	msg.msg_plain = (char*)plain_message;
-	msg.msg_xhtml = (char*)html_message;
-
-	if (chat_id) {
-		msg.dummy3 = "";
-		msg.has_chat_id = 1;
-		msg.chat_id = chat_id;
-	}
-
-	if (!GG_PROTOBUF_SEND(sess, NULL, packet_type, gg110_send_message, msg))
-		succ = 0;
-
-	free(html_message_gen);
-	free(plain_message_gen);
-
-	return succ ? seq : -1;
-}
-
-static char *
-gg_message_legacy_text_to_html(const char *src, gg_encoding_t encoding,
-	const unsigned char *format, size_t format_len)
-{
-	size_t len;
-	char *dst;
-
-	if (format == NULL || format_len <= 3) {
-		format = NULL;
-		format_len = 0;
-	} else {
-		format += 3;
-		format_len -= 3;
-	}
-
-	len = gg_message_text_to_html(NULL, src, encoding, format, format_len);
-
-	dst = malloc(len + 1);
-	if (dst == NULL)
-		return NULL;
-
-	gg_message_text_to_html(dst, src, encoding, format, format_len);
-
-	return dst;
-}
-
-/**
- * \internal Wysyła wiadomość.
- *
- * Zwraca losowy numer sekwencyjny, który można zignorować albo wykorzystać
- * do potwierdzenia.
- *
- * \param sess Struktura sesji
- * \param msgclass Klasa wiadomości
- * \param recipients_count Liczba adresatów
- * \param recipients Wskaźnik do tablicy z numerami adresatów
- * \param message Treść wiadomości
- * \param format Informacje o formatowaniu
- * \param formatlen Długość informacji o formatowaniu
- * \param html_message Treść wiadomości HTML
- *
- * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
- *
- * \ingroup messages
- */
-static int gg_send_message_common(struct gg_session *sess, int msgclass,
-	int recipients_count, uin_t *recipients, const unsigned char *message,
-	const unsigned char *format, int formatlen,
-	const unsigned char *html_message)
-{
-	struct gg_send_msg80 s80;
-	const char *cp_msg = NULL, *utf_html_msg = NULL;
-	char *recoded_msg = NULL, *recoded_html_msg = NULL;
-	unsigned char *generated_format = NULL;
-	int seq_no = -1;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_common("
-		"%p, %d, %d, %p, %p, %p, %d, %p);\n", sess, msgclass,
-		recipients_count, recipients, message, format,
-		formatlen, html_message);
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	if ((message == NULL && html_message == NULL) ||
-		recipients_count <= 0 || recipients_count > 0xffff ||
-		recipients == NULL || (format == NULL && formatlen != 0))
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (sess->protocol_version >= GG_PROTOCOL_VERSION_110 &&
-		recipients_count == 1)
-	{
-		int is_html = (html_message != NULL);
-		char *formatted_msg = NULL;
-
-		if (formatlen > 3 && !is_html) {
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_WARNING,
-				"// gg_send_message_common() using legacy "
-				"formatting with new protocol\n");
-			formatted_msg = gg_message_legacy_text_to_html(
-				(const char *)message, sess->encoding,
-				format, formatlen);
-			if (formatted_msg == NULL)
-				goto cleanup;
-			html_message = (unsigned char*)formatted_msg;
-			is_html = 1;
-		}
-
-		seq_no = gg_send_message_110(sess, recipients[0], 0,
-			(const char*)(is_html ? html_message : message),
-			is_html);
-		goto cleanup;
-	}
-
-	if (sess->protocol_version >= GG_PROTOCOL_VERSION_110 &&
-		!gg_compat_feature_is_enabled(sess, GG_COMPAT_FEATURE_LEGACY_CONFER))
-	{
-		gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"// gg_send_message_common() legacy conferences disabled\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (message == NULL) {
-		char *tmp_msg;
-		size_t len, fmt_len;
-		uint16_t fixed_fmt_len;
-
-		len = gg_message_html_to_text(NULL, NULL, &fmt_len, (const char*) html_message, sess->encoding);
-
-		tmp_msg = malloc(len + 1);
-
-		if (tmp_msg == NULL)
-			goto cleanup;
-
-		if (fmt_len != 0) {
-			generated_format = malloc(fmt_len + 3);
-
-			if (generated_format == NULL) {
-				free(tmp_msg);
-				goto cleanup;
-			}
-
-			generated_format[0] = '\x02';
-			fixed_fmt_len = gg_fix16(fmt_len);
-			memcpy(generated_format + 1, &fixed_fmt_len, sizeof(fixed_fmt_len));
-			gg_message_html_to_text(tmp_msg, generated_format + 3,
-				NULL, (const char*)html_message, sess->encoding);
-
-			format = generated_format;
-			formatlen = fmt_len + 3;
-		} else {
-			gg_message_html_to_text(tmp_msg, NULL, NULL, (const char*) html_message, sess->encoding);
-
-			format = NULL;
-			formatlen = 0;
-		}
-
-		if (sess->encoding != GG_ENCODING_CP1250) {
-			cp_msg = recoded_msg = gg_encoding_convert(tmp_msg, sess->encoding, GG_ENCODING_CP1250, -1, -1);
-			free(tmp_msg);
-
-			if (cp_msg == NULL)
-				goto cleanup;
-		} else {
-			cp_msg = recoded_msg = tmp_msg;
-		}
-	} else {
-		if (sess->encoding != GG_ENCODING_CP1250) {
-			cp_msg = recoded_msg = gg_encoding_convert(
-				(const char*)message, sess->encoding,
-				GG_ENCODING_CP1250, -1, -1);
-
-			if (cp_msg == NULL)
-				goto cleanup;
-		} else {
-			cp_msg = (const char*) message;
-		}
-	}
-
-	if (html_message == NULL) {
-		char *formatted_msg;
-
-		formatted_msg = gg_message_legacy_text_to_html(
-			(const char*)message, sess->encoding, format, formatlen);
-		if (formatted_msg == NULL)
-			goto cleanup;
-
-		if (sess->encoding == GG_ENCODING_UTF8) {
-			utf_html_msg = recoded_html_msg = formatted_msg;
-		} else {
-			utf_html_msg = recoded_html_msg = gg_encoding_convert(
-				formatted_msg, sess->encoding,
-				GG_ENCODING_UTF8, -1, -1);
-			free(formatted_msg);
-
-			if (utf_html_msg == NULL)
-				goto cleanup;
-		}
-	} else {
-		if (sess->encoding == GG_ENCODING_UTF8) {
-			utf_html_msg = (const char*) html_message;
-		} else {
-			utf_html_msg = recoded_html_msg = gg_encoding_convert(
-				(const char*)html_message, sess->encoding,
-				GG_ENCODING_UTF8, -1, -1);
-
-			if (utf_html_msg == NULL)
-				goto cleanup;
-		}
-	}
-
-	/* Drobne odchylenie od protokołu. Jeśli wysyłamy kilka
-	 * wiadomości w ciągu jednej sekundy, zwiększamy poprzednią
-	 * wartość, żeby każda wiadomość miała unikalny numer.
-	 */
-
-	seq_no = time(NULL);
-
-	if (seq_no <= sess->seq)
-		seq_no = sess->seq + 1;
-
-	sess->seq = seq_no;
-
-	s80.seq = gg_fix32(seq_no);
-	s80.msgclass = gg_fix32(msgclass);
-	s80.offset_plain = gg_fix32(sizeof(s80) + strlen(utf_html_msg) + 1);
-	s80.offset_attr = gg_fix32(sizeof(s80) + strlen(utf_html_msg) + 1 + strlen(cp_msg) + 1);
-
-	if (recipients_count > 1) {
-		struct gg_msg_recipients r;
-		int i, j, k;
-		uin_t *recps;
-
-		r.flag = GG_MSG_OPTION_CONFERENCE;
-		r.count = gg_fix32(recipients_count - 1);
-
-		recps = malloc(sizeof(uin_t) * (recipients_count - 1));
-
-		if (!recps) {
-			seq_no = -1;
-			goto cleanup;
-		}
-
-		for (i = 0; i < recipients_count; i++) {
-			for (j = 0, k = 0; j < recipients_count; j++) {
-				if (j != i) {
-					recps[k] = gg_fix32(recipients[j]);
-					k++;
-				}
-			}
-
-			s80.recipient = gg_fix32(recipients[i]);
-
-			if (gg_send_packet(sess, GG_SEND_MSG80, &s80,
-				sizeof(s80), utf_html_msg,
-				strlen(utf_html_msg) + 1, cp_msg,
-				strlen(cp_msg) + 1, &r, sizeof(r), recps,
-				(recipients_count - 1) * sizeof(uin_t), format,
-				formatlen, NULL) == -1)
-			{
-				seq_no = -1;
-			}
-		}
-
-		free(recps);
-	} else {
-		s80.recipient = gg_fix32(recipients[0]);
-
-		if (gg_send_packet(sess, GG_SEND_MSG80, &s80, sizeof(s80),
-			utf_html_msg, strlen(utf_html_msg) + 1, cp_msg,
-			strlen(cp_msg) + 1, format, formatlen, NULL) == -1)
-		{
-			seq_no = -1;
-		}
-	}
-
-cleanup:
-	free(recoded_msg);
-	free(recoded_html_msg);
-	free(generated_format);
-
-	if (seq_no >= 0)
-		gg_compat_message_sent(sess, seq_no, recipients_count, recipients);
-
-	return seq_no;
-}
-
-#endif /* DOXYGEN */
-
-/**
- * Wysyła wiadomość do użytkownika.
- *
- * Zwraca losowy numer sekwencyjny, który można zignorować albo wykorzystać
- * do potwierdzenia.
- *
- * \param sess Struktura sesji
- * \param msgclass Klasa wiadomości
- * \param recipient Numer adresata
- * \param message Treść wiadomości
- *
- * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
- *
- * \ingroup messages
- */
-int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message(%p, %d, "
-		"%u, %p)\n", sess, msgclass, recipient, message);
-
-	if (sess->protocol_version >= GG_PROTOCOL_VERSION_110) {
-		int seq_no;
-
-		seq_no = gg_send_message_110(sess, recipient, 0, (const char*)message, 0);
-
-		if (seq_no >= 0)
-			gg_compat_message_sent(sess, seq_no, 1, &recipient);
-
-		return seq_no;
-	}
-
-	return gg_send_message_common(sess, msgclass, 1, &recipient, message,
-		(const unsigned char*)"\x02\x06\x00\x00\x00\x08\x00\x00\x00",
-		9, NULL);
-}
-
-/**
- * Wysyła wiadomość formatowaną.
- *
- * Zwraca losowy numer sekwencyjny, który można zignorować albo wykorzystać
- * do potwierdzenia.
- *
- * \param sess Struktura sesji
- * \param msgclass Klasa wiadomości
- * \param recipient Numer adresata
- * \param message Treść wiadomości
- * \param format Informacje o formatowaniu
- * \param formatlen Długość informacji o formatowaniu
- *
- * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
- *
- * \ingroup messages
- */
-int gg_send_message_richtext(struct gg_session *sess, int msgclass,
-	uin_t recipient, const unsigned char *message,
-	const unsigned char *format, int formatlen)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_richtext("
-		"%p, %d, %u, %p, %p, %d);\n", sess, msgclass, recipient,
-		message, format, formatlen);
-
-	return gg_send_message_common(sess, msgclass, 1, &recipient, message, format, formatlen, NULL);
-}
-
-/**
- * Wysyła formatowaną wiadomość HTML.
- *
- * Zwraca losowy numer sekwencyjny, który można zignorować albo wykorzystać
- * do potwierdzenia.
- *
- * \param sess Struktura sesji
- * \param msgclass Klasa wiadomości
- * \param recipient Numer adresata
- * \param html_message Treść wiadomości HTML
- *
- * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
- *
- * \ingroup messages
- */
-int gg_send_message_html(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *html_message)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_html(%p, "
-		"%d, %u, %p);\n", sess, msgclass, recipient, html_message);
-
-	return gg_send_message_common(sess, msgclass, 1, &recipient, NULL, NULL, 0, html_message);
-}
-
-/**
- * Wysyła wiadomość w ramach konferencji.
- *
- * Zwraca losowy numer sekwencyjny, który można zignorować albo wykorzystać
- * do potwierdzenia.
- *
- * \param sess Struktura sesji
- * \param msgclass Klasa wiadomości
- * \param recipients_count Liczba adresatów
- * \param recipients Wskaźnik do tablicy z numerami adresatów
- * \param message Treść wiadomości
- *
- * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
- *
- * \ingroup messages
- */
-int gg_send_message_confer(struct gg_session *sess, int msgclass,
-	int recipients_count, uin_t *recipients, const unsigned char *message)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_confer("
-		"%p, %d, %d, %p, %p);\n", sess, msgclass, recipients_count,
-		recipients, message);
-
-	return gg_send_message_common(sess, msgclass, recipients_count,
-		recipients, message,
-		(const unsigned char*)"\x02\x06\x00\x00\x00\x08\x00\x00\x00",
-		9, NULL);
-}
-
-/**
- * Wysyła wiadomość formatowaną w ramach konferencji.
- *
- * Zwraca losowy numer sekwencyjny, który można zignorować albo wykorzystać
- * do potwierdzenia.
- *
- * \param sess Struktura sesji
- * \param msgclass Klasa wiadomości
- * \param recipients_count Liczba adresatów
- * \param recipients Wskaźnik do tablicy z numerami adresatów
- * \param message Treść wiadomości
- * \param format Informacje o formatowaniu
- * \param formatlen Długość informacji o formatowaniu
- *
- * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
- *
- * \ingroup messages
- */
-int gg_send_message_confer_richtext(struct gg_session *sess, int msgclass,
-	int recipients_count, uin_t *recipients, const unsigned char *message,
-	const unsigned char *format, int formatlen)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION,
-		"** gg_send_message_confer_richtext(%p, %d, %d, %p, %p, %p, "
-		"%d);\n", sess, msgclass, recipients_count, recipients, message,
-		format, formatlen);
-
-	return gg_send_message_common(sess, msgclass, recipients_count, recipients, message, format, formatlen, NULL);
-}
-
-/**
- * Wysyła formatowaną wiadomość HTML w ramach konferencji.
- *
- * Zwraca losowy numer sekwencyjny, który można zignorować albo wykorzystać
- * do potwierdzenia.
- *
- * \param sess Struktura sesji
- * \param msgclass Klasa wiadomości
- * \param recipients_count Liczba adresatów
- * \param recipients Wskaźnik do tablicy z numerami adresatów
- * \param html_message Treść wiadomości HTML
- *
- * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
- *
- * \ingroup messages
- */
-int gg_send_message_confer_html(struct gg_session *sess, int msgclass,
-	int recipients_count, uin_t *recipients,
-	const unsigned char *html_message)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION,
-		"** gg_send_message_confer_html(%p, %d, %d, %p, %p);\n", sess,
-		msgclass, recipients_count, recipients, html_message);
-
-	return gg_send_message_common(sess, msgclass, recipients_count, recipients, NULL, NULL, 0, html_message);
-}
-
-/**
- * Wysyła wiadomość binarną przeznaczoną dla klienta.
- *
- * Wiadomości między klientami przesyła się np. w celu wywołania zwrotnego
- * połączenia bezpośredniego. Funkcja zwraca losowy numer sekwencyjny,
- * który można zignorować albo wykorzystać do potwierdzenia.
- *
- * \param sess Struktura sesji
- * \param msgclass Klasa wiadomości
- * \param recipient Numer adresata
- * \param message Treść wiadomości
- * \param message_len Długość wiadomości
- *
- * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
- *
- * \ingroup messages
- */
-int gg_send_message_ctcp(struct gg_session *sess, int msgclass, uin_t recipient,
-	const unsigned char *message, int message_len)
-{
-	struct gg_send_msg s;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_ctcp(%p, "
-		"%d, %u, ...);\n", sess, msgclass, recipient);
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	s.recipient = gg_fix32(recipient);
-	s.seq = gg_fix32(0);
-	s.msgclass = gg_fix32(msgclass);
-
-	return gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), message, message_len, NULL);
-}
-
-/**
- * Wysyła żądanie obrazka o podanych parametrach.
- *
- * Wiadomości obrazkowe nie zawierają samych obrazków, a tylko ich rozmiary
- * i sumy kontrolne. Odbiorca najpierw szuka obrazków w swojej pamięci
- * podręcznej i dopiero gdy ich nie znajdzie, wysyła żądanie do nadawcy.
- * Wynik zostanie przekazany zdarzeniem \c GG_EVENT_IMAGE_REPLY.
- *
- * \param sess Struktura sesji
- * \param recipient Numer adresata
- * \param size Rozmiar obrazka w bajtach
- * \param crc32 Suma kontrola obrazka
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup messages
- */
-int gg_image_request(struct gg_session *sess, uin_t recipient, int size, uint32_t crc32)
-{
-	struct gg_send_msg s;
-	struct gg_msg_image_request r;
-	char dummy = 0;
-	int res;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_request(%p, %d, "
-		"%u, 0x%.4x);\n", sess, recipient, size, crc32);
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	if (size < 0) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	s.recipient = gg_fix32(recipient);
-	s.seq = gg_fix32(0);
-	s.msgclass = gg_fix32(GG_CLASS_MSG);
-
-	r.flag = GG_MSG_OPTION_IMAGE_REQUEST;
-	r.size = gg_fix32(size);
-	r.crc32 = gg_fix32(crc32);
-
-	res = gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), &dummy, 1, &r, sizeof(r), NULL);
-
-	if (!res) {
-		struct gg_image_queue *q = malloc(sizeof(*q));
-		char *buf;
-
-		if (!q) {
-			gg_debug_session(sess, GG_DEBUG_MISC,
-				"// gg_image_request() not enough memory for "
-				"image queue\n");
-			return -1;
-		}
-
-		buf = malloc(size);
-		if (size && !buf) {
-			gg_debug_session(sess, GG_DEBUG_MISC, "// gg_image_request() not enough memory for image\n");
-			free(q);
-			return -1;
-		}
-
-		memset(q, 0, sizeof(*q));
-
-		q->sender = recipient;
-		q->size = size;
-		q->crc32 = crc32;
-		q->image = buf;
-
-		if (!sess->images)
-			sess->images = q;
-		else {
-			struct gg_image_queue *qq;
-
-			for (qq = sess->images; qq->next; qq = qq->next);
-
-			qq->next = q;
-		}
-	}
-
-	return res;
-}
-
-/**
- * Wysyła żądany obrazek.
- *
- * \param sess Struktura sesji
- * \param recipient Numer adresata
- * \param filename Nazwa pliku
- * \param image Bufor z obrazkiem
- * \param size Rozmiar obrazka
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup messages
- */
-int gg_image_reply(struct gg_session *sess, uin_t recipient, const char *filename, const char *image, int size)
-{
-	struct gg_session_private *p;
-	struct gg_msg_image_reply *r;
-	struct gg_send_msg s;
-	const char *tmp;
-	char buf[1910];
-	gg_imgout_queue_t *queue = NULL, *queue_end = NULL;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_reply(%p, %d, "
-		"\"%s\", %p, %d);\n", sess, recipient, filename, image, size);
-
-	if (!sess || !filename || !image) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	p = sess->private_data;
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	if (size < 0) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	/* wytnij ścieżki, zostaw tylko nazwę pliku */
-	while ((tmp = strrchr(filename, '/')) || (tmp = strrchr(filename, '\\')))
-		filename = tmp + 1;
-
-	if (strlen(filename) < 1 || strlen(filename) > 1024) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	s.recipient = gg_fix32(recipient);
-	s.seq = gg_fix32(0);
-	s.msgclass = gg_fix32(GG_CLASS_MSG);
-
-	buf[0] = 0;
-	r = (void*) &buf[1];
-
-	r->flag = GG_MSG_OPTION_IMAGE_REPLY;
-	r->size = gg_fix32(size);
-	r->crc32 = gg_fix32(gg_crc32(0, (const unsigned char*) image, size));
-
-	while (size > 0) {
-		gg_imgout_queue_t *it;
-		size_t buflen, chunklen;
-
-		/* \0 + struct gg_msg_image_reply */
-		buflen = sizeof(struct gg_msg_image_reply) + 1;
-
-		/* w pierwszym kawałku jest nazwa pliku */
-		if (r->flag == GG_MSG_OPTION_IMAGE_REPLY) {
-			strcpy(buf + buflen, filename);
-			buflen += strlen(filename) + 1;
-		}
-
-		chunklen = ((size_t) size >= sizeof(buf) - buflen) ? (sizeof(buf) - buflen) : (size_t) size;
-
-		memcpy(buf + buflen, image, chunklen);
-		size -= chunklen;
-		image += chunklen;
-
-		it = gg_new0(sizeof(gg_imgout_queue_t));
-		if (!it)
-			break;
-		if (queue_end) {
-			queue_end->next = it;
-			queue_end = it;
-		} else {
-			queue = queue_end = it;
-		}
-
-		memcpy(&it->msg_hdr, &s, sizeof(s));
-		memcpy(it->buf, buf, buflen + chunklen);
-		it->buf_len = buflen + chunklen;
-
-		r->flag = GG_MSG_OPTION_IMAGE_REPLY_MORE;
-	}
-
-	if (p->imgout_queue) {
-		queue_end = p->imgout_queue;
-		while (queue_end->next)
-			queue_end = queue_end->next;
-		queue_end->next = queue;
-	} else {
-		p->imgout_queue = queue;
-	}
-	gg_image_sendout(sess);
-
-	return 0;
-}
-
-void gg_image_sendout(struct gg_session *sess)
-{
-	struct gg_session_private *p = sess->private_data;
-
-	while (p->imgout_waiting_ack < GG_IMGOUT_WAITING_MAX && p->imgout_queue) {
-		gg_imgout_queue_t *it = p->imgout_queue;
-		int res;
-
-		p->imgout_queue = p->imgout_queue->next;
-		p->imgout_waiting_ack++;
-
-		res = gg_send_packet(sess, GG_SEND_MSG,
-			&it->msg_hdr, sizeof(it->msg_hdr),
-			it->buf, it->buf_len,
-			NULL);
-
-		free(it);
-
-		if (res == -1)
-			break;
-	}
-}
-
-static int gg_notify105_ex(struct gg_session *sess, uin_t *userlist, char *types, int count)
-{
-	int i = 0;
-
-	if (!userlist || !count)
-		return gg_send_packet(sess, GG_NOTIFY105_LIST_EMPTY, NULL);
-
-	while (i < count) {
-		gg_tvbuilder_t *tvb = gg_tvbuilder_new(sess, NULL);
-		gg_tvbuilder_expected_size(tvb, 2100);
-
-		while (i < count) {
-			size_t prev_size = gg_tvbuilder_get_size(tvb);
-			gg_tvbuilder_write_uin(tvb, userlist[i]);
-			gg_tvbuilder_write_uint8(tvb,
-				(types == NULL) ? GG_USER_NORMAL : types[i]);
-
-			/* Oryginalny klient wysyła maksymalnie 2048 bajtów
-			 * danych w każdym pakiecie tego typu.
-			 */
-			if (gg_tvbuilder_get_size(tvb) > 2048) {
-				gg_tvbuilder_strip(tvb, prev_size);
-				break;
-			}
-			i++;
-		}
-
-		if (!gg_tvbuilder_send(tvb, (i < count) ?
-			GG_NOTIFY105_FIRST : GG_NOTIFY105_LAST))
-		{
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-/**
- * Wysyła do serwera listę kontaktów.
- *
- * Funkcja informuje serwer o liście kontaktów, których statusy będą
- * obserwowane lub kontaktów, które bedą blokowane. Dla każdego z \c count
- * kontaktów tablica \c userlist zawiera numer, a tablica \c types rodzaj
- * kontaktu (\c GG_USER_NORMAL, \c GG_USER_OFFLINE, \c GG_USER_BLOCKED).
- *
- * Listę kontaktów należy \b zawsze wysyłać po połączeniu, nawet jeśli
- * jest pusta.
- *
- * \param sess Struktura sesji
- * \param userlist Wskaźnik do tablicy numerów kontaktów
- * \param types    Wskaźnik do tablicy rodzajów kontaktów. Jeżeli NULL, wszystkie kontakty są typu GG_USER_NORMAL.
- * \param count Liczba kontaktów
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup contacts
- */
-int gg_notify_ex(struct gg_session *sess, uin_t *userlist, char *types, int count)
-{
-	struct gg_notify *n;
-	int i, res = 0;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_notify_ex(%p, %p, %p, %d);\n", sess, userlist, types, count);
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	if (sess->protocol_version >= GG_PROTOCOL_VERSION_110)
-		return gg_notify105_ex(sess, userlist, types, count);
-
-	if (!userlist || !count)
-		return gg_send_packet(sess, GG_LIST_EMPTY, NULL);
-
-	while (count > 0) {
-		int part_count, packet_type;
-
-		if (count > 400) {
-			part_count = 400;
-			packet_type = GG_NOTIFY_FIRST;
-		} else {
-			part_count = count;
-			packet_type = GG_NOTIFY_LAST;
-		}
-
-		if (!(n = (struct gg_notify*) malloc(sizeof(*n) * part_count)))
-			return -1;
-
-		for (i = 0; i < part_count; i++) {
-			n[i].uin = gg_fix32(userlist[i]);
-			if (types == NULL)
-				n[i].dunno1 = GG_USER_NORMAL;
-			else
-				n[i].dunno1 = types[i];
-		}
-
-		if (gg_send_packet(sess, packet_type, n, sizeof(*n) * part_count, NULL) == -1) {
-			free(n);
-			res = -1;
-			break;
-		}
-
-		count -= part_count;
-		userlist += part_count;
-		if (types != NULL)
-			types += part_count;
-
-		free(n);
-	}
-
-	return res;
-}
-
-/**
- * Wysyła do serwera listę kontaktów.
- *
- * Funkcja jest odpowiednikiem \c gg_notify_ex(), gdzie wszystkie kontakty
- * są rodzaju \c GG_USER_NORMAL.
- *
- * \param sess Struktura sesji
- * \param userlist Wskaźnik do tablicy numerów kontaktów
- * \param count Liczba kontaktów
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup contacts
- */
-int gg_notify(struct gg_session *sess, uin_t *userlist, int count)
-{
-	return gg_notify_ex(sess, userlist, NULL, count);
-}
-
-/**
- * Dodaje kontakt.
- *
- * Dodaje do listy kontaktów dany numer w trakcie połączenia. Aby zmienić
- * rodzaj kontaktu (np. z normalnego na zablokowany), należy najpierw usunąć
- * poprzedni rodzaj, ponieważ serwer operuje na maskach bitowych.
- *
- * \param sess Struktura sesji
- * \param uin Numer kontaktu
- * \param type Rodzaj kontaktu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup contacts
- */
-int gg_add_notify_ex(struct gg_session *sess, uin_t uin, char type)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_add_notify_ex(%p, %u, %d);\n", sess, uin, type);
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	if (sess->protocol_version >= GG_PROTOCOL_VERSION_110) {
-		gg_tvbuilder_t *tvb = gg_tvbuilder_new(sess, NULL);
-		gg_tvbuilder_expected_size(tvb, 16);
-
-		gg_tvbuilder_write_uin(tvb, uin);
-		gg_tvbuilder_write_uint8(tvb, type);
-
-		if (!gg_tvbuilder_send(tvb, GG_ADD_NOTIFY105))
-			return -1;
-		return 0;
-	} else {
-		struct gg_add_remove a;
-
-		a.uin = gg_fix32(uin);
-		a.dunno1 = type;
-
-		return gg_send_packet(sess, GG_ADD_NOTIFY, &a, sizeof(a), NULL);
-	}
-}
-
-/**
- * Dodaje kontakt.
- *
- * Funkcja jest odpowiednikiem \c gg_add_notify_ex(), gdzie rodzaj wszystkich
- * kontaktów to \c GG_USER_NORMAL.
- *
- * \param sess Struktura sesji
- * \param uin Numer kontaktu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup contacts
- */
-int gg_add_notify(struct gg_session *sess, uin_t uin)
-{
-	return gg_add_notify_ex(sess, uin, GG_USER_NORMAL);
-}
-
-/**
- * Usuwa kontakt.
- *
- * Usuwa z listy kontaktów dany numer w trakcie połączenia.
- *
- * \param sess Struktura sesji
- * \param uin Numer kontaktu
- * \param type Rodzaj kontaktu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup contacts
- */
-int gg_remove_notify_ex(struct gg_session *sess, uin_t uin, char type)
-{
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_remove_notify_ex(%p, %u, %d);\n", sess, uin, type);
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	if (sess->protocol_version >= GG_PROTOCOL_VERSION_110) {
-		gg_tvbuilder_t *tvb = gg_tvbuilder_new(sess, NULL);
-		gg_tvbuilder_expected_size(tvb, 16);
-
-		gg_tvbuilder_write_uin(tvb, uin);
-		gg_tvbuilder_write_uint8(tvb, type);
-
-		if (!gg_tvbuilder_send(tvb, GG_REMOVE_NOTIFY105))
-			return -1;
-		return 0;
-	} else {
-		struct gg_add_remove a;
-
-		a.uin = gg_fix32(uin);
-		a.dunno1 = type;
-
-		return gg_send_packet(sess, GG_REMOVE_NOTIFY, &a, sizeof(a), NULL);
-	}
-}
-
-/**
- * Usuwa kontakt.
- *
- * Funkcja jest odpowiednikiem \c gg_add_notify_ex(), gdzie rodzaj wszystkich
- * kontaktów to \c GG_USER_NORMAL.
- *
- * \param sess Struktura sesji
- * \param uin Numer kontaktu
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup contacts
- */
-int gg_remove_notify(struct gg_session *sess, uin_t uin)
-{
-	return gg_remove_notify_ex(sess, uin, GG_USER_NORMAL);
-}
-
-/**
- * Wysyła do serwera zapytanie dotyczące listy kontaktów.
- *
- * Funkcja służy do importu lub eksportu listy kontaktów do serwera.
- * W odróżnieniu od funkcji \c gg_notify(), ta lista kontaktów jest przez
- * serwer jedynie przechowywana i nie ma wpływu na połączenie. Format
- * listy kontaktów jest ignorowany przez serwer, ale ze względu na
- * kompatybilność z innymi klientami, należy przechowywać dane w tym samym
- * formacie co oryginalny klient Gadu-Gadu.
- *
- * Program nie musi się przejmować fragmentacją listy kontaktów wynikającą
- * z protokołu -- wysyła i odbiera kompletną listę.
- *
- * \param sess Struktura sesji
- * \param type Rodzaj zapytania
- * \param request Treść zapytania (może być równe NULL)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup importexport
- */
-int gg_userlist_request(struct gg_session *sess, char type, const char *request)
-{
-	int len;
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	if (!request) {
-		sess->userlist_blocks = 1;
-		return gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), NULL);
-	}
-
-	len = strlen(request);
-
-	sess->userlist_blocks = 0;
-
-	while (len > 2047) {
-		sess->userlist_blocks++;
-
-		if (gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), request, 2047, NULL) == -1)
-			return -1;
-
-		if (type == GG_USERLIST_PUT)
-			type = GG_USERLIST_PUT_MORE;
-
-		request += 2047;
-		len -= 2047;
-	}
-
-	sess->userlist_blocks++;
-
-	return gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), request, len, NULL);
-}
-
-/**
- * Wysyła do serwera zapytanie dotyczące listy kontaktów (10.0).
- *
- * Funkcja służy do importu lub eksportu listy kontaktów do serwera.
- * W odróżnieniu od funkcji \c gg_notify(), ta lista kontaktów jest przez
- * serwer jedynie przechowywana i nie ma wpływu na połączenie. Format
- * listy kontaktów jest jednak weryfikowany przez serwer, który stara się
- * synchronizować listę kontaktów zapisaną w formatach GG 7.0 oraz GG 10.0.
- * Serwer przyjmuje listy kontaktów przysłane w formacie niezgodnym z podanym
- * jako \c format_type, ale nie zachowuje ich, a przesłanie takiej listy jest
- * równoznaczne z usunięciem listy kontaktów.
- *
- * Program nie musi się przejmować kompresją listy kontaktów zgodną
- * z protokołem -- wysyła i odbiera kompletną listę zapisaną czystym tekstem.
- *
- * \param sess Struktura sesji
- * \param type Rodzaj zapytania
- * \param version Numer ostatniej znanej programowi wersji listy kontaktów lub 0
- * \param format_type Typ formatu listy kontaktów
- * \param request Treść zapytania (może być równe NULL)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup importexport
- */
-int gg_userlist100_request(struct gg_session *sess, char type,
-	unsigned int version, char format_type, const char *request)
-{
-	struct gg_userlist100_request pkt;
-	unsigned char *zrequest;
-	size_t zrequest_len;
-	int ret;
-
-	if (!sess) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
-	pkt.type = type;
-	pkt.version = gg_fix32(version);
-	pkt.format_type = format_type;
-	pkt.unknown1 = 0x01;
-
-	if (request == NULL)
-		return gg_send_packet(sess, GG_USERLIST100_REQUEST, &pkt, sizeof(pkt), NULL);
-
-	zrequest = gg_deflate(request, &zrequest_len);
-
-	if (zrequest == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_userlist100_request() gg_deflate() failed\n");
-		return -1;
-	}
-
-	ret = gg_send_packet(sess, GG_USERLIST100_REQUEST, &pkt, sizeof(pkt), zrequest, zrequest_len, NULL);
-
-	free(zrequest);
-
-	return ret;
-}
-
-/**
- * Informuje rozmówcę o pisaniu wiadomości.
- *
- * \param sess Struktura sesji
- * \param recipient Numer adresata
- * \param length Długość wiadomości lub 0 jeśli jest pusta
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup messages
- */
-int gg_typing_notification(struct gg_session *sess, uin_t recipient, int length){
-	struct gg_typing_notification pkt;
-	uin_t uin;
-
-	pkt.length = gg_fix16(length);
-	uin = gg_fix32(recipient);
-	memcpy(&pkt.uin, &uin, sizeof(uin_t));
-
-	return gg_send_packet(sess, GG_TYPING_NOTIFICATION, &pkt, sizeof(pkt), NULL);
-}
-
-/**
- * Rozłącza inną sesję multilogowania.
- *
- * \param gs Struktura sesji
- * \param conn_id Sesja do rozłączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup login
- */
-int gg_multilogon_disconnect(struct gg_session *gs, gg_multilogon_id_t conn_id)
-{
-	struct gg_multilogon_disconnect pkt;
-
-	pkt.conn_id = conn_id;
-
-	return gg_send_packet(gs, GG_MULTILOGON_DISCONNECT, &pkt, sizeof(pkt), NULL);
-}
-
-/**
- * Tworzy nową konferencję (11.0).
- *
- * \param gs Struktura sesji
- *
- * \return Numer sekwencyjny (ten sam, co w \c gg_event_chat_created), lub -1
- *         w przypadku błędu
- *
- * \ingroup chat
- */
-int gg_chat_create(struct gg_session *gs)
-{
-	struct gg_chat_create pkt;
-	int seq;
-
-	if (!gg_required_proto(gs, GG_PROTOCOL_VERSION_110))
-		return -1;
-
-	seq = ++gs->seq;
-
-	pkt.seq = gg_fix32(seq);
-	pkt.dummy = 0;
-
-	if (gg_send_packet(gs, GG_CHAT_CREATE, &pkt, sizeof(pkt), NULL) == -1)
-		return -1;
-
-	return seq;
-}
-
-/**
- * Zaprasza nowych użytkowników do konferencji (11.0).
- *
- * \param gs                 Struktura sesji
- * \param id                 Identyfikator konferencji
- * \param participants       Lista użytkowników do zaproszenia
- * \param participants_count Liczba użytkowników
- *
- * \return Numer sekwencyjny w przypadku powodzenia (ten sam, co w
- *         \c gg_event_chat_invite_ack), lub -1 w przypadku błędu
- *
- * \ingroup chat
- */
-int gg_chat_invite(struct gg_session *gs, uint64_t id, uin_t *participants,
-	unsigned int participants_count)
-{
-	struct gg_chat_invite pkt;
-	int seq, ret;
-	unsigned int i;
-	struct gg_chat_participant
-	{
-		uint32_t uin;
-		uint32_t dummy;
-	} GG_PACKED;
-	struct gg_chat_participant *participants_list;
-	size_t participants_list_size;
-
-	if (!gg_required_proto(gs, GG_PROTOCOL_VERSION_110))
-		return -1;
-
-	if (participants_count == 0 || participants_count >=
-		~(unsigned int)0 / sizeof(struct gg_chat_participant))
-	{
-		return -1;
-	}
-
-	participants_list_size = sizeof(struct gg_chat_participant) *
-		participants_count;
-	participants_list = malloc(participants_list_size);
-	if (participants_list == NULL)
-		return -1;
-
-	seq = ++gs->seq;
-	pkt.id = gg_fix64(id);
-	pkt.seq = gg_fix32(seq);
-	pkt.participants_count = gg_fix32(participants_count);
-
-	for (i = 0; i < participants_count; i++) {
-		participants_list[i].uin = gg_fix32(participants[i]);
-		participants_list[i].dummy = gg_fix32(0x1e);
-	}
-
-	ret = gg_send_packet(gs, GG_CHAT_INVITE,
-		&pkt, sizeof(pkt),
-		participants_list, participants_list_size,
-		NULL);
-	free(participants_list);
-
-	if (ret == -1)
-		return -1;
-	return seq;
-}
-
-/**
- * Opuszcza konferencję (11.0).
- *
- * \param gs Struktura sesji
- * \param id Identyfikator konferencji
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup chat
- */
-int gg_chat_leave(struct gg_session *gs, uint64_t id)
-{
-	struct gg_chat_leave pkt;
-	int seq;
-
-	if (!gg_required_proto(gs, GG_PROTOCOL_VERSION_110))
-		return -1;
-
-	seq = ++gs->seq;
-	pkt.id = gg_fix64(id);
-	pkt.seq = gg_fix32(seq);
-
-	if (gg_send_packet(gs, GG_CHAT_LEAVE, &pkt, sizeof(pkt), NULL) == -1)
-		return -1;
-
-	return seq;
-}
-
-/**
- * Wysyła wiadomość w ramach konferencji (11.0).
- *
- * \param gs      Struktura sesji
- * \param id      Identyfikator konferencji
- * \param message Wiadomość
- * \param is_html 1, jeżeli wiadomość jest zapisana jako HTML, 0 w p.p.
- *
- * \return Numer sekwencyjny (taki sam, jak w \c gg_event_chat_send_msg_ack)
- *         jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup chat
- */
-int gg_chat_send_message(struct gg_session *gs, uint64_t id, const char *message, int is_html)
-{
-	if (!gg_required_proto(gs, GG_PROTOCOL_VERSION_110))
-		return -1;
-
-	return gg_send_message_110(gs, 0, id, message, is_html);
-}
-
-/* @} */
-
-/**
- * Sprawdza czy biblioteka obsługuje daną funkcję.
- *
- * \param feature Identyfikator funkcji.
- *
- * \return Wartość niezerowa jeśli funkcja jest obsłgiwana.
- *
- * \ingroup version
- */
-int gg_libgadu_check_feature(gg_libgadu_feature_t feature)
-{
-	switch (feature)
-	{
-	case GG_LIBGADU_FEATURE_SSL:
-#if defined(GG_CONFIG_HAVE_OPENSSL) || defined(GG_CONFIG_HAVE_GNUTLS)
-		return 1;
-#else
-		return 0;
-#endif
-
-	case GG_LIBGADU_FEATURE_PTHREAD:
-#ifdef GG_CONFIG_HAVE_PTHREAD
-		return 1;
-#else
-		return 0;
-#endif
-
-	case GG_LIBGADU_FEATURE_USERLIST100:
-#ifdef GG_CONFIG_HAVE_ZLIB
-		return 1;
-#else
-		return 0;
-#endif
-
-	/* Celowo nie ma default, żeby kompilator wyłapał brakujące funkcje */
-
-	}
-
-	return 0;
-}
-
-static void gg_socket_manager_error(struct gg_session *sess, enum gg_failure_t failure)
-{
-	int pipes[2];
-	uint8_t dummy = 0;
-	struct gg_session_private *p = sess->private_data;
-
-	p->socket_failure = failure;
-
-	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pipes) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_socket_manager_error() unable to"
-			" create pipes (errno=%d, %s)\n", errno,
-			strerror(errno));
-		return;
-	}
-
-	p->socket_is_external = 0;
-	sess->fd = pipes[1];
-	sess->check = GG_CHECK_READ;
-	sess->state = GG_STATE_ERROR;
-	if (send(pipes[0], &dummy, sizeof(dummy), 0) != sizeof(dummy)) {
-		gg_debug(GG_DEBUG_MISC, "// gg_socket_manager_error() unable to"
-			" send via pipe (errno=%d, %s)\n", errno,
-			strerror(errno));
-		return;
-	}
-	close(pipes[0]);
-}
-
-int gg_compat_feature_is_enabled(struct gg_session *sess, gg_compat_feature_t feature)
-{
-	gg_compat_t level;
-
-	if (sess == NULL)
-		return 0;
-
-	level = sess->private_data->compatibility;
-
-	switch (feature) {
-		case GG_COMPAT_FEATURE_ACK_EVENT:
-		case GG_COMPAT_FEATURE_LEGACY_CONFER:
-			return (level < GG_COMPAT_1_12_0);
-	}
-
-	return 0;
-}
-
-static gg_msg_list_t * gg_compat_find_sent_message(struct gg_session *sess, int seq, int remove)
-{
-	struct gg_session_private *p = sess->private_data;
-	gg_msg_list_t *it, *previous = NULL;
-
-	for (it = p->sent_messages; it; it = it->next) {
-		if (it->seq == seq)
-			break;
-		else
-			previous = it;
-	}
-
-	if (remove && it) {
-		if (previous == NULL)
-			p->sent_messages = it->next;
-		else
-			previous->next = it->next;
-	}
-
-	return it;
-}
-
-static void gg_compat_message_cleanup(struct gg_session *sess)
-{
-	struct gg_session_private *p = sess->private_data;
-
-	while (p->sent_messages) {
-		gg_msg_list_t *next = p->sent_messages->next;
-		free(p->sent_messages->recipients);
-		free(p->sent_messages);
-		p->sent_messages = next;
-	}
-}
-
-static void gg_compat_message_sent(struct gg_session *sess, int seq, size_t recipients_count, uin_t *recipients)
-{
-	struct gg_session_private *p = sess->private_data;
-	gg_msg_list_t *sm;
-	uin_t *new_recipients;
-	size_t old_count, i;
-
-	if (sess->protocol_version < GG_PROTOCOL_VERSION_110)
-		return;
-
-	if (!gg_compat_feature_is_enabled(sess, GG_COMPAT_FEATURE_ACK_EVENT))
-		return;
-
-	sm = gg_compat_find_sent_message(sess, seq, 0);
-	if (!sm) {
-		sm = gg_new0(sizeof(gg_msg_list_t));
-		if (!sm)
-			return;
-		sm->next = p->sent_messages;
-		p->sent_messages = sm;
-	}
-
-	sm->seq = seq;
-	old_count = sm->recipients_count;
-	sm->recipients_count += recipients_count;
-
-	new_recipients = realloc(sm->recipients, sizeof(uin_t) * sm->recipients_count);
-	if (new_recipients == NULL) {
-		gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"// gg_compat_message_sent() not enough memory\n");
-		return;
-	}
-	sm->recipients = new_recipients;
-
-	for (i = 0; i < recipients_count; i++)
-		sm->recipients[old_count + i] = recipients[i];
-}
-
-void gg_compat_message_ack(struct gg_session *sess, int seq)
-{
-	gg_msg_list_t *sm;
-	size_t i;
-
-	if (sess->protocol_version < GG_PROTOCOL_VERSION_110)
-		return;
-
-	if (!gg_compat_feature_is_enabled(sess, GG_COMPAT_FEATURE_ACK_EVENT))
-		return;
-
-	sm = gg_compat_find_sent_message(sess, seq, 1);
-	if (!sm)
-		return;
-
-	for (i = 0; i < sm->recipients_count; i++) {
-		struct gg_event *qev;
-
-		qev = gg_eventqueue_add(sess);
-
-		qev->type = GG_EVENT_ACK;
-		qev->event.ack.status = GG_ACK_DELIVERED;
-		qev->event.ack.recipient = sm->recipients[i];
-		qev->event.ack.seq = seq;
-	}
-
-	free(sm->recipients);
-	free(sm);
-}
-
-/**
- * Odbiera nowo utworzone gniazdo TCP/TLS.
- *
- * Po wywołaniu tej funkcji należy zacząć obserwować deskryptor sesji (nawet
- * w przypadku niepowodzenia).
- *
- * Jeżeli gniazdo nie zostanie obsłużone, należy je zniszczyć.
- *
- * \param handle Uchwyt gniazda
- * \param priv Dane prywatne biblioteki libgadu
- * \param fd Deskryptor nowo utworzonego gniazda, lub -1 w przypadku błędu
- *
- * \return Wartość różna od zera, jeżeli gniazdo zostało obsłużone, 0 w przeciwnym przypadku
- *
- * \ingroup socketmanager
- */
-int gg_socket_manager_connected(void *handle, void *priv, int fd)
-{
-	struct gg_session *sess = priv;
-	struct gg_session_private *p = sess->private_data;
-
-	if (p->socket_handle != handle) {
-		gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"// gg_socket_manager_connected() invalid handle\n");
-		return 0;
-	}
-
-	sess->fd = -1;
-
-	if (fd < 0) {
-		gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-			"// gg_socket_manager_connected() connection error\n");
-		p->socket_handle = NULL;
-		gg_socket_manager_error(sess, GG_FAILURE_CONNECTING);
-		return 0;
-	}
-
-	if (p->socket_next_state == GG_STATE_TLS_NEGOTIATION) {
-		if (gg_session_init_ssl(sess) == -1) {
-			gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
-				"// gg_socket_manager_connected() couldn't "
-				"initialize ssl\n");
-			p->socket_handle = NULL;
-			gg_socket_manager_error(sess, GG_FAILURE_TLS);
-			return 0;
-		}
-	}
-
-	p->socket_is_external = 1;
-	sess->fd = fd;
-	sess->timeout = GG_DEFAULT_TIMEOUT;
-	sess->state = p->socket_next_state;
-
-	gg_debug_session(sess, GG_DEBUG_MISC, "// next state=%s\n",
-		gg_debug_state(p->socket_next_state));
-
-	if (p->socket_next_state == GG_STATE_READING_KEY)
-		sess->check = GG_CHECK_READ;
-	else
-		sess->check = GG_CHECK_WRITE;
-
-	return 1;
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
--- a/libpurple/protocols/gg/lib/libgadu.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2639 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2009 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *                          Arkadiusz Miśkiewicz <arekm@pld-linux.org>
- *                          Tomasz Chiliński <chilek@chilan.com>
- *                          Piotr Wysocki <wysek@linux.bydg.org>
- *                          Dawid Jarosz <dawjar@poczta.onet.pl>
- *                          Jakub Zawadzki <darkjames@darkjames.ath.cx>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file libgadu.h
- *
- * \brief Główny plik nagłówkowy biblioteki
- */
-
-#ifndef LIBGADU_LIBGADU_H
-#define LIBGADU_LIBGADU_H
-
-#ifdef _WIN32
-#pragma pack(push, 1)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-/** \cond ignore */
-
-/* Defined if libgadu was compiled for bigendian machine. */
-#undef GG_CONFIG_BIGENDIAN
-
-/* Defined if this machine has gethostbyname_r(). */
-#undef GG_CONFIG_HAVE_GETHOSTBYNAME_R
-
-/* Defined if libgadu was compiled and linked with fork support. */
-#undef GG_CONFIG_HAVE_FORK
-
-/* Defined if libgadu was compiled and linked with pthread support. */
-#undef GG_CONFIG_HAVE_PTHREAD
-
-/* Defined if pthread resolver is the default one. */
-#undef GG_CONFIG_PTHREAD_DEFAULT
-
-/* Defined if this machine has C99-compiliant vsnprintf(). */
-#undef GG_CONFIG_HAVE_C99_VSNPRINTF
-
-/* Defined if this machine has va_copy(). */
-#undef GG_CONFIG_HAVE_VA_COPY
-
-/* Defined if this machine has __va_copy(). */
-#undef GG_CONFIG_HAVE___VA_COPY
-
-/* Defined if this machine supports long long. */
-#undef GG_CONFIG_HAVE_LONG_LONG
-
-/* Defined if libgadu was compiled and linked with GnuTLS support. */
-#undef GG_CONFIG_HAVE_GNUTLS
-
-/* Defined if libgadu was compiled and linked with OpenSSL support. */
-#undef GG_CONFIG_HAVE_OPENSSL
-
-/* Defined if libgadu was compiled and linked with zlib support. */
-#undef GG_CONFIG_HAVE_ZLIB
-
-/* Defined if uintX_t types are defined in <stdint.h>. */
-#undef GG_CONFIG_HAVE_STDINT_H
-
-/* Defined if uintX_t types are defined in <inttypes.h>. */
-#undef GG_CONFIG_HAVE_INTTYPES_H
-
-/* Defined if uintX_t types are defined in <sys/inttypes.h>. */
-#undef GG_CONFIG_HAVE_SYS_INTTYPES_H
-
-/* Defined if uintX_t types are defined in <sys/int_types.h>. */
-#undef GG_CONFIG_HAVE_SYS_INT_TYPES_H
-
-/* Defined if uintX_t types are defined in <sys/types.h>. */
-#undef GG_CONFIG_HAVE_SYS_TYPES_H
-
-/* Defined if this machine has uint64_t. */
-#undef GG_CONFIG_HAVE_UINT64_T
-
-/* Defined if libgadu is GPL compliant (was not linked with OpenSSL or any
-   other non-GPL compliant library support). */
-#undef GG_CONFIG_IS_GPL_COMPLIANT
-
-#include "config.h"
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-#include <openssl/ssl.h>
-#endif
-
-#ifdef GG_CONFIG_HAVE_STDINT_H
-#include <stdint.h>
-#else
-#  ifdef GG_CONFIG_HAVE_INTTYPES_H
-#  include <inttypes.h>
-#  else
-#    ifdef GG_CONFIG_HAVE_SYS_INTTYPES_H
-#    include <sys/inttypes.h>
-#    else
-#      ifdef GG_CONFIG_HAVE_SYS_INT_TYPES_H
-#      include <sys/int_types.h>
-#      else
-#        ifdef GG_CONFIG_HAVE_SYS_TYPES_H
-#        include <sys/types.h>
-#        else
-
-/* ISO C 9X: 7.18 Integer types <stdint.h> */
-
-typedef unsigned char   uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int   uint32_t;
-
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-
-#ifndef GG_CONFIG_HAVE_UINT64_T
-typedef unsigned long long uint64_t;
-#endif
-
-#ifdef _MSC_VER
-#include <BaseTsd.h>
-typedef SSIZE_T ssize_t;
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4))
-#  define GG_GNUC_PRINTF(format_idx, arg_idx) \
-     __attribute__((format (printf, (format_idx), (arg_idx))))
-#else
-#  define GG_GNUC_PRINTF(format_idx, arg_idx)
-#endif
-
-/** \endcond */
-
-/**
- * Numer Gadu-Gadu.
- */
-typedef uint32_t uin_t;
-
-/**
- * Identyfikator połączenia bezpośredniego Gadu-Gadu 7.x.
- */
-typedef struct {
-	uint8_t id[8];
-} gg_dcc7_id_t;
-
-/**
- * Identyfikator sesji multilogowania.
- */
-typedef struct {
-	uint8_t id[8];
-} gg_multilogon_id_t;
-
-/**
- * Makro deklarujące pola wspólne dla struktur sesji.
- */
-#define gg_common_head(x) \
-	int fd;			/**< Obserwowany deskryptor */ \
-	int check;		/**< Informacja o żądaniu odczytu/zapisu (patrz \ref gg_check_t) */ \
-	int state;		/**< Aktualny stan połączenia (patrz \ref gg_state_t) */ \
-	int error;		/**< Kod błędu dla \c GG_STATE_ERROR (patrz \ref gg_error_t) */ \
-	int type;		/**< Rodzaj sesji (patrz \ref gg_session_t) */ \
-	int id;			/**< Identyfikator sesji */ \
-	int timeout;		/**< Czas pozostały do zakończenia stanu */ \
-	int (*callback)(x*); 	/**< Funkcja zwrotna */ \
-	void (*destroy)(x*); 	/**< Funkcja zwalniania zasobów */
-
-/**
- * Struktura wspólna dla wszystkich sesji i połączeń. Pozwala na proste
- * rzutowanie niezależne od rodzaju połączenia.
- */
-struct gg_common {
-	gg_common_head(struct gg_common)
-};
-
-struct gg_image_queue;
-
-struct gg_dcc7;
-
-struct gg_dcc7_relay;
-
-struct gg_session_private;
-
-/**
- * Sposób rozwiązywania nazw serwerów.
- */
-typedef enum {
-	GG_RESOLVER_DEFAULT = 0,	/**< Domyślny sposób rozwiązywania nazw (jeden z poniższych) */
-	GG_RESOLVER_FORK,		/**< Rozwiązywanie nazw bazujące na procesach */
-	GG_RESOLVER_PTHREAD,		/**< Rozwiązywanie nazw bazujące na wątkach */
-	GG_RESOLVER_CUSTOM,		/**< Funkcje rozwiązywania nazw dostarczone przed aplikację */
-	GG_RESOLVER_WIN32,		/**< Rozwiązywanie nazw bazujące na wątkach Win32 */
-	GG_RESOLVER_INVALID = -1	/**< Nieprawidłowy sposób rozwiązywania nazw (wynik \c gg_session_get_resolver) */
-} gg_resolver_t;
-
-/**
- * Rodzaj kodowania znaków.
- */
-typedef enum {
-	GG_ENCODING_CP1250 = 0,		/**< Kodowanie CP1250 */
-	GG_ENCODING_UTF8,		/**< Kodowanie UTF-8 */
-	GG_ENCODING_INVALID = -1	/**< Nieprawidłowe kodowanie */
-} gg_encoding_t;
-
-/**
- * Stopień kompatybilności ze starymi wersjami API.
- */
-typedef enum {
-	GG_COMPAT_LEGACY = 0,	/**< Całkowita kompatybilność (nie wyłącza żadnych funkcji) */
-	GG_COMPAT_1_12_0 = 1	/**< Wyłącza: dostarczanie eventów GG_EVENT_ACK, stary format konferencji */
-} gg_compat_t;
-
-/**
- * Flaga połączenia szyfrowanego.
- *
- * \ingroup login
- */
-typedef enum {
-	GG_SSL_DISABLED = 0,	/**< Połączenie SSL wyłączone */
-	GG_SSL_ENABLED,		/**< Połączenie SSL włączone gdy dostępne. Błędny certyfikat serwera nie powoduje odrzucenia połączenia. */
-	GG_SSL_REQUIRED		/**< Połączenie SSL wymagane. Błędny certyfikat serwera powoduje odrzucenie połączenia. */
-} gg_ssl_t;
-
-/**
- * Sesja Gadu-Gadu.
- *
- * Tworzona przez funkcję \c gg_login(), zwalniana przez \c gg_free_session().
- *
- * \ingroup login
- */
-struct gg_session {
-	gg_common_head(struct gg_session)
-
-	int async;      	/**< Flaga połączenia asynchronicznego */
-	int pid;        	/**< Numer procesu rozwiązującego nazwę serwera */
-	int port;       	/**< Port serwera */
-	int seq;        	/**< Numer sekwencyjny ostatniej wiadomości */
-	int last_pong;  	/**< Czas otrzymania ostatniej ramki utrzymaniowej */
-	int last_event;		/**< Czas otrzymania ostatniego pakietu */
-
-	struct gg_event *event;	/**< Zdarzenie po wywołaniu \c callback */
-
-	uint32_t proxy_addr;	/**< Adres serwera pośredniczącego */
-	uint16_t proxy_port;	/**< Port serwera pośredniczącego */
-
-	uint32_t hub_addr;	/**< Adres huba po rozwiązaniu nazwy */
-	uint32_t server_addr;	/**< Adres serwera otrzymany od huba */
-
-	uint32_t client_addr;	/**< Adres gniazda dla połączeń bezpośrednich */
-	uint16_t client_port;	/**< Port gniazda dla połączeń bezpośrednich */
-
-	uint32_t external_addr;	/**< Publiczny adres dla połączeń bezpośrednich */
-	uint16_t external_port;	/**< Publiczny port dla połączeń bezpośrednich */
-
-	uin_t uin;		/**< Własny numer Gadu-Gadu */
-	char *password;		/**< Hasło (zwalniane po użyciu) */
-
-	int initial_status;	/**< Początkowy status */
-	int status;		/**< Aktualny status */
-
-	char *recv_buf;		/**< Bufor na odbierane pakiety. Wskaźnik zawsze maksymalnie wyrównany, tak jak w wyniku działania \c malloc(). */
-	int recv_done;		/**< Liczba wczytanych bajtów pakietu */
-	int recv_left;		/**< Liczba pozostałych do wczytania bajtów pakietu */
-
-	int protocol_version;	/**< Wersja protokołu (bez flag) */
-	char *client_version;	/**< Wersja klienta */
-	int last_sysmsg;	/**< Numer ostatniej wiadomości systemowej */
-
-	char *initial_descr;	/**< Początkowy opis statusu */
-
-	void *resolver;		/**< Dane prywatne procesu lub wątku rozwiązującego nazwę serwera */
-
-#ifndef DOXYGEN
-	char *header_buf;	/**< Bufor na początek nagłówka pakietu (nieaktualne) */
-	unsigned int header_done;	/**< Liczba wczytanych bajtów nagłówka pakietu (nieaktualne) */
-#endif
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-	SSL *ssl;		/**< Struktura TLS */
-	SSL_CTX *ssl_ctx;	/**< Kontekst sesji TLS */
-#else
-	void *ssl;		/**< Struktura TLS */
-	void *ssl_ctx;		/**< Kontekst sesji TLS */
-#endif
-
-	int image_size;		/**< Maksymalny rozmiar obsługiwanych obrazków w KiB */
-
-	char *userlist_reply;	/**< Bufor z odbieraną listą kontaktów */
-
-	int userlist_blocks;	/**< Liczba części listy kontaktów */
-
-	struct gg_image_queue *images;	/**< Lista wczytywanych obrazków */
-
-	int hash_type;		/**< Rodzaj funkcji skrótu hasła (\c GG_LOGIN_HASH_GG32 lub \c GG_LOGIN_HASH_SHA1) */
-
-	char *send_buf;		/**< Bufor z danymi do wysłania */
-	int send_left;		/**< Liczba bajtów do wysłania */
-
-	struct gg_dcc7 *dcc7_list;	/**< Lista połączeń bezpośrednich skojarzonych z sesją */
-	
-	int soft_timeout;	/**< Flaga mówiąca, że po przekroczeniu \c timeout należy wywołać \c gg_watch_fd() */
-
-	int protocol_flags;	/**< Flagi protokołu */
-
-	gg_encoding_t encoding;		/**< Rodzaj kodowania znaków */
-
-	gg_resolver_t resolver_type;	/**< Sposób rozwiązywania nazw serwerów */
-	int (*resolver_start)(int *fd, void **private_data, const char *hostname);	/**< Funkcja rozpoczynająca rozwiązywanie nazwy */
-	void (*resolver_cleanup)(void **private_data, int force);	/**< Funkcja zwalniająca zasoby po rozwiązaniu nazwy */
-
-	int protocol_features;	/**< Opcje protokołu */
-	int status_flags;	/**< Flagi statusu */
-	int recv_msg_count;	/**< Liczba odebranych wiadomości */
-
-	const char *resolver_host;		/**< Nazwa do rozwiązania */
-	struct in_addr *resolver_result;	/**< Wynik rozwiązywania nazwy */
-	unsigned int resolver_index;		/**< Indeks aktualnie obsługiwanego wyniku rozwiązywania nazwy */
-	unsigned int resolver_count;		/**< Liczba wyników rozwiązywania nazwy */
-
-	uint16_t connect_port[2];		/**< Lista portów do połączenia */
-	unsigned int connect_index;		/**< Indeks aktualnie obsługiwanego portu */
-
-	char *connect_host;			/**< Adres serwera Gadu-Gadu, z którym się łączymy */
-	gg_ssl_t ssl_flag;			/**< Flaga połączenia szyfrowanego */
-
-	struct gg_session_private *private_data;	/**< Prywatne dane sesji, nie udostępnione w API */
-};
-
-/**
- * Połączenie HTTP.
- *
- * Tworzone przez \c gg_http_connect(), zwalniane przez \c gg_http_free().
- *
- * \ingroup http
- */
-struct gg_http {
-	gg_common_head(struct gg_http)
-
-	int async;              /**< Flaga połączenia asynchronicznego */
-	int pid;                /**< Identyfikator procesu rozwiązującego nazwę serwera */
-	int port;               /**< Port */
-
-	char *query;            /**< Zapytanie HTTP */
-	char *header;           /**< Odebrany nagłówek */
-	int header_size;        /**< Rozmiar wczytanego nagłówka */
-	char *body;             /**< Odebrana strona */
-	unsigned int body_size; /**< Rozmiar strony */
-
-	void *data;             /**< Dane prywatne usługi HTTP */
-
-	char *user_data;	/**< Dane prywatne użytkownika (nie są zwalniane) */
-
-	void *resolver;		/**< Dane prywatne procesu lub wątku rozwiązującego nazwę */
-
-	unsigned int body_done;	/**< Liczba odebranych bajtów strony */
-
-	gg_resolver_t resolver_type;	/**< Sposób rozwiązywania nazw serwerów */
-	int (*resolver_start)(int *fd, void **private_data, const char *hostname);	/**< Funkcja rozpoczynająca rozwiązywanie nazwy */
-	void (*resolver_cleanup)(void **private_data, int force);	/**< Funkcja zwalniająca zasoby po rozwiązaniu nazwy */
-};
-
-/** \cond ignore */
-
-#ifdef __GNUC__
-#define GG_PACKED __attribute__ ((packed))
-#ifndef GG_IGNORE_DEPRECATED
-#define GG_DEPRECATED __attribute__ ((deprecated))
-#else
-#define GG_DEPRECATED
-#endif
-#else
-#define GG_PACKED
-#define GG_DEPRECATED
-#endif
-
-/** \endcond */
-
-#define GG_MAX_PATH 276		/**< Maksymalny rozmiar nazwy pliku w strukturze \c gg_file_info */
-
-/**
- * Odpowiednik struktury WIN32_FIND_DATA z API WIN32.
- *
- * Wykorzystywana przy połączeniach bezpośrednich do wersji Gadu-Gadu 6.x.
- */
-struct gg_file_info {
-	uint32_t mode;			/**< dwFileAttributes */
-	uint32_t ctime[2];		/**< ftCreationTime */
-	uint32_t atime[2];		/**< ftLastAccessTime */
-	uint32_t mtime[2];		/**< ftLastWriteTime */
-	uint32_t size_hi;		/**< nFileSizeHigh */
-	uint32_t size;			/**< nFileSizeLow */
-	uint32_t reserved0;		/**< dwReserved0 */
-	uint32_t reserved1;		/**< dwReserved1 */
-	unsigned char filename[GG_MAX_PATH - 14];	/**< cFileName */
-	unsigned char short_filename[14];		/**< cAlternateFileName */
-} /** \cond ignore */ GG_PACKED /** \endcond */;
-
-/**
- * Połączenie bezpośrednie do wersji Gadu-Gadu 6.x.
- *
- * Tworzone przez \c gg_dcc_socket_create(), \c gg_dcc_get_file(),
- * \c gg_dcc_send_file() lub \c gg_dcc_voice_chat(), zwalniane przez
- * \c gg_dcc_free().
- *
- * \ingroup dcc6
- */
-struct gg_dcc {
-	gg_common_head(struct gg_dcc)
-
-	struct gg_event *event;	/**< Zdarzenie po wywołaniu \c callback */
-
-	int active;		/**< Flaga połączenia aktywnego (nieużywana) */
-	int port;		/**< Port gniazda nasłuchującego */
-	uin_t uin;		/**< Własny numer Gadu-Gadu */
-	uin_t peer_uin;		/**< Numer Gadu-Gadu drugiej strony połączenia */
-	int file_fd;		/**< deskryptor pliku */
-	unsigned int offset;	/**< Położenie w pliku */
-	unsigned int chunk_size;
-				/**< Rozmiar kawałka pliku */
-	unsigned int chunk_offset;
-				/**< Położenie w aktualnym kawałku pliku */
-	struct gg_file_info file_info;
-				/**< Informacje o pliku */
-	int established;	/**< Flaga ustanowienia połączenia */
-	char *voice_buf;	/**< Bufor na pakiet połączenia głosowego */
-	int incoming;		/**< Flaga połączenia przychodzącego */
-	char *chunk_buf;	/**< Bufor na fragment danych */
-	uint32_t remote_addr;	/**< Adres drugiej strony */
-	uint16_t remote_port;	/**< Port drugiej strony */
-};
-
-#define GG_DCC7_HASH_LEN	20	/**< Maksymalny rozmiar skrótu pliku w połączeniach bezpośrenich */
-#define GG_DCC7_FILENAME_LEN	255	/**< Maksymalny rozmiar nazwy pliku w połączeniach bezpośrednich */
-#define GG_DCC7_INFO_LEN	32	/**< Maksymalny rozmiar informacji o połączeniach bezpośrednich */
-#define GG_DCC7_INFO_HASH_LEN	32	/**< Maksymalny rozmiar skrótu ip informacji o połączeniach bezpośrednich */
-
-/**
- * Połączenie bezpośrednie od wersji Gadu-Gadu 7.x.
- *
- * \ingroup dcc7
- */
-struct gg_dcc7 {
-	gg_common_head(struct gg_dcc7)
-
-	gg_dcc7_id_t cid;	/**< Identyfikator połączenia */
-
-	struct gg_event *event;	/**< Struktura zdarzenia */
-
-	uin_t uin;		/**< Własny numer Gadu-Gadu */
-	uin_t peer_uin;		/**< Numer Gadu-Gadu drugiej strony połączenia */
-
-	int file_fd;		/**< Deskryptor przesyłanego pliku */
-	unsigned int offset;	/**< Aktualne położenie w przesyłanym pliku */
-	unsigned int size;	/**< Rozmiar przesyłanego pliku */
-	unsigned char filename[GG_DCC7_FILENAME_LEN + 1];
-				/**< Nazwa przesyłanego pliku */
-	unsigned char hash[GG_DCC7_HASH_LEN];
-				/**< Skrót SHA1 przesyłanego pliku */
-
-	int dcc_type;		/**< Rodzaj połączenia bezpośredniego */
-	int established;	/**< Flaga ustanowienia połączenia */
-	int incoming;		/**< Flaga połączenia przychodzącego */
-	int reverse;		/**< Flaga połączenia zwrotnego */
-
-	uint32_t local_addr;	/**< Adres lokalny */
-	uint16_t local_port;	/**< Port lokalny */
-
-	uint32_t remote_addr;	/**< Adres drugiej strony */
-	uint16_t remote_port;	/**< Port drugiej strony */
-
-	struct gg_session *sess;
-				/**< Sesja do której przypisano połączenie */
-	struct gg_dcc7 *next;	/**< Następne połączenie w liście */
-
-	int soft_timeout;	/**< Flaga mówiąca, że po przekroczeniu \c timeout należy wywołać \c gg_dcc7_watch_fd() */
-	int seek;		/**< Flaga mówiąca, że można zmieniać położenie w wysyłanym pliku */
-
-	void *resolver;		/**< Dane prywatne procesu lub wątku rozwiązującego nazwę serwera */
-
-	int relay;		/**< Flaga mówiąca, że laczymy sie przez serwer */
-	int relay_index;	/**< Numer serwera pośredniczącego, do którego się łączymy */
-	int relay_count;	/**< Rozmiar listy serwerów pośredniczących */
-	struct gg_dcc7_relay *relay_list;	/**< Lista serwerów pośredniczących */
-};
-
-/**
- * Rodzaj sesji.
- */
-enum gg_session_t {
-	GG_SESSION_GG = 1,	/**< Połączenie z serwerem Gadu-Gadu */
-	GG_SESSION_HTTP,	/**< Połączenie HTTP */
-	GG_SESSION_SEARCH,	/**< Wyszukiwanie w katalogu publicznym (nieaktualne) */
-	GG_SESSION_REGISTER,	/**< Rejestracja nowego konta */
-	GG_SESSION_REMIND,	/**< Przypominanie hasła */
-	GG_SESSION_PASSWD,	/**< Zmiana hasła */
-	GG_SESSION_CHANGE,	/**< Zmiana informacji w katalogu publicznym (nieaktualne) */
-	GG_SESSION_DCC,		/**< Połączenie bezpośrednie (do wersji 6.x) */
-	GG_SESSION_DCC_SOCKET,	/**< Gniazdo nasłuchujące (do wersji 6.x) */
-	GG_SESSION_DCC_SEND,	/**< Wysyłanie pliku (do wersji 6.x) */
-	GG_SESSION_DCC_GET,	/**< Odbieranie pliku (do wersji 6.x) */
-	GG_SESSION_DCC_VOICE,	/**< Rozmowa głosowa (do wersji 6.x) */
-	GG_SESSION_USERLIST_GET,	/**< Import listy kontaktów z serwera (nieaktualne) */
-	GG_SESSION_USERLIST_PUT,	/**< Eksport listy kontaktów do serwera (nieaktualne) */
-	GG_SESSION_UNREGISTER,	/**< Usuwanie konta */
-	GG_SESSION_USERLIST_REMOVE,	/**< Usuwanie listy kontaktów z serwera (nieaktualne) */
-	GG_SESSION_TOKEN,	/**< Pobieranie tokenu */
-	GG_SESSION_DCC7_SOCKET,	/**< Gniazdo nasłuchujące (od wersji 7.x) */
-	GG_SESSION_DCC7_SEND,	/**< Wysyłanie pliku (od wersji 7.x) */
-	GG_SESSION_DCC7_GET,	/**< Odbieranie pliku (od wersji 7.x) */
-	GG_SESSION_DCC7_VOICE,	/**< Rozmowa głosowa (od wersji 7.x) */
-
-	GG_SESSION_USER0 = 256,	/**< Rodzaj zadeklarowany dla użytkownika */
-	GG_SESSION_USER1,	/**< Rodzaj zadeklarowany dla użytkownika */
-	GG_SESSION_USER2,	/**< Rodzaj zadeklarowany dla użytkownika */
-	GG_SESSION_USER3,	/**< Rodzaj zadeklarowany dla użytkownika */
-	GG_SESSION_USER4,	/**< Rodzaj zadeklarowany dla użytkownika */
-	GG_SESSION_USER5,	/**< Rodzaj zadeklarowany dla użytkownika */
-	GG_SESSION_USER6,	/**< Rodzaj zadeklarowany dla użytkownika */
-	GG_SESSION_USER7	/**< Rodzaj zadeklarowany dla użytkownika */
-};
-
-/**
- * Aktualny stan sesji.
- */
-enum gg_state_t {
-	/* wspólne */
-	GG_STATE_IDLE = 0,		/**< Nie dzieje się nic */
-	GG_STATE_RESOLVING,             /**< Oczekiwanie na rozwiązanie nazwy serwera */
-	GG_STATE_CONNECTING,            /**< Oczekiwanie na połączenie */
-	GG_STATE_READING_DATA,		/**< Oczekiwanie na dane */
-	GG_STATE_ERROR,			/**< Kod błędu w polu \c error */
-
-	/* gg_session */
-	GG_STATE_CONNECTING_HUB,	/**< Oczekiwanie na połączenie z hubem */
-	GG_STATE_CONNECTING_GG,         /**< Oczekiwanie na połączenie z serwerem */
-	GG_STATE_READING_KEY,           /**< Oczekiwanie na klucz */
-	GG_STATE_READING_REPLY,         /**< Oczekiwanie na odpowiedź serwera */
-	GG_STATE_CONNECTED,             /**< Połączono z serwerem */
-
-	/* gg_http */
-	GG_STATE_SENDING_QUERY,		/**< Wysłano zapytanie HTTP */
-	GG_STATE_READING_HEADER,	/**< Oczekiwanie na nagłówek HTTP */
-	GG_STATE_PARSING,               /**< Przetwarzanie danych */
-	GG_STATE_DONE,                  /**< Połączenie zakończone */
-
-	/* gg_dcc */
-	GG_STATE_LISTENING,		/* czeka na połączenia */
-	GG_STATE_READING_UIN_1,		/* czeka na uin peera */
-	GG_STATE_READING_UIN_2,		/* czeka na swój uin */
-	GG_STATE_SENDING_ACK,		/* wysyła potwierdzenie dcc */
-	GG_STATE_READING_ACK,		/* czeka na potwierdzenie dcc */
-	GG_STATE_READING_REQUEST,	/* czeka na komendę */
-	GG_STATE_SENDING_REQUEST,	/* wysyła komendę */
-	GG_STATE_SENDING_FILE_INFO,	/* wysyła informacje o pliku */
-	GG_STATE_READING_PRE_FILE_INFO,	/* czeka na pakiet przed file_info */
-	GG_STATE_READING_FILE_INFO,	/* czeka na informacje o pliku */
-	GG_STATE_SENDING_FILE_ACK,	/* wysyła potwierdzenie pliku */
-	GG_STATE_READING_FILE_ACK,	/* czeka na potwierdzenie pliku */
-	GG_STATE_SENDING_FILE_HEADER,	/* wysyła nagłówek pliku */
-	GG_STATE_READING_FILE_HEADER,	/* czeka na nagłówek */
-	GG_STATE_GETTING_FILE,		/* odbiera plik */
-	GG_STATE_SENDING_FILE,		/* wysyła plik */
-	GG_STATE_READING_VOICE_ACK,	/* czeka na potwierdzenie voip */
-	GG_STATE_READING_VOICE_HEADER,	/* czeka na rodzaj bloku voip */
-	GG_STATE_READING_VOICE_SIZE,	/* czeka na rozmiar bloku voip */
-	GG_STATE_READING_VOICE_DATA,	/* czeka na dane voip */
-	GG_STATE_SENDING_VOICE_ACK,	/* wysyła potwierdzenie voip */
-	GG_STATE_SENDING_VOICE_REQUEST,	/* wysyła żądanie voip */
-	GG_STATE_READING_TYPE,		/* czeka na typ połączenia */
-
-	/* nowe. bez sensu jest to API. */
-	GG_STATE_TLS_NEGOTIATION,	/**< Negocjacja połączenia szyfrowanego */
-
-	GG_STATE_REQUESTING_ID,		/**< Oczekiwanie na nadanie identyfikatora połączenia bezpośredniego */
-	GG_STATE_WAITING_FOR_ACCEPT,	/**< Oczekiwanie na potwierdzenie lub odrzucenie połączenia bezpośredniego */
-	GG_STATE_WAITING_FOR_INFO,	/**< Oczekiwanie na informacje o połączeniu bezpośrednim */
-
-	GG_STATE_READING_ID,		/**< Odebranie identyfikatora połączenia bezpośredniego */
-	GG_STATE_SENDING_ID,		/**< Wysłano identyfikator połączenia bezpośredniego */
-	GG_STATE_RESOLVING_GG,		/**< Oczekiwanie na rozwiązanie nazwy serwera Gadu-Gadu */
-
-	GG_STATE_RESOLVING_RELAY,	/**< Oczekiwanie na rozwiązanie nazwy serwera pośredniczącego */
-	GG_STATE_CONNECTING_RELAY,	/**< Oczekiwanie na połączenie z serwerem pośredniczącym */
-	GG_STATE_READING_RELAY,		/**< Odbieranie danych */
-
-	GG_STATE_DISCONNECTING,		/**< Oczekiwanie na potwierdzenie rozłączenia */
-
-	GG_STATE_CONNECT_HUB,		/**< Nawiązanie połączenia z hubem */
-	GG_STATE_CONNECT_PROXY_HUB,
-	GG_STATE_CONNECT_GG,		/**< Nawiązanie połączenia z serwerem */
-	GG_STATE_CONNECT_PROXY_GG,
-	GG_STATE_CONNECTING_PROXY_HUB,
-	GG_STATE_CONNECTING_PROXY_GG,
-	GG_STATE_RESOLVE_HUB_SYNC,
-	GG_STATE_RESOLVE_HUB_ASYNC,
-	GG_STATE_RESOLVE_PROXY_HUB_SYNC,
-	GG_STATE_RESOLVE_PROXY_HUB_ASYNC,
-	GG_STATE_RESOLVE_PROXY_GG_SYNC,
-	GG_STATE_RESOLVE_PROXY_GG_ASYNC,
-	GG_STATE_RESOLVE_GG_SYNC,
-	GG_STATE_RESOLVE_GG_ASYNC,
-	GG_STATE_RESOLVING_HUB,
-	GG_STATE_RESOLVING_PROXY_HUB,
-	GG_STATE_RESOLVING_PROXY_GG,
-	GG_STATE_SEND_HUB,
-	GG_STATE_SEND_PROXY_HUB,
-	GG_STATE_SEND_PROXY_GG,
-	GG_STATE_SENDING_HUB,
-	GG_STATE_SENDING_PROXY_HUB,
-	GG_STATE_SENDING_PROXY_GG,
-	GG_STATE_READING_HUB,
-	GG_STATE_READING_PROXY_HUB,
-	GG_STATE_READING_PROXY_GG,
-};
-
-/**
- * Informacja o tym, czy biblioteka chce zapisywać i/lub czytać
- * z deskryptora. Maska bitowa.
- *
- * \ingroup events
- */
-enum gg_check_t {
-	GG_CHECK_NONE = 0,		/**< Nie sprawdzaj niczego */
-	GG_CHECK_WRITE = 1,		/**< Sprawdź możliwość zapisu */
-	GG_CHECK_READ = 2		/**< Sprawdź możliwość odczytu */
-};
-
-/**
- * Metody nawiązywania połączeń TCP/TLS.
- *
- * \ingroup socketmanager
- */
-typedef enum {
-	GG_SOCKET_MANAGER_TYPE_INTERNAL = 0, /**< Wewnętrzna obsługa gniazd (domyślne). */
-	GG_SOCKET_MANAGER_TYPE_TCP, /**< Dostarczona przez aplikację - tylko obsługa TCP. */
-	GG_SOCKET_MANAGER_TYPE_TLS /**< Dostarczona przez aplikację - obsługa zarówno TCP, jak i TLS. */
-} gg_socket_manager_type_t;
-
-/**
- * Funkcja dostarczona przez aplikację, tworząca nowe gniazdo TCP/TLS.
- *
- * Po nawiązaniu połączenia aplikacja musi wywołać gg_socket_manager_connected.
- * Jeżeli połączenie jest asynchroniczne, wywołanie musi nastąpić po wyjściu z
- * kontekstu tej funkcji. Dla połączeń synchronicznych z kolei, musi nastąpić
- * jeszcze przed wyjściem z kontekstu.
- *
- * \param cb_data Dane prywatne aplikacji
- * \param host Nazwa hosta
- * \param port Numer portu
- * \param is_tls Flaga określająca, czy ma zostać nawiązane połączenie TLS
- * \param is_async Flaga określająca połączenie asynchroniczne (patrz szczegóły powyżej)
- * \param priv Dane prywatne biblioteki libgadu (do przekazania do gg_socket_manager_connected)
- *
- * \return Uchwyt gniazda
- *
- * \ingroup socketmanager
- */
-typedef void* (*gg_socket_manager_connect_cb_t)(void *cb_data, const char *host, int port, int is_tls, int is_async, void *priv);
-
-/**
- * Niszczy gniazdo i zwalnia wszystkie powiązane z nim zasoby.
- *
- * \param cb_data Dane prywatne aplikacji
- * \param handle Uchwyt gniazda
- *
- * \ingroup socketmanager
- */
-typedef void (*gg_socket_manager_close_cb_t)(void *cb_data, void *handle);
-
-/**
- * Odbiera z gniazda dane binarne.
- *
- * Funkcja powinna zajmować się obsługą TLS, jeżeli gniazdo jest w takim trybie.
- *
- * \param cb_data Dane prywatne aplikacji
- * \param handle Uchwyt gniazda
- * \param buffer Bufor do zapisu danych
- * \param bufsize Rozmiar bufora
- *
- * \return Ilość zapisanych danych, lub -1 (oraz ustawiony errno) w przypadku niepowodzenia
- *
- * \ingroup socketmanager
- */
-typedef ssize_t (*gg_socket_manager_read_cb_t)(void *cb_data, void *handle, unsigned char *buffer, size_t bufsize);
-
-/**
- * Wysyła przez gniazdo dane binarne.
- *
- * Funkcja powinna zajmować się obsługą TLS, jeżeli gniazdo jest w takim trybie.
- *
- * \param cb_data Dane prywatne aplikacji
- * \param handle Uchwyt gniazda
- * \param data Dane do wysłania
- * \param length Rozmiar danych
- *
- * \return Ilość wysłanych danych, lub -1 (oraz ustawiony errno) w przypadku niepowodzenia
- *
- * \ingroup socketmanager
- */
-typedef ssize_t (*gg_socket_manager_write_cb_t)(void *cb_data, void *handle, const unsigned char *data, size_t length);
-
-/**
- * Struktura opisująca funkcje zarządzające gniazdami, jeżeli aplikacja sama je
- * obsługuje.
- *
- * \ingroup socketmanager
- */
-typedef struct {
-	void *cb_data; /**< Dane prywatne aplikacji */
-	gg_socket_manager_connect_cb_t connect_cb; /**< Funkcja tworząca nowe gniazdo */
-	gg_socket_manager_close_cb_t close_cb; /**< Funkcja niszcząca gniazdo */
-	gg_socket_manager_read_cb_t read_cb; /**< Funkcja odczytująca dane z gniazda */
-	gg_socket_manager_write_cb_t write_cb; /**< Funkcja wysyłająca dane przez gniazdo */
-#ifndef DOXYGEN
-	void *reserved1;
-	void *reserved2;
-	void *reserved3;
-	void *reserved4;
-#endif
-} gg_socket_manager_t;
-
-int gg_socket_manager_connected(void *handle, void *priv, int fd);
-
-/**
- * Parametry połączenia z serwerem Gadu-Gadu. Parametry zostały przeniesione
- * do struktury, by uniknąć zmian API po rozszerzeniu protokołu i dodaniu
- * kolejnych opcji połączenia. Część parametrów, które nie są już aktualne
- * lub nie mają znaczenia, została usunięta z dokumentacji.
- *
- * \ingroup login
- */
-struct gg_login_params {
-	uin_t uin;			/**< Numer Gadu-Gadu */
-	char *password;			/**< Hasło */
-	int async;			/**< Flaga asynchronicznego połączenia (domyślnie nie) */
-	int status;			/**< Początkowy status użytkownika (domyślnie \c GG_STATUS_AVAIL) */
-	char *status_descr;		/**< Początkowy opis użytkownika (domyślnie brak) */
-	uint32_t server_addr;		/**< Adres serwera Gadu-Gadu (domyślnie pobierany automatycznie) */
-	uint16_t server_port;		/**< Port serwera Gadu-Gadu (domyślnie pobierany automatycznie) */
-	uint32_t client_addr;		/**< Adres połączeń bezpośrednich (domyślnie dobierany automatycznie) */
-	uint16_t client_port;		/**< Port połączeń bezpośrednich (domyślnie dobierany automatycznie) */
-	int protocol_version;		/**< Wersja protokołu wysyłana do serwera (domyślnie najnowsza obsługiwana) */
-	char *client_version;		/**< Wersja klienta wysyłana do serwera (domyślnie najnowsza znana) */
-	int has_audio;			/**< Flaga obsługi połączeń głosowych */
-	int last_sysmsg;		/**< Numer ostatnio odebranej wiadomości systemowej */
-	uint32_t external_addr;		/**< Adres publiczny dla połączeń bezpośrednich (domyślnie dobierany automatycznie) */
-	uint16_t external_port;		/**< Port publiczny dla połączeń bezpośrednich (domyślnie dobierany automatycznie) */
-	int tls;			/**< Flaga połączenia szyfrowanego (patrz \ref gg_ssl_t) */
-	int image_size;			/**< Maksymalny rozmiar obsługiwanych obrazków w kilobajtach */
-#ifndef DOXYGEN
-	int era_omnix;			/**< Flaga udawania klienta Era Omnix (nieaktualna) */
-#endif
-	int hash_type;			/**< Rodzaj skrótu hasła (\c GG_LOGIN_HASH_GG32 lub \c GG_LOGIN_HASH_SHA1, domyślnie SHA1) */
-	gg_encoding_t encoding;		/**< Rodzaj kodowania używanego w sesji (domyślnie CP1250) */
-	gg_resolver_t resolver;		/**< Sposób rozwiązywania nazw (patrz \ref build-resolver) */
-	int protocol_features;		/**< Opcje protokołu (flagi GG_FEATURE_*). */
-	int status_flags;		/**< Flagi statusu (flagi GG_STATUS_FLAG_*, patrz \ref status). */
-
-	unsigned int struct_size;	/**< Rozmiar struktury. To pole powinno być inicjowane wartością sizeof(struct gg_login_params) - w przeciwnym przypadku pola za nim nie będą obsługiwane. Pozwala na rozszerzanie struktury bez łamania ABI. */
-
-	gg_compat_t compatibility;	/**< Stopień kompatybilności ze starym API. */
-
-	char *connect_host;		/**< Nazwa hosta (oraz opcjonalnie port, podany po dwukropku) serwera Gadu-Gadu (domyślnie pobierany automatycznie) (patrz pole struct_size). */
-
-	gg_socket_manager_type_t socket_manager_type; /**< Wybrana metoda nawiązywania połączeń TCP/TLS (domyślnie wewnętrzna) */
-	gg_socket_manager_t socket_manager; /**< Jeżeli wybrano metodę zewnętrzną - konfiguracja jej */
-
-	char **host_white_list;		/**< Lista zakończona wskaźnikiem NULL, domen akceptowanych w odpowiedziach od huba (domyślnie wszystkie do tej pory znane). Używane tylko przy GG_SSL_REQUIRED. Pusta lista wyłącza sprawdzanie. */
-};
-
-#ifdef GG_CONFIG_IS_GPL_COMPLIANT
-int gg_is_gpl_compliant(void);
-#endif
-struct gg_session *gg_login(const struct gg_login_params *p);
-void gg_free_session(struct gg_session *sess);
-void gg_logoff(struct gg_session *sess);
-int gg_change_status(struct gg_session *sess, int status);
-int gg_change_status_descr(struct gg_session *sess, int status, const char *descr);
-int gg_change_status_descr_time(struct gg_session *sess, int status, const char *descr, int time);
-int gg_change_status_flags(struct gg_session *sess, int flags);
-int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message);
-int gg_send_message_richtext(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, const unsigned char *format, int formatlen);
-int gg_send_message_html(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *html_message);
-int gg_send_message_confer(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message);
-int gg_send_message_confer_richtext(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message, const unsigned char *format, int formatlen);
-int gg_send_message_confer_html(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *html_message);
-int gg_send_message_ctcp(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, int message_len);
-int gg_ping(struct gg_session *sess);
-int gg_userlist_request(struct gg_session *sess, char type, const char *request);
-int gg_userlist100_request(struct gg_session *sess, char type, unsigned int version, char format_type, const char *request);
-int gg_image_request(struct gg_session *sess, uin_t recipient, int size, uint32_t crc32);
-int gg_image_reply(struct gg_session *sess, uin_t recipient, const char *filename, const char *image, int size);
-int gg_typing_notification(struct gg_session *sess, uin_t recipient, int length);
-
-uint32_t gg_crc32(uint32_t crc, const unsigned char *buf, int len);
-
-int gg_session_set_resolver(struct gg_session *gs, gg_resolver_t type);
-gg_resolver_t gg_session_get_resolver(struct gg_session *gs);
-int gg_session_set_custom_resolver(struct gg_session *gs, int (*resolver_start)(int*, void**, const char*), void (*resolver_cleanup)(void**, int));
-
-int gg_http_set_resolver(struct gg_http *gh, gg_resolver_t type);
-gg_resolver_t gg_http_get_resolver(struct gg_http *gh);
-int gg_http_set_custom_resolver(struct gg_http *gh, int (*resolver_start)(int*, void**, const char*), void (*resolver_cleanup)(void**, int));
-
-int gg_global_set_resolver(gg_resolver_t type);
-gg_resolver_t gg_global_get_resolver(void);
-int gg_global_set_custom_resolver(int (*resolver_start)(int*, void**, const char*), void (*resolver_cleanup)(void**, int));
-
-int gg_multilogon_disconnect(struct gg_session *gs, gg_multilogon_id_t conn_id);
-
-int gg_chat_create(struct gg_session *gs);
-int gg_chat_invite(struct gg_session *gs, uint64_t id, uin_t *participants, unsigned int participants_count);
-int gg_chat_leave(struct gg_session *gs, uint64_t id);
-int gg_chat_send_message(struct gg_session *gs, uint64_t id, const char *message, int is_html);
-
-/**
- * Rodzaj zdarzenia.
- *
- * \ingroup events
- */
-enum gg_event_t {
-	GG_EVENT_NONE = 0,		/**< Nie wydarzyło się nic wartego uwagi */
-	GG_EVENT_MSG,			/**< \brief Otrzymano wiadomość. Przekazuje również wiadomości systemowe od numeru 0. */
-	GG_EVENT_NOTIFY,		/**< \brief Informacja o statusach osób z listy kontaktów (przed 6.0). Zdarzenie należy obsługiwać, jeśli planuje się używać protokołu w wersji starszej niż domyślna. Ostatni element tablicy zawiera uin równy 0, a pozostałe pola są niezainicjowane. */
-	GG_EVENT_NOTIFY_DESCR,		/**< \brief Informacja o statusie opisowym osoby z listy kontaktów (przed 6.0). Zdarzenie należy obsługiwać, jeśli planuje się używać protokołu w wersji starszej niż domyślna. */
-	GG_EVENT_STATUS,		/**< \brief Zmiana statusu osoby z listy kontaktów (przed 6.0). Zdarzenie należy obsługiwać, jeśli planuje się używać protokołu w wersji starszej niż domyślna. */
-	GG_EVENT_ACK,			/**< Potwierdzenie doręczenia wiadomości */
-	GG_EVENT_PONG,			/**< \brief Utrzymanie połączenia. Obecnie serwer nie wysyła już do klienta ramek utrzymania połączenia, polega wyłącznie na wysyłaniu ramek przez klienta. */
-	GG_EVENT_CONN_FAILED,		/**< \brief Nie udało się połączyć */
-	GG_EVENT_CONN_SUCCESS,		/**< \brief Połączono z serwerem. Pierwszą rzeczą, jaką należy zrobić jest wysłanie listy kontaktów. */
-	GG_EVENT_DISCONNECT,		/**< \brief Serwer zrywa połączenie. Zdarza się, gdy równolegle do serwera podłączy się druga sesja i trzeba zerwać połączenie z pierwszą. */
-
-	GG_EVENT_DCC_NEW,		/**< Nowe połączenie bezpośrednie (6.x) */
-	GG_EVENT_DCC_ERROR,		/**< Błąd połączenia bezpośredniego (6.x) */
-	GG_EVENT_DCC_DONE,		/**< Zakończono połączenie bezpośrednie (6.x) */
-	GG_EVENT_DCC_CLIENT_ACCEPT,	/**< Moment akceptacji klienta w połączeniu bezpośrednim (6.x) */
-	GG_EVENT_DCC_CALLBACK,		/**< Zwrotne połączenie bezpośrednie (6.x) */
-	GG_EVENT_DCC_NEED_FILE_INFO,	/**< Należy wypełnić \c file_info dla połączenia bezpośredniego (6.x) */
-	GG_EVENT_DCC_NEED_FILE_ACK,	/**< Czeka na potwierdzenie pliku w połączeniu bezpośrednim (6.x) */
-	GG_EVENT_DCC_NEED_VOICE_ACK,	/**< Czeka na potwierdzenie rozmowy w połączeniu bezpośrednim (6.x) */
-	GG_EVENT_DCC_VOICE_DATA, 	/**< Dane bezpośredniego połączenia głosowego (6.x) */
-
-	GG_EVENT_PUBDIR50_SEARCH_REPLY,	/**< Odpowiedź katalogu publicznego */
-	GG_EVENT_PUBDIR50_READ,		/**< Odczytano własne dane z katalogu publicznego */
-	GG_EVENT_PUBDIR50_WRITE,	/**< Zmieniono własne dane w katalogu publicznym */
-
-	GG_EVENT_STATUS60,		/**< Zmiana statusu osoby z listy kontaktów */
-	GG_EVENT_NOTIFY60,		/**< Informacja o statusach osób z listy kontaktów. Ostatni element tablicy zawiera uin równy 0, a pozostałe pola są niezainicjowane.  */
-	GG_EVENT_USERLIST,		/**< Wynik importu lub eksportu listy kontaktów */
-	GG_EVENT_IMAGE_REQUEST,		/**< Żądanie przesłania obrazka z wiadomości */
-	GG_EVENT_IMAGE_REPLY,		/**< Przysłano obrazek z wiadomości */
-	GG_EVENT_DCC_ACK,		/**< Potwierdzenie transmisji w połączeniu bezpośrednim (6.x) */
-
-	GG_EVENT_DCC7_NEW,		/**< Nowe połączenie bezpośrednie (7.x) */
-	GG_EVENT_DCC7_ACCEPT,		/**< Zaakceptowano połączenie bezpośrednie (7.x), nowy deskryptor */
-	GG_EVENT_DCC7_REJECT,		/**< Odrzucono połączenie bezpośrednie (7.x) */
-	GG_EVENT_DCC7_CONNECTED,	/**< Zestawiono połączenie bezpośrednie (7.x), nowy deskryptor */
-	GG_EVENT_DCC7_ERROR,		/**< Błąd połączenia bezpośredniego (7.x) */
-	GG_EVENT_DCC7_DONE,		/**< Zakończono połączenie bezpośrednie (7.x) */
-	GG_EVENT_DCC7_PENDING,		/**< Trwa próba połączenia bezpośredniego (7.x), nowy deskryptor */
-
-	GG_EVENT_XML_EVENT,		/**< Otrzymano komunikat systemowy (7.7) */
-	GG_EVENT_DISCONNECT_ACK,	/**< \brief Potwierdzenie zakończenia sesji. Informuje o tym, że zmiana stanu na niedostępny z opisem dotarła do serwera i można zakończyć połączenie TCP. */
-	GG_EVENT_TYPING_NOTIFICATION,	/**< Powiadomienie o pisaniu */
-	GG_EVENT_USER_DATA,		/**< Informacja o kontaktach */
-	GG_EVENT_MULTILOGON_MSG,	/**< Wiadomość wysłana z innej sesji multilogowania */
-	GG_EVENT_MULTILOGON_INFO,	/**< Informacja o innych sesjach multilogowania */
-
-	GG_EVENT_USERLIST100_VERSION,	/**< Otrzymano numer wersji listy kontaktów na serwerze (10.0) */
-	GG_EVENT_USERLIST100_REPLY,	/**< Wynik importu lub eksportu listy kontaktów (10.0) */
-
-	GG_EVENT_IMTOKEN,		/**< Otrzymano ciąg IMTOKEN (11.0) */
-	GG_EVENT_PONG110,		/**< \brief Utrzymanie połączenia (11.0). Może służyć do synchronizacji czasu z serwerem. */
-	GG_EVENT_JSON_EVENT,		/**< Otrzymano komunikat systemowy (11.0) */
-	GG_EVENT_ACK110,		/**< Potwierdzenie wysłania wiadomości (11.0) */
-
-	GG_EVENT_CHAT_INFO,		/**< Otrzymano informację o konferencji (11.0). */
-	GG_EVENT_CHAT_INFO_GOT_ALL,	/**< \brief Informacje o wszystkich konferencjach zostały już wysłane (11.0). Otrzymywany po ostatnim pakiecie \c GG_EVENT_CHAT_INFO */
-	GG_EVENT_CHAT_INFO_UPDATE,	/**< \brief Aktualizacja informacji o konferencji (11.0). Dodanie, usunięcie jednego z uczestników. */
-	GG_EVENT_CHAT_CREATED,		/**< Potwierdzenie utworzenia konferencji (11.0) */
-	GG_EVENT_CHAT_INVITE_ACK,	/**< Potwierdzenie wysłania zaproszenia do konferencji (11.0) */
-};
-
-#define GG_EVENT_SEARCH50_REPLY GG_EVENT_PUBDIR50_SEARCH_REPLY
-
-/**
- * Powód nieudanego połączenia.
- */
-enum gg_failure_t {
-	GG_FAILURE_RESOLVING = 1,	/**< Nie znaleziono serwera */
-	GG_FAILURE_CONNECTING,		/**< Błąd połączenia */
-	GG_FAILURE_INVALID,		/**< Serwer zwrócił nieprawidłowe dane */
-	GG_FAILURE_READING,		/**< Zerwano połączenie podczas odczytu */
-	GG_FAILURE_WRITING,		/**< Zerwano połączenie podczas zapisu */
-	GG_FAILURE_PASSWORD,		/**< Nieprawidłowe hasło */
-	GG_FAILURE_404, 		/**< Nieużywane */
-	GG_FAILURE_TLS,			/**< Błąd negocjacji szyfrowanego połączenia */
-	GG_FAILURE_NEED_EMAIL, 		/**< Serwer rozłączył nas z prośbą o zmianę adresu e-mail */
-	GG_FAILURE_INTRUDER,		/**< Zbyt wiele prób połączenia z nieprawidłowym hasłem */
-	GG_FAILURE_UNAVAILABLE,		/**< Serwery są wyłączone */
-	GG_FAILURE_PROXY,		/**< Błąd serwera pośredniczącego */
-	GG_FAILURE_HUB,			/**< Błąd połączenia z hubem */
-	GG_FAILURE_INTERNAL,		/**< Błąd wewnętrzny */
-};
-
-/**
- * Kod błędu danej operacji.
- *
- * Nie zawiera przesadnie szczegółowych informacji o powodach błędów, by nie
- * komplikować ich obsługi. Jeśli wymagana jest większa dokładność, należy
- * sprawdzić zawartość zmiennej systemowej \c errno.
- */
-enum gg_error_t {
-	GG_ERROR_RESOLVING = 1,		/**< Nie znaleziono hosta */
-	GG_ERROR_CONNECTING,		/**< Błąd połączenia */
-	GG_ERROR_READING,		/**< Błąd odczytu/odbierania */
-	GG_ERROR_WRITING,		/**< Błąd zapisu/wysyłania */
-
-	GG_ERROR_DCC_HANDSHAKE,		/**< Błąd negocjacji */
-	GG_ERROR_DCC_FILE,		/**< Błąd odczytu/zapisu pliku */
-	GG_ERROR_DCC_EOF,		/**< Przedwczesny koniec pliku */
-	GG_ERROR_DCC_NET,		/**< Błąd wysyłania/odbierania */
-	GG_ERROR_DCC_REFUSED, 		/**< Połączenie odrzucone */
-
-	GG_ERROR_DCC7_HANDSHAKE,	/**< Błąd negocjacji */
-	GG_ERROR_DCC7_FILE,		/**< Błąd odczytu/zapisu pliku */
-	GG_ERROR_DCC7_EOF,		/**< Przedwczesny koniec pliku */
-	GG_ERROR_DCC7_NET,		/**< Błąd wysyłania/odbierania */
-	GG_ERROR_DCC7_REFUSED, 		/**< Połączenie odrzucone */
-	GG_ERROR_DCC7_RELAY,		/**< Problem z serwerem pośredniczącym */
-};
-
-/**
- * Pole zapytania lub odpowiedzi katalogu publicznego.
- */
-struct gg_pubdir50_entry {
-	int num;	/**< Numer wyniku */
-	char *field;	/**< Nazwa pola */
-	char *value;	/**< Wartość pola */
-} /* GG_DEPRECATED */;
-
-/**
- * Zapytanie lub odpowiedź katalogu publicznego.
- *
- * Patrz \c gg_pubdir50_t.
- */
-struct gg_pubdir50_s {
-	int count;	/**< Liczba wyników odpowiedzi */
-	uin_t next;	/**< Numer początkowy następnego zapytania */
-	int type;	/**< Rodzaj zapytania */
-	uint32_t seq;	/**< Numer sekwencyjny */
-	struct gg_pubdir50_entry *entries;	/**< Pola zapytania lub odpowiedzi */
-	int entries_count;	/**< Liczba pól */
-} /* GG_DEPRECATED */;
-
-/**
- * Zapytanie lub odpowiedź katalogu publicznego.
- *
- * Do pól nie należy się odwoływać bezpośrednio -- wszystkie niezbędne
- * informacje są dostępne za pomocą funkcji \c gg_pubdir50_*
- */
-typedef struct gg_pubdir50_s *gg_pubdir50_t;
-
-/**
- * Opis zdarzeń \c GG_EVENT_MSG i \c GG_EVENT_MULTILOGON_MSG.
- */
-struct gg_event_msg {
-	uin_t sender;		/**< Numer nadawcy/odbiorcy */
-	int msgclass;		/**< Klasa wiadomości */
-#ifndef _WIN32
-	time_t time;		/**< Czas nadania */
-#else
-	uint32_t time;		/**< Czas nadania */
-#endif
-	unsigned char *message;	/**< Treść wiadomości */
-
-	int recipients_count;	/**< Liczba odbiorców konferencji */
-	uin_t *recipients;	/**< Odbiorcy konferencji */
-
-	int formats_length;	/**< Długość informacji o formatowaniu tekstu */
-	void *formats;		/**< Informacje o formatowaniu tekstu */
-	uint32_t seq;		/**< Numer sekwencyjny wiadomości */
-
-	char *xhtml_message;	/**< Treść wiadomości w formacie XHTML */
-
-	uint64_t chat_id;	/**< Identyfikator konferencji lub 0, jeżeli jest to zwykła wiadomość (11.0) */
-	uint64_t flags;		/**< Flagi wiadomości (11.0) */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_NOTIFY_DESCR.
- */
-struct gg_event_notify_descr {
-	struct gg_notify_reply *notify;	/**< Informacje o liście kontaktów */
-	char *descr;		/**< Opis status */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_STATUS.
- */
-struct gg_event_status {
-	uin_t uin;		/**< Numer Gadu-Gadu */
-	uint32_t status;	/**< Nowy status */
-	char *descr;		/**< Opis */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_STATUS60.
- */
-struct gg_event_status60 {
-	uin_t uin;		/**< Numer Gadu-Gadu */
-	int status;		/**< Nowy status */
-	uint32_t remote_ip;	/**< Adres IP dla połączeń bezpośrednich */
-	uint16_t remote_port;	/**< Port dla połączeń bezpośrednich */
-	int version;		/**< Wersja protokołu */
-	int image_size;		/**< Maksymalny rozmiar obsługiwanych obrazków w KiB */
-	char *descr;		/**< Opis statusu */
-#ifndef _WIN32
-	time_t time;		/**< Czas powrotu */
-#else
-	uint32_t time;		/**< Czas powrotu */
-#endif
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_NOTIFY_REPLY60.
- */
-struct gg_event_notify60 {
-	uin_t uin;		/**< Numer Gadu-Gadu. W ostatnim elemencie jest równy 0, a pozostałe pola są niezainicjowane. */
-	int status;		/**< Nowy status */
-	uint32_t remote_ip;	/**< Adres IP dla połączeń bezpośrednich */
-	uint16_t remote_port;	/**< Port dla połączeń bezpośrednich */
-	int version;		/**< Wersja protokołu */
-	int image_size;		/**< Maksymalny rozmiar obsługiwanych obrazków w KiB */
-	char *descr;		/**< Opis statusu */
-#ifndef _WIN32
-	time_t time;		/**< Czas powrotu */
-#else
-	uint32_t time;		/**< Czas powrotu */
-#endif
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_ACK.
- */
-struct gg_event_ack {
-	uin_t recipient;	/**< Numer odbiorcy */
-	int status;		/**< Status doręczenia */
-	int seq;		/**< Numer sekwencyjny wiadomości */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_ACK110.
- */
-struct gg_event_ack110 {
-	uint8_t msg_type;	/**< Rodzaj wiadomości (0x01 - zwykła, 0x02 - konferencja) */
-	uint32_t seq;		/**< Numer sekwencyjny */
-	uint32_t time;		/**< Czas zdarzenia */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_USERLIST.
- */
-struct gg_event_userlist {
-	char type;		/**< Rodzaj odpowiedzi */
-	char *reply;		/**< Treść odpowiedzi */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_DCC_VOICE_DATA.
- */
-struct gg_event_dcc_voice_data {
-	uint8_t *data;		/**< Dane dźwiękowe */
-	int length;		/**< Rozmiar danych dźwiękowych */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_IMAGE_REQUEST.
- */
-struct gg_event_image_request {
-	uin_t sender;		/**< Nadawca żądania */
-	uint32_t size;		/**< Rozmiar obrazka */
-	uint32_t crc32;		/**< Suma kontrolna CRC32 */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_IMAGE_REPLY.
- */
-struct gg_event_image_reply {
-	uin_t sender;		/**< Nadawca obrazka */
-	uint32_t size;		/**< Rozmiar obrazka */
-	uint32_t crc32;		/**< Suma kontrolna CRC32 */
-	char *filename;		/**< Nazwa pliku */
-	char *image;		/**< Bufor z obrazkiem */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_XML_EVENT.
- */
-struct gg_event_xml_event {
-	char *data;		/**< Bufor z komunikatem */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_JSON_EVENT.
- */
-struct gg_event_json_event {
-	char *data;		/**< Bufor z komunikatem */
-	char *type;		/**< Bufor z typem komunikatu */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_DCC7_CONNECTED.
- */
-struct gg_event_dcc7_connected {
-	struct gg_dcc7 *dcc7;	/**< Struktura połączenia */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_DCC7_PENDING.
- */
-struct gg_event_dcc7_pending {
-	struct gg_dcc7 *dcc7;	/**< Struktura połączenia */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_DCC7_REJECT.
- */
-struct gg_event_dcc7_reject {
-	struct gg_dcc7 *dcc7;	/**< Struktura połączenia */
-	int reason;		/**< powód odrzucenia */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_DCC7_ACCEPT.
- */
-struct gg_event_dcc7_accept {
-	struct gg_dcc7 *dcc7;	/**< Struktura połączenia */
-	int type;		/**< Sposób połączenia (P2P, przez serwer) */
-	uint32_t remote_ip;	/**< Adres zdalnego klienta */
-	uint16_t remote_port;	/**< Port zdalnego klienta */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_DCC7_DONE.
- */
-struct gg_event_dcc7_done {
-	struct gg_dcc7 *dcc7;	/**< Struktura połączenia */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_TYPING_NOTIFICATION.
- */
-struct gg_event_typing_notification {
-	uin_t uin;		/**< Numer rozmówcy */
-	int length;		/**< Długość tekstu */
-};
-
-/**
- * Atrybut użytkownika.
- */
-struct gg_event_user_data_attr {
-	int type;		/**< Typ atrybutu */
-	char *key;		/**< Klucz */
-	char *value;		/**< Wartość */
-};
-
-/**
- * Struktura opisująca kontakt w zdarzeniu GG_EVENT_USER_DATA.
- */
-struct gg_event_user_data_user {
-	uin_t uin;		/**< Numer kontaktu */
-	size_t attr_count;	/**< Liczba atrybutów */
-	struct gg_event_user_data_attr *attrs;	/**< Lista atrybutów */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_USER_DATA.
- */
-struct gg_event_user_data {
-	int type;		/**< Rodzaj informacji o kontaktach */
-	size_t user_count;	/**< Liczba kontaktów */
-	struct gg_event_user_data_user *users;	/**< Lista kontaktów */
-};
-
-/**
- * Struktura opisująca sesję multilogowania.
- */
-struct gg_multilogon_session {
-	gg_multilogon_id_t id;		/**< Identyfikator sesji */
-	char *name;			/**< Nazwa sesji (podana w \c gg_login_params.client_version) */
-	uint32_t remote_addr;		/**< Adres sesji */
-	int status_flags;		/**< Flagi statusu sesji */
-	int protocol_features;		/**< Opcje protokolu sesji */
-#ifndef _WIN32
-	time_t logon_time;		/**< Czas zalogowania */
-#else
-	uint32_t logon_time;		/**< Czas zalogowania */
-#endif
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_MULTILOGON_INFO.
- */
-struct gg_event_multilogon_info {
-	int count;		/**< Liczba sesji */
-	struct gg_multilogon_session *sessions;	/** Lista sesji */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_USERLIST100_VERSION.
- */
-struct gg_event_userlist100_version {
-	uint32_t version;		/**< Numer wersji listy kontaktów na serwerze */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_USERLIST100_REPLY.
- */
-struct gg_event_userlist100_reply {
-	char type;			/**< Rodzaj odpowiedzi */
-	uint32_t version;		/**< Aktualna wersja listy kontaktów na serwerze */
-	char format_type;		/**< Typ formatu listy kontaktów (żądany w \c gg_userlist100_request.format_type) */
-	char *reply;			/**< Treść listy kontaktów w przesyłanej wersji i formacie */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_IMTOKEN.
- */
-struct gg_event_imtoken {
-	char *imtoken;			/**< Wartość IMTOKEN */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_PONG110.
- */
-struct gg_event_pong110 {
-#ifndef _WIN32
-	time_t time;			/**< Aktualny czas na serwerze */
-#else
-	uint32_t time;			/**< Aktualny czas na serwerze */
-#endif
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_CHAT_INFO.
- */
-struct gg_event_chat_info {
-	uint64_t id;			/**< Identyfikator konferencji */
-	uint32_t version;		/**< Wersja informacji o konferencji */
-	uint32_t participants_count;	/**< Ilość uczestników */
-	uin_t *participants;		/**< Lista uczestników */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_CHAT_INFO_UPDATE.
- */
-struct gg_event_chat_info_update {
-	uint64_t id;			/**< Identyfikator konferencji */
-	uint32_t type;			/**< Typ aktualizacji (\c GG_CHAT_INFO_UPDATE_*) */
-	uin_t participant;		/**< Uczestnik, którego dotyczy aktualizacja */
-	uin_t inviter;			/**< Uczestnik inicjujący aktualizację (zapraszający) */
-	uint32_t version;		/**< Wersja informacji o konferencji */
-	uint32_t time;			/**< Czas zdarzenia */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_CHAT_CREATED.
- */
-struct gg_event_chat_created {
-	uint64_t id;			/**< Identyfikator konferencji */
-	uint32_t seq;			/**< Numer sekwencyjny */
-};
-
-/**
- * Opis zdarzenia \c GG_EVENT_CHAT_INVITE_ACK.
- */
-struct gg_event_chat_invite_ack {
-	uint64_t id;			/**< Identyfikator konferencji */
-	uint32_t seq;			/**< Numer sekwencyjny */
-};
-
-/**
- * Unia wszystkich zdarzeń zwracanych przez funkcje \c gg_watch_fd(), 
- * \c gg_dcc_watch_fd() i \c gg_dcc7_watch_fd().
- *
- * \ingroup events
- */
-union gg_event_union {
-	enum gg_failure_t failure;	/**< Błąd połączenia (\c GG_EVENT_CONN_FAILED) */
-	struct gg_notify_reply *notify;	/**< Zmiana statusu kontaktów (\c GG_EVENT_NOTIFY) */
-	struct gg_event_notify_descr notify_descr;	/**< Zmiana statusu kontaktów (\c GG_EVENT_NOTIFY_DESCR) */
-	struct gg_event_status status;	/**< Zmiana statusu kontaktów (\c GG_EVENT_STATUS) */
-	struct gg_event_status60 status60;	/**< Zmiana statusu kontaktów (\c GG_EVENT_STATUS60) */
-	struct gg_event_notify60 *notify60;	/**< Zmiana statusu kontaktów (\c GG_EVENT_NOTIFY60) */
-	struct gg_event_msg msg;	/**< Otrzymano wiadomość (\c GG_EVENT_MSG) */
-	struct gg_event_ack ack;	/**< Potwierdzenie wiadomości (\c GG_EVENT_ACK) */
-	struct gg_event_ack110 ack110;	/**< Potwierdzenie wysłania wiadomości (11.0) (\c GG_EVENT_ACK110) */
-	struct gg_event_image_request image_request;	/**< Żądanie wysłania obrazka (\c GG_EVENT_IMAGE_REQUEST) */
-	struct gg_event_image_reply image_reply;	/**< Odpowiedź z obrazkiem (\c GG_EVENT_IMAGE_REPLY) */
-	struct gg_event_userlist userlist;	/**< Odpowiedź listy kontaktów (\c GG_EVENT_USERLIST) */
-	gg_pubdir50_t pubdir50;	/**< Odpowiedź katalogu publicznego (\c GG_EVENT_PUBDIR50_*) */
-	struct gg_event_xml_event xml_event;	/**< Zdarzenie systemowe (\c GG_EVENT_XML_EVENT) */
-	struct gg_event_json_event json_event;	/**< Zdarzenie systemowe (\c GG_EVENT_JSON_EVENT) */
-	struct gg_dcc *dcc_new;	/**< Nowe połączenie bezpośrednie (\c GG_EVENT_DCC_NEW) */
-	enum gg_error_t dcc_error;	/**< Błąd połączenia bezpośredniego (\c GG_EVENT_DCC_ERROR) */
-	struct gg_event_dcc_voice_data dcc_voice_data;	/**< Dane połączenia głosowego (\c GG_EVENT_DCC_VOICE_DATA) */
-	struct gg_dcc7 *dcc7_new;	/**< Nowe połączenie bezpośrednie (\c GG_EVENT_DCC7_NEW) */
-	enum gg_error_t dcc7_error;	/**< Błąd połączenia bezpośredniego (\c GG_EVENT_DCC7_ERROR) */
-	struct gg_event_dcc7_connected dcc7_connected;	/**< Informacja o zestawieniu połączenia bezpośredniego (\c GG_EVENT_DCC7_CONNECTED) */
-	struct gg_event_dcc7_pending dcc7_pending;	/**< Trwa próba połączenia bezpośredniego (\c GG_EVENT_DCC7_PENDING) */
-	struct gg_event_dcc7_reject dcc7_reject;	/**< Odrzucono połączenia bezpośredniego (\c GG_EVENT_DCC7_REJECT) */
-	struct gg_event_dcc7_accept dcc7_accept;	/**< Zaakceptowano połączenie bezpośrednie (\c GG_EVENT_DCC7_ACCEPT) */
-	struct gg_event_dcc7_done dcc7_done;	/**< Zakończono połączenie bezpośrednie (\c GG_EVENT_DCC7_DONE) */
-	struct gg_event_typing_notification typing_notification;	/**< Powiadomienie o pisaniu */
-	struct gg_event_user_data user_data;	/**< Informacje o kontaktach */
-	struct gg_event_msg multilogon_msg;	/**< Inna sesja wysłała wiadomość (\c GG_EVENT_MULTILOGON_MSG) */
-	struct gg_event_multilogon_info multilogon_info;	/**< Informacja o innych sesjach multilogowania (\c GG_EVENT_MULTILOGON_INFO) */
-	struct gg_event_userlist100_version userlist100_version;	/**< Informacja o numerze wersji listy kontaktów na serwerze (\c GG_EVENT_USERLIST100_VERSION) */
-	struct gg_event_userlist100_reply userlist100_reply;	/**< Odpowiedź listy kontaktów (10.0) (\c GG_EVENT_USERLIST100_REPLY) */
-	struct gg_event_imtoken imtoken;	/**< Ciąg IMTOKEN (11.0) (\c GG_EVENT_IMTOKEN) */
-	struct gg_event_pong110 pong110;	/**< Utrzymanie połączenia (11.0) (\c GG_EVENT_PONG110) */
-	struct gg_event_chat_info chat_info;	/**< Informacje o konferencji (11.0) (\c GG_EVENT_CHAT_INFO) */
-	struct gg_event_chat_info_update chat_info_update;	/**< Aktualizacja informacji o konferencji (11.0) (\c GG_EVENT_CHAT_INFO_UPDATE) */
-	struct gg_event_chat_created chat_created;	/**< Potwierdzenie utworzenia konferencji (11.0) (\c GG_EVENT_CHAT_CREATED) */
-	struct gg_event_chat_invite_ack chat_invite_ack;	/**< Potwierdzenie wysłania zaproszenia do konferencji (11.0) (\c GG_EVENT_CHAT_INVITE_ACK) */
-};
-
-/**
- * Opis zdarzenia.
- *
- * Zwracany przez funkcje \c gg_watch_fd(), \c gg_dcc_watch_fd()
- * i \c gg_dcc7_watch_fd(). Po przeanalizowaniu należy zwolnić
- * za pomocą \c gg_event_free().
- *
- * \ingroup events
- */
-struct gg_event {
-	int type;			/**< Rodzaj zdarzenia */
-	union gg_event_union event;	/**< Informacja o zdarzeniu */
-};
-
-struct gg_event *gg_watch_fd(struct gg_session *sess);
-void gg_event_free(struct gg_event *e);
-
-int gg_notify_ex(struct gg_session *sess, uin_t *userlist, char *types, int count);
-int gg_notify(struct gg_session *sess, uin_t *userlist, int count);
-int gg_add_notify_ex(struct gg_session *sess, uin_t uin, char type);
-int gg_add_notify(struct gg_session *sess, uin_t uin);
-int gg_remove_notify_ex(struct gg_session *sess, uin_t uin, char type);
-int gg_remove_notify(struct gg_session *sess, uin_t uin);
-
-struct gg_http *gg_http_connect(const char *hostname, int port, int async, const char *method, const char *path, const char *header);
-int gg_http_watch_fd(struct gg_http *h);
-void gg_http_stop(struct gg_http *h);
-void gg_http_free(struct gg_http *h);
-
-uint32_t gg_pubdir50(struct gg_session *sess, gg_pubdir50_t req);
-gg_pubdir50_t gg_pubdir50_new(int type);
-int gg_pubdir50_add(gg_pubdir50_t req, const char *field, const char *value);
-int gg_pubdir50_seq_set(gg_pubdir50_t req, uint32_t seq);
-const char *gg_pubdir50_get(gg_pubdir50_t res, int num, const char *field);
-int gg_pubdir50_type(gg_pubdir50_t res);
-int gg_pubdir50_count(gg_pubdir50_t res);
-uin_t gg_pubdir50_next(gg_pubdir50_t res);
-uint32_t gg_pubdir50_seq(gg_pubdir50_t res);
-void gg_pubdir50_free(gg_pubdir50_t res);
-
-#ifndef DOXYGEN
-
-#define GG_PUBDIR50_UIN "FmNumber"
-#define GG_PUBDIR50_STATUS "FmStatus"
-#define GG_PUBDIR50_FIRSTNAME "firstname"
-#define GG_PUBDIR50_LASTNAME "lastname"
-#define GG_PUBDIR50_NICKNAME "nickname"
-#define GG_PUBDIR50_BIRTHYEAR "birthyear"
-#define GG_PUBDIR50_CITY "city"
-#define GG_PUBDIR50_GENDER "gender"
-#define GG_PUBDIR50_GENDER_FEMALE "1"
-#define GG_PUBDIR50_GENDER_MALE "2"
-#define GG_PUBDIR50_GENDER_SET_FEMALE "2"
-#define GG_PUBDIR50_GENDER_SET_MALE "1"
-#define GG_PUBDIR50_ACTIVE "ActiveOnly"
-#define GG_PUBDIR50_ACTIVE_TRUE "1"
-#define GG_PUBDIR50_START "fmstart"
-#define GG_PUBDIR50_FAMILYNAME "familyname"
-#define GG_PUBDIR50_FAMILYCITY "familycity"
-
-#else
-
-/** 
- * \ingroup pubdir50
- *
- * Rodzaj pola zapytania.
- */
-enum {
-	GG_PUBDIR50_UIN,	/**< Numer Gadu-Gadu */
-	GG_PUBDIR50_STATUS,	/**< Status (tylko wynik wyszukiwania) */
-	GG_PUBDIR50_FIRSTNAME,	/**< Imię */
-	GG_PUBDIR50_LASTNAME,	/**< Nazwisko */
-	GG_PUBDIR50_NICKNAME,	/**< Pseudonim */
-	GG_PUBDIR50_BIRTHYEAR,	/**< Rok urodzenia lub przedział lat oddzielony spacją */
-	GG_PUBDIR50_CITY,	/**< Miejscowość */
-	GG_PUBDIR50_GENDER,	/**< Płeć */
-	GG_PUBDIR50_ACTIVE,	/**< Osoba dostępna (tylko wyszukiwanie) */
-	GG_PUBDIR50_START,	/**< Numer początkowy wyszukiwania (tylko wyszukiwanie) */
-	GG_PUBDIR50_FAMILYNAME,	/**< Nazwisko rodowe (tylko wysyłanie informacji o sobie) */
-	GG_PUBDIR50_FAMILYCITY,	/**< Miejscowość pochodzenia (tylko wysyłanie informacji o sobie) */
-};
-
-/**
- * \ingroup pubdir50
- *
- * Wartość pola GG_PUBDIR50_GENDER przy wyszukiwaniu. Brak pola oznacza dowolną płeć.
- */
-enum {
-	GG_PUBDIR50_GENDER_FEMALE,	/**< Kobieta */
-	GG_PUBDIR50_GENDER_MALE,	/**< Mężczyzna */
-};
-
-/**
- * \ingroup pubdir50
- *
- * Wartość pola GG_PUBDIR50_GENDER przy wysyłaniu informacji o sobie.
- */
-enum {
-	GG_PUBDIR50_GENDER_SET_FEMALE,	/**< Kobieta */
-	GG_PUBDIR50_GENDER_SET_MALE,	/**< Mężczyzna */
-};
-
-/**
- * \ingroup pubdir50
- *
- * Wartość pola GG_PUBDIR50_ACTIVE.
- */
-enum {
-	GG_PUBDIR50_ACTIVE_TRUE,	/**< Wyszukaj tylko osoby dostępne */
-};
-
-#endif	/* DOXYGEN */
-
-/**
- * Powód błędu operacji na katalogu publicznym.
- *
- * \ingroup http
- */
-typedef enum {
-	GG_PUBDIR_ERROR_NONE = 0,	/**< Brak błędu */
-	GG_PUBDIR_ERROR_OTHER,	/**< Nieznany błąd */
-	GG_PUBDIR_ERROR_TOKEN,	/**< Błędny token */
-	GG_PUBDIR_ERROR_OLD_PASSWORD,	/**< Niepoprawne stare hasło */
-	GG_PUBDIR_ERROR_NEW_PASSWORD,	/**< Niepoprawne nowe hasło */
-} gg_pubdir_error_t;
-
-/**
- * Wynik operacji na katalogu publicznym.
- *
- * \ingroup http
- */
-struct gg_pubdir {
-	int success;		/**< Flaga powodzenia operacji */
-	uin_t uin;		/**< Otrzymany numer lub 0 w przypadku błędu */
-	gg_pubdir_error_t error;	/**< Powód błędu */
-};
-
-int gg_pubdir_watch_fd(struct gg_http *f);
-void gg_pubdir_free(struct gg_http *f);
-
-/**
- * Token autoryzacji niektórych operacji HTTP.
- * 
- * \ingroup token
- */
-struct gg_token {
-	int width;		/**< Szerokość obrazka */
-	int height;		/**< Wysokość obrazka */
-	int length;		/**< Liczba znaków w tokenie */
-	char *tokenid;		/**< Identyfikator tokenu */
-};
-
-struct gg_http *gg_token(int async);
-int gg_token_watch_fd(struct gg_http *h);
-void gg_token_free(struct gg_http *h);
-
-struct gg_http *gg_register3(const char *email, const char *password, const char *tokenid, const char *tokenval, int async);
-#ifndef DOXYGEN
-#define gg_register_watch_fd gg_pubdir_watch_fd
-#define gg_register_free gg_pubdir_free
-#endif
-
-struct gg_http *gg_unregister3(uin_t uin, const char *password, const char *tokenid, const char *tokenval, int async);
-#ifndef DOXYGEN
-#define gg_unregister_watch_fd gg_pubdir_watch_fd
-#define gg_unregister_free gg_pubdir_free
-#endif
-
-struct gg_http *gg_remind_passwd3(uin_t uin, const char *email, const char *tokenid, const char *tokenval, int async);
-#ifndef DOXYGEN
-#define gg_remind_passwd_watch_fd gg_pubdir_watch_fd
-#define gg_remind_passwd_free gg_pubdir_free
-#endif
-
-struct gg_http *gg_change_passwd4(uin_t uin, const char *email, const char *passwd, const char *newpasswd, const char *tokenid, const char *tokenval, int async);
-#ifndef DOXYGEN
-#define gg_change_passwd_watch_fd gg_pubdir_watch_fd
-#define gg_change_passwd_free gg_pubdir_free
-#endif
-
-extern int gg_dcc_port;
-extern unsigned long gg_dcc_ip;
-
-int gg_dcc_request(struct gg_session *sess, uin_t uin);
-
-struct gg_dcc *gg_dcc_send_file(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin);
-struct gg_dcc *gg_dcc_get_file(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin);
-struct gg_dcc *gg_dcc_voice_chat(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin);
-void gg_dcc_set_type(struct gg_dcc *d, int type);
-int gg_dcc_fill_file_info(struct gg_dcc *d, const char *filename);
-int gg_dcc_fill_file_info2(struct gg_dcc *d, const char *filename, const char *local_filename);
-int gg_dcc_voice_send(struct gg_dcc *d, char *buf, int length);
-
-#define GG_DCC_VOICE_FRAME_LENGTH 195		/**< Rozmiar pakietu głosowego przed wersją Gadu-Gadu 5.0.5 */
-#define GG_DCC_VOICE_FRAME_LENGTH_505 326	/**< Rozmiar pakietu głosowego od wersji Gadu-Gadu 5.0.5 */
-
-struct gg_dcc *gg_dcc_socket_create(uin_t uin, uint16_t port);
-#ifndef DOXYGEN
-#define gg_dcc_socket_free gg_dcc_free
-#define gg_dcc_socket_watch_fd gg_dcc_watch_fd
-#endif
-
-struct gg_event *gg_dcc_watch_fd(struct gg_dcc *d);
-
-void gg_dcc_free(struct gg_dcc *c);
-
-struct gg_event *gg_dcc7_watch_fd(struct gg_dcc7 *d);
-struct gg_dcc7 *gg_dcc7_send_file(struct gg_session *sess, uin_t rcpt, const char *filename, const char *filename1250, const char *hash);
-struct gg_dcc7 *gg_dcc7_send_file_fd(struct gg_session *sess, uin_t rcpt, int fd, size_t size, const char *filename1250, const char *hash);
-int gg_dcc7_accept(struct gg_dcc7 *dcc, unsigned int offset);
-int gg_dcc7_reject(struct gg_dcc7 *dcc, int reason);
-void gg_dcc7_free(struct gg_dcc7 *d);
-
-extern int gg_debug_level;
-
-extern void (*gg_debug_handler)(int level, const char *format, va_list ap);
-extern void (*gg_debug_handler_session)(struct gg_session *sess, int level, const char *format, va_list ap);
-
-extern FILE *gg_debug_file;
-
-/**
- * \ingroup debug
- * @{
- */
-#define GG_DEBUG_NET 1		/**< Rejestracja zdarzeń związanych z siecią */
-#define GG_DEBUG_TRAFFIC 2	/**< Rejestracja ruchu sieciowego */
-#define GG_DEBUG_DUMP 4		/**< Rejestracja zawartości pakietów */
-#define GG_DEBUG_FUNCTION 8	/**< Rejestracja wywołań funkcji */
-#define GG_DEBUG_MISC 16	/**< Rejestracja różnych informacji */
-#define GG_DEBUG_VERBOSE 32	/**< Rejestracja informacji szczegółowych */
-#define GG_DEBUG_WARNING 64	/**< Rejestracja ostrzeżeń */
-#define GG_DEBUG_ERROR 128	/**< Rejestracja błędów krytycznych */
-/** @} */
-
-const char *gg_debug_state(enum gg_state_t state);
-const char *gg_debug_event(enum gg_event_t event);
-
-#ifdef GG_DEBUG_DISABLE
-#define gg_debug(...) do { } while (0)
-#define gg_debug_session(...) do { } while (0)
-#else
-void gg_debug(int level, const char *format, ...) GG_GNUC_PRINTF(2, 3);
-void gg_debug_session(struct gg_session *sess, int level, const char *format, ...) GG_GNUC_PRINTF(3, 4);
-#endif
-
-const char *gg_libgadu_version(void);
-
-/**
- * Lista funkcji biblioteki, które zależą od zewnętrznych bibliotek.
- *
- * \ingroup version
- */
-typedef enum {
-	GG_LIBGADU_FEATURE_SSL,		/**< Biblioteka obsługuje połączenia szyfrowane */
-	GG_LIBGADU_FEATURE_PTHREAD,	/**< Biblioteka obsługuje rozwiązywanie nazw za pomocą wątków */
-	GG_LIBGADU_FEATURE_USERLIST100,	/**< Biblioteka obsługuje listę kontaktów zgodną z Gadu-Gadu 10 */
-} gg_libgadu_feature_t;
-
-int gg_libgadu_check_feature(gg_libgadu_feature_t feature);
-
-extern int gg_proxy_enabled;
-extern char *gg_proxy_host;
-extern int gg_proxy_port;
-extern char *gg_proxy_username;
-extern char *gg_proxy_password;
-extern int gg_proxy_http_only;
-
-extern unsigned long gg_local_ip;
-
-#define GG_LOGIN_HASH_GG32 0x01	/**< Algorytm Gadu-Gadu */
-#define GG_LOGIN_HASH_SHA1 0x02	/**< Algorytm SHA1 */
-
-#ifndef DOXYGEN
-
-#define GG_PUBDIR50_WRITE 0x01
-#define GG_PUBDIR50_READ 0x02
-#define GG_PUBDIR50_SEARCH 0x03
-#define GG_PUBDIR50_SEARCH_REQUEST GG_PUBDIR50_SEARCH
-#define GG_PUBDIR50_SEARCH_REPLY 0x05
-
-#else
-
-/**
- * \ingroup pubdir50
- * 
- * Rodzaj zapytania lub odpowiedzi katalogu publicznego.
- */
-enum {
-	GG_PUBDIR50_WRITE,	/**< Wysłanie do serwera informacji o sobie */
-	GG_PUBDIR50_READ,	/**< Pobranie z serwera informacji o sobie */
-	GG_PUBDIR50_SEARCH,	/**< Wyszukiwanie w katalogu publicznym */
-	GG_PUBDIR50_SEARCH_REPLY,	/**< Wynik wyszukiwania w katalogu publicznym */
-};
-
-#endif	/* DOXYGEN */
-
-/** \cond obsolete */
-
-#define gg_free_event gg_event_free
-#define gg_free_http gg_http_free
-#define gg_free_pubdir gg_pubdir_free
-#define gg_free_register gg_pubdir_free
-#define gg_free_remind_passwd gg_pubdir_free
-#define gg_free_dcc gg_dcc_free
-#define gg_free_change_passwd gg_pubdir_free
-
-struct gg_search_request {
-	int active;
-	unsigned int start;
-	char *nickname;
-	char *first_name;
-	char *last_name;
-	char *city;
-	int gender;
-	int min_birth;
-	int max_birth;
-	char *email;
-	char *phone;
-	uin_t uin;
-} /* GG_DEPRECATED */;
-
-struct gg_search {
-	int count;
-	struct gg_search_result *results;
-} GG_DEPRECATED;
-
-struct gg_search_result {
-	uin_t uin;
-	char *first_name;
-	char *last_name;
-	char *nickname;
-	int born;
-	int gender;
-	char *city;
-	int active;
-} GG_DEPRECATED;
-
-#define GG_GENDER_NONE 0
-#define GG_GENDER_FEMALE 1
-#define GG_GENDER_MALE 2
-
-struct gg_http *gg_search(const struct gg_search_request *r, int async) GG_DEPRECATED;
-int gg_search_watch_fd(struct gg_http *f) GG_DEPRECATED;
-void gg_free_search(struct gg_http *f) GG_DEPRECATED;
-#define gg_search_free gg_free_search
-
-const struct gg_search_request *gg_search_request_mode_0(char *nickname, char *first_name, char *last_name, char *city, int gender, int min_birth, int max_birth, int active, int start) GG_DEPRECATED;
-const struct gg_search_request *gg_search_request_mode_1(char *email, int active, int start) GG_DEPRECATED;
-const struct gg_search_request *gg_search_request_mode_2(char *phone, int active, int start) GG_DEPRECATED;
-const struct gg_search_request *gg_search_request_mode_3(uin_t uin, int active, int start) GG_DEPRECATED;
-void gg_search_request_free(struct gg_search_request *r) GG_DEPRECATED;
-
-struct gg_http *gg_register(const char *email, const char *password, int async) GG_DEPRECATED;
-struct gg_http *gg_register2(const char *email, const char *password, const char *qa, int async) GG_DEPRECATED;
-
-struct gg_http *gg_unregister(uin_t uin, const char *password, const char *email, int async) GG_DEPRECATED;
-struct gg_http *gg_unregister2(uin_t uin, const char *password, const char *qa, int async) GG_DEPRECATED;
-
-struct gg_http *gg_remind_passwd(uin_t uin, int async) GG_DEPRECATED;
-struct gg_http *gg_remind_passwd2(uin_t uin, const char *tokenid, const char *tokenval, int async) GG_DEPRECATED;
-
-struct gg_http *gg_change_passwd(uin_t uin, const char *passwd, const char *newpasswd, const char *newemail, int async) GG_DEPRECATED;
-struct gg_http *gg_change_passwd2(uin_t uin, const char *passwd, const char *newpasswd, const char *email, const char *newemail, int async) GG_DEPRECATED;
-struct gg_http *gg_change_passwd3(uin_t uin, const char *passwd, const char *newpasswd, const char *qa, int async) GG_DEPRECATED;
-
-struct gg_change_info_request {
-	char *first_name;
-	char *last_name;
-	char *nickname;
-	char *email;
-	int born;
-	int gender;
-	char *city;
-} /* GG_DEPRECATED */;
-
-struct gg_change_info_request *gg_change_info_request_new(const char *first_name, const char *last_name, const char *nickname, const char *email, int born, int gender, const char *city) GG_DEPRECATED;
-void gg_change_info_request_free(struct gg_change_info_request *r) GG_DEPRECATED;
-
-struct gg_http *gg_change_info(uin_t uin, const char *passwd, const struct gg_change_info_request *request, int async) GG_DEPRECATED;
-#define gg_change_pubdir_watch_fd gg_pubdir_watch_fd
-#define gg_change_pubdir_free gg_pubdir_free
-#define gg_free_change_pubdir gg_pubdir_free
-
-struct gg_http *gg_userlist_get(uin_t uin, const char *password, int async) GG_DEPRECATED;
-int gg_userlist_get_watch_fd(struct gg_http *f) GG_DEPRECATED;
-void gg_userlist_get_free(struct gg_http *f) GG_DEPRECATED;
-
-struct gg_http *gg_userlist_put(uin_t uin, const char *password, const char *contacts, int async) GG_DEPRECATED;
-int gg_userlist_put_watch_fd(struct gg_http *f) GG_DEPRECATED;
-void gg_userlist_put_free(struct gg_http *f) GG_DEPRECATED;
-
-struct gg_http *gg_userlist_remove(uin_t uin, const char *password, int async) GG_DEPRECATED;
-int gg_userlist_remove_watch_fd(struct gg_http *f) GG_DEPRECATED;
-void gg_userlist_remove_free(struct gg_http *f) GG_DEPRECATED;
-
-int gg_pubdir50_handle_reply(struct gg_event *e, const char *packet, int length) GG_DEPRECATED;
-
-/** \endcond */
-
-int gg_file_hash_sha1(int fd, uint8_t *result) GG_DEPRECATED;
-
-char *gg_saprintf(const char *format, ...) GG_GNUC_PRINTF(1, 2) GG_DEPRECATED;
-char *gg_vsaprintf(const char *format, va_list ap) GG_DEPRECATED;
-
-#define gg_alloc_sprintf gg_saprintf
-
-char *gg_get_line(char **ptr) GG_DEPRECATED;
-
-int gg_connect(void *addr, int port, int async) GG_DEPRECATED;
-struct in_addr *gg_gethostbyname(const char *hostname) GG_DEPRECATED;
-char *gg_read_line(int sock, char *buf, int length) GG_DEPRECATED;
-void gg_chomp(char *line) GG_DEPRECATED;
-char *gg_urlencode(const char *str) GG_DEPRECATED;
-int gg_http_hash(const char *format, ...) GG_DEPRECATED;
-void gg_http_free_fields(struct gg_http *h) GG_DEPRECATED;
-int gg_read(struct gg_session *sess, char *buf, int length) GG_DEPRECATED;
-int gg_write(struct gg_session *sess, const char *buf, int length) GG_DEPRECATED;
-void *gg_recv_packet(struct gg_session *sess) GG_DEPRECATED;
-int gg_send_packet(struct gg_session *sess, int type, ...) GG_DEPRECATED;
-unsigned int gg_login_hash(const unsigned char *password, unsigned int seed) GG_DEPRECATED;
-void gg_login_hash_sha1(const char *password, uint32_t seed, uint8_t *result) GG_DEPRECATED;
-uint32_t gg_fix32(uint32_t x);
-uint16_t gg_fix16(uint16_t x);
-#define fix16 gg_fix16
-#define fix32 gg_fix32
-char *gg_proxy_auth(void) GG_DEPRECATED;
-char *gg_base64_encode(const char *buf) GG_DEPRECATED;
-char *gg_base64_decode(const char *buf) GG_DEPRECATED;
-int gg_image_queue_remove(struct gg_session *s, struct gg_image_queue *q, int freeq) GG_DEPRECATED;
-
-/**
- * Kolejka odbieranych obrazków.
- */
-struct gg_image_queue {
-	uin_t sender;			/**< Nadawca obrazka */
-	uint32_t size;			/**< Rozmiar obrazka */
-	uint32_t crc32;			/**< Suma kontrolna CRC32 */
-	char *filename;			/**< Nazwa pliku */
-	char *image;			/**< Bufor z odebranymi danymi */
-	uint32_t done;			/**< Rozmiar odebranych danych */
-
-	struct gg_image_queue *next;	/**< Kolejny element listy */
-
-	uint32_t packet_type;		/**< \brief Rodzaj odbieranych pakietów. W niektórych przypadkach (przy multilogowaniu) serwer wysyła nam dwie kopie obrazka jako dwa różne typy pakietów */
-} GG_DEPRECATED;
-
-int gg_dcc7_handle_id(struct gg_session *sess, struct gg_event *e, const void *payload, int len) GG_DEPRECATED;
-int gg_dcc7_handle_new(struct gg_session *sess, struct gg_event *e, const void *payload, int len) GG_DEPRECATED;
-int gg_dcc7_handle_info(struct gg_session *sess, struct gg_event *e, const void *payload, int len) GG_DEPRECATED;
-int gg_dcc7_handle_accept(struct gg_session *sess, struct gg_event *e, const void *payload, int len) GG_DEPRECATED;
-int gg_dcc7_handle_reject(struct gg_session *sess, struct gg_event *e, const void *payload, int len) GG_DEPRECATED;
-
-#define GG_APPMSG_HOST "appmsg.gadu-gadu.pl"
-#define GG_APPMSG_PORT 80
-#define GG_PUBDIR_HOST "pubdir.gadu-gadu.pl"
-#define GG_PUBDIR_PORT 80
-#define GG_REGISTER_HOST "register.gadu-gadu.pl"
-#define GG_REGISTER_PORT 80
-#define GG_REMIND_HOST "retr.gadu-gadu.pl"
-#define GG_REMIND_PORT 80
-#define GG_RELAY_HOST "relay.gadu-gadu.pl"
-#define GG_RELAY_PORT 80
-
-#define GG_DEFAULT_PORT 8074
-#define GG_HTTPS_PORT 443
-#define GG_HTTP_USERAGENT "Mozilla/4.7 [en] (Win98; I)"
-
-#define GG_PROTOCOL_VERSION_100 0x2e
-#define GG_PROTOCOL_VERSION_110 0x40
-
-/* GG_DEPRECATED */
-#define GG_DEFAULT_CLIENT_VERSION "-"
-
-#define GG_DEFAULT_PROTOCOL_VERSION GG_PROTOCOL_VERSION_110
-#define GG_DEFAULT_TIMEOUT 30
-#define GG_HAS_AUDIO_MASK 0x40000000
-#define GG_HAS_AUDIO7_MASK 0x20000000
-#define GG_ERA_OMNIX_MASK 0x04000000
-#undef GG_LIBGADU_VERSION
-
-#ifndef DOXYGEN
-
-#define GG_FEATURE_MSG77		0x0001
-#define GG_FEATURE_STATUS77		0x0002
-#define GG_FEATURE_UNKNOWN_4		0x0004
-#define GG_FEATURE_UNKNOWN_8		0x0008
-#define GG_FEATURE_DND_FFC		0x0010
-#define GG_FEATURE_IMAGE_DESCR		0x0020
-#define GG_FEATURE_UNKNOWN_40		0x0040
-#define GG_FEATURE_UNKNOWN_80		0x0080
-#define GG_FEATURE_UNKNOWN_100		0x0100
-#define GG_FEATURE_USER_DATA		0x0200
-#define GG_FEATURE_MSG_ACK		0x0400
-#define GG_FEATURE_UNKNOWN_800		0x0800
-#define GG_FEATURE_UNKNOWN_1000		0x1000
-#define GG_FEATURE_TYPING_NOTIFICATION	0x2000
-#define GG_FEATURE_MULTILOGON		0x4000
-
-/* Poniższe makra zostały zachowane dla zgodności API */
-#define GG_FEATURE_MSG80		0
-#define GG_FEATURE_STATUS80		0
-#define GG_FEATURE_STATUS80BETA		0
-
-#define GG_FEATURE_ALL			(GG_FEATURE_MSG80 | GG_FEATURE_STATUS80 | GG_FEATURE_DND_FFC | GG_FEATURE_IMAGE_DESCR | GG_FEATURE_UNKNOWN_100 | GG_FEATURE_USER_DATA | GG_FEATURE_MSG_ACK | GG_FEATURE_TYPING_NOTIFICATION)
-
-#else
-
-/** 
- * \ingroup login
- *
- * Flagi opcji protokołu.
- */
-enum {
-	GG_FEATURE_MSG77,	/**< Klient życzy sobie otrzymywać wiadomości zgodnie z protokołem 7.7 */
-	GG_FEATURE_STATUS77,	/**< Klient życzy sobie otrzymywać zmiany stanu zgodnie z protokołem 7.7 */
-	GG_FEATURE_DND_FFC,	/**< Klient obsługuje statusy "nie przeszkadzać" i "poGGadaj ze mną" */
-	GG_FEATURE_IMAGE_DESCR,	/**< Klient obsługuje opisy graficzne oraz flagę \c GG_STATUS80_DESCR_MASK */
-};
-
-
-#endif
-
-#define GG_DEFAULT_DCC_PORT 1550
-
-struct gg_header {
-	uint32_t type;			/* typ pakietu */
-	uint32_t length;		/* długość reszty pakietu */
-} GG_PACKED;
-
-#define GG_WELCOME 0x0001
-#define GG_NEED_EMAIL 0x0014
-
-struct gg_welcome {
-	uint32_t key;			/* klucz szyfrowania hasła */
-} GG_PACKED;
-
-#define GG_LOGIN 0x000c
-
-struct gg_login {
-	uint32_t uin;			/* mój numerek */
-	uint32_t hash;			/* hash hasła */
-	uint32_t status;		/* status na dzień dobry */
-	uint32_t version;		/* moja wersja klienta */
-	uint32_t local_ip;		/* mój adres ip */
-	uint16_t local_port;		/* port, na którym słucham */
-} GG_PACKED;
-
-#define GG_LOGIN_EXT 0x0013
-
-struct gg_login_ext {
-	uint32_t uin;			/* mój numerek */
-	uint32_t hash;			/* hash hasła */
-	uint32_t status;		/* status na dzień dobry */
-	uint32_t version;		/* moja wersja klienta */
-	uint32_t local_ip;		/* mój adres ip */
-	uint16_t local_port;		/* port, na którym słucham */
-	uint32_t external_ip;		/* zewnętrzny adres ip */
-	uint16_t external_port;		/* zewnętrzny port */
-} GG_PACKED;
-
-#define GG_LOGIN60 0x0015
-
-struct gg_login60 {
-	uint32_t uin;			/* mój numerek */
-	uint32_t hash;			/* hash hasła */
-	uint32_t status;		/* status na dzień dobry */
-	uint32_t version;		/* moja wersja klienta */
-	uint8_t dunno1;			/* 0x00 */
-	uint32_t local_ip;		/* mój adres ip */
-	uint16_t local_port;		/* port, na którym słucham */
-	uint32_t external_ip;		/* zewnętrzny adres ip */
-	uint16_t external_port;		/* zewnętrzny port */
-	uint8_t image_size;		/* maksymalny rozmiar grafiki w KiB */
-	uint8_t dunno2;			/* 0xbe */
-} GG_PACKED;
-
-#define GG_LOGIN70 0x0019
-
-struct gg_login70 {
-	uint32_t uin;			/* mój numerek */
-	uint8_t hash_type;		/* rodzaj hashowania hasła */
-	uint8_t hash[64];		/* hash hasła dopełniony zerami */
-	uint32_t status;		/* status na dzień dobry */
-	uint32_t version;		/* moja wersja klienta */
-	uint8_t dunno1;			/* 0x00 */
-	uint32_t local_ip;		/* mój adres ip */
-	uint16_t local_port;		/* port, na którym słucham */
-	uint32_t external_ip;		/* zewnętrzny adres ip (???) */
-	uint16_t external_port;		/* zewnętrzny port (???) */
-	uint8_t image_size;		/* maksymalny rozmiar grafiki w KiB */
-	uint8_t dunno2;			/* 0xbe */
-} GG_PACKED;
-
-#define GG_LOGIN_OK 0x0003
-
-#define GG_LOGIN_FAILED 0x0009
-
-#define GG_PUBDIR50_REQUEST 0x0014
-
-struct gg_pubdir50_request {
-	uint8_t type;			/* GG_PUBDIR50_* */
-	uint32_t seq;			/* czas wysłania zapytania */
-} GG_PACKED;
-
-#define GG_PUBDIR50_REPLY 0x000e
-
-struct gg_pubdir50_reply {
-	uint8_t type;			/* GG_PUBDIR50_* */
-	uint32_t seq;			/* czas wysłania zapytania */
-} GG_PACKED;
-
-#define GG_NEW_STATUS 0x0002
-
-#ifndef DOXYGEN
-
-#define GG_STATUS_NOT_AVAIL 0x0001
-#define GG_STATUS_NOT_AVAIL_DESCR 0x0015
-#define GG_STATUS_FFC 0x0017
-#define GG_STATUS_FFC_DESCR 0x0018
-#define GG_STATUS_AVAIL 0x0002
-#define GG_STATUS_AVAIL_DESCR 0x0004
-#define GG_STATUS_BUSY 0x0003
-#define GG_STATUS_BUSY_DESCR 0x0005
-#define GG_STATUS_DND 0x0021
-#define GG_STATUS_DND_DESCR 0x0022
-#define GG_STATUS_INVISIBLE 0x0014
-#define GG_STATUS_INVISIBLE_DESCR 0x0016
-#define GG_STATUS_BLOCKED 0x0006
-
-#define GG_STATUS_GGPLUS 0x0020
-#define GG_STATUS_NOT_SET 0x0023
-#define GG_STATUS_UNKNOWN 0x0025
-
-#define GG_STATUS_IMAGE_MASK 0x0100
-#define GG_STATUS_DESCR_MASK 0x4000
-#define GG_STATUS_FRIENDS_MASK 0x8000
-
-#define GG_STATUS_FLAG_UNKNOWN 0x00000001
-#define GG_STATUS_FLAG_VIDEO 0x00000002
-#define GG_STATUS_FLAG_INHERIT 0x00000020
-#define GG_STATUS_FLAG_MOBILE 0x00100000
-#define GG_STATUS_FLAG_SPAM 0x00800000
-
-#else
-
-/**
- * Rodzaje statusów użytkownika.
- *
- * \ingroup status
- */
-enum {
-	GG_STATUS_NOT_AVAIL,		/**< Niedostępny */
-	GG_STATUS_NOT_AVAIL_DESCR,	/**< Niedostępny z opisem */
-	GG_STATUS_FFC,			/**< PoGGadaj ze mną */
-	GG_STATUS_FFC_DESCR,		/**< PoGGadaj ze mną z opisem */
-	GG_STATUS_AVAIL,		/**< Dostępny */
-	GG_STATUS_AVAIL_DESCR,		/**< Dostępny z opisem */
-	GG_STATUS_BUSY,			/**< Zajęty */
-	GG_STATUS_BUSY_DESCR,		/**< Zajęty z opisem */
-	GG_STATUS_DND,			/**< Nie przeszkadzać */
-	GG_STATUS_DND_DESCR,		/**< Nie przeszakdzać z opisem */
-	GG_STATUS_INVISIBLE,		/**< Niewidoczny (tylko własny status) */
-	GG_STATUS_INVISIBLE_DESCR,	/**< Niewidoczny z opisem (tylko własny status) */
-	GG_STATUS_BLOCKED,		/**< Zablokowany (tylko status innych) */
-	GG_STATUS_GGPLUS,		/**< Status "Korzystam z GG Plus" */
-	GG_STATUS_NOT_SET,		/**< Status nie ustawiony (przy logowaniu się do sieci) */
-	GG_STATUS_IMAGE_MASK,		/**< Flaga bitowa oznaczająca opis graficzny (tylko jeśli wybrano \c GG_FEATURE_IMAGE_DESCR) */
-	GG_STATUS_DESCR_MASK,		/**< Flaga bitowa oznaczająca status z opisem (tylko jeśli wybrano \c GG_FEATURE_IMAGE_DESCR) */
-	GG_STATUS_FRIENDS_MASK,		/**< Flaga bitowa dostępności tylko dla znajomych */
-};
-
-/**
- * Rodzaje statusów użytkownika. Mapa bitowa.
- *
- * \ingroup status
- */
-enum {
-	GG_STATUS_FLAG_UNKNOWN,		/**< Przeznaczenie nieznane, ale występuje zawsze */
-	GG_STATUS_FLAG_VIDEO,		/**< Klient obsługuje wideorozmowy */
-	GG_STATUS_FLAG_INHERIT,		/**< Synchronizacja statusu do innych klientów (przy logowaniu się do sieci) */
-	GG_STATUS_FLAG_MOBILE,		/**< Klient mobilny (ikona telefonu komórkowego) */
-	GG_STATUS_FLAG_SPAM,		/**< Klient chce otrzymywać linki od nieznajomych */
-};
-
-#endif	/* DOXYGEN */
-
-/**
- * \ingroup status
- *
- * Flaga bitowa dostepnosci informujaca ze mozemy voipowac
- */
-
-#define GG_STATUS_VOICE_MASK 0x20000	/**< czy ma wlaczone audio (7.7) */
-
-/**
- * \ingroup status
- *
- * Maksymalna długośc opisu.
- */
-#define GG_STATUS_DESCR_MAXSIZE 255
-#define GG_STATUS_DESCR_MAXSIZE_PRE_8_0 70
-
-#define GG_STATUS_MASK 0xff
-
-/* GG_S_F() tryb tylko dla znajomych */
-#define GG_S_F(x) (((x) & GG_STATUS_FRIENDS_MASK) != 0)
-
-/* GG_S() stan bez uwzględnienia dodatkowych flag */
-#define GG_S(x) ((x) & GG_STATUS_MASK)
-
-
-/* GG_S_FF() chętny do rozmowy */
-#define GG_S_FF(x) (GG_S(x) == GG_STATUS_FFC || GG_S(x) == GG_STATUS_FFC_DESCR)
-
-/* GG_S_AV() dostępny */
-#define GG_S_AV(x) (GG_S(x) == GG_STATUS_AVAIL || GG_S(x) == GG_STATUS_AVAIL_DESCR)
-
-/* GG_S_AW() zaraz wracam */
-#define GG_S_AW(x) (GG_S(x) == GG_STATUS_BUSY || GG_S(x) == GG_STATUS_BUSY_DESCR)
-
-/* GG_S_DD() nie przeszkadzać */
-#define GG_S_DD(x) (GG_S(x) == GG_STATUS_DND || GG_S(x) == GG_STATUS_DND_DESCR)
-
-/* GG_S_NA() niedostępny */
-#define GG_S_NA(x) (GG_S(x) == GG_STATUS_NOT_AVAIL || GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR)
-
-/* GG_S_I() niewidoczny */
-#define GG_S_I(x) (GG_S(x) == GG_STATUS_INVISIBLE || GG_S(x) == GG_STATUS_INVISIBLE_DESCR)
-
-
-/* GG_S_A() dostępny lub chętny do rozmowy */
-#define GG_S_A(x) (GG_S_FF(x) || GG_S_AV(x))
-
-/* GG_S_B() zajęty lub nie przeszkadzać */
-#define GG_S_B(x) (GG_S_AW(x) || GG_S_DD(x))
-
-
-/* GG_S_D() stan opisowy */
-#define GG_S_D(x) (GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR || \
-		   GG_S(x) == GG_STATUS_FFC_DESCR || \
-		   GG_S(x) == GG_STATUS_AVAIL_DESCR || \
-		   GG_S(x) == GG_STATUS_BUSY_DESCR || \
-		   GG_S(x) == GG_STATUS_DND_DESCR || \
-		   GG_S(x) == GG_STATUS_INVISIBLE_DESCR)
-
-/* GG_S_BL() blokowany lub blokujący */
-#define GG_S_BL(x) (GG_S(x) == GG_STATUS_BLOCKED)
-
-/**
- * Zmiana statusu (pakiet \c GG_NEW_STATUS i \c GG_NEW_STATUS80BETA)
- */
-struct gg_new_status {
-	uint32_t status;			/**< Nowy status */
-} GG_PACKED;
-
-#define GG_NOTIFY_FIRST 0x000f
-#define GG_NOTIFY_LAST 0x0010
-
-#define GG_NOTIFY 0x0010
-
-struct gg_notify {
-	uint32_t uin;				/* numerek danej osoby */
-	uint8_t dunno1;				/* rodzaj wpisu w liście */
-} GG_PACKED;
-
-#ifndef DOXYGEN
-
-#define GG_USER_OFFLINE 0x01
-#define GG_USER_NORMAL 0x03
-#define GG_USER_BLOCKED 0x04
-
-#else
-
-/**
- * \ingroup contacts
- *
- * Rodzaj kontaktu.
- */
-enum {
-	GG_USER_NORMAL,		/**< Zwykły kontakt */
-	GG_USER_BLOCKED,	/**< Zablokowany */
-	GG_USER_OFFLINE,	/**< Niewidoczny dla kontaktu */
-};
-
-#endif	/* DOXYGEN */
-
-#define GG_LIST_EMPTY 0x0012
-
-#define GG_NOTIFY_REPLY 0x000c	/* tak, to samo co GG_LOGIN */
-
-struct gg_notify_reply {
-	uint32_t uin;			/* numerek */
-	uint32_t status;		/* status danej osoby */
-	uint32_t remote_ip;		/* adres ip delikwenta */
-	uint16_t remote_port;		/* port, na którym słucha klient */
-	uint32_t version;		/* wersja klienta */
-	uint16_t dunno2;		/* znowu port? */
-} GG_PACKED;
-
-#define GG_NOTIFY_REPLY60 0x0011
-
-struct gg_notify_reply60 {
-	uint32_t uin;			/* numerek plus flagi w MSB */
-	uint8_t status;			/* status danej osoby */
-	uint32_t remote_ip;		/* adres ip delikwenta */
-	uint16_t remote_port;		/* port, na którym słucha klient */
-	uint8_t version;		/* wersja klienta */
-	uint8_t image_size;		/* maksymalny rozmiar grafiki w KiB */
-	uint8_t dunno1;			/* 0x00 */
-} GG_PACKED;
-
-#define GG_STATUS60 0x000f
-
-struct gg_status60 {
-	uint32_t uin;			/* numerek plus flagi w MSB */
-	uint8_t status;			/* status danej osoby */
-	uint32_t remote_ip;		/* adres ip delikwenta */
-	uint16_t remote_port;		/* port, na którym słucha klient */
-	uint8_t version;		/* wersja klienta */
-	uint8_t image_size;		/* maksymalny rozmiar grafiki w KiB */
-	uint8_t dunno1;			/* 0x00 */
-} GG_PACKED;
-
-#define GG_NOTIFY_REPLY77 0x0018
-
-struct gg_notify_reply77 {
-	uint32_t uin;			/* numerek plus flagi w MSB */
-	uint8_t status;			/* status danej osoby */
-	uint32_t remote_ip;		/* adres ip delikwenta */
-	uint16_t remote_port;		/* port, na którym słucha klient */
-	uint8_t version;		/* wersja klienta */
-	uint8_t image_size;		/* maksymalny rozmiar grafiki w KiB */
-	uint8_t dunno1;			/* 0x00 */
-	uint32_t dunno2;		/* ? */
-} GG_PACKED;
-
-#define GG_STATUS77 0x0017
-
-struct gg_status77 {
-	uint32_t uin;			/* numerek plus flagi w MSB */
-	uint8_t status;			/* status danej osoby */
-	uint32_t remote_ip;		/* adres ip delikwenta */
-	uint16_t remote_port;		/* port, na którym słucha klient */
-	uint8_t version;		/* wersja klienta */
-	uint8_t image_size;		/* maksymalny rozmiar grafiki w KiB */
-	uint8_t dunno1;			/* 0x00 */
-	uint32_t dunno2;		/* ? */
-} GG_PACKED;
-
-#define GG_ADD_NOTIFY 0x000d
-#define GG_REMOVE_NOTIFY 0x000e
-
-struct gg_add_remove {
-	uint32_t uin;			/* numerek */
-	uint8_t dunno1;			/* bitmapa */
-} GG_PACKED;
-
-#define GG_STATUS 0x0002
-
-struct gg_status {
-	uint32_t uin;			/* numerek */
-	uint32_t status;		/* nowy stan */
-} GG_PACKED;
-
-#define GG_SEND_MSG 0x000b
-
-#ifndef DOXYGEN
-
-#define GG_CLASS_QUEUED 0x0001
-#define GG_CLASS_OFFLINE GG_CLASS_QUEUED
-#define GG_CLASS_MSG 0x0004
-#define GG_CLASS_CHAT 0x0008
-#define GG_CLASS_CTCP 0x0010
-#define GG_CLASS_ACK 0x0020
-#define GG_CLASS_EXT GG_CLASS_ACK	/**< Dla kompatybilności wstecz */
-
-#else
-
-/**
- * Klasy wiadomości. Wartości są maskami bitowymi, które w większości
- * przypadków można łączyć (połączenie \c GG_CLASS_MSG i \c GG_CLASS_CHAT
- * nie ma sensu).
- *
- * \ingroup messages
- */
-enum {
-	GG_CLASS_MSG,		/**< Wiadomość ma pojawić się w osobnym oknie */
-	GG_CLASS_CHAT,		/**< Wiadomość ma pojawić się w oknie rozmowy */
-	GG_CLASS_CTCP,		/**< Wiadomość przeznaczona dla klienta Gadu-Gadu */
-	GG_CLASS_ACK,		/**< Klient nie życzy sobie potwierdzenia */
-	GG_CLASS_QUEUED,	/**< Wiadomość zakolejkowana na serwerze (tylko przy odbieraniu) */
-};
-
-#endif	/* DOXYGEN */
-
-/**
- * Maksymalna długość wiadomości.
- *
- * \ingroup messages
- */
-#define GG_MSG_MAXSIZE 1989
-
-struct gg_send_msg {
-	uint32_t recipient;
-	uint32_t seq;
-	uint32_t msgclass;
-} GG_PACKED;
-
-struct gg_msg_richtext {
-	uint8_t flag;
-	uint16_t length;
-} GG_PACKED;
-
-/**
- * Struktura opisująca formatowanie tekstu. W zależności od wartości pola
- * \c font, zaraz za tą strukturą może wystąpić \c gg_msg_richtext_color
- * lub \c gg_msg_richtext_image.
- *
- * \ingroup messages
- */
-struct gg_msg_richtext_format {
-	uint16_t position;	/**< Początkowy znak formatowania (liczony od 0) */
-	uint8_t font;		/**< Atrybuty formatowania */
-} GG_PACKED;
-
-#ifndef DOXYGEN
-
-#define GG_FONT_BOLD 0x01
-#define GG_FONT_ITALIC 0x02
-#define GG_FONT_UNDERLINE 0x04
-#define GG_FONT_COLOR 0x08
-#define GG_FONT_IMAGE 0x80
-
-#else
-
-/**
- * Atrybuty formatowania wiadomości.
- *
- * \ingroup messages
- */
-enum {
-	GG_FONT_BOLD,
-	GG_FONT_ITALIC,
-	GG_FONT_UNDERLINE,
-	GG_FONT_COLOR,
-	GG_FONT_IMAGE
-};
-
-#endif	/* DOXYGEN */
-
-/**
- * Struktura opisującą kolor tekstu dla atrybutu \c GG_FONT_COLOR.
- *
- * \ingroup messages
- */
-struct gg_msg_richtext_color {
-	uint8_t red;		/**< Składowa czerwona koloru */
-	uint8_t green;		/**< Składowa zielona koloru */
-	uint8_t blue;		/**< Składowa niebieska koloru */
-} GG_PACKED;
-
-/**
- * Strukturya opisująca obrazek wstawiony do wiadomości dla atrubutu
- * \c GG_FONT_IMAGE.
- *
- * \ingroup messages
- */
-struct gg_msg_richtext_image {
-	uint16_t unknown1;	/**< Nieznane pole o wartości 0x0109 */
-	uint32_t size;		/**< Rozmiar obrazka */
-	uint32_t crc32;		/**< Suma kontrolna CRC32 obrazka */
-} GG_PACKED;
-
-struct gg_msg_recipients {
-	uint8_t flag;
-	uint32_t count;
-} GG_PACKED;
-
-struct gg_msg_image_request {
-	uint8_t flag;
-	uint32_t size;
-	uint32_t crc32;
-} GG_PACKED;
-
-struct gg_msg_image_reply {
-	uint8_t flag;
-	uint32_t size;
-	uint32_t crc32;
-	/* char filename[]; */
-	/* char image[]; */
-} GG_PACKED;
-
-#define GG_SEND_MSG_ACK 0x0005
-
-#ifndef DOXYGEN
-
-#define GG_ACK_BLOCKED 0x0001
-#define GG_ACK_DELIVERED 0x0002
-#define GG_ACK_QUEUED 0x0003
-#define GG_ACK_MBOXFULL 0x0004
-#define GG_ACK_NOT_DELIVERED 0x0006
-
-#else
-
-/**
- * Status doręczenia wiadomości.
- *
- * \ingroup messages
- */
-enum
-{
-	GG_ACK_DELIVERED,	/**< Wiadomość dostarczono. */
-	GG_ACK_QUEUED,		/**< Wiadomość zakolejkowano z powodu niedostępności odbiorcy. */
-	GG_ACK_BLOCKED,		/**< Wiadomość zablokowana przez serwer (spam, świąteczne ograniczenia itd.) */
-	GG_ACK_MBOXFULL,	/**< Wiadomości nie dostarczono z powodu zapełnionej kolejki wiadomości odbiorcy. */
-	GG_ACK_NOT_DELIVERED	/**< Wiadomości nie dostarczono (tylko dla \c GG_CLASS_CTCP). */
-};
-
-#endif	/* DOXYGEN */
-
-struct gg_send_msg_ack {
-	uint32_t status;
-	uint32_t recipient;
-	uint32_t seq;
-} GG_PACKED;
-
-#define GG_RECV_MSG 0x000a
-
-struct gg_recv_msg {
-	uint32_t sender;
-	uint32_t seq;
-	uint32_t time;
-	uint32_t msgclass;
-} GG_PACKED;
-
-#define GG_PING 0x0008
-
-#define GG_PONG 0x0007
-
-#define GG_DISCONNECTING 0x000b
-
-#define GG_USERLIST_REQUEST 0x0016
-
-#define GG_XML_EVENT 0x0027
-
-#ifndef DOXYGEN
-
-#define GG_USERLIST_PUT 0x00
-#define GG_USERLIST_PUT_MORE 0x01
-#define GG_USERLIST_GET 0x02
-
-#else
-
-/**
- * \ingroup importexport
- *
- * Rodzaj zapytania.
- */
-enum {
-	GG_USERLIST_PUT,	/**< Eksport listy kontaktów. */
-	GG_USERLIST_GET,	/**< Import listy kontaktów. */
-};
-
-#endif	/* DOXYGEN */
-
-struct gg_userlist_request {
-	uint8_t type;
-} GG_PACKED;
-
-#define GG_USERLIST_REPLY 0x0010
-
-#ifndef DOXYGEN
-
-#define GG_USERLIST_PUT_REPLY 0x00
-#define GG_USERLIST_PUT_MORE_REPLY 0x02
-#define GG_USERLIST_GET_REPLY 0x06
-#define GG_USERLIST_GET_MORE_REPLY 0x04
-
-#else
-
-/**
- * \ingroup importexport
- *
- * Rodzaj odpowiedzi.
- */
-enum {
-	GG_USERLIST_PUT_REPLY,	/**< Wyeksportowano listy kontaktów. */
-	GG_USERLIST_GET_REPLY,	/**< Zaimportowano listę kontaktów. */
-};
-
-#endif	/* DOXYGEN */
-
-struct gg_userlist_reply {
-	uint8_t type;
-} GG_PACKED;
-
-#ifndef DOXYGEN
-
-#define GG_USERLIST100_PUT 0x00
-#define GG_USERLIST100_GET 0x02
-
-#else
-
-/**
- * \ingroup importexport
- *
- * Rodzaj zapytania (10.0).
- */
-enum {
-	GG_USERLIST100_PUT,	/**< Eksport listy kontaktów. */
-	GG_USERLIST100_GET,	/**< Import listy kontaktów. */
-};
-
-#endif	/* DOXYGEN */
-
-#ifndef DOXYGEN
-
-#define GG_USERLIST100_FORMAT_TYPE_NONE 0x00
-#define GG_USERLIST100_FORMAT_TYPE_GG70 0x01
-#define GG_USERLIST100_FORMAT_TYPE_GG100 0x02
-
-#else
-
-/**
- * \ingroup importexport
- *
- * Typ formatu listy kontaktów (10.0).
- */
-enum {
-	GG_USERLIST100_FORMAT_TYPE_NONE,	/**< Brak treści listy kontaktów. */
-	GG_USERLIST100_FORMAT_TYPE_GG70,	/**< Format listy kontaktów zgodny z Gadu-Gadu 7.0. */
-	GG_USERLIST100_FORMAT_TYPE_GG100,	/**< Format listy kontaktów zgodny z Gadu-Gadu 10.0. */
-};
-
-#endif	/* DOXYGEN */
-
-#ifndef DOXYGEN
-
-#define GG_USERLIST100_REPLY_LIST 0x00
-#define GG_USERLIST100_REPLY_UPTODATE 0x01
-#define GG_USERLIST100_REPLY_ACK 0x10
-#define GG_USERLIST100_REPLY_REJECT 0x12
-
-#else
-
-/**
- * \ingroup importexport
- *
- * Typ odpowiedzi listy kontaktów (10.0).
- */
-enum {
-	GG_USERLIST100_REPLY_LIST,	/**< W odpowiedzi znajduje się aktualna lista kontaktów na serwerze. */
-	GG_USERLIST100_REPLY_UPTODATE,	/**< Komunikat o tym, że lista kontaktów jest już zsynchronizowana. */
-	GG_USERLIST100_REPLY_ACK,	/**< Potwierdzenie odebrania nowej wersji listy kontaktów. W polu \c gg_userlist100_reply.version znajduje się numer nowej wersji listy kontaktów. */
-	GG_USERLIST100_REPLY_REJECT,	/**< Odmowa przyjęcia nowej wersji listy kontaktów. W polu \c gg_userlist100_reply.version znajduje się numer wersji listy kontaktów aktualnie przechowywanej przez serwer. */
-};
-
-#endif /* DOXYGEN */
-
-struct gg_dcc_tiny_packet {
-	uint8_t type;		/* rodzaj pakietu */
-} GG_PACKED;
-
-struct gg_dcc_small_packet {
-	uint32_t type;		/* rodzaj pakietu */
-} GG_PACKED;
-
-struct gg_dcc_big_packet {
-	uint32_t type;		/* rodzaj pakietu */
-	uint32_t dunno1;		/* niewiadoma */
-	uint32_t dunno2;		/* niewiadoma */
-} GG_PACKED;
-
-/*
- * póki co, nie znamy dokładnie protokołu. nie wiemy, co czemu odpowiada.
- * nazwy są niepoważne i tymczasowe.
- */
-#define GG_DCC_WANT_FILE 0x0003		/* peer chce plik */
-#define GG_DCC_HAVE_FILE 0x0001		/* więc mu damy */
-#define GG_DCC_HAVE_FILEINFO 0x0003	/* niech ma informacje o pliku */
-#define GG_DCC_GIMME_FILE 0x0006	/* peer jest pewny */
-#define GG_DCC_CATCH_FILE 0x0002	/* wysyłamy plik */
-
-#define GG_DCC_FILEATTR_READONLY 0x0020
-
-#define GG_DCC_TIMEOUT_SEND 1800	/* 30 minut */
-#define GG_DCC_TIMEOUT_GET 1800		/* 30 minut */
-#define GG_DCC_TIMEOUT_FILE_ACK 300	/* 5 minut */
-#define GG_DCC_TIMEOUT_VOICE_ACK 300	/* 5 minut */
-
-#define GG_DCC7_INFO 0x1f
-
-struct gg_dcc7_info {
-	uint32_t uin;			/* numer nadawcy */
-	uint32_t type;			/* sposób połączenia */
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-	char info[GG_DCC7_INFO_LEN];	/* informacje o połączeniu "ip port" */
-	char hash[GG_DCC7_INFO_HASH_LEN];/* skrót "ip" */
-} GG_PACKED;
-
-#define GG_DCC7_NEW 0x20
-
-struct gg_dcc7_new {
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-	uint32_t uin_from;		/* numer nadawcy */
-	uint32_t uin_to;		/* numer odbiorcy */
-	uint32_t type;			/* rodzaj transmisji */
-	unsigned char filename[GG_DCC7_FILENAME_LEN];	/* nazwa pliku */
-	uint32_t size;			/* rozmiar pliku */
-	uint32_t size_hi;		/* rozmiar pliku (starsze bajty) */
-	unsigned char hash[GG_DCC7_HASH_LEN];	/* hash SHA1 */
-} GG_PACKED;
-
-#define GG_DCC7_ACCEPT 0x21
-
-struct gg_dcc7_accept {
-	uint32_t uin;			/* numer przyjmującego połączenie */
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-	uint32_t offset;		/* offset przy wznawianiu transmisji */
-	uint32_t dunno1;		/* 0x00000000 */
-} GG_PACKED;
-
-/* XXX API */
-#define GG_DCC7_TYPE_P2P 0x00000001	/**< Połączenie bezpośrednie */
-#define GG_DCC7_TYPE_SERVER 0x00000002	/**< Połączenie przez serwer */
-
-#define GG_DCC7_REJECT 0x22
-
-struct gg_dcc7_reject {
-	uint32_t uin;			/**< Numer odrzucającego połączenie */
-	gg_dcc7_id_t id;		/**< Identyfikator połączenia */
-	uint32_t reason;		/**< Powód rozłączenia */
-} GG_PACKED;
-
-/* XXX API */
-#define GG_DCC7_REJECT_BUSY 0x00000001	/**< Połączenie bezpośrednie już trwa, nie umiem obsłużyć więcej */
-#define GG_DCC7_REJECT_USER 0x00000002	/**< Użytkownik odrzucił połączenie */
-#define GG_DCC7_REJECT_VERSION 0x00000006	/**< Druga strona ma wersję klienta nieobsługującą połączeń bezpośrednich tego typu */
-
-#define GG_DCC7_ID_REQUEST 0x23
-
-struct gg_dcc7_id_request {
-	uint32_t type;			/**< Rodzaj tranmisji */
-} GG_PACKED;
-
-/* XXX API */
-#define GG_DCC7_TYPE_VOICE 0x00000001	/**< Transmisja głosu */
-#define GG_DCC7_TYPE_FILE 0x00000004	/**< transmisja pliku */
-
-#define GG_DCC7_ID_REPLY 0x23
-
-struct gg_dcc7_id_reply {
-	uint32_t type;			/** Rodzaj transmisji */
-	gg_dcc7_id_t id;		/** Przyznany identyfikator */
-} GG_PACKED;
-
-#define GG_DCC7_DUNNO1 0x24
-
-#define GG_DCC7_TIMEOUT_CONNECT 10	/* 10 sekund */
-#define GG_DCC7_TIMEOUT_SEND 1800	/* 30 minut */
-#define GG_DCC7_TIMEOUT_GET 1800	/* 30 minut */
-#define GG_DCC7_TIMEOUT_FILE_ACK 300	/* 5 minut */
-#define GG_DCC7_TIMEOUT_VOICE_ACK 300	/* 5 minut */
-
-#define GG_CHAT_INFO_UPDATE_ENTERED 0x01
-#define GG_CHAT_INFO_UPDATE_EXITED 0x03
-
-#ifdef __cplusplus
-}
-#endif
-
-#ifdef _WIN32
-#pragma pack(pop)
-#endif
-
-#endif /* LIBGADU_LIBGADU_H */
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
--- a/libpurple/protocols/gg/lib/message.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1016 +0,0 @@
-/*
- *  (C) Copyright 2001-2010 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file message.c
- *
- * \brief Obsługa wiadomości
- *
- * Plik zawiera funkcje dotyczące obsługi "klasy" gg_message_t, które
- * w przyszłości zostaną dołączone do API. Obecnie używane są funkcje
- * konwersji między tekstem z atrybutami i HTML.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "message.h"
-
-#if 0
-
-gg_message_t *gg_message_new(void)
-{
-	gg_message_t *gm;
-
-	gm = malloc(sizeof(gg_message_t));
-
-	if (gm == NULL)
-		return NULL;
-
-	memset(gm, 0, sizeof(gg_message_t));
-
-	gm->msgclass = GG_CLASS_CHAT;
-	gm->seq = (uint32_t) -1;
-
-	return gm;
-}
-
-int gg_message_init(gg_message_t *gm, int msgclass, int seq, uin_t *recipients,
-	size_t recipient_count, char *text, char *html, char *attributes,
-	size_t attributes_length, int auto_convert)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	memset(gm, 0, sizeof(gg_message_t));
-	gm->recipients = recipients;
-	gm->recipient_count = recipient_count;
-	gm->text = text;
-	gm->html = html;
-	gm->attributes = attributes;
-	gm->attributes_length = attributes_length;
-	gm->msgclass = msgclass;
-	gm->seq = seq;
-	gm->auto_convert = auto_convert;
-
-	return 0;
-}
-
-void gg_message_free(gg_message_t *gm)
-{
-	if (gm == NULL) {
-		errno = EINVAL;
-		return;
-	}
-
-	free(gm->text);
-	free(gm->text_converted);
-	free(gm->html);
-	free(gm->html_converted);
-	free(gm->recipients);
-	free(gm->attributes);
-
-	free(gm);
-}
-
-int gg_message_set_auto_convert(gg_message_t *gm, int auto_convert)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	gm->auto_convert = !!auto_convert;
-
-	if (!gm->auto_convert) {
-		free(gm->text_converted);
-		free(gm->html_converted);
-		gm->text_converted = NULL;
-		gm->html_converted = NULL;
-	}
-
-	return 0;
-}
-
-int gg_message_get_auto_convert(gg_message_t *gm)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	return gm->auto_convert;
-}
-
-int gg_message_set_recipients(gg_message_t *gm, const uin_t *recipients, size_t recipient_count)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	if (recipient_count >= INT_MAX / sizeof(uin_t)) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	if ((recipients == NULL) || (recipient_count == 0)) {
-		free(gm->recipients);
-		gm->recipients = NULL;
-		gm->recipient_count = 0;
-	} else {
-		uin_t *tmp;
-
-		tmp = realloc(gm->recipients, recipient_count * sizeof(uin_t));
-
-		if (tmp == NULL)
-			return -1;
-
-		memcpy(tmp, recipients, recipient_count * sizeof(uin_t));
-
-		gm->recipients = tmp;
-		gm->recipient_count = recipient_count;
-	}
-
-	return 0;
-}
-
-int gg_message_set_recipient(gg_message_t *gm, uin_t recipient)
-{
-	return gg_message_set_recipients(gm, &recipient, 1);
-}
-
-int gg_message_get_recipients(gg_message_t *gm, const uin_t **recipients, size_t *recipient_count)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	if (recipients != NULL)
-		*recipients = gm->recipients;
-
-	if (recipient_count != NULL)
-		*recipient_count = gm->recipient_count;
-
-	return 0;
-}
-
-uin_t gg_message_get_recipient(gg_message_t *gm)
-{
-	GG_MESSAGE_CHECK(gm, (uin_t) -1);
-
-	if ((gm->recipients == NULL) || (gm->recipient_count < 1)) {
-		/* errno = XXX; */
-		return (uin_t) -1;
-	}
-
-	return gm->recipients[0];
-}
-
-int gg_message_set_class(gg_message_t *gm, uint32_t msgclass)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	gm->msgclass = msgclass;
-
-	return 0;
-}
-
-uint32_t gg_message_get_class(gg_message_t *gm)
-{
-	GG_MESSAGE_CHECK(gm, (uint32_t) -1);
-
-	return gm->msgclass;
-}
-
-int gg_message_set_seq(gg_message_t *gm, uint32_t seq)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	gm->seq = seq;
-
-	return 0;
-}
-
-uint32_t gg_message_get_seq(gg_message_t *gm)
-{
-	GG_MESSAGE_CHECK(gm, (uint32_t) -1);
-
-	return gm->seq;
-}
-
-int gg_message_set_text(gg_message_t *gm, const char *text)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	if (text == NULL) {
-		free(gm->text);
-		gm->text = NULL;
-	} else {
-		char *tmp;
-
-		tmp = strdup(text);
-
-		if (tmp == NULL)
-			return -1;
-
-		free(gm->text);
-		gm->text = tmp;
-	}
-
-	free(gm->html_converted);
-	gm->html_converted = NULL;
-
-	return 0;
-}
-
-const char *gg_message_get_text(gg_message_t *gm)
-{
-	GG_MESSAGE_CHECK(gm, NULL);
-
-	if (gm->text_converted != NULL)
-		return gm->text_converted;
-
-	if (gm->text == NULL && gm->html != NULL && gm->auto_convert) {
-		size_t len;
-
-		free(gm->text_converted);
-
-		len = gg_message_html_to_text(NULL, gm->html);
-
-		gm->text_converted = malloc(len + 1);
-
-		if (gm->text_converted == NULL)
-			return NULL;
-
-		gg_message_html_to_text(gm->text_converted, gm->html);
-
-		return gm->text_converted;
-	}
-
-	return gm->text;
-}
-
-int gg_message_set_html(gg_message_t *gm, const char *html)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	if (html == NULL) {
-		free(gm->html);
-		gm->html = NULL;
-	} else {
-		char *tmp;
-
-		tmp = strdup(html);
-
-		if (tmp == NULL)
-			return -1;
-
-		free(gm->html);
-		gm->html = tmp;
-	}
-
-	free(gm->text_converted);
-	gm->text_converted = NULL;
-
-	return 0;
-}
-
-const char *gg_message_get_html(gg_message_t *gm)
-{
-	GG_MESSAGE_CHECK(gm, NULL);
-
-	if (gm->html_converted != NULL)
-		return gm->html_converted;
-
-	if (gm->html == NULL && gm->text != NULL && gm->auto_convert) {
-		size_t len;
-
-		free(gm->html_converted);
-
-		len = gg_message_text_to_html(NULL, gm->text, GG_ENCODING_UTF8, gm->attributes, gm->attributes_length);
-
-		gm->html_converted = malloc(len + 1);
-
-		if (gm->html_converted == NULL)
-			return NULL;
-
-		gg_message_text_to_html(gm->html_converted, gm->text,
-			GG_ENCODING_UTF8, gm->attributes, gm->attributes_length);
-
-		return gm->html_converted;
-	}
-
-	return gm->html;
-}
-
-int gg_message_set_attributes(gg_message_t *gm, const char *attributes, size_t length)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	if (length > 0xfffd) {
-		/* errno = XXX; */
-		return -1;
-	}
-
-	if ((attributes == NULL) || (length == 0)) {
-		free(gm->attributes);
-		gm->attributes = NULL;
-		gm->attributes_length = 0;
-	} else {
-		char *tmp;
-
-		tmp = realloc(gm->attributes, length);
-
-		if (tmp == NULL)
-			return -1;
-
-		gm->attributes = tmp;
-		gm->attributes_length = length;
-	}
-
-	free(gm->html_converted);
-	gm->html_converted = NULL;
-
-	return 0;
-}
-
-int gg_message_get_attributes(gg_message_t *gm, const char **attributes, size_t *attributes_length)
-{
-	GG_MESSAGE_CHECK(gm, -1);
-
-	if (attributes != NULL)
-		*attributes = gm->attributes;
-
-	if (attributes_length != NULL)
-		*attributes_length = gm->attributes_length;
-
-	return 0;
-}
-
-#endif
-
-/**
- * \internal Dodaje tekst na koniec bufora.
- *
- * \param dst Wskaźnik na bufor roboczy
- * \param pos Wskaźnik na aktualne położenie w buforze roboczym
- * \param src Dodawany tekst
- * \param len Długość dodawanego tekstu
- */
-static void gg_append(char *dst, size_t *pos, const void *src, size_t len)
-{
-	if (dst != NULL)
-		memcpy(&dst[*pos], src, len);
-
-	*pos += len;
-}
-
-/**
- * \internal Zamienia tekst z formatowaniem Gadu-Gadu na HTML.
- *
- * \param dst Bufor wynikowy (może być \c NULL)
- * \param src Tekst źródłowy
- * \param encoding Kodowanie tekstu źródłowego oraz wynikowego
- * \param format Atrybuty tekstu źródłowego
- * \param format_len Długość bloku atrybutów tekstu źródłowego
- *
- * \note Wynikowy tekst nie jest idealnym kodem HTML, ponieważ ma jak
- * dokładniej odzwierciedlać to, co wygenerowałby oryginalny klient.
- *
- * \note Dokleja \c \\0 na końcu bufora wynikowego.
- *
- * \return Długość tekstu wynikowego bez \c \\0 (nawet jeśli \c dst to \c NULL).
- */
-size_t gg_message_text_to_html(char *dst, const char *src,
-	gg_encoding_t encoding, const unsigned char *format, size_t format_len)
-{
-	const char span_fmt[] = "<span style=\"color:#%02x%02x%02x; font-family:'MS Shell Dlg 2'; font-size:9pt; \">";
-	const size_t span_len = 75;
-	const char img_fmt[] = "<img name=\"%02x%02x%02x%02x%02x%02x%02x%02x\">";
-	const size_t img_len = 29;
-	size_t char_pos = 0;
-	unsigned char old_attr = 0;
-	const unsigned char default_color[] = {'\x00', '\x00', '\x00'};
-	const unsigned char *old_color = NULL;
-	int in_span = 0;
-	unsigned int i;
-	size_t len = 0;
-
-	if (format == NULL)
-		format_len = 0;
-
-	/* Pętla przechodzi też przez kończące \0, żeby móc dokleić obrazek
-	 * na końcu tekstu. */
-
-	for (i = 0; ; i++) {
-		int in_char = 0;
-		size_t format_idx = 0;
-
-		/* Sprawdź, czy bajt jest kontynuacją znaku UTF-8. */
-		if (encoding == GG_ENCODING_UTF8 && (src[i] & 0xc0) == 0x80)
-			in_char = 1;
-
-		/* GG_FONT_IMAGE powinno dotyczyć tylko jednego znaku, więc czyścimy stary atrybut */
-
-		if (!in_char && (old_attr & GG_FONT_IMAGE) != 0)
-			old_attr &= ~GG_FONT_IMAGE;
-
-		/* Analizuj wszystkie atrybuty dotyczące aktualnego znaku. */
-		for (;;) {
-			unsigned char attr;
-			size_t attr_pos;
-
-			/* Nie wstawiamy niczego wewnątrz wielobajtowego znaku UTF-8. */
-			if (in_char)
-				break;
-
-			if (format_idx + 3 > format_len)
-				break;
-
-			/* (format_idx + 3 <= format_len) && (format_idx > 0)
-			 * 3 < format_len
-			 * 0 != format_len
-			 * format != NULL
-			 */
-			assert(format != NULL);
-
-			attr_pos = format[format_idx] | (format[format_idx + 1] << 8);
-			attr = format[format_idx + 2];
-
-			/* Nie doklejaj atrybutów na końcu, co najwyżej obrazki. */
-
-			if (src[i] == 0)
-				attr &= ~(GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR);
-
-			format_idx += 3;
-
-			if (attr_pos != char_pos) {
-				if ((attr & GG_FONT_COLOR) != 0)
-					format_idx += 3;
-				if ((attr & GG_FONT_IMAGE) != 0)
-					format_idx += 10;
-
-				continue;
-			}
-
-			if ((old_attr & GG_FONT_UNDERLINE) != 0)
-				gg_append(dst, &len, "</u>", 4);
-
-			if ((old_attr & GG_FONT_ITALIC) != 0)
-				gg_append(dst, &len, "</i>", 4);
-
-			if ((old_attr & GG_FONT_BOLD) != 0)
-				gg_append(dst, &len, "</b>", 4);
-
-			if ((attr & (GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR)) != 0) {
-				const unsigned char *color;
-
-				if (((attr & GG_FONT_COLOR) != 0) && (format_idx + 3 <= format_len)) {
-					color = &format[format_idx];
-					format_idx += 3;
-				} else {
-					color = default_color;
-				}
-
-				if (old_color == NULL || memcmp(color, old_color, 3) != 0) {
-					if (in_span) {
-						gg_append(dst, &len, "</span>", 7);
-						in_span = 0;
-					}
-
-					if (src[i] != 0) {
-						if (dst != NULL)
-							sprintf(&dst[len], span_fmt, color[0], color[1], color[2]);
-
-						len += span_len;
-						in_span = 1;
-						old_color = color;
-					}
-				}
-			}
-
-			if ((attr & GG_FONT_BOLD) != 0)
-				gg_append(dst, &len, "<b>", 3);
-
-			if ((attr & GG_FONT_ITALIC) != 0)
-				gg_append(dst, &len, "<i>", 3);
-
-			if ((attr & GG_FONT_UNDERLINE) != 0)
-				gg_append(dst, &len, "<u>", 3);
-
-			if (((attr & GG_FONT_IMAGE) != 0) && (format_idx + 10 <= format_len)) {
-				if (dst != NULL) {
-					sprintf(&dst[len], img_fmt,
-						format[format_idx + 9],
-						format[format_idx + 8],
-						format[format_idx + 7],
-						format[format_idx + 6],
-						format[format_idx + 5],
-						format[format_idx + 4],
-						format[format_idx + 3],
-						format[format_idx + 2]);
-				}
-
-				len += img_len;
-				format_idx += 10;
-			}
-
-			old_attr = attr;
-		}
-
-		if (src[i] == 0)
-			break;
-
-		/* Znaki oznaczone jako GG_FONT_IMAGE nie są częścią wiadomości. */
-
-		if ((old_attr & GG_FONT_IMAGE) != 0) {
-			if (!in_char)
-				char_pos++;
-
-			continue;
-		}
-
-		/* Jesteśmy na początku tekstu i choć nie było atrybutów dla pierwszego
-		* znaku, ponieważ tekst nie jest pusty, trzeba otworzyć <span>. */
-
-		if (!in_span) {
-			if (dst != NULL)
-				sprintf(&dst[len], span_fmt, default_color[0], default_color[1], default_color[2]);
-
-			len += span_len;
-			in_span = 1;
-			old_color = default_color;
-		}
-
-		/* Doklej znak zachowując htmlowe escapowanie. */
-
-		switch (src[i]) {
-			case '&':
-				gg_append(dst, &len, "&amp;", 5);
-				break;
-			case '<':
-				gg_append(dst, &len, "&lt;", 4);
-				break;
-			case '>':
-				gg_append(dst, &len, "&gt;", 4);
-				break;
-			case '\'':
-				gg_append(dst, &len, "&apos;", 6);
-				break;
-			case '\"':
-				gg_append(dst, &len, "&quot;", 6);
-				break;
-			case '\n':
-				gg_append(dst, &len, "<br>", 4);
-				break;
-			case '\r':
-				break;
-			default:
-				if (dst != NULL)
-					dst[len] = src[i];
-				len++;
-		}
-
-		if (!in_char)
-			char_pos++;
-	}
-
-	/* Zamknij tagi. */
-
-	if ((old_attr & GG_FONT_UNDERLINE) != 0)
-		gg_append(dst, &len, "</u>", 4);
-
-	if ((old_attr & GG_FONT_ITALIC) != 0)
-		gg_append(dst, &len, "</i>", 4);
-
-	if ((old_attr & GG_FONT_BOLD) != 0)
-		gg_append(dst, &len, "</b>", 4);
-
-	if (in_span)
-		gg_append(dst, &len, "</span>", 7);
-
-	if (dst != NULL)
-		dst[len] = 0;
-
-	return len;
-}
-
-/**
- * \internal Dokleja nowe atrybuty formatowania, jeśli konieczne, oraz inkrementuje pozycję znaku w tekście.
- *
- * \param pos Wskaźnik na zmienną przechowującą pozycję znaku w tekście
- * \param attr_flag Aktualna flaga atrybutu formatowania
- * \param old_attr_flag Wskaźnik na poprzednią flagę atrybutu formatowania
- * \param color Wskaźnik na tablicę z aktualnym kolorem RGB (jeśli \p attr_flag
- *        nie zawiera flagi \c GG_FONT_COLOR, ignorowane)
- * \param old_color Wskaźnik na tablicę z poprzednim kolorem RGB
- * \param imgs_size Rozmiar atrybutów formatowania obrazków znajdujących się
- *        obecnie w tablicy atrybutów formatowania, w bajtach
- * \param format Wskaźnik na wskaźnik do tablicy atrybutów formatowania
- * \param format_len Wskaźnik na zmienną zawierającą długość tablicy atrybutów
- *        formatowania, w bajtach (może być \c NULL)
- */
-static void gg_after_append_formatted_char(uint16_t *pos,
-	unsigned char attr_flag, unsigned char *old_attr_flag,
-	const unsigned char *color, unsigned char *old_color, size_t imgs_size,
-	unsigned char **format, size_t *format_len)
-{
-	const size_t color_size = 3;
-	int has_color = 0;
-
-	if ((attr_flag & GG_FONT_COLOR) != 0)
-		has_color = 1;
-
-	if (*old_attr_flag != attr_flag || (has_color && memcmp(old_color, color, color_size) != 0)) {
-		size_t attr_size = sizeof(*pos) + sizeof(attr_flag) + (has_color ? color_size : 0);
-
-		if (*format != NULL) {
-			/* Staramy się naśladować oryginalnego klienta i atrybuty obrazków trzymamy na końcu */
-
-			*format -= imgs_size;
-			memmove(*format + attr_size, *format, imgs_size);
-
-			**format = (unsigned char) (*pos & (uint16_t) 0x00ffU);
-			*format += 1;
-			**format = (unsigned char) ((*pos & (uint16_t) 0xff00U) >> 8);
-			*format += 1;
-
-			**format = attr_flag;
-			*format += 1;
-
-			if (has_color) {
-				memcpy(*format, color, color_size);
-				*format += color_size;
-			}
-
-			*format += imgs_size;
-		}
-
-		if (format_len != NULL)
-			*format_len += attr_size;
-
-		*old_attr_flag = attr_flag;
-		if (has_color)
-			memcpy(old_color, color, color_size);
-	}
-
-	*pos += 1;
-}
-
-/**
- * \internal Zamienia tekst w formacie HTML na czysty tekst.
- *
- * \param dst Bufor wynikowy (może być \c NULL)
- * \param format Bufor wynikowy z atrybutami formatowania (może być \c NULL)
- * \param format_len Wskaźnik na zmienną, do której zostanie zapisana potrzebna
- *                   wielkość bufora wynikowego z atrybutami formatowania,
- *                   w bajtach (może być \c NULL)
- * \param html Tekst źródłowy
- * \param encoding Kodowanie tekstu źródłowego oraz wynikowego
- *
- * \note Dokleja \c \\0 na końcu bufora wynikowego.
- *
- * \return Długość bufora wynikowego bez \c \\0 (nawet jeśli \c dst to \c NULL).
- */
-size_t gg_message_html_to_text(char *dst, unsigned char *format,
-	size_t *format_len, const char *html, gg_encoding_t encoding)
-{
-	const char *src, *entity = NULL, *tag = NULL;
-	int in_tag = 0, in_entity = 0, in_bold = 0, in_italic = 0, in_underline = 0;
-	unsigned char color[3] = { 0 }, old_color[3] = { 0 };
-	unsigned char attr_flag = 0, old_attr_flag = 0;
-	uint16_t pos = 0;
-	size_t len = 0, imgs_size = 0;
-
-	if (format_len != NULL)
-		*format_len = 0;
-
-	for (src = html; *src != 0; src++) {
-		if (in_entity && !(isalnum(*src) || *src == '#' || *src == ';')) {
-			int first = 1;
-			size_t i, append_len = src - entity;
-
-			gg_append(dst, &len, entity, append_len);
-			for (i = 0; i < append_len; i++) {
-				if (encoding != GG_ENCODING_UTF8 || (entity[i] & 0xc0) != 0x80) {
-					if (first) {
-						gg_after_append_formatted_char(&pos, attr_flag,
-							&old_attr_flag, color, old_color, imgs_size,
-							&format, format_len);
-						first = 0;
-					} else {
-						pos++;
-					}
-				}
-			}
-
-			in_entity = 0;
-		}
-
-		if (*src == '<') {
-			tag = src;
-			in_tag = 1;
-			continue;
-		}
-
-		if (in_tag && (*src == '>')) {
-			if (strncmp(tag, "<br", 3) == 0) {
-				if (dst != NULL)
-					dst[len] = '\n';
-				len++;
-
-				gg_after_append_formatted_char(&pos, attr_flag,
-					&old_attr_flag, color, old_color,
-					imgs_size, &format, format_len);
-			} else if (strncmp(tag, "<img name=\"", 11) == 0 || strncmp(tag, "<img name=\'", 11) == 0) {
-				tag += 11;
-
-				/* 17 bo jeszcze cudzysłów musi być zamknięty */
-				if (tag + 17 <= src) {
-					int i, ok = 1;
-
-					for (i = 0; i < 16; i++) {
-						if (!isxdigit(tag[i])) {
-							ok = 0;
-							break;
-						}
-					}
-
-					if (ok) {
-						unsigned char img_attr[13];
-
-						if (format != NULL) {
-							char buf[3] = { 0 };
-
-							img_attr[0] = (unsigned char) (pos & (uint16_t) 0x00ffU);
-							img_attr[1] = (unsigned char) ((pos & (uint16_t) 0xff00U) >> 8);
-							img_attr[2] = GG_FONT_IMAGE;
-							img_attr[3] = '\x09';
-							img_attr[4] = '\x01';
-							for (i = 0; i < 16; i += 2) {
-								buf[0] = tag[i];
-								buf[1] = tag[i + 1];
-								/* buf[2] to '\0' */
-								img_attr[12 - i / 2] =
-									(unsigned char)strtoul(buf, NULL, 16);
-							}
-
-							memcpy(format, img_attr, sizeof(img_attr));
-							format += sizeof(img_attr);
-						}
-
-						if (format_len != NULL)
-							*format_len += sizeof(img_attr);
-						imgs_size += sizeof(img_attr);
-
-						if (dst != NULL) {
-							if (encoding == GG_ENCODING_UTF8)
-								dst[len++] = '\xc2';
-							dst[len++] = '\xa0';
-						} else {
-							len += 2;
-						}
-
-						/* Nie używamy tutaj gg_after_append_formatted_char().
-						 * Po pierwsze to praktycznie niczego by nie
-						 * zmieniło, a po drugie nie wszystkim klientom
-						 * mogłaby się spodobać redefinicja atrybutów
-						 * formatowania dla jednego znaku (bo np. najpierw
-						 * byśmy zdefiniowali bolda od znaku 10, a potem
-						 * by się okazało, że znak 10 to obrazek).
-						 */
-
-						pos++;
-
-						/* Resetujemy atrybuty, aby je w razie czego
-						 * redefiniować od następnego znaku, co by sobie
-						 * nikt przypadkiem nie pomyślał, że GG_FONT_IMAGE
-						 * dotyczy więcej, niż jednego znaku.
-						 * Tak samo robi oryginalny klient.
-						 */
-
-						old_attr_flag = -1;
-					}
-				}
-			} else if (strncmp(tag, "<b>", 3) == 0) {
-				in_bold++;
-				attr_flag |= GG_FONT_BOLD;
-			} else if (strncmp(tag, "</b>", 4) == 0) {
-				if (in_bold > 0) {
-					in_bold--;
-					if (in_bold == 0)
-						attr_flag &= ~GG_FONT_BOLD;
-				}
-			} else if (strncmp(tag, "<i>", 3) == 0) {
-				in_italic++;
-				attr_flag |= GG_FONT_ITALIC;
-			} else if (strncmp(tag, "</i>", 4) == 0) {
-				if (in_italic > 0) {
-					in_italic--;
-					if (in_italic == 0)
-						attr_flag &= ~GG_FONT_ITALIC;
-				}
-			} else if (strncmp(tag, "<u>", 3) == 0) {
-				in_underline++;
-				attr_flag |= GG_FONT_UNDERLINE;
-			} else if (strncmp(tag, "</u>", 4) == 0) {
-				if (in_underline > 0) {
-					in_underline--;
-					if (in_underline == 0)
-						attr_flag &= ~GG_FONT_UNDERLINE;
-				}
-			} else if (strncmp(tag, "<span ", 6) == 0) {
-				for (tag += 6; tag < src - 8; tag++) {
-					if (*tag == '\"' || *tag == '\'' || *tag == ' ') {
-						if (strncmp(tag + 1, "color:#", 7) == 0) {
-							int i, ok = 1;
-							char buf[3] = { 0 };
-
-							tag += 8;
-							if (tag + 6 > src)
-								break;
-
-							for (i = 0; i < 6; i++) {
-								if (!isxdigit(tag[i])) {
-									ok = 0;
-									break;
-								}
-							}
-
-							if (!ok)
-								break;
-
-							for (i = 0; i < 6; i += 2) {
-								buf[0] = tag[i];
-								buf[1] = tag[i + 1];
-								/* buf[2] to '\0' */
-								color[i / 2] = (unsigned char) strtoul(buf, NULL, 16);
-							}
-
-							attr_flag |= GG_FONT_COLOR;
-						}
-					}
-				}
-			} else if (strncmp(tag, "</span", 6) == 0) {
-				/* Można by trzymać kolory na stosie i tutaj
-				 * przywracać poprzedni, ale to raczej zbędne */
-
-				attr_flag &= ~GG_FONT_COLOR;
-			}
-
-			tag = NULL;
-			in_tag = 0;
-			continue;
-		}
-
-		if (in_tag)
-			continue;
-
-		if (*src == '&') {
-			in_entity = 1;
-			entity = src;
-			continue;
-		}
-
-		if (in_entity && *src == ';') {
-			in_entity = 0;
-
-			if (dst != NULL) {
-				if (strncmp(entity, "&lt;", 4) == 0)
-					dst[len++] = '<';
-				else if (strncmp(entity, "&gt;", 4) == 0)
-					dst[len++] = '>';
-				else if (strncmp(entity, "&quot;", 6) == 0)
-					dst[len++] = '"';
-				else if (strncmp(entity, "&apos;", 6) == 0)
-					dst[len++] = '\'';
-				else if (strncmp(entity, "&amp;", 5) == 0)
-					dst[len++] = '&';
-				else if (strncmp(entity, "&nbsp;", 6) == 0) {
-					if (encoding == GG_ENCODING_UTF8)
-						dst[len++] = '\xc2';
-					dst[len++] = '\xa0';
-				} else
-					dst[len++] = '?';
-			} else {
-				if (strncmp(entity, "&nbsp;", 6) == 0)
-					len += 2;
-				else
-					len++;
-			}
-
-			gg_after_append_formatted_char(&pos, attr_flag,
-				&old_attr_flag, color, old_color, imgs_size,
-				&format, format_len);
-
-			continue;
-		}
-
-		if (in_entity && !(isalnum(*src) || *src == '#'))
-			in_entity = 0;
-
-		if (in_entity)
-			continue;
-
-		if (dst != NULL)
-			dst[len] = *src;
-		len++;
-
-		if (encoding != GG_ENCODING_UTF8 || (*src & 0xc0) != 0x80) {
-			gg_after_append_formatted_char(&pos, attr_flag,
-				&old_attr_flag, color, old_color, imgs_size,
-				&format, format_len);
-		}
-	}
-
-	if (dst != NULL)
-		dst[len] = '\0';
-
-	return len;
-}
-
-static size_t gg_message_html_to_text_110_buff(char *dst, const char *html)
-{
-	return gg_message_html_to_text(dst, NULL, NULL, html, GG_ENCODING_UTF8);
-}
-
-static size_t gg_message_text_to_html_110_buff(char *dst, const char *text,
-	ssize_t text_len)
-{
-	size_t i, dst_len;
-
-	if (text_len == -1)
-		text_len = strlen(text);
-	dst_len = 0;
-
-	gg_append(dst, &dst_len, "<span>", 6);
-
-	for (i = 0; i < (size_t)text_len; i++) {
-		char c = text[i];
-		if (c == '<')
-			gg_append(dst, &dst_len, "&lt;", 4);
-		else if (c == '>')
-			gg_append(dst, &dst_len, "&gt;", 4);
-		else if (c == '&')
-			gg_append(dst, &dst_len, "&amp;", 5);
-		else if (c == '"')
-			gg_append(dst, &dst_len, "&quot;", 6);
-		else if (c == '\'')
-			gg_append(dst, &dst_len, "&apos;", 6);
-		else if (c == '\n')
-			gg_append(dst, &dst_len, "<br>", 4);
-		else if (c == '\r')
-			continue;
-		else if (c == '\xc2' && text[i + 1] == '\xa0') {
-			gg_append(dst, &dst_len, "&nbsp;", 6);
-			i++;
-		} else {
-			if (dst)
-				dst[dst_len] = c;
-			dst_len++;
-		}
-	}
-
-	gg_append(dst, &dst_len, "</span>", 7);
-
-	if (dst)
-		dst[dst_len] = '\0';
-
-	return dst_len;
-}
-
-char *gg_message_html_to_text_110(const char *html)
-{
-	size_t dst_len;
-	char *dst;
-
-	dst_len = gg_message_html_to_text_110_buff(NULL, html) + 1;
-	dst = malloc(dst_len);
-	if (!dst)
-		return NULL;
-	gg_message_html_to_text_110_buff(dst, html);
-
-	return dst;
-}
-
-char *gg_message_text_to_html_110(const char *text, ssize_t text_len)
-{
-	size_t dst_len;
-	char *dst;
-
-	dst_len = gg_message_text_to_html_110_buff(NULL, text, text_len) + 1;
-	dst = malloc(dst_len);
-	if (!dst)
-		return NULL;
-	gg_message_text_to_html_110_buff(dst, text, text_len);
-
-	return dst;
-}
--- a/libpurple/protocols/gg/lib/message.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- *  (C) Copyright 2009 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_MESSAGE_H
-#define LIBGADU_MESSAGE_H
-
-#include <sys/types.h>
-#include "libgadu.h"
-
-#if 0
-
-struct gg_message {
-	uin_t *recipients;
-	size_t recipient_count;
-	char *text;
-	char *html;
-	char *attributes;
-	size_t attributes_length;
-	uint32_t msgclass;
-	uint32_t seq;
-
-	int auto_convert;
-	char *text_converted;
-	char *html_converted;
-};
-
-#define GG_MESSAGE_CHECK(gm, result) \
-	if ((gm) == NULL) { \
-		errno = EINVAL; \
-		return (result); \
-	}
-
-int gg_message_init(gg_message_t *gm, int msgclass, int seq, uin_t *recipients,
-	size_t recipient_count, char *text, char *xhtml, char *attributes,
-	size_t attributes_length, int auto_convert);
-
-#endif
-
-size_t gg_message_html_to_text(char *dst, unsigned char *format,
-	size_t *format_len, const char *html, gg_encoding_t encoding);
-size_t gg_message_text_to_html(char *dst, const char *src,
-	gg_encoding_t encoding, const unsigned char *format, size_t format_len);
-
-char * gg_message_html_to_text_110(const char *html);
-char * gg_message_text_to_html_110(const char *text, ssize_t text_len);
-
-#endif /* LIBGADU_MESSAGE_H */
--- a/libpurple/protocols/gg/lib/network.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-/*
- *  (C) Copyright 2011 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#include "network.h"
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef _WIN32
-
-/* Code losely based on sockerpair implementation by Nathan C. Meyrs.
- * The original copyright notice follows: */
-
-/* socketpair.c
- * Copyright 2007, 2010 by Nathan C. Myers <ncm@cantrip.org>
- * This code is Free Software. It may be copied freely, in original or
- * modified form, subject only to the restrictions that (1) the author is
- * relieved from all responsibilities for any use for any purpose, and (2)
- * this copyright notice must be retained, unchanged, in its entirety. If
- * for any reason the author might be held responsible for any consequences
- * of copying or use, license is withheld.
- */
-
-int gg_win32_socketpair(int sv[2])
-{
-	struct sockaddr_in sin;
-	socklen_t sin_len = sizeof(sin);
-	int server = -1;
-	int tmp = 1;
-	int errno_copy;
-
-	server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
-	sv[0] = -1;
-	sv[1] = -1;
-
-	if (server == -1)
-		goto fail;
-
-	memset(&sin, 0, sizeof(sin));
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-	sin.sin_port = 0;
-
-	if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)) == -1)
-		goto fail;
-
-	if (bind(server, (struct sockaddr*) &sin, sin_len) == -1)
-		goto fail;
-
-	if (listen(server, 1) == -1)
-		goto fail;
-
-	if (getsockname(server, (struct sockaddr*) &sin, &sin_len) == -1)
-		goto fail;
-
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-	sv[0] = socket(AF_INET, SOCK_STREAM, 0);
-
-	if (sv[0] == -1)
-		goto fail;
-
-	if (connect(sv[0], (struct sockaddr*) &sin, sin_len) == -1)
-		goto fail;
-
-	sv[1] = accept(server, NULL, NULL);
-
-	if (sv[1] == -1)
-		goto fail;
-
-	close(server);
-
-	return 0;
-
-fail:
-	errno_copy = errno;
-	close(server);
-	close(sv[0]);
-	close(sv[1]);
-	errno = errno_copy;
-
-	return -1;
-}
-
-static int gg_win32_map_wsa_error_to_errno(int wsaewouldblock_map)
-{
-	int wsa_error;
-
-	wsa_error = WSAGetLastError();
-
-	/* Tutaj powinny być tłumaczone wszystkie typy błędów sprawdzane przez
-	 * kod libgadu. Dla spójność są również tłumaczone typy błędów ustawiane
-	 * przez libgadu.
-	 * Ponadto gdyby okazało się, że jakaś aplikacja na Win32 chce móc
-	 * polegać jeszcze na innych wartościach errno, można tutaj dodać
-	 * ich tłumaczenie. Najpierw jednak zawsze trzeba porównać dokumentacje,
-	 * aby upewnić się co do poprawności tłumaczenia (patrz WSAEWOULDBLOCK,
-	 * które można tłumaczyć na EWOULDBLOCK lub EAGAIN, a nawet na
-	 * EINPROGRESS w przypadku connect()).
-	 */
-	switch (wsa_error)
-	{
-	/* Typy błędów sprawdzane przez libgadu. */
-	case WSAEINTR:
-		return EINTR;
-	case WSAEWOULDBLOCK:
-		return wsaewouldblock_map;
-	/* Typy błędów ustawiane przez libgadu. */
-	case WSAECONNRESET:
-		return ECONNRESET;
-	case WSAEFAULT:
-		return EFAULT;
-	case WSAEINVAL:
-		return EINVAL;
-	case WSAENOTCONN:
-		return ENOTCONN;
-	case WSAETIMEDOUT:
-		return ETIMEDOUT;
-	default:
-		/* Najlepiej zwrócić oryginalny kod błędu. I tak będzie co najwyżej
-		 * wyświetlony w komunikacie debugowym, a tym sposobem będzie łatwiej
-		 * dojść przyczyny problemu. */
-		return wsa_error;
-	}
-}
-
-#undef accept
-int gg_win32_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
-{
-	int res;
-
-	res = accept(sockfd, addr, addrlen);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef bind
-int gg_win32_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
-{
-	int res;
-
-	res = bind(sockfd, addr, addrlen);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-int gg_win32_close(int sockfd)
-{
-	int res;
-
-	res = closesocket(sockfd);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef connect
-int gg_win32_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
-{
-	int res;
-
-	res = connect(sockfd, addr, addrlen);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EINPROGRESS);
-
-	return res;
-}
-
-#undef gethostbyname
-struct hostent *gg_win32_gethostbyname(const char *name)
-{
-	struct hostent *res;
-
-	res = gethostbyname(name);
-
-	if (res == NULL)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef getsockname
-int gg_win32_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
-{
-	int res;
-
-	res = getsockname(sockfd, addr, addrlen);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef getsockopt
-int gg_win32_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
-{
-	int res;
-
-	res = getsockopt(sockfd, level, optname, optval, optlen);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-int gg_win32_ioctl(int d, int request, int *argp)
-{
-	int res;
-
-	res = ioctlsocket(d, request, (u_long *)argp);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef listen
-int gg_win32_listen(int sockfd, int backlog)
-{
-	int res;
-
-	res = listen(sockfd, backlog);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef recv
-int gg_win32_recv(int sockfd, void *buf, size_t len, int flags)
-{
-	int res;
-
-	res = recv(sockfd, buf, len, flags);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef send
-int gg_win32_send(int sockfd, const void *buf, size_t len, int flags)
-{
-	int res;
-
-	res = send(sockfd, buf, len, flags);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef setsockopt
-int gg_win32_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
-{
-	int res;
-
-	res = setsockopt(sockfd, level, optname, optval, optlen);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#undef socket
-int gg_win32_socket(int domain, int type, int protocol)
-{
-	int res;
-
-	res = socket(domain, type, protocol);
-
-	if (res == -1)
-		errno = gg_win32_map_wsa_error_to_errno(EAGAIN);
-
-	return res;
-}
-
-#endif /* _WIN32 */
--- a/libpurple/protocols/gg/lib/network.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file network.h
- *
- * \brief Makra zapewniające kompatybilność API do obsługi sieci na różnych systemach
- */
-
-#ifndef LIBGADU_NETWORK_H
-#define LIBGADU_NETWORK_H
-
-#ifdef _WIN32
-#  include <ws2tcpip.h>
-#  include <winsock2.h>
-#  include <stdlib.h>
-#  include <stdio.h>
-#  include <errno.h>
-/* Obecnie na Win32 tylko MSVC definiuje te typy błędów. Na wypadek, gdyby
- * jednak Cygwin bądź MinGW zaczęły je definiować, używamy bardziej ogólnych
- * ifdefów. */
-#  ifndef ECONNRESET
-#    define ECONNRESET WSAECONNRESET
-#  endif
-#  ifndef EINPROGRESS
-#    define EINPROGRESS WSAEINPROGRESS
-#  endif
-#  ifndef ENOTCONN
-#    define ENOTCONN WSAENOTCONN
-#  endif
-#  ifndef ETIMEDOUT
-#    define ETIMEDOUT WSAETIMEDOUT
-#  endif
-#  define accept gg_win32_accept
-#  define bind gg_win32_bind
-#  define close gg_win32_close
-#  define connect gg_win32_connect
-#  define gethostbyname gg_win32_gethostbyname
-#  define getsockname gg_win32_getsockname
-#  define getsockopt gg_win32_getsockopt
-#  define ioctl gg_win32_ioctl
-#  define listen gg_win32_listen
-#  define recv gg_win32_recv
-#  define send gg_win32_send
-#  define setsockopt gg_win32_setsockopt
-#  define socket gg_win32_socket
-#  define socketpair(a, b, c, d) gg_win32_socketpair(d)
-int gg_win32_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
-int gg_win32_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
-int gg_win32_close(int sockfd);
-int gg_win32_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
-struct hostent *gg_win32_gethostbyname(const char *name);
-int gg_win32_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
-int gg_win32_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
-int gg_win32_ioctl(int d, int request, int *argp);
-int gg_win32_listen(int sockfd, int backlog);
-int gg_win32_recv(int sockfd, void *buf, size_t len, int flags);
-int gg_win32_send(int sockfd, const void *buf, size_t len, int flags);
-int gg_win32_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
-int gg_win32_socket(int domain, int type, int protocol);
-int gg_win32_socketpair(int sv[2]);
-
-static inline void gg_win32_init_network(void)
-{
-	WSADATA wsaData;
-
-	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
-		perror("WSAStartup");
-		exit(1);
-	}
-}
-
-#else
-#  include <sys/ioctl.h>
-#  include <sys/types.h>
-#  include <sys/socket.h>
-#  include <netinet/in.h>
-#  include <arpa/inet.h>
-#  include <netdb.h>
-#  include <unistd.h>
-#  ifndef FIONBIO
-#    include <fcntl.h>
-#  endif
-#endif
-
-#ifndef INADDR_NONE
-#  define INADDR_NONE ((in_addr_t) 0xffffffff)
-#endif
-
-#ifndef AF_LOCAL
-#  define AF_LOCAL AF_UNIX
-#endif
-
-static inline int gg_fd_set_nonblocking(int fd)
-{
-	int success;
-#ifdef FIONBIO
-	int one = 1;
-	success = (ioctl(fd, FIONBIO, &one) == 0);
-#else
-	success = (fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
-#endif
-
-	return success;
-}
-
-#endif /* LIBGADU_NETWORK_H */
--- a/libpurple/protocols/gg/lib/obsolete.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,250 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2003 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file obsolete.c
- *
- * \brief Nieaktualne funkcje
- *
- * Plik zawiera definicje funkcji, które są już nieaktualne ze względu
- * na zmiany w protokole. Programy konsolidowane ze starszych wersjami
- * bibliotek powinny nadal mieć możliwość działania, mimo ograniczonej
- * funkcjonalności.
- */
-
-/** \cond obsolete */
-
-#include <errno.h>
-#include <string.h>
-
-#include "libgadu.h"
-#include "internal.h"
-
-struct gg_http *gg_userlist_get(uin_t uin, const char *passwd, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_userlist_get() is obsolete. use gg_userlist_request() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-int gg_userlist_get_watch_fd(struct gg_http *h)
-{
-	errno = EINVAL;
-	return -1;
-}
-
-void gg_userlist_get_free(struct gg_http *h)
-{
-
-}
-
-struct gg_http *gg_userlist_put(uin_t uin, const char *password, const char *contacts, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_userlist_put() is obsolete. use gg_userlist_request() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-int gg_userlist_put_watch_fd(struct gg_http *h)
-{
-	errno = EINVAL;
-	return -1;
-}
-
-void gg_userlist_put_free(struct gg_http *h)
-{
-
-}
-
-struct gg_http *gg_userlist_remove(uin_t uin, const char *passwd, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_userlist_remove() is obsolete. use gg_userlist_request() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-int gg_userlist_remove_watch_fd(struct gg_http *h)
-{
-	errno = EINVAL;
-	return -1;
-}
-
-void gg_userlist_remove_free(struct gg_http *h)
-{
-
-}
-
-struct gg_http *gg_search(const struct gg_search_request *r, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_search() is obsolete. use gg_search50() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-int gg_search_watch_fd(struct gg_http *h)
-{
-	errno = EINVAL;
-	return -1;
-}
-
-void gg_search_free(struct gg_http *h)
-{
-
-}
-
-const struct gg_search_request *gg_search_request_mode_0(char *nickname,
-	char *first_name, char *last_name, char *city, int gender,
-	int min_birth, int max_birth, int active, int start)
-{
-	return NULL;
-}
-
-const struct gg_search_request *gg_search_request_mode_1(char *email, int active, int start)
-{
-	return NULL;
-}
-
-const struct gg_search_request *gg_search_request_mode_2(char *phone, int active, int start)
-{
-	return NULL;
-}
-
-const struct gg_search_request *gg_search_request_mode_3(uin_t uin, int active, int start)
-{
-	return NULL;
-}
-
-void gg_search_request_free(struct gg_search_request *r)
-{
-
-}
-
-struct gg_http *gg_register(const char *email, const char *password, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_register() is obsolete. use gg_register3() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_http *gg_register2(const char *email, const char *password, const char *qa, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_register2() is obsolete. use gg_register3() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_http *gg_unregister(uin_t uin, const char *password, const char *email, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_unregister() is obsolete. use gg_unregister3() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_http *gg_unregister2(uin_t uin, const char *password, const char *qa, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_unregister2() is obsolete. use gg_unregister3() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-
-struct gg_http *gg_change_passwd(uin_t uin, const char *passwd, const char *newpasswd, const char *newemail, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_change_passwd() is obsolete. use gg_change_passwd4() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_http *gg_change_passwd2(uin_t uin, const char *passwd,
-	const char *newpasswd, const char *email, const char *newemail,
-	int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_change_passwd2() is obsolete. use gg_change_passwd4() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_http *gg_change_passwd3(uin_t uin, const char *passwd, const char *newpasswd, const char *qa, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_change_passwd3() is obsolete. use gg_change_passwd4() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_http *gg_remind_passwd(uin_t uin, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_remind_passwd() is obsolete. use gg_remind_passwd3() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_http *gg_remind_passwd2(uin_t uin, const char *tokenid, const char *tokenval, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_remind_passwd2() is obsolete. use gg_remind_passwd3() instead!\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_http *gg_change_info(uin_t uin, const char *passwd, const struct gg_change_info_request *request, int async)
-{
-	gg_debug(GG_DEBUG_MISC, "// gg_change_info() is obsolete. use gg_pubdir50() instead\n");
-	errno = EINVAL;
-	return NULL;
-}
-
-struct gg_change_info_request *gg_change_info_request_new(
-	const char *first_name, const char *last_name, const char *nickname,
-	const char *email, int born, int gender, const char *city)
-{
-	return NULL;
-}
-
-void gg_change_info_request_free(struct gg_change_info_request *r)
-{
-
-}
-
-int gg_resolve(int *fd, int *pid, const char *hostname)
-{
-	return -1;
-}
-
-void gg_resolve_pthread_cleanup(void *arg, int kill)
-{
-
-}
-
-int gg_resolve_pthread(int *fd, void **resolver, const char *hostname)
-{
-	return -1;
-}
-
-int gg_pubdir50_handle_reply(struct gg_event *e, const char *packet, int length)
-{
-	return -1;
-}
-
-void gg_login_hash_sha1(const char *password, uint32_t seed, uint8_t *result)
-{
-	if (gg_login_hash_sha1_2(password, seed, result) != 0)
-		memset(result, 0, 20);
-}
-
-/** \endcond */
--- a/libpurple/protocols/gg/lib/packets.pb-c.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2603 +0,0 @@
-/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
-/* Generated from: packets.proto */
-
-/* Do not generate deprecated warnings for self */
-#ifndef PROTOBUF_C__NO_DEPRECATED
-#define PROTOBUF_C__NO_DEPRECATED
-#endif
-
-#include "packets.pb-c.h"
-void   gg110_login_ok__init
-                     (GG110LoginOK         *message)
-{
-  static GG110LoginOK init_value = GG110_LOGIN_OK__INIT;
-  *message = init_value;
-}
-size_t gg110_login_ok__get_packed_size
-                     (const GG110LoginOK *message)
-{
-  assert(message->base.descriptor == &gg110_login_ok__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_login_ok__pack
-                     (const GG110LoginOK *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_login_ok__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_login_ok__pack_to_buffer
-                     (const GG110LoginOK *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_login_ok__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110LoginOK *
-       gg110_login_ok__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110LoginOK *)
-     protobuf_c_message_unpack (&gg110_login_ok__descriptor,
-                                allocator, len, data);
-}
-void   gg110_login_ok__free_unpacked
-                     (GG110LoginOK *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_login_ok__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_pong__init
-                     (GG110Pong         *message)
-{
-  static GG110Pong init_value = GG110_PONG__INIT;
-  *message = init_value;
-}
-size_t gg110_pong__get_packed_size
-                     (const GG110Pong *message)
-{
-  assert(message->base.descriptor == &gg110_pong__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_pong__pack
-                     (const GG110Pong *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_pong__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_pong__pack_to_buffer
-                     (const GG110Pong *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_pong__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110Pong *
-       gg110_pong__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110Pong *)
-     protobuf_c_message_unpack (&gg110_pong__descriptor,
-                                allocator, len, data);
-}
-void   gg110_pong__free_unpacked
-                     (GG110Pong *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_pong__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_ack__init
-                     (GG110Ack         *message)
-{
-  static GG110Ack init_value = GG110_ACK__INIT;
-  *message = init_value;
-}
-size_t gg110_ack__get_packed_size
-                     (const GG110Ack *message)
-{
-  assert(message->base.descriptor == &gg110_ack__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_ack__pack
-                     (const GG110Ack *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_ack__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_ack__pack_to_buffer
-                     (const GG110Ack *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_ack__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110Ack *
-       gg110_ack__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110Ack *)
-     protobuf_c_message_unpack (&gg110_ack__descriptor,
-                                allocator, len, data);
-}
-void   gg110_ack__free_unpacked
-                     (GG110Ack *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_ack__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg105_login__init
-                     (GG105Login         *message)
-{
-  static GG105Login init_value = GG105_LOGIN__INIT;
-  *message = init_value;
-}
-size_t gg105_login__get_packed_size
-                     (const GG105Login *message)
-{
-  assert(message->base.descriptor == &gg105_login__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg105_login__pack
-                     (const GG105Login *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg105_login__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg105_login__pack_to_buffer
-                     (const GG105Login *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg105_login__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG105Login *
-       gg105_login__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG105Login *)
-     protobuf_c_message_unpack (&gg105_login__descriptor,
-                                allocator, len, data);
-}
-void   gg105_login__free_unpacked
-                     (GG105Login *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg105_login__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_message_ack_link__init
-                     (GG110MessageAckLink         *message)
-{
-  static GG110MessageAckLink init_value = GG110_MESSAGE_ACK_LINK__INIT;
-  *message = init_value;
-}
-size_t gg110_message_ack_link__get_packed_size
-                     (const GG110MessageAckLink *message)
-{
-  assert(message->base.descriptor == &gg110_message_ack_link__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_message_ack_link__pack
-                     (const GG110MessageAckLink *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_message_ack_link__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_message_ack_link__pack_to_buffer
-                     (const GG110MessageAckLink *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_message_ack_link__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110MessageAckLink *
-       gg110_message_ack_link__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110MessageAckLink *)
-     protobuf_c_message_unpack (&gg110_message_ack_link__descriptor,
-                                allocator, len, data);
-}
-void   gg110_message_ack_link__free_unpacked
-                     (GG110MessageAckLink *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_message_ack_link__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_message_ack__init
-                     (GG110MessageAck         *message)
-{
-  static GG110MessageAck init_value = GG110_MESSAGE_ACK__INIT;
-  *message = init_value;
-}
-size_t gg110_message_ack__get_packed_size
-                     (const GG110MessageAck *message)
-{
-  assert(message->base.descriptor == &gg110_message_ack__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_message_ack__pack
-                     (const GG110MessageAck *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_message_ack__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_message_ack__pack_to_buffer
-                     (const GG110MessageAck *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_message_ack__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110MessageAck *
-       gg110_message_ack__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110MessageAck *)
-     protobuf_c_message_unpack (&gg110_message_ack__descriptor,
-                                allocator, len, data);
-}
-void   gg110_message_ack__free_unpacked
-                     (GG110MessageAck *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_message_ack__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_event__init
-                     (GG110Event         *message)
-{
-  static GG110Event init_value = GG110_EVENT__INIT;
-  *message = init_value;
-}
-size_t gg110_event__get_packed_size
-                     (const GG110Event *message)
-{
-  assert(message->base.descriptor == &gg110_event__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_event__pack
-                     (const GG110Event *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_event__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_event__pack_to_buffer
-                     (const GG110Event *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_event__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110Event *
-       gg110_event__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110Event *)
-     protobuf_c_message_unpack (&gg110_event__descriptor,
-                                allocator, len, data);
-}
-void   gg110_event__free_unpacked
-                     (GG110Event *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_event__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_recv_message__init
-                     (GG110RecvMessage         *message)
-{
-  static GG110RecvMessage init_value = GG110_RECV_MESSAGE__INIT;
-  *message = init_value;
-}
-size_t gg110_recv_message__get_packed_size
-                     (const GG110RecvMessage *message)
-{
-  assert(message->base.descriptor == &gg110_recv_message__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_recv_message__pack
-                     (const GG110RecvMessage *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_recv_message__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_recv_message__pack_to_buffer
-                     (const GG110RecvMessage *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_recv_message__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110RecvMessage *
-       gg110_recv_message__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110RecvMessage *)
-     protobuf_c_message_unpack (&gg110_recv_message__descriptor,
-                                allocator, len, data);
-}
-void   gg110_recv_message__free_unpacked
-                     (GG110RecvMessage *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_recv_message__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_send_message__init
-                     (GG110SendMessage         *message)
-{
-  static GG110SendMessage init_value = GG110_SEND_MESSAGE__INIT;
-  *message = init_value;
-}
-size_t gg110_send_message__get_packed_size
-                     (const GG110SendMessage *message)
-{
-  assert(message->base.descriptor == &gg110_send_message__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_send_message__pack
-                     (const GG110SendMessage *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_send_message__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_send_message__pack_to_buffer
-                     (const GG110SendMessage *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_send_message__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110SendMessage *
-       gg110_send_message__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110SendMessage *)
-     protobuf_c_message_unpack (&gg110_send_message__descriptor,
-                                allocator, len, data);
-}
-void   gg110_send_message__free_unpacked
-                     (GG110SendMessage *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_send_message__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_imtoken__init
-                     (GG110Imtoken         *message)
-{
-  static GG110Imtoken init_value = GG110_IMTOKEN__INIT;
-  *message = init_value;
-}
-size_t gg110_imtoken__get_packed_size
-                     (const GG110Imtoken *message)
-{
-  assert(message->base.descriptor == &gg110_imtoken__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_imtoken__pack
-                     (const GG110Imtoken *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_imtoken__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_imtoken__pack_to_buffer
-                     (const GG110Imtoken *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_imtoken__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110Imtoken *
-       gg110_imtoken__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110Imtoken *)
-     protobuf_c_message_unpack (&gg110_imtoken__descriptor,
-                                allocator, len, data);
-}
-void   gg110_imtoken__free_unpacked
-                     (GG110Imtoken *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_imtoken__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_chat_info_update__init
-                     (GG110ChatInfoUpdate         *message)
-{
-  static GG110ChatInfoUpdate init_value = GG110_CHAT_INFO_UPDATE__INIT;
-  *message = init_value;
-}
-size_t gg110_chat_info_update__get_packed_size
-                     (const GG110ChatInfoUpdate *message)
-{
-  assert(message->base.descriptor == &gg110_chat_info_update__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_chat_info_update__pack
-                     (const GG110ChatInfoUpdate *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_chat_info_update__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_chat_info_update__pack_to_buffer
-                     (const GG110ChatInfoUpdate *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_chat_info_update__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110ChatInfoUpdate *
-       gg110_chat_info_update__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110ChatInfoUpdate *)
-     protobuf_c_message_unpack (&gg110_chat_info_update__descriptor,
-                                allocator, len, data);
-}
-void   gg110_chat_info_update__free_unpacked
-                     (GG110ChatInfoUpdate *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_chat_info_update__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   protobuf_kvp__init
-                     (ProtobufKVP         *message)
-{
-  static ProtobufKVP init_value = PROTOBUF_KVP__INIT;
-  *message = init_value;
-}
-size_t protobuf_kvp__get_packed_size
-                     (const ProtobufKVP *message)
-{
-  assert(message->base.descriptor == &protobuf_kvp__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t protobuf_kvp__pack
-                     (const ProtobufKVP *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &protobuf_kvp__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t protobuf_kvp__pack_to_buffer
-                     (const ProtobufKVP *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &protobuf_kvp__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-ProtobufKVP *
-       protobuf_kvp__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (ProtobufKVP *)
-     protobuf_c_message_unpack (&protobuf_kvp__descriptor,
-                                allocator, len, data);
-}
-void   protobuf_kvp__free_unpacked
-                     (ProtobufKVP *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &protobuf_kvp__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_options__init
-                     (GG110Options         *message)
-{
-  static GG110Options init_value = GG110_OPTIONS__INIT;
-  *message = init_value;
-}
-size_t gg110_options__get_packed_size
-                     (const GG110Options *message)
-{
-  assert(message->base.descriptor == &gg110_options__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_options__pack
-                     (const GG110Options *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_options__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_options__pack_to_buffer
-                     (const GG110Options *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_options__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110Options *
-       gg110_options__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110Options *)
-     protobuf_c_message_unpack (&gg110_options__descriptor,
-                                allocator, len, data);
-}
-void   gg110_options__free_unpacked
-                     (GG110Options *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_options__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_access_info__init
-                     (GG110AccessInfo         *message)
-{
-  static GG110AccessInfo init_value = GG110_ACCESS_INFO__INIT;
-  *message = init_value;
-}
-size_t gg110_access_info__get_packed_size
-                     (const GG110AccessInfo *message)
-{
-  assert(message->base.descriptor == &gg110_access_info__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_access_info__pack
-                     (const GG110AccessInfo *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_access_info__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_access_info__pack_to_buffer
-                     (const GG110AccessInfo *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_access_info__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110AccessInfo *
-       gg110_access_info__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110AccessInfo *)
-     protobuf_c_message_unpack (&gg110_access_info__descriptor,
-                                allocator, len, data);
-}
-void   gg110_access_info__free_unpacked
-                     (GG110AccessInfo *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_access_info__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg112_transfer_info_uin__init
-                     (GG112TransferInfoUin         *message)
-{
-  static GG112TransferInfoUin init_value = GG112_TRANSFER_INFO_UIN__INIT;
-  *message = init_value;
-}
-size_t gg112_transfer_info_uin__get_packed_size
-                     (const GG112TransferInfoUin *message)
-{
-  assert(message->base.descriptor == &gg112_transfer_info_uin__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg112_transfer_info_uin__pack
-                     (const GG112TransferInfoUin *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg112_transfer_info_uin__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg112_transfer_info_uin__pack_to_buffer
-                     (const GG112TransferInfoUin *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg112_transfer_info_uin__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG112TransferInfoUin *
-       gg112_transfer_info_uin__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG112TransferInfoUin *)
-     protobuf_c_message_unpack (&gg112_transfer_info_uin__descriptor,
-                                allocator, len, data);
-}
-void   gg112_transfer_info_uin__free_unpacked
-                     (GG112TransferInfoUin *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg112_transfer_info_uin__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg112_transfer_info_file__init
-                     (GG112TransferInfoFile         *message)
-{
-  static GG112TransferInfoFile init_value = GG112_TRANSFER_INFO_FILE__INIT;
-  *message = init_value;
-}
-size_t gg112_transfer_info_file__get_packed_size
-                     (const GG112TransferInfoFile *message)
-{
-  assert(message->base.descriptor == &gg112_transfer_info_file__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg112_transfer_info_file__pack
-                     (const GG112TransferInfoFile *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg112_transfer_info_file__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg112_transfer_info_file__pack_to_buffer
-                     (const GG112TransferInfoFile *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg112_transfer_info_file__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG112TransferInfoFile *
-       gg112_transfer_info_file__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG112TransferInfoFile *)
-     protobuf_c_message_unpack (&gg112_transfer_info_file__descriptor,
-                                allocator, len, data);
-}
-void   gg112_transfer_info_file__free_unpacked
-                     (GG112TransferInfoFile *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg112_transfer_info_file__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg112_transfer_info__init
-                     (GG112TransferInfo         *message)
-{
-  static GG112TransferInfo init_value = GG112_TRANSFER_INFO__INIT;
-  *message = init_value;
-}
-size_t gg112_transfer_info__get_packed_size
-                     (const GG112TransferInfo *message)
-{
-  assert(message->base.descriptor == &gg112_transfer_info__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg112_transfer_info__pack
-                     (const GG112TransferInfo *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg112_transfer_info__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg112_transfer_info__pack_to_buffer
-                     (const GG112TransferInfo *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg112_transfer_info__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG112TransferInfo *
-       gg112_transfer_info__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG112TransferInfo *)
-     protobuf_c_message_unpack (&gg112_transfer_info__descriptor,
-                                allocator, len, data);
-}
-void   gg112_transfer_info__free_unpacked
-                     (GG112TransferInfo *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg112_transfer_info__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-void   gg110_magic_notification__init
-                     (GG110MagicNotification         *message)
-{
-  static GG110MagicNotification init_value = GG110_MAGIC_NOTIFICATION__INIT;
-  *message = init_value;
-}
-size_t gg110_magic_notification__get_packed_size
-                     (const GG110MagicNotification *message)
-{
-  assert(message->base.descriptor == &gg110_magic_notification__descriptor);
-  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
-}
-size_t gg110_magic_notification__pack
-                     (const GG110MagicNotification *message,
-                      uint8_t       *out)
-{
-  assert(message->base.descriptor == &gg110_magic_notification__descriptor);
-  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
-}
-size_t gg110_magic_notification__pack_to_buffer
-                     (const GG110MagicNotification *message,
-                      ProtobufCBuffer *buffer)
-{
-  assert(message->base.descriptor == &gg110_magic_notification__descriptor);
-  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
-}
-GG110MagicNotification *
-       gg110_magic_notification__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data)
-{
-  return (GG110MagicNotification *)
-     protobuf_c_message_unpack (&gg110_magic_notification__descriptor,
-                                allocator, len, data);
-}
-void   gg110_magic_notification__free_unpacked
-                     (GG110MagicNotification *message,
-                      ProtobufCAllocator *allocator)
-{
-  assert(message->base.descriptor == &gg110_magic_notification__descriptor);
-  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
-}
-static const int32_t gg110_login_ok__dummy1__default_value = 1;
-static const ProtobufCFieldDescriptor gg110_login_ok__field_descriptors[4] =
-{
-  {
-    "dummy1",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_INT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110LoginOK, dummy1),
-    NULL,
-    &gg110_login_ok__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummyhash",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110LoginOK, dummyhash),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "uin",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110LoginOK, uin),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "server_time",
-    4,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG110LoginOK, server_time),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_login_ok__field_indices_by_name[] = {
-  0,   /* field[0] = dummy1 */
-  1,   /* field[1] = dummyhash */
-  3,   /* field[3] = server_time */
-  2,   /* field[2] = uin */
-};
-static const ProtobufCIntRange gg110_login_ok__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 4 }
-};
-const ProtobufCMessageDescriptor gg110_login_ok__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110LoginOK",
-  "GG110LoginOK",
-  "GG110LoginOK",
-  "",
-  sizeof(GG110LoginOK),
-  4,
-  gg110_login_ok__field_descriptors,
-  gg110_login_ok__field_indices_by_name,
-  1,  gg110_login_ok__number_ranges,
-  (ProtobufCMessageInit) gg110_login_ok__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const ProtobufCFieldDescriptor gg110_pong__field_descriptors[1] =
-{
-  {
-    "server_time",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG110Pong, server_time),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_pong__field_indices_by_name[] = {
-  0,   /* field[0] = server_time */
-};
-static const ProtobufCIntRange gg110_pong__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 1 }
-};
-const ProtobufCMessageDescriptor gg110_pong__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110Pong",
-  "GG110Pong",
-  "GG110Pong",
-  "",
-  sizeof(GG110Pong),
-  1,
-  gg110_pong__field_descriptors,
-  gg110_pong__field_indices_by_name,
-  1,  gg110_pong__number_ranges,
-  (ProtobufCMessageInit) gg110_pong__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-const ProtobufCEnumValue gg110_ack__type__enum_values_by_number[6] =
-{
-  { "MSG", "GG110_ACK__TYPE__MSG", 1 },
-  { "CHAT", "GG110_ACK__TYPE__CHAT", 2 },
-  { "CHAT_INFO", "GG110_ACK__TYPE__CHAT_INFO", 3 },
-  { "MAGIC_NOTIFICATION", "GG110_ACK__TYPE__MAGIC_NOTIFICATION", 5 },
-  { "MPA", "GG110_ACK__TYPE__MPA", 6 },
-  { "TRANSFER_INFO", "GG110_ACK__TYPE__TRANSFER_INFO", 7 },
-};
-static const ProtobufCIntRange gg110_ack__type__value_ranges[] = {
-{1, 0},{5, 3},{0, 6}
-};
-const ProtobufCEnumValueIndex gg110_ack__type__enum_values_by_name[6] =
-{
-  { "CHAT", 1 },
-  { "CHAT_INFO", 2 },
-  { "MAGIC_NOTIFICATION", 3 },
-  { "MPA", 4 },
-  { "MSG", 0 },
-  { "TRANSFER_INFO", 5 },
-};
-const ProtobufCEnumDescriptor gg110_ack__type__descriptor =
-{
-  PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
-  "GG110Ack.Type",
-  "Type",
-  "GG110Ack__Type",
-  "",
-  6,
-  gg110_ack__type__enum_values_by_number,
-  6,
-  gg110_ack__type__enum_values_by_name,
-  2,
-  gg110_ack__type__value_ranges,
-  NULL,NULL,NULL,NULL   /* reserved[1234] */
-};
-static const uint32_t gg110_ack__dummy1__default_value = 1u;
-static const ProtobufCFieldDescriptor gg110_ack__field_descriptors[3] =
-{
-  {
-    "type",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_ENUM,
-    0,   /* quantifier_offset */
-    offsetof(GG110Ack, type),
-    &gg110_ack__type__descriptor,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "seq",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110Ack, seq),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy1",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110Ack, dummy1),
-    NULL,
-    &gg110_ack__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_ack__field_indices_by_name[] = {
-  2,   /* field[2] = dummy1 */
-  1,   /* field[1] = seq */
-  0,   /* field[0] = type */
-};
-static const ProtobufCIntRange gg110_ack__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 3 }
-};
-const ProtobufCMessageDescriptor gg110_ack__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110Ack",
-  "GG110Ack",
-  "GG110Ack",
-  "",
-  sizeof(GG110Ack),
-  3,
-  gg110_ack__field_descriptors,
-  gg110_ack__field_indices_by_name,
-  1,  gg110_ack__number_ranges,
-  (ProtobufCMessageInit) gg110_ack__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-char gg105_login__initial_descr__default_value[] = "";
-static const uint32_t gg105_login__initial_status__default_value = 8227u;
-static const int32_t gg105_login__dummy1__default_value = 4;
-static const uint32_t gg105_login__dummy2__default_value = 65994615u;
-static const uint32_t gg105_login__dummy3__default_value = 198164u;
-static const int32_t gg105_login__dummy5__default_value = 255;
-static const int32_t gg105_login__dummy6__default_value = 100;
-static const uint32_t gg105_login__dummy7__default_value = 127u;
-static const int32_t gg105_login__dummy8__default_value = 0;
-static const uint32_t gg105_login__dummy10__default_value = 0u;
-static const ProtobufCFieldDescriptor gg105_login__field_descriptors[16] =
-{
-  {
-    "lang",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, lang),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "uin",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_BYTES,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, uin),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "hash",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_BYTES,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, hash),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy1",
-    4,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_INT32,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, dummy1),
-    NULL,
-    &gg105_login__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy2",
-    5,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, dummy2),
-    NULL,
-    &gg105_login__dummy2__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy3",
-    6,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, dummy3),
-    NULL,
-    &gg105_login__dummy3__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "client",
-    7,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, client),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "initial_status",
-    8,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, initial_status),
-    NULL,
-    &gg105_login__initial_status__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "initial_descr",
-    9,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, initial_descr),
-    NULL,
-    &gg105_login__initial_descr__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy4",
-    10,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_BYTES,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, dummy4),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "supported_features",
-    11,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, supported_features),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy5",
-    12,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_INT32,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, dummy5),
-    NULL,
-    &gg105_login__dummy5__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy6",
-    13,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_INT32,
-    0,   /* quantifier_offset */
-    offsetof(GG105Login, dummy6),
-    NULL,
-    &gg105_login__dummy6__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy7",
-    14,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_FIXED32,
-    offsetof(GG105Login, has_dummy7),
-    offsetof(GG105Login, dummy7),
-    NULL,
-    &gg105_login__dummy7__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy8",
-    15,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_INT32,
-    offsetof(GG105Login, has_dummy8),
-    offsetof(GG105Login, dummy8),
-    NULL,
-    &gg105_login__dummy8__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy10",
-    17,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_UINT32,
-    offsetof(GG105Login, has_dummy10),
-    offsetof(GG105Login, dummy10),
-    NULL,
-    &gg105_login__dummy10__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg105_login__field_indices_by_name[] = {
-  6,   /* field[6] = client */
-  3,   /* field[3] = dummy1 */
-  15,   /* field[15] = dummy10 */
-  4,   /* field[4] = dummy2 */
-  5,   /* field[5] = dummy3 */
-  9,   /* field[9] = dummy4 */
-  11,   /* field[11] = dummy5 */
-  12,   /* field[12] = dummy6 */
-  13,   /* field[13] = dummy7 */
-  14,   /* field[14] = dummy8 */
-  2,   /* field[2] = hash */
-  8,   /* field[8] = initial_descr */
-  7,   /* field[7] = initial_status */
-  0,   /* field[0] = lang */
-  10,   /* field[10] = supported_features */
-  1,   /* field[1] = uin */
-};
-static const ProtobufCIntRange gg105_login__number_ranges[2 + 1] =
-{
-  { 1, 0 },
-  { 17, 15 },
-  { 0, 16 }
-};
-const ProtobufCMessageDescriptor gg105_login__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG105Login",
-  "GG105Login",
-  "GG105Login",
-  "",
-  sizeof(GG105Login),
-  16,
-  gg105_login__field_descriptors,
-  gg105_login__field_indices_by_name,
-  2,  gg105_login__number_ranges,
-  (ProtobufCMessageInit) gg105_login__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const ProtobufCFieldDescriptor gg110_message_ack_link__field_descriptors[2] =
-{
-  {
-    "id",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED64,
-    0,   /* quantifier_offset */
-    offsetof(GG110MessageAckLink, id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "url",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110MessageAckLink, url),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_message_ack_link__field_indices_by_name[] = {
-  0,   /* field[0] = id */
-  1,   /* field[1] = url */
-};
-static const ProtobufCIntRange gg110_message_ack_link__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 2 }
-};
-const ProtobufCMessageDescriptor gg110_message_ack_link__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110MessageAckLink",
-  "GG110MessageAckLink",
-  "GG110MessageAckLink",
-  "",
-  sizeof(GG110MessageAckLink),
-  2,
-  gg110_message_ack_link__field_descriptors,
-  gg110_message_ack_link__field_indices_by_name,
-  1,  gg110_message_ack_link__number_ranges,
-  (ProtobufCMessageInit) gg110_message_ack_link__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const uint32_t gg110_message_ack__dummy1__default_value = 0u;
-static const ProtobufCFieldDescriptor gg110_message_ack__field_descriptors[7] =
-{
-  {
-    "msg_type",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110MessageAck, msg_type),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "seq",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110MessageAck, seq),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "time",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG110MessageAck, time),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_id",
-    4,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_FIXED64,
-    offsetof(GG110MessageAck, has_msg_id),
-    offsetof(GG110MessageAck, msg_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "conv_id",
-    5,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_FIXED64,
-    offsetof(GG110MessageAck, has_conv_id),
-    offsetof(GG110MessageAck, conv_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "links",
-    6,
-    PROTOBUF_C_LABEL_REPEATED,
-    PROTOBUF_C_TYPE_MESSAGE,
-    offsetof(GG110MessageAck, n_links),
-    offsetof(GG110MessageAck, links),
-    &gg110_message_ack_link__descriptor,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy1",
-    7,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110MessageAck, dummy1),
-    NULL,
-    &gg110_message_ack__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_message_ack__field_indices_by_name[] = {
-  4,   /* field[4] = conv_id */
-  6,   /* field[6] = dummy1 */
-  5,   /* field[5] = links */
-  3,   /* field[3] = msg_id */
-  0,   /* field[0] = msg_type */
-  1,   /* field[1] = seq */
-  2,   /* field[2] = time */
-};
-static const ProtobufCIntRange gg110_message_ack__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 7 }
-};
-const ProtobufCMessageDescriptor gg110_message_ack__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110MessageAck",
-  "GG110MessageAck",
-  "GG110MessageAck",
-  "",
-  sizeof(GG110MessageAck),
-  7,
-  gg110_message_ack__field_descriptors,
-  gg110_message_ack__field_indices_by_name,
-  1,  gg110_message_ack__number_ranges,
-  (ProtobufCMessageInit) gg110_message_ack__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-const ProtobufCEnumValue gg110_event__type__enum_values_by_number[2] =
-{
-  { "XML", "GG110_EVENT__TYPE__XML", 0 },
-  { "JSON", "GG110_EVENT__TYPE__JSON", 2 },
-};
-static const ProtobufCIntRange gg110_event__type__value_ranges[] = {
-{0, 0},{2, 1},{0, 2}
-};
-const ProtobufCEnumValueIndex gg110_event__type__enum_values_by_name[2] =
-{
-  { "JSON", 1 },
-  { "XML", 0 },
-};
-const ProtobufCEnumDescriptor gg110_event__type__descriptor =
-{
-  PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
-  "GG110Event.Type",
-  "Type",
-  "GG110Event__Type",
-  "",
-  2,
-  gg110_event__type__enum_values_by_number,
-  2,
-  gg110_event__type__enum_values_by_name,
-  2,
-  gg110_event__type__value_ranges,
-  NULL,NULL,NULL,NULL   /* reserved[1234] */
-};
-static const ProtobufCFieldDescriptor gg110_event__field_descriptors[5] =
-{
-  {
-    "type",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_ENUM,
-    0,   /* quantifier_offset */
-    offsetof(GG110Event, type),
-    &gg110_event__type__descriptor,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "seq",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110Event, seq),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "data",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110Event, data),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "subtype",
-    4,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110Event, subtype),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "id",
-    5,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_UINT64,
-    offsetof(GG110Event, has_id),
-    offsetof(GG110Event, id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_event__field_indices_by_name[] = {
-  2,   /* field[2] = data */
-  4,   /* field[4] = id */
-  1,   /* field[1] = seq */
-  3,   /* field[3] = subtype */
-  0,   /* field[0] = type */
-};
-static const ProtobufCIntRange gg110_event__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 5 }
-};
-const ProtobufCMessageDescriptor gg110_event__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110Event",
-  "GG110Event",
-  "GG110Event",
-  "",
-  sizeof(GG110Event),
-  5,
-  gg110_event__field_descriptors,
-  gg110_event__field_indices_by_name,
-  1,  gg110_event__number_ranges,
-  (ProtobufCMessageInit) gg110_event__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-char gg110_recv_message__msg_plain__default_value[] = "";
-static const ProtobufCFieldDescriptor gg110_recv_message__field_descriptors[10] =
-{
-  {
-    "sender",
-    1,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_BYTES,
-    offsetof(GG110RecvMessage, has_sender),
-    offsetof(GG110RecvMessage, sender),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "flags",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110RecvMessage, flags),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "seq",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110RecvMessage, seq),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "time",
-    4,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG110RecvMessage, time),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_plain",
-    5,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110RecvMessage, msg_plain),
-    NULL,
-    &gg110_recv_message__msg_plain__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_xhtml",
-    6,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110RecvMessage, msg_xhtml),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "data",
-    7,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_BYTES,
-    offsetof(GG110RecvMessage, has_data),
-    offsetof(GG110RecvMessage, data),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_id",
-    9,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_FIXED64,
-    offsetof(GG110RecvMessage, has_msg_id),
-    offsetof(GG110RecvMessage, msg_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "chat_id",
-    10,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_FIXED64,
-    offsetof(GG110RecvMessage, has_chat_id),
-    offsetof(GG110RecvMessage, chat_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "conv_id",
-    11,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_FIXED64,
-    offsetof(GG110RecvMessage, has_conv_id),
-    offsetof(GG110RecvMessage, conv_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_recv_message__field_indices_by_name[] = {
-  8,   /* field[8] = chat_id */
-  9,   /* field[9] = conv_id */
-  6,   /* field[6] = data */
-  1,   /* field[1] = flags */
-  7,   /* field[7] = msg_id */
-  4,   /* field[4] = msg_plain */
-  5,   /* field[5] = msg_xhtml */
-  0,   /* field[0] = sender */
-  2,   /* field[2] = seq */
-  3,   /* field[3] = time */
-};
-static const ProtobufCIntRange gg110_recv_message__number_ranges[2 + 1] =
-{
-  { 1, 0 },
-  { 9, 7 },
-  { 0, 10 }
-};
-const ProtobufCMessageDescriptor gg110_recv_message__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110RecvMessage",
-  "GG110RecvMessage",
-  "GG110RecvMessage",
-  "",
-  sizeof(GG110RecvMessage),
-  10,
-  gg110_recv_message__field_descriptors,
-  gg110_recv_message__field_indices_by_name,
-  2,  gg110_recv_message__number_ranges,
-  (ProtobufCMessageInit) gg110_recv_message__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-char gg110_send_message__dummy3__default_value[] = "";
-static const uint32_t gg110_send_message__dummy1__default_value = 8u;
-static const ProtobufCFieldDescriptor gg110_send_message__field_descriptors[7] =
-{
-  {
-    "recipient",
-    1,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_BYTES,
-    offsetof(GG110SendMessage, has_recipient),
-    offsetof(GG110SendMessage, recipient),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy1",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110SendMessage, dummy1),
-    NULL,
-    &gg110_send_message__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "seq",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110SendMessage, seq),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_plain",
-    5,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110SendMessage, msg_plain),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_xhtml",
-    6,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110SendMessage, msg_xhtml),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy3",
-    7,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110SendMessage, dummy3),
-    NULL,
-    &gg110_send_message__dummy3__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "chat_id",
-    10,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_FIXED64,
-    offsetof(GG110SendMessage, has_chat_id),
-    offsetof(GG110SendMessage, chat_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_send_message__field_indices_by_name[] = {
-  6,   /* field[6] = chat_id */
-  1,   /* field[1] = dummy1 */
-  5,   /* field[5] = dummy3 */
-  3,   /* field[3] = msg_plain */
-  4,   /* field[4] = msg_xhtml */
-  0,   /* field[0] = recipient */
-  2,   /* field[2] = seq */
-};
-static const ProtobufCIntRange gg110_send_message__number_ranges[3 + 1] =
-{
-  { 1, 0 },
-  { 5, 3 },
-  { 10, 6 },
-  { 0, 7 }
-};
-const ProtobufCMessageDescriptor gg110_send_message__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110SendMessage",
-  "GG110SendMessage",
-  "GG110SendMessage",
-  "",
-  sizeof(GG110SendMessage),
-  7,
-  gg110_send_message__field_descriptors,
-  gg110_send_message__field_indices_by_name,
-  3,  gg110_send_message__number_ranges,
-  (ProtobufCMessageInit) gg110_send_message__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const ProtobufCFieldDescriptor gg110_imtoken__field_descriptors[1] =
-{
-  {
-    "imtoken",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110Imtoken, imtoken),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_imtoken__field_indices_by_name[] = {
-  0,   /* field[0] = imtoken */
-};
-static const ProtobufCIntRange gg110_imtoken__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 1 }
-};
-const ProtobufCMessageDescriptor gg110_imtoken__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110Imtoken",
-  "GG110Imtoken",
-  "GG110Imtoken",
-  "",
-  sizeof(GG110Imtoken),
-  1,
-  gg110_imtoken__field_descriptors,
-  gg110_imtoken__field_indices_by_name,
-  1,  gg110_imtoken__number_ranges,
-  (ProtobufCMessageInit) gg110_imtoken__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const ProtobufCFieldDescriptor gg110_chat_info_update__field_descriptors[10] =
-{
-  {
-    "participant",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_BYTES,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, participant),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "inviter",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_BYTES,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, inviter),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "update_type",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, update_type),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "time",
-    4,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, time),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy1",
-    5,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, dummy1),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "version",
-    6,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, version),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy2",
-    7,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, dummy2),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_id",
-    9,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED64,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, msg_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "chat_id",
-    10,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED64,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, chat_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "conv_id",
-    11,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED64,
-    0,   /* quantifier_offset */
-    offsetof(GG110ChatInfoUpdate, conv_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_chat_info_update__field_indices_by_name[] = {
-  8,   /* field[8] = chat_id */
-  9,   /* field[9] = conv_id */
-  4,   /* field[4] = dummy1 */
-  6,   /* field[6] = dummy2 */
-  1,   /* field[1] = inviter */
-  7,   /* field[7] = msg_id */
-  0,   /* field[0] = participant */
-  3,   /* field[3] = time */
-  2,   /* field[2] = update_type */
-  5,   /* field[5] = version */
-};
-static const ProtobufCIntRange gg110_chat_info_update__number_ranges[2 + 1] =
-{
-  { 1, 0 },
-  { 9, 7 },
-  { 0, 10 }
-};
-const ProtobufCMessageDescriptor gg110_chat_info_update__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110ChatInfoUpdate",
-  "GG110ChatInfoUpdate",
-  "GG110ChatInfoUpdate",
-  "",
-  sizeof(GG110ChatInfoUpdate),
-  10,
-  gg110_chat_info_update__field_descriptors,
-  gg110_chat_info_update__field_indices_by_name,
-  2,  gg110_chat_info_update__number_ranges,
-  (ProtobufCMessageInit) gg110_chat_info_update__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const ProtobufCFieldDescriptor protobuf_kvp__field_descriptors[2] =
-{
-  {
-    "key",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(ProtobufKVP, key),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "value",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(ProtobufKVP, value),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned protobuf_kvp__field_indices_by_name[] = {
-  0,   /* field[0] = key */
-  1,   /* field[1] = value */
-};
-static const ProtobufCIntRange protobuf_kvp__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 2 }
-};
-const ProtobufCMessageDescriptor protobuf_kvp__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "ProtobufKVP",
-  "ProtobufKVP",
-  "ProtobufKVP",
-  "",
-  sizeof(ProtobufKVP),
-  2,
-  protobuf_kvp__field_descriptors,
-  protobuf_kvp__field_indices_by_name,
-  1,  protobuf_kvp__number_ranges,
-  (ProtobufCMessageInit) protobuf_kvp__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const uint32_t gg110_options__dummy1__default_value = 0u;
-static const ProtobufCFieldDescriptor gg110_options__field_descriptors[2] =
-{
-  {
-    "options",
-    1,
-    PROTOBUF_C_LABEL_REPEATED,
-    PROTOBUF_C_TYPE_MESSAGE,
-    offsetof(GG110Options, n_options),
-    offsetof(GG110Options, options),
-    &protobuf_kvp__descriptor,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy1",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110Options, dummy1),
-    NULL,
-    &gg110_options__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_options__field_indices_by_name[] = {
-  1,   /* field[1] = dummy1 */
-  0,   /* field[0] = options */
-};
-static const ProtobufCIntRange gg110_options__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 2 }
-};
-const ProtobufCMessageDescriptor gg110_options__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110Options",
-  "GG110Options",
-  "GG110Options",
-  "",
-  sizeof(GG110Options),
-  2,
-  gg110_options__field_descriptors,
-  gg110_options__field_indices_by_name,
-  1,  gg110_options__number_ranges,
-  (ProtobufCMessageInit) gg110_options__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const uint32_t gg110_access_info__dummy1__default_value = 1u;
-static const ProtobufCFieldDescriptor gg110_access_info__field_descriptors[5] =
-{
-  {
-    "dummy1",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110AccessInfo, dummy1),
-    NULL,
-    &gg110_access_info__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy2",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110AccessInfo, dummy2),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "last_message",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110AccessInfo, last_message),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "last_file_transfer",
-    4,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110AccessInfo, last_file_transfer),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "last_conference_ch",
-    5,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110AccessInfo, last_conference_ch),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_access_info__field_indices_by_name[] = {
-  0,   /* field[0] = dummy1 */
-  1,   /* field[1] = dummy2 */
-  4,   /* field[4] = last_conference_ch */
-  3,   /* field[3] = last_file_transfer */
-  2,   /* field[2] = last_message */
-};
-static const ProtobufCIntRange gg110_access_info__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 5 }
-};
-const ProtobufCMessageDescriptor gg110_access_info__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110AccessInfo",
-  "GG110AccessInfo",
-  "GG110AccessInfo",
-  "",
-  sizeof(GG110AccessInfo),
-  5,
-  gg110_access_info__field_descriptors,
-  gg110_access_info__field_indices_by_name,
-  1,  gg110_access_info__number_ranges,
-  (ProtobufCMessageInit) gg110_access_info__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const uint32_t gg112_transfer_info_uin__dummy1__default_value = 1u;
-static const ProtobufCFieldDescriptor gg112_transfer_info_uin__field_descriptors[2] =
-{
-  {
-    "dummy1",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfoUin, dummy1),
-    NULL,
-    &gg112_transfer_info_uin__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "uin",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_BYTES,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfoUin, uin),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg112_transfer_info_uin__field_indices_by_name[] = {
-  0,   /* field[0] = dummy1 */
-  1,   /* field[1] = uin */
-};
-static const ProtobufCIntRange gg112_transfer_info_uin__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 2 }
-};
-const ProtobufCMessageDescriptor gg112_transfer_info_uin__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG112TransferInfoUin",
-  "GG112TransferInfoUin",
-  "GG112TransferInfoUin",
-  "",
-  sizeof(GG112TransferInfoUin),
-  2,
-  gg112_transfer_info_uin__field_descriptors,
-  gg112_transfer_info_uin__field_indices_by_name,
-  1,  gg112_transfer_info_uin__number_ranges,
-  (ProtobufCMessageInit) gg112_transfer_info_uin__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-char gg112_transfer_info_file__type__default_value[] = "other";
-static const ProtobufCFieldDescriptor gg112_transfer_info_file__field_descriptors[6] =
-{
-  {
-    "type",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfoFile, type),
-    NULL,
-    &gg112_transfer_info_file__type__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "url",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfoFile, url),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "content_type",
-    6,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfoFile, content_type),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "filename",
-    7,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfoFile, filename),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "filesize",
-    8,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfoFile, filesize),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_id",
-    1001,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED64,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfoFile, msg_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg112_transfer_info_file__field_indices_by_name[] = {
-  2,   /* field[2] = content_type */
-  3,   /* field[3] = filename */
-  4,   /* field[4] = filesize */
-  5,   /* field[5] = msg_id */
-  0,   /* field[0] = type */
-  1,   /* field[1] = url */
-};
-static const ProtobufCIntRange gg112_transfer_info_file__number_ranges[3 + 1] =
-{
-  { 1, 0 },
-  { 6, 2 },
-  { 1001, 5 },
-  { 0, 6 }
-};
-const ProtobufCMessageDescriptor gg112_transfer_info_file__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG112TransferInfoFile",
-  "GG112TransferInfoFile",
-  "GG112TransferInfoFile",
-  "",
-  sizeof(GG112TransferInfoFile),
-  6,
-  gg112_transfer_info_file__field_descriptors,
-  gg112_transfer_info_file__field_indices_by_name,
-  3,  gg112_transfer_info_file__number_ranges,
-  (ProtobufCMessageInit) gg112_transfer_info_file__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-static const ProtobufCFieldDescriptor gg112_transfer_info__field_descriptors[9] =
-{
-  {
-    "dummy1",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfo, dummy1),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "peer",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_MESSAGE,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfo, peer),
-    &gg112_transfer_info_uin__descriptor,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "time",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED32,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfo, time),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "sender",
-    4,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_MESSAGE,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfo, sender),
-    &gg112_transfer_info_uin__descriptor,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "data",
-    5,
-    PROTOBUF_C_LABEL_REPEATED,
-    PROTOBUF_C_TYPE_MESSAGE,
-    offsetof(GG112TransferInfo, n_data),
-    offsetof(GG112TransferInfo, data),
-    &protobuf_kvp__descriptor,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "file",
-    6,
-    PROTOBUF_C_LABEL_OPTIONAL,
-    PROTOBUF_C_TYPE_MESSAGE,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfo, file),
-    &gg112_transfer_info_file__descriptor,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "seq",
-    7,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_UINT32,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfo, seq),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "msg_id",
-    1001,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED64,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfo, msg_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "conv_id",
-    1002,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_FIXED64,
-    0,   /* quantifier_offset */
-    offsetof(GG112TransferInfo, conv_id),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg112_transfer_info__field_indices_by_name[] = {
-  8,   /* field[8] = conv_id */
-  4,   /* field[4] = data */
-  0,   /* field[0] = dummy1 */
-  5,   /* field[5] = file */
-  7,   /* field[7] = msg_id */
-  1,   /* field[1] = peer */
-  3,   /* field[3] = sender */
-  6,   /* field[6] = seq */
-  2,   /* field[2] = time */
-};
-static const ProtobufCIntRange gg112_transfer_info__number_ranges[2 + 1] =
-{
-  { 1, 0 },
-  { 1001, 7 },
-  { 0, 9 }
-};
-const ProtobufCMessageDescriptor gg112_transfer_info__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG112TransferInfo",
-  "GG112TransferInfo",
-  "GG112TransferInfo",
-  "",
-  sizeof(GG112TransferInfo),
-  9,
-  gg112_transfer_info__field_descriptors,
-  gg112_transfer_info__field_indices_by_name,
-  2,  gg112_transfer_info__number_ranges,
-  (ProtobufCMessageInit) gg112_transfer_info__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
-char gg110_magic_notification__dummy4__default_value[] = "";
-static const int32_t gg110_magic_notification__dummy1__default_value = 2;
-static const int32_t gg110_magic_notification__dummy2__default_value = 1;
-static const int32_t gg110_magic_notification__dummy3__default_value = 1;
-static const ProtobufCFieldDescriptor gg110_magic_notification__field_descriptors[6] =
-{
-  {
-    "dummy1",
-    1,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_INT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110MagicNotification, dummy1),
-    NULL,
-    &gg110_magic_notification__dummy1__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "seq",
-    2,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_INT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110MagicNotification, seq),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy2",
-    3,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_INT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110MagicNotification, dummy2),
-    NULL,
-    &gg110_magic_notification__dummy2__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy3",
-    4,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_INT32,
-    0,   /* quantifier_offset */
-    offsetof(GG110MagicNotification, dummy3),
-    NULL,
-    &gg110_magic_notification__dummy3__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "uin",
-    5,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_BYTES,
-    0,   /* quantifier_offset */
-    offsetof(GG110MagicNotification, uin),
-    NULL,
-    NULL,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-  {
-    "dummy4",
-    6,
-    PROTOBUF_C_LABEL_REQUIRED,
-    PROTOBUF_C_TYPE_STRING,
-    0,   /* quantifier_offset */
-    offsetof(GG110MagicNotification, dummy4),
-    NULL,
-    &gg110_magic_notification__dummy4__default_value,
-    0,             /* flags */
-    0,NULL,NULL    /* reserved1,reserved2, etc */
-  },
-};
-static const unsigned gg110_magic_notification__field_indices_by_name[] = {
-  0,   /* field[0] = dummy1 */
-  2,   /* field[2] = dummy2 */
-  3,   /* field[3] = dummy3 */
-  5,   /* field[5] = dummy4 */
-  1,   /* field[1] = seq */
-  4,   /* field[4] = uin */
-};
-static const ProtobufCIntRange gg110_magic_notification__number_ranges[1 + 1] =
-{
-  { 1, 0 },
-  { 0, 6 }
-};
-const ProtobufCMessageDescriptor gg110_magic_notification__descriptor =
-{
-  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
-  "GG110MagicNotification",
-  "GG110MagicNotification",
-  "GG110MagicNotification",
-  "",
-  sizeof(GG110MagicNotification),
-  6,
-  gg110_magic_notification__field_descriptors,
-  gg110_magic_notification__field_indices_by_name,
-  1,  gg110_magic_notification__number_ranges,
-  (ProtobufCMessageInit) gg110_magic_notification__init,
-  NULL,NULL,NULL    /* reserved[123] */
-};
--- a/libpurple/protocols/gg/lib/packets.pb-c.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,766 +0,0 @@
-/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
-/* Generated from: packets.proto */
-
-#ifndef PROTOBUF_C_packets_2eproto__INCLUDED
-#define PROTOBUF_C_packets_2eproto__INCLUDED
-
-#include "protobuf.h"
-
-PROTOBUF_C__BEGIN_DECLS
-
-#if PROTOBUF_C_VERSION_NUMBER < 1000000
-# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
-#elif 1000002 < PROTOBUF_C_MIN_COMPILER_VERSION
-# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
-#endif
-
-
-typedef struct _GG110LoginOK GG110LoginOK;
-typedef struct _GG110Pong GG110Pong;
-typedef struct _GG110Ack GG110Ack;
-typedef struct _GG105Login GG105Login;
-typedef struct _GG110MessageAckLink GG110MessageAckLink;
-typedef struct _GG110MessageAck GG110MessageAck;
-typedef struct _GG110Event GG110Event;
-typedef struct _GG110RecvMessage GG110RecvMessage;
-typedef struct _GG110SendMessage GG110SendMessage;
-typedef struct _GG110Imtoken GG110Imtoken;
-typedef struct _GG110ChatInfoUpdate GG110ChatInfoUpdate;
-typedef struct _ProtobufKVP ProtobufKVP;
-typedef struct _GG110Options GG110Options;
-typedef struct _GG110AccessInfo GG110AccessInfo;
-typedef struct _GG112TransferInfoUin GG112TransferInfoUin;
-typedef struct _GG112TransferInfoFile GG112TransferInfoFile;
-typedef struct _GG112TransferInfo GG112TransferInfo;
-typedef struct _GG110MagicNotification GG110MagicNotification;
-
-
-/* --- enums --- */
-
-typedef enum _GG110Ack__Type {
-  GG110_ACK__TYPE__MSG = 1,
-  GG110_ACK__TYPE__CHAT = 2,
-  GG110_ACK__TYPE__CHAT_INFO = 3,
-  GG110_ACK__TYPE__MAGIC_NOTIFICATION = 5,
-  GG110_ACK__TYPE__MPA = 6,
-  GG110_ACK__TYPE__TRANSFER_INFO = 7
-    PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(GG110_ACK__TYPE)
-} GG110Ack__Type;
-typedef enum _GG110Event__Type {
-  GG110_EVENT__TYPE__XML = 0,
-  GG110_EVENT__TYPE__JSON = 2
-    PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(GG110_EVENT__TYPE)
-} GG110Event__Type;
-
-/* --- messages --- */
-
-struct  _GG110LoginOK
-{
-  ProtobufCMessage base;
-  int32_t dummy1;
-  char *dummyhash;
-  uint32_t uin;
-  uint32_t server_time;
-};
-#define GG110_LOGIN_OK__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_login_ok__descriptor) \
-    , 1, NULL, 0, 0 }
-
-
-struct  _GG110Pong
-{
-  ProtobufCMessage base;
-  uint32_t server_time;
-};
-#define GG110_PONG__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_pong__descriptor) \
-    , 0 }
-
-
-struct  _GG110Ack
-{
-  ProtobufCMessage base;
-  GG110Ack__Type type;
-  uint32_t seq;
-  uint32_t dummy1;
-};
-#define GG110_ACK__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_ack__descriptor) \
-    , 0, 0, 1u }
-
-
-struct  _GG105Login
-{
-  ProtobufCMessage base;
-  char *lang;
-  ProtobufCBinaryData uin;
-  ProtobufCBinaryData hash;
-  char *client;
-  uint32_t initial_status;
-  char *initial_descr;
-  char *supported_features;
-  int32_t dummy1;
-  uint32_t dummy2;
-  uint32_t dummy3;
-  ProtobufCBinaryData dummy4;
-  int32_t dummy5;
-  int32_t dummy6;
-  protobuf_c_boolean has_dummy7;
-  uint32_t dummy7;
-  protobuf_c_boolean has_dummy8;
-  int32_t dummy8;
-  protobuf_c_boolean has_dummy10;
-  uint32_t dummy10;
-};
-extern char gg105_login__initial_descr__default_value[];
-#define GG105_LOGIN__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg105_login__descriptor) \
-    , NULL, {0,NULL}, {0,NULL}, NULL, 8227u, gg105_login__initial_descr__default_value, NULL, 4, 65994615u, 198164u, {0,NULL}, 255, 100, 0,127u, 0,0, 0,0u }
-
-
-struct  _GG110MessageAckLink
-{
-  ProtobufCMessage base;
-  uint64_t id;
-  char *url;
-};
-#define GG110_MESSAGE_ACK_LINK__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_message_ack_link__descriptor) \
-    , 0, NULL }
-
-
-struct  _GG110MessageAck
-{
-  ProtobufCMessage base;
-  uint32_t msg_type;
-  uint32_t seq;
-  uint32_t time;
-  protobuf_c_boolean has_msg_id;
-  uint64_t msg_id;
-  protobuf_c_boolean has_conv_id;
-  uint64_t conv_id;
-  size_t n_links;
-  GG110MessageAckLink **links;
-  uint32_t dummy1;
-};
-#define GG110_MESSAGE_ACK__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_message_ack__descriptor) \
-    , 0, 0, 0, 0,0, 0,0, 0,NULL, 0u }
-
-
-struct  _GG110Event
-{
-  ProtobufCMessage base;
-  GG110Event__Type type;
-  uint32_t seq;
-  char *data;
-  char *subtype;
-  protobuf_c_boolean has_id;
-  uint64_t id;
-};
-#define GG110_EVENT__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_event__descriptor) \
-    , 0, 0, NULL, NULL, 0,0 }
-
-
-struct  _GG110RecvMessage
-{
-  ProtobufCMessage base;
-  protobuf_c_boolean has_sender;
-  ProtobufCBinaryData sender;
-  uint32_t flags;
-  uint32_t seq;
-  uint32_t time;
-  char *msg_plain;
-  char *msg_xhtml;
-  protobuf_c_boolean has_data;
-  ProtobufCBinaryData data;
-  protobuf_c_boolean has_msg_id;
-  uint64_t msg_id;
-  protobuf_c_boolean has_chat_id;
-  uint64_t chat_id;
-  protobuf_c_boolean has_conv_id;
-  uint64_t conv_id;
-};
-extern char gg110_recv_message__msg_plain__default_value[];
-#define GG110_RECV_MESSAGE__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_recv_message__descriptor) \
-    , 0,{0,NULL}, 0, 0, 0, gg110_recv_message__msg_plain__default_value, NULL, 0,{0,NULL}, 0,0, 0,0, 0,0 }
-
-
-struct  _GG110SendMessage
-{
-  ProtobufCMessage base;
-  protobuf_c_boolean has_recipient;
-  ProtobufCBinaryData recipient;
-  uint32_t dummy1;
-  uint32_t seq;
-  char *msg_plain;
-  char *msg_xhtml;
-  char *dummy3;
-  protobuf_c_boolean has_chat_id;
-  uint64_t chat_id;
-};
-extern char gg110_send_message__dummy3__default_value[];
-#define GG110_SEND_MESSAGE__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_send_message__descriptor) \
-    , 0,{0,NULL}, 8u, 0, NULL, NULL, gg110_send_message__dummy3__default_value, 0,0 }
-
-
-struct  _GG110Imtoken
-{
-  ProtobufCMessage base;
-  char *imtoken;
-};
-#define GG110_IMTOKEN__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_imtoken__descriptor) \
-    , NULL }
-
-
-struct  _GG110ChatInfoUpdate
-{
-  ProtobufCMessage base;
-  ProtobufCBinaryData participant;
-  ProtobufCBinaryData inviter;
-  uint32_t update_type;
-  uint32_t time;
-  uint32_t dummy1;
-  uint32_t version;
-  uint32_t dummy2;
-  uint64_t msg_id;
-  uint64_t chat_id;
-  uint64_t conv_id;
-};
-#define GG110_CHAT_INFO_UPDATE__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_chat_info_update__descriptor) \
-    , {0,NULL}, {0,NULL}, 0, 0, 0, 0, 0, 0, 0, 0 }
-
-
-struct  _ProtobufKVP
-{
-  ProtobufCMessage base;
-  char *key;
-  char *value;
-};
-#define PROTOBUF_KVP__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&protobuf_kvp__descriptor) \
-    , NULL, NULL }
-
-
-struct  _GG110Options
-{
-  ProtobufCMessage base;
-  size_t n_options;
-  ProtobufKVP **options;
-  uint32_t dummy1;
-};
-#define GG110_OPTIONS__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_options__descriptor) \
-    , 0,NULL, 0u }
-
-
-struct  _GG110AccessInfo
-{
-  ProtobufCMessage base;
-  uint32_t dummy1;
-  uint32_t dummy2;
-  uint32_t last_message;
-  uint32_t last_file_transfer;
-  uint32_t last_conference_ch;
-};
-#define GG110_ACCESS_INFO__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_access_info__descriptor) \
-    , 1u, 0, 0, 0, 0 }
-
-
-struct  _GG112TransferInfoUin
-{
-  ProtobufCMessage base;
-  uint32_t dummy1;
-  ProtobufCBinaryData uin;
-};
-#define GG112_TRANSFER_INFO_UIN__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg112_transfer_info_uin__descriptor) \
-    , 1u, {0,NULL} }
-
-
-struct  _GG112TransferInfoFile
-{
-  ProtobufCMessage base;
-  char *type;
-  char *url;
-  char *content_type;
-  char *filename;
-  uint32_t filesize;
-  uint64_t msg_id;
-};
-extern char gg112_transfer_info_file__type__default_value[];
-#define GG112_TRANSFER_INFO_FILE__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg112_transfer_info_file__descriptor) \
-    , gg112_transfer_info_file__type__default_value, NULL, NULL, NULL, 0, 0 }
-
-
-struct  _GG112TransferInfo
-{
-  ProtobufCMessage base;
-  uint32_t dummy1;
-  GG112TransferInfoUin *peer;
-  GG112TransferInfoUin *sender;
-  uint32_t time;
-  size_t n_data;
-  ProtobufKVP **data;
-  GG112TransferInfoFile *file;
-  uint32_t seq;
-  uint64_t msg_id;
-  uint64_t conv_id;
-};
-#define GG112_TRANSFER_INFO__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg112_transfer_info__descriptor) \
-    , 0, NULL, NULL, 0, 0,NULL, NULL, 0, 0, 0 }
-
-
-struct  _GG110MagicNotification
-{
-  ProtobufCMessage base;
-  int32_t dummy1;
-  int32_t seq;
-  int32_t dummy2;
-  int32_t dummy3;
-  ProtobufCBinaryData uin;
-  char *dummy4;
-};
-extern char gg110_magic_notification__dummy4__default_value[];
-#define GG110_MAGIC_NOTIFICATION__INIT \
- { PROTOBUF_C_MESSAGE_INIT (&gg110_magic_notification__descriptor) \
-    , 2, 0, 1, 1, {0,NULL}, gg110_magic_notification__dummy4__default_value }
-
-
-/* GG110LoginOK methods */
-void   gg110_login_ok__init
-                     (GG110LoginOK         *message);
-size_t gg110_login_ok__get_packed_size
-                     (const GG110LoginOK   *message);
-size_t gg110_login_ok__pack
-                     (const GG110LoginOK   *message,
-                      uint8_t             *out);
-size_t gg110_login_ok__pack_to_buffer
-                     (const GG110LoginOK   *message,
-                      ProtobufCBuffer     *buffer);
-GG110LoginOK *
-       gg110_login_ok__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_login_ok__free_unpacked
-                     (GG110LoginOK *message,
-                      ProtobufCAllocator *allocator);
-/* GG110Pong methods */
-void   gg110_pong__init
-                     (GG110Pong         *message);
-size_t gg110_pong__get_packed_size
-                     (const GG110Pong   *message);
-size_t gg110_pong__pack
-                     (const GG110Pong   *message,
-                      uint8_t             *out);
-size_t gg110_pong__pack_to_buffer
-                     (const GG110Pong   *message,
-                      ProtobufCBuffer     *buffer);
-GG110Pong *
-       gg110_pong__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_pong__free_unpacked
-                     (GG110Pong *message,
-                      ProtobufCAllocator *allocator);
-/* GG110Ack methods */
-void   gg110_ack__init
-                     (GG110Ack         *message);
-size_t gg110_ack__get_packed_size
-                     (const GG110Ack   *message);
-size_t gg110_ack__pack
-                     (const GG110Ack   *message,
-                      uint8_t             *out);
-size_t gg110_ack__pack_to_buffer
-                     (const GG110Ack   *message,
-                      ProtobufCBuffer     *buffer);
-GG110Ack *
-       gg110_ack__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_ack__free_unpacked
-                     (GG110Ack *message,
-                      ProtobufCAllocator *allocator);
-/* GG105Login methods */
-void   gg105_login__init
-                     (GG105Login         *message);
-size_t gg105_login__get_packed_size
-                     (const GG105Login   *message);
-size_t gg105_login__pack
-                     (const GG105Login   *message,
-                      uint8_t             *out);
-size_t gg105_login__pack_to_buffer
-                     (const GG105Login   *message,
-                      ProtobufCBuffer     *buffer);
-GG105Login *
-       gg105_login__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg105_login__free_unpacked
-                     (GG105Login *message,
-                      ProtobufCAllocator *allocator);
-/* GG110MessageAckLink methods */
-void   gg110_message_ack_link__init
-                     (GG110MessageAckLink         *message);
-size_t gg110_message_ack_link__get_packed_size
-                     (const GG110MessageAckLink   *message);
-size_t gg110_message_ack_link__pack
-                     (const GG110MessageAckLink   *message,
-                      uint8_t             *out);
-size_t gg110_message_ack_link__pack_to_buffer
-                     (const GG110MessageAckLink   *message,
-                      ProtobufCBuffer     *buffer);
-GG110MessageAckLink *
-       gg110_message_ack_link__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_message_ack_link__free_unpacked
-                     (GG110MessageAckLink *message,
-                      ProtobufCAllocator *allocator);
-/* GG110MessageAck methods */
-void   gg110_message_ack__init
-                     (GG110MessageAck         *message);
-size_t gg110_message_ack__get_packed_size
-                     (const GG110MessageAck   *message);
-size_t gg110_message_ack__pack
-                     (const GG110MessageAck   *message,
-                      uint8_t             *out);
-size_t gg110_message_ack__pack_to_buffer
-                     (const GG110MessageAck   *message,
-                      ProtobufCBuffer     *buffer);
-GG110MessageAck *
-       gg110_message_ack__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_message_ack__free_unpacked
-                     (GG110MessageAck *message,
-                      ProtobufCAllocator *allocator);
-/* GG110Event methods */
-void   gg110_event__init
-                     (GG110Event         *message);
-size_t gg110_event__get_packed_size
-                     (const GG110Event   *message);
-size_t gg110_event__pack
-                     (const GG110Event   *message,
-                      uint8_t             *out);
-size_t gg110_event__pack_to_buffer
-                     (const GG110Event   *message,
-                      ProtobufCBuffer     *buffer);
-GG110Event *
-       gg110_event__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_event__free_unpacked
-                     (GG110Event *message,
-                      ProtobufCAllocator *allocator);
-/* GG110RecvMessage methods */
-void   gg110_recv_message__init
-                     (GG110RecvMessage         *message);
-size_t gg110_recv_message__get_packed_size
-                     (const GG110RecvMessage   *message);
-size_t gg110_recv_message__pack
-                     (const GG110RecvMessage   *message,
-                      uint8_t             *out);
-size_t gg110_recv_message__pack_to_buffer
-                     (const GG110RecvMessage   *message,
-                      ProtobufCBuffer     *buffer);
-GG110RecvMessage *
-       gg110_recv_message__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_recv_message__free_unpacked
-                     (GG110RecvMessage *message,
-                      ProtobufCAllocator *allocator);
-/* GG110SendMessage methods */
-void   gg110_send_message__init
-                     (GG110SendMessage         *message);
-size_t gg110_send_message__get_packed_size
-                     (const GG110SendMessage   *message);
-size_t gg110_send_message__pack
-                     (const GG110SendMessage   *message,
-                      uint8_t             *out);
-size_t gg110_send_message__pack_to_buffer
-                     (const GG110SendMessage   *message,
-                      ProtobufCBuffer     *buffer);
-GG110SendMessage *
-       gg110_send_message__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_send_message__free_unpacked
-                     (GG110SendMessage *message,
-                      ProtobufCAllocator *allocator);
-/* GG110Imtoken methods */
-void   gg110_imtoken__init
-                     (GG110Imtoken         *message);
-size_t gg110_imtoken__get_packed_size
-                     (const GG110Imtoken   *message);
-size_t gg110_imtoken__pack
-                     (const GG110Imtoken   *message,
-                      uint8_t             *out);
-size_t gg110_imtoken__pack_to_buffer
-                     (const GG110Imtoken   *message,
-                      ProtobufCBuffer     *buffer);
-GG110Imtoken *
-       gg110_imtoken__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_imtoken__free_unpacked
-                     (GG110Imtoken *message,
-                      ProtobufCAllocator *allocator);
-/* GG110ChatInfoUpdate methods */
-void   gg110_chat_info_update__init
-                     (GG110ChatInfoUpdate         *message);
-size_t gg110_chat_info_update__get_packed_size
-                     (const GG110ChatInfoUpdate   *message);
-size_t gg110_chat_info_update__pack
-                     (const GG110ChatInfoUpdate   *message,
-                      uint8_t             *out);
-size_t gg110_chat_info_update__pack_to_buffer
-                     (const GG110ChatInfoUpdate   *message,
-                      ProtobufCBuffer     *buffer);
-GG110ChatInfoUpdate *
-       gg110_chat_info_update__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_chat_info_update__free_unpacked
-                     (GG110ChatInfoUpdate *message,
-                      ProtobufCAllocator *allocator);
-/* ProtobufKVP methods */
-void   protobuf_kvp__init
-                     (ProtobufKVP         *message);
-size_t protobuf_kvp__get_packed_size
-                     (const ProtobufKVP   *message);
-size_t protobuf_kvp__pack
-                     (const ProtobufKVP   *message,
-                      uint8_t             *out);
-size_t protobuf_kvp__pack_to_buffer
-                     (const ProtobufKVP   *message,
-                      ProtobufCBuffer     *buffer);
-ProtobufKVP *
-       protobuf_kvp__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   protobuf_kvp__free_unpacked
-                     (ProtobufKVP *message,
-                      ProtobufCAllocator *allocator);
-/* GG110Options methods */
-void   gg110_options__init
-                     (GG110Options         *message);
-size_t gg110_options__get_packed_size
-                     (const GG110Options   *message);
-size_t gg110_options__pack
-                     (const GG110Options   *message,
-                      uint8_t             *out);
-size_t gg110_options__pack_to_buffer
-                     (const GG110Options   *message,
-                      ProtobufCBuffer     *buffer);
-GG110Options *
-       gg110_options__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_options__free_unpacked
-                     (GG110Options *message,
-                      ProtobufCAllocator *allocator);
-/* GG110AccessInfo methods */
-void   gg110_access_info__init
-                     (GG110AccessInfo         *message);
-size_t gg110_access_info__get_packed_size
-                     (const GG110AccessInfo   *message);
-size_t gg110_access_info__pack
-                     (const GG110AccessInfo   *message,
-                      uint8_t             *out);
-size_t gg110_access_info__pack_to_buffer
-                     (const GG110AccessInfo   *message,
-                      ProtobufCBuffer     *buffer);
-GG110AccessInfo *
-       gg110_access_info__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_access_info__free_unpacked
-                     (GG110AccessInfo *message,
-                      ProtobufCAllocator *allocator);
-/* GG112TransferInfoUin methods */
-void   gg112_transfer_info_uin__init
-                     (GG112TransferInfoUin         *message);
-size_t gg112_transfer_info_uin__get_packed_size
-                     (const GG112TransferInfoUin   *message);
-size_t gg112_transfer_info_uin__pack
-                     (const GG112TransferInfoUin   *message,
-                      uint8_t             *out);
-size_t gg112_transfer_info_uin__pack_to_buffer
-                     (const GG112TransferInfoUin   *message,
-                      ProtobufCBuffer     *buffer);
-GG112TransferInfoUin *
-       gg112_transfer_info_uin__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg112_transfer_info_uin__free_unpacked
-                     (GG112TransferInfoUin *message,
-                      ProtobufCAllocator *allocator);
-/* GG112TransferInfoFile methods */
-void   gg112_transfer_info_file__init
-                     (GG112TransferInfoFile         *message);
-size_t gg112_transfer_info_file__get_packed_size
-                     (const GG112TransferInfoFile   *message);
-size_t gg112_transfer_info_file__pack
-                     (const GG112TransferInfoFile   *message,
-                      uint8_t             *out);
-size_t gg112_transfer_info_file__pack_to_buffer
-                     (const GG112TransferInfoFile   *message,
-                      ProtobufCBuffer     *buffer);
-GG112TransferInfoFile *
-       gg112_transfer_info_file__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg112_transfer_info_file__free_unpacked
-                     (GG112TransferInfoFile *message,
-                      ProtobufCAllocator *allocator);
-/* GG112TransferInfo methods */
-void   gg112_transfer_info__init
-                     (GG112TransferInfo         *message);
-size_t gg112_transfer_info__get_packed_size
-                     (const GG112TransferInfo   *message);
-size_t gg112_transfer_info__pack
-                     (const GG112TransferInfo   *message,
-                      uint8_t             *out);
-size_t gg112_transfer_info__pack_to_buffer
-                     (const GG112TransferInfo   *message,
-                      ProtobufCBuffer     *buffer);
-GG112TransferInfo *
-       gg112_transfer_info__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg112_transfer_info__free_unpacked
-                     (GG112TransferInfo *message,
-                      ProtobufCAllocator *allocator);
-/* GG110MagicNotification methods */
-void   gg110_magic_notification__init
-                     (GG110MagicNotification         *message);
-size_t gg110_magic_notification__get_packed_size
-                     (const GG110MagicNotification   *message);
-size_t gg110_magic_notification__pack
-                     (const GG110MagicNotification   *message,
-                      uint8_t             *out);
-size_t gg110_magic_notification__pack_to_buffer
-                     (const GG110MagicNotification   *message,
-                      ProtobufCBuffer     *buffer);
-GG110MagicNotification *
-       gg110_magic_notification__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-void   gg110_magic_notification__free_unpacked
-                     (GG110MagicNotification *message,
-                      ProtobufCAllocator *allocator);
-/* --- per-message closures --- */
-
-typedef void (*GG110LoginOK_Closure)
-                 (const GG110LoginOK *message,
-                  void *closure_data);
-typedef void (*GG110Pong_Closure)
-                 (const GG110Pong *message,
-                  void *closure_data);
-typedef void (*GG110Ack_Closure)
-                 (const GG110Ack *message,
-                  void *closure_data);
-typedef void (*GG105Login_Closure)
-                 (const GG105Login *message,
-                  void *closure_data);
-typedef void (*GG110MessageAckLink_Closure)
-                 (const GG110MessageAckLink *message,
-                  void *closure_data);
-typedef void (*GG110MessageAck_Closure)
-                 (const GG110MessageAck *message,
-                  void *closure_data);
-typedef void (*GG110Event_Closure)
-                 (const GG110Event *message,
-                  void *closure_data);
-typedef void (*GG110RecvMessage_Closure)
-                 (const GG110RecvMessage *message,
-                  void *closure_data);
-typedef void (*GG110SendMessage_Closure)
-                 (const GG110SendMessage *message,
-                  void *closure_data);
-typedef void (*GG110Imtoken_Closure)
-                 (const GG110Imtoken *message,
-                  void *closure_data);
-typedef void (*GG110ChatInfoUpdate_Closure)
-                 (const GG110ChatInfoUpdate *message,
-                  void *closure_data);
-typedef void (*ProtobufKVP_Closure)
-                 (const ProtobufKVP *message,
-                  void *closure_data);
-typedef void (*GG110Options_Closure)
-                 (const GG110Options *message,
-                  void *closure_data);
-typedef void (*GG110AccessInfo_Closure)
-                 (const GG110AccessInfo *message,
-                  void *closure_data);
-typedef void (*GG112TransferInfoUin_Closure)
-                 (const GG112TransferInfoUin *message,
-                  void *closure_data);
-typedef void (*GG112TransferInfoFile_Closure)
-                 (const GG112TransferInfoFile *message,
-                  void *closure_data);
-typedef void (*GG112TransferInfo_Closure)
-                 (const GG112TransferInfo *message,
-                  void *closure_data);
-typedef void (*GG110MagicNotification_Closure)
-                 (const GG110MagicNotification *message,
-                  void *closure_data);
-
-/* --- services --- */
-
-
-/* --- descriptors --- */
-
-extern const ProtobufCMessageDescriptor gg110_login_ok__descriptor;
-extern const ProtobufCMessageDescriptor gg110_pong__descriptor;
-extern const ProtobufCMessageDescriptor gg110_ack__descriptor;
-extern const ProtobufCEnumDescriptor    gg110_ack__type__descriptor;
-extern const ProtobufCMessageDescriptor gg105_login__descriptor;
-extern const ProtobufCMessageDescriptor gg110_message_ack_link__descriptor;
-extern const ProtobufCMessageDescriptor gg110_message_ack__descriptor;
-extern const ProtobufCMessageDescriptor gg110_event__descriptor;
-extern const ProtobufCEnumDescriptor    gg110_event__type__descriptor;
-extern const ProtobufCMessageDescriptor gg110_recv_message__descriptor;
-extern const ProtobufCMessageDescriptor gg110_send_message__descriptor;
-extern const ProtobufCMessageDescriptor gg110_imtoken__descriptor;
-extern const ProtobufCMessageDescriptor gg110_chat_info_update__descriptor;
-extern const ProtobufCMessageDescriptor protobuf_kvp__descriptor;
-extern const ProtobufCMessageDescriptor gg110_options__descriptor;
-extern const ProtobufCMessageDescriptor gg110_access_info__descriptor;
-extern const ProtobufCMessageDescriptor gg112_transfer_info_uin__descriptor;
-extern const ProtobufCMessageDescriptor gg112_transfer_info_file__descriptor;
-extern const ProtobufCMessageDescriptor gg112_transfer_info__descriptor;
-extern const ProtobufCMessageDescriptor gg110_magic_notification__descriptor;
-
-PROTOBUF_C__END_DECLS
-
-
-#endif  /* PROTOBUF_C_packets_2eproto__INCLUDED */
--- a/libpurple/protocols/gg/lib/protobuf-c.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3288 +0,0 @@
-/*
- * Copyright (c) 2008-2014, Dave Benson and the protobuf-c authors.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*! \file
- * Support library for `protoc-c` generated code.
- *
- * This file implements the public API used by the code generated
- * by `protoc-c`.
- *
- * \authors Dave Benson and the protobuf-c authors
- *
- * \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license.
- */
-
-/**
- * \todo 64-BIT OPTIMIZATION: certain implementations use 32-bit math
- * even on 64-bit platforms (uint64_size, uint64_pack, parse_uint64).
- *
- * \todo Use size_t consistently.
- */
-
-#include <stdlib.h>	/* for malloc, free */
-#include <string.h>	/* for strcmp, strlen, memcpy, memmove, memset */
-
-/* Pull WORDS_BIGENDIAN etc */
-#include "config.h"
-
-#include "protobuf-c.h"
-
-#define TRUE				1
-#define FALSE				0
-
-#define PROTOBUF_C__ASSERT_NOT_REACHED() assert(0)
-
-/* Workaround for Microsoft compilers. */
-#ifdef _MSC_VER
-# define inline __inline
-#endif
-
-/**
- * \defgroup internal Internal functions and macros
- *
- * These are not exported by the library but are useful to developers working
- * on `libprotobuf-c` itself.
- */
-
-/**
- * \defgroup macros Utility macros for manipulating structures
- *
- * Macros and constants used to manipulate the base "classes" generated by
- * `protobuf-c`. They also define limits and check correctness.
- *
- * \ingroup internal
- * @{
- */
-
-/** The maximum length of a 64-bit integer in varint encoding. */
-#define MAX_UINT64_ENCODED_SIZE		10
-
-#ifndef PROTOBUF_C_UNPACK_ERROR
-# define PROTOBUF_C_UNPACK_ERROR(...)
-#endif
-
-/**
- * Internal `ProtobufCMessage` manipulation macro.
- *
- * Base macro for manipulating a `ProtobufCMessage`. Used by STRUCT_MEMBER() and
- * STRUCT_MEMBER_PTR().
- */
-#define STRUCT_MEMBER_P(struct_p, struct_offset) \
-    ((void *) ((uint8_t *) (struct_p) + (struct_offset)))
-
-/**
- * Return field in a `ProtobufCMessage` based on offset.
- *
- * Take a pointer to a `ProtobufCMessage` and find the field at the offset.
- * Cast it to the passed type.
- */
-#define STRUCT_MEMBER(member_type, struct_p, struct_offset) \
-    (*(member_type *) STRUCT_MEMBER_P((struct_p), (struct_offset)))
-
-/**
- * Return field in a `ProtobufCMessage` based on offset.
- *
- * Take a pointer to a `ProtobufCMessage` and find the field at the offset. Cast
- * it to a pointer to the passed type.
- */
-#define STRUCT_MEMBER_PTR(member_type, struct_p, struct_offset) \
-    ((member_type *) STRUCT_MEMBER_P((struct_p), (struct_offset)))
-
-/* Assertions for magic numbers. */
-
-#define ASSERT_IS_ENUM_DESCRIPTOR(desc) \
-	assert((desc)->magic == PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC)
-
-#define ASSERT_IS_MESSAGE_DESCRIPTOR(desc) \
-	assert((desc)->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC)
-
-#define ASSERT_IS_MESSAGE(message) \
-	ASSERT_IS_MESSAGE_DESCRIPTOR((message)->descriptor)
-
-#define ASSERT_IS_SERVICE_DESCRIPTOR(desc) \
-	assert((desc)->magic == PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC)
-
-/**@}*/
-
-/* --- version --- */
-
-const char *
-protobuf_c_version(void)
-{
-	return PROTOBUF_C_VERSION;
-}
-
-uint32_t
-protobuf_c_version_number(void)
-{
-	return PROTOBUF_C_VERSION_NUMBER;
-}
-
-/* --- allocator --- */
-
-static void *
-system_alloc(void *allocator_data, size_t size)
-{
-	return malloc(size);
-}
-
-static void
-system_free(void *allocator_data, void *data)
-{
-	free(data);
-}
-
-static inline void *
-do_alloc(ProtobufCAllocator *allocator, size_t size)
-{
-	return allocator->alloc(allocator->allocator_data, size);
-}
-
-static inline void
-do_free(ProtobufCAllocator *allocator, void *data)
-{
-	if (data != NULL)
-		allocator->free(allocator->allocator_data, data);
-}
-
-/*
- * This allocator uses the system's malloc() and free(). It is the default
- * allocator used if NULL is passed as the ProtobufCAllocator to an exported
- * function.
- */
-static ProtobufCAllocator protobuf_c__allocator = {
-	.alloc = &system_alloc,
-	.free = &system_free,
-	.allocator_data = NULL,
-};
-
-/* === buffer-simple === */
-
-void
-protobuf_c_buffer_simple_append(ProtobufCBuffer *buffer,
-				size_t len, const uint8_t *data)
-{
-	ProtobufCBufferSimple *simp = (ProtobufCBufferSimple *) buffer;
-	size_t new_len = simp->len + len;
-
-	if (new_len > simp->alloced) {
-		ProtobufCAllocator *allocator = simp->allocator;
-		size_t new_alloced = simp->alloced * 2;
-		uint8_t *new_data;
-
-		if (allocator == NULL)
-			allocator = &protobuf_c__allocator;
-		while (new_alloced < new_len)
-			new_alloced += new_alloced;
-		new_data = do_alloc(allocator, new_alloced);
-		if (!new_data)
-			return;
-		memcpy(new_data, simp->data, simp->len);
-		if (simp->must_free_data)
-			do_free(allocator, simp->data);
-		else
-			simp->must_free_data = TRUE;
-		simp->data = new_data;
-		simp->alloced = new_alloced;
-	}
-	memcpy(simp->data + simp->len, data, len);
-	simp->len = new_len;
-}
-
-/**
- * \defgroup packedsz protobuf_c_message_get_packed_size() implementation
- *
- * Routines mainly used by protobuf_c_message_get_packed_size().
- *
- * \ingroup internal
- * @{
- */
-
-/**
- * Return the number of bytes required to store the tag for the field. Includes
- * 3 bits for the wire-type, and a single bit that denotes the end-of-tag.
- *
- * \param number
- *      Field tag to encode.
- * \return
- *      Number of bytes required.
- */
-static inline size_t
-get_tag_size(unsigned number)
-{
-	if (number < (1 << 4)) {
-		return 1;
-	} else if (number < (1 << 11)) {
-		return 2;
-	} else if (number < (1 << 18)) {
-		return 3;
-	} else if (number < (1 << 25)) {
-		return 4;
-	} else {
-		return 5;
-	}
-}
-
-/**
- * Return the number of bytes required to store a variable-length unsigned
- * 32-bit integer in base-128 varint encoding.
- *
- * \param v
- *      Value to encode.
- * \return
- *      Number of bytes required.
- */
-static inline size_t
-uint32_size(uint32_t v)
-{
-	if (v < (1 << 7)) {
-		return 1;
-	} else if (v < (1 << 14)) {
-		return 2;
-	} else if (v < (1 << 21)) {
-		return 3;
-	} else if (v < (1 << 28)) {
-		return 4;
-	} else {
-		return 5;
-	}
-}
-
-/**
- * Return the number of bytes required to store a variable-length signed 32-bit
- * integer in base-128 varint encoding.
- *
- * \param v
- *      Value to encode.
- * \return
- *      Number of bytes required.
- */
-static inline size_t
-int32_size(int32_t v)
-{
-	if (v < 0) {
-		return 10;
-	} else if (v < (1 << 7)) {
-		return 1;
-	} else if (v < (1 << 14)) {
-		return 2;
-	} else if (v < (1 << 21)) {
-		return 3;
-	} else if (v < (1 << 28)) {
-		return 4;
-	} else {
-		return 5;
-	}
-}
-
-/**
- * Return the ZigZag-encoded 32-bit unsigned integer form of a 32-bit signed
- * integer.
- *
- * \param v
- *      Value to encode.
- * \return
- *      ZigZag encoded integer.
- */
-static inline uint32_t
-zigzag32(int32_t v)
-{
-	if (v < 0)
-		return ((uint32_t) (-v)) * 2 - 1;
-	else
-		return v * 2;
-}
-
-/**
- * Return the number of bytes required to store a signed 32-bit integer,
- * converted to an unsigned 32-bit integer with ZigZag encoding, using base-128
- * varint encoding.
- *
- * \param v
- *      Value to encode.
- * \return
- *      Number of bytes required.
- */
-static inline size_t
-sint32_size(int32_t v)
-{
-	return uint32_size(zigzag32(v));
-}
-
-/**
- * Return the number of bytes required to store a 64-bit unsigned integer in
- * base-128 varint encoding.
- *
- * \param v
- *      Value to encode.
- * \return
- *      Number of bytes required.
- */
-static inline size_t
-uint64_size(uint64_t v)
-{
-	uint32_t upper_v = (uint32_t) (v >> 32);
-
-	if (upper_v == 0) {
-		return uint32_size((uint32_t) v);
-	} else if (upper_v < (1 << 3)) {
-		return 5;
-	} else if (upper_v < (1 << 10)) {
-		return 6;
-	} else if (upper_v < (1 << 17)) {
-		return 7;
-	} else if (upper_v < (1 << 24)) {
-		return 8;
-	} else if (upper_v < (1U << 31)) {
-		return 9;
-	} else {
-		return 10;
-	}
-}
-
-/**
- * Return the ZigZag-encoded 64-bit unsigned integer form of a 64-bit signed
- * integer.
- *
- * \param v
- *      Value to encode.
- * \return
- *      ZigZag encoded integer.
- */
-static inline uint64_t
-zigzag64(int64_t v)
-{
-	if (v < 0)
-		return ((uint64_t) (-v)) * 2 - 1;
-	else
-		return v * 2;
-}
-
-/**
- * Return the number of bytes required to store a signed 64-bit integer,
- * converted to an unsigned 64-bit integer with ZigZag encoding, using base-128
- * varint encoding.
- *
- * \param v
- *      Value to encode.
- * \return
- *      Number of bytes required.
- */
-static inline size_t
-sint64_size(int64_t v)
-{
-	return uint64_size(zigzag64(v));
-}
-
-/**
- * Calculate the serialized size of a single required message field, including
- * the space needed by the preceding tag.
- *
- * \param field
- *      Field descriptor for member.
- * \param member
- *      Field to encode.
- * \return
- *      Number of bytes required.
- */
-static size_t
-required_field_get_packed_size(const ProtobufCFieldDescriptor *field,
-			       const void *member)
-{
-	size_t rv = get_tag_size(field->id);
-
-	switch (field->type) {
-	case PROTOBUF_C_TYPE_SINT32:
-		return rv + sint32_size(*(const int32_t *) member);
-	case PROTOBUF_C_TYPE_INT32:
-		return rv + int32_size(*(const uint32_t *) member);
-	case PROTOBUF_C_TYPE_UINT32:
-		return rv + uint32_size(*(const uint32_t *) member);
-	case PROTOBUF_C_TYPE_SINT64:
-		return rv + sint64_size(*(const int64_t *) member);
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64:
-		return rv + uint64_size(*(const uint64_t *) member);
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-		return rv + 4;
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-		return rv + 8;
-	case PROTOBUF_C_TYPE_BOOL:
-		return rv + 1;
-	case PROTOBUF_C_TYPE_FLOAT:
-		return rv + 4;
-	case PROTOBUF_C_TYPE_DOUBLE:
-		return rv + 8;
-	case PROTOBUF_C_TYPE_ENUM:
-		/* \todo Is this correct for negative-valued enums? */
-		return rv + uint32_size(*(const uint32_t *) member);
-	case PROTOBUF_C_TYPE_STRING: {
-		const char *str = *(char * const *) member;
-		size_t len = str ? strlen(str) : 0;
-		return rv + uint32_size(len) + len;
-	}
-	case PROTOBUF_C_TYPE_BYTES: {
-		size_t len = ((const ProtobufCBinaryData *) member)->len;
-		return rv + uint32_size(len) + len;
-	}
-	case PROTOBUF_C_TYPE_MESSAGE: {
-		const ProtobufCMessage *msg = *(ProtobufCMessage * const *) member;
-		size_t subrv = msg ? protobuf_c_message_get_packed_size(msg) : 0;
-		return rv + uint32_size(subrv) + subrv;
-	}
-	}
-	PROTOBUF_C__ASSERT_NOT_REACHED();
-	return 0;
-}
-
-/**
- * Calculate the serialized size of a single optional message field, including
- * the space needed by the preceding tag. Returns 0 if the optional field isn't
- * set.
- *
- * \param field
- *      Field descriptor for member.
- * \param has
- *      True if the field exists, false if not.
- * \param member
- *      Field to encode.
- * \return
- *      Number of bytes required.
- */
-static size_t
-optional_field_get_packed_size(const ProtobufCFieldDescriptor *field,
-			       const protobuf_c_boolean *has,
-			       const void *member)
-{
-	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
-	    field->type == PROTOBUF_C_TYPE_STRING)
-	{
-		const void *ptr = *(const void * const *) member;
-		if (ptr == NULL || ptr == field->default_value)
-			return 0;
-	} else {
-		if (!*has)
-			return 0;
-	}
-	return required_field_get_packed_size(field, member);
-}
-
-/**
- * Calculate the serialized size of repeated message fields, which may consist
- * of any number of values (including 0). Includes the space needed by the
- * preceding tags (as needed).
- *
- * \param field
- *      Field descriptor for member.
- * \param count
- *      Number of repeated field members.
- * \param member
- *      Field to encode.
- * \return
- *      Number of bytes required.
- */
-static size_t
-repeated_field_get_packed_size(const ProtobufCFieldDescriptor *field,
-			       size_t count, const void *member)
-{
-	size_t header_size;
-	size_t rv = 0;
-	unsigned i;
-	void *array = *(void * const *) member;
-
-	if (count == 0)
-		return 0;
-	header_size = get_tag_size(field->id);
-	if (0 == (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED))
-		header_size *= count;
-
-	switch (field->type) {
-	case PROTOBUF_C_TYPE_SINT32:
-		for (i = 0; i < count; i++)
-			rv += sint32_size(((int32_t *) array)[i]);
-		break;
-	case PROTOBUF_C_TYPE_INT32:
-		for (i = 0; i < count; i++)
-			rv += int32_size(((uint32_t *) array)[i]);
-		break;
-	case PROTOBUF_C_TYPE_UINT32:
-	case PROTOBUF_C_TYPE_ENUM:
-		for (i = 0; i < count; i++)
-			rv += uint32_size(((uint32_t *) array)[i]);
-		break;
-	case PROTOBUF_C_TYPE_SINT64:
-		for (i = 0; i < count; i++)
-			rv += sint64_size(((int64_t *) array)[i]);
-		break;
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64:
-		for (i = 0; i < count; i++)
-			rv += uint64_size(((uint64_t *) array)[i]);
-		break;
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-		rv += 4 * count;
-		break;
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-		rv += 8 * count;
-		break;
-	case PROTOBUF_C_TYPE_BOOL:
-		rv += count;
-		break;
-	case PROTOBUF_C_TYPE_STRING:
-		for (i = 0; i < count; i++) {
-			size_t len = strlen(((char **) array)[i]);
-			rv += uint32_size(len) + len;
-		}
-		break;
-	case PROTOBUF_C_TYPE_BYTES:
-		for (i = 0; i < count; i++) {
-			size_t len = ((ProtobufCBinaryData *) array)[i].len;
-			rv += uint32_size(len) + len;
-		}
-		break;
-	case PROTOBUF_C_TYPE_MESSAGE:
-		for (i = 0; i < count; i++) {
-			size_t len = protobuf_c_message_get_packed_size(
-				((ProtobufCMessage **) array)[i]);
-			rv += uint32_size(len) + len;
-		}
-		break;
-	}
-
-	if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED))
-		header_size += uint32_size(rv);
-	return header_size + rv;
-}
-
-/**
- * Calculate the serialized size of an unknown field, i.e. one that is passed
- * through mostly uninterpreted. This is required for forward compatibility if
- * new fields are added to the message descriptor.
- *
- * \param field
- *      Unknown field type.
- * \return
- *      Number of bytes required.
- */
-static inline size_t
-unknown_field_get_packed_size(const ProtobufCMessageUnknownField *field)
-{
-	return get_tag_size(field->tag) + field->len;
-}
-
-/**@}*/
-
-/*
- * Calculate the serialized size of the message.
- */
-size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message)
-{
-	unsigned i;
-	size_t rv = 0;
-
-	ASSERT_IS_MESSAGE(message);
-	for (i = 0; i < message->descriptor->n_fields; i++) {
-		const ProtobufCFieldDescriptor *field =
-			message->descriptor->fields + i;
-		const void *member =
-			((const char *) message) + field->offset;
-		const void *qmember =
-			((const char *) message) + field->quantifier_offset;
-
-		if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
-			rv += required_field_get_packed_size(field, member);
-		} else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) {
-			rv += optional_field_get_packed_size(field, qmember, member);
-		} else {
-			rv += repeated_field_get_packed_size(
-				field,
-				*(const size_t *) qmember,
-				member
-			);
-		}
-	}
-	for (i = 0; i < message->n_unknown_fields; i++)
-		rv += unknown_field_get_packed_size(&message->unknown_fields[i]);
-	return rv;
-}
-
-/**
- * \defgroup pack protobuf_c_message_pack() implementation
- *
- * Routines mainly used by protobuf_c_message_pack().
- *
- * \ingroup internal
- * @{
- */
-
-/**
- * Pack an unsigned 32-bit integer in base-128 varint encoding and return the
- * number of bytes written, which must be 5 or less.
- *
- * \param value
- *      Value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-uint32_pack(uint32_t value, uint8_t *out)
-{
-	unsigned rv = 0;
-
-	if (value >= 0x80) {
-		out[rv++] = value | 0x80;
-		value >>= 7;
-		if (value >= 0x80) {
-			out[rv++] = value | 0x80;
-			value >>= 7;
-			if (value >= 0x80) {
-				out[rv++] = value | 0x80;
-				value >>= 7;
-				if (value >= 0x80) {
-					out[rv++] = value | 0x80;
-					value >>= 7;
-				}
-			}
-		}
-	}
-	/* assert: value<128 */
-	out[rv++] = value;
-	return rv;
-}
-
-/**
- * Pack a signed 32-bit integer and return the number of bytes written.
- * Negative numbers are encoded as two's complement 64-bit integers.
- *
- * \param value
- *      Value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-int32_pack(int32_t value, uint8_t *out)
-{
-	if (value < 0) {
-		out[0] = value | 0x80;
-		out[1] = (value >> 7) | 0x80;
-		out[2] = (value >> 14) | 0x80;
-		out[3] = (value >> 21) | 0x80;
-		out[4] = (value >> 28) | 0x80;
-		out[5] = out[6] = out[7] = out[8] = 0xff;
-		out[9] = 0x01;
-		return 10;
-	} else {
-		return uint32_pack(value, out);
-	}
-}
-
-/**
- * Pack a signed 32-bit integer using ZigZag encoding and return the number of
- * bytes written.
- *
- * \param value
- *      Value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-sint32_pack(int32_t value, uint8_t *out)
-{
-	return uint32_pack(zigzag32(value), out);
-}
-
-/**
- * Pack a 64-bit unsigned integer using base-128 varint encoding and return the
- * number of bytes written.
- *
- * \param value
- *      Value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static size_t
-uint64_pack(uint64_t value, uint8_t *out)
-{
-	uint32_t hi = (uint32_t) (value >> 32);
-	uint32_t lo = (uint32_t) value;
-	unsigned rv;
-
-	if (hi == 0)
-		return uint32_pack((uint32_t) lo, out);
-	out[0] = (lo) | 0x80;
-	out[1] = (lo >> 7) | 0x80;
-	out[2] = (lo >> 14) | 0x80;
-	out[3] = (lo >> 21) | 0x80;
-	if (hi < 8) {
-		out[4] = (hi << 4) | (lo >> 28);
-		return 5;
-	} else {
-		out[4] = ((hi & 7) << 4) | (lo >> 28) | 0x80;
-		hi >>= 3;
-	}
-	rv = 5;
-	while (hi >= 128) {
-		out[rv++] = hi | 0x80;
-		hi >>= 7;
-	}
-	out[rv++] = hi;
-	return rv;
-}
-
-/**
- * Pack a 64-bit signed integer in ZigZag encoding and return the number of
- * bytes written.
- *
- * \param value
- *      Value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-sint64_pack(int64_t value, uint8_t *out)
-{
-	return uint64_pack(zigzag64(value), out);
-}
-
-/**
- * Pack a 32-bit quantity in little-endian byte order. Used for protobuf wire
- * types fixed32, sfixed32, float. Similar to "htole32".
- *
- * \param value
- *      Value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-fixed32_pack(uint32_t value, void *out)
-{
-#if !defined(WORDS_BIGENDIAN)
-	memcpy(out, &value, 4);
-#else
-	uint8_t *buf = out;
-
-	buf[0] = value;
-	buf[1] = value >> 8;
-	buf[2] = value >> 16;
-	buf[3] = value >> 24;
-#endif
-	return 4;
-}
-
-/**
- * Pack a 64-bit quantity in little-endian byte order. Used for protobuf wire
- * types fixed64, sfixed64, double. Similar to "htole64".
- *
- * \todo The big-endian impl is really only good for 32-bit machines, a 64-bit
- * version would be appreciated, plus a way to decide to use 64-bit math where
- * convenient.
- *
- * \param value
- *      Value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-fixed64_pack(uint64_t value, void *out)
-{
-#if !defined(WORDS_BIGENDIAN)
-	memcpy(out, &value, 8);
-#else
-	fixed32_pack(value, out);
-	fixed32_pack(value >> 32, ((char *) out) + 4);
-#endif
-	return 8;
-}
-
-/**
- * Pack a boolean value as an integer and return the number of bytes written.
- *
- * \todo Perhaps on some platforms *out = !!value would be a better impl, b/c
- * that is idiomatic C++ in some STL implementations.
- *
- * \param value
- *      Value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-boolean_pack(protobuf_c_boolean value, uint8_t *out)
-{
-	*out = value ? TRUE : FALSE;
-	return 1;
-}
-
-/**
- * Pack a NUL-terminated C string and return the number of bytes written. The
- * output includes a length delimiter.
- *
- * The NULL pointer is treated as an empty string. This isn't really necessary,
- * but it allows people to leave required strings blank. (See Issue #13 in the
- * bug tracker for a little more explanation).
- *
- * \param str
- *      String to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-string_pack(const char *str, uint8_t *out)
-{
-	if (str == NULL) {
-		out[0] = 0;
-		return 1;
-	} else {
-		size_t len = strlen(str);
-		size_t rv = uint32_pack(len, out);
-		memcpy(out + rv, str, len);
-		return rv + len;
-	}
-}
-
-/**
- * Pack a ProtobufCBinaryData and return the number of bytes written. The output
- * includes a length delimiter.
- *
- * \param bd
- *      ProtobufCBinaryData to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-binary_data_pack(const ProtobufCBinaryData *bd, uint8_t *out)
-{
-	size_t len = bd->len;
-	size_t rv = uint32_pack(len, out);
-	memcpy(out + rv, bd->data, len);
-	return rv + len;
-}
-
-/**
- * Pack a ProtobufCMessage and return the number of bytes written. The output
- * includes a length delimiter.
- *
- * \param message
- *      ProtobufCMessage object to pack.
- * \param[out] out
- *      Packed message.
- * \return
- *      Number of bytes written to `out`.
- */
-static inline size_t
-prefixed_message_pack(const ProtobufCMessage *message, uint8_t *out)
-{
-	if (message == NULL) {
-		out[0] = 0;
-		return 1;
-	} else {
-		size_t rv = protobuf_c_message_pack(message, out + 1);
-		uint32_t rv_packed_size = uint32_size(rv);
-		if (rv_packed_size != 1)
-			memmove(out + rv_packed_size, out + 1, rv);
-		return uint32_pack(rv, out) + rv;
-	}
-}
-
-/**
- * Pack a field tag.
- *
- * Wire-type will be added in required_field_pack().
- *
- * \todo Just call uint64_pack on 64-bit platforms.
- *
- * \param id
- *      Tag value to encode.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static size_t
-tag_pack(uint32_t id, uint8_t *out)
-{
-	if (id < (1 << (32 - 3)))
-		return uint32_pack(id << 3, out);
-	else
-		return uint64_pack(((uint64_t) id) << 3, out);
-}
-
-/**
- * Pack a required field and return the number of bytes written.
- *
- * \param field
- *      Field descriptor.
- * \param member
- *      The field member.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static size_t
-required_field_pack(const ProtobufCFieldDescriptor *field,
-		    const void *member, uint8_t *out)
-{
-	size_t rv = tag_pack(field->id, out);
-
-	switch (field->type) {
-	case PROTOBUF_C_TYPE_SINT32:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		return rv + sint32_pack(*(const int32_t *) member, out + rv);
-	case PROTOBUF_C_TYPE_INT32:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		return rv + int32_pack(*(const uint32_t *) member, out + rv);
-	case PROTOBUF_C_TYPE_UINT32:
-	case PROTOBUF_C_TYPE_ENUM:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		return rv + uint32_pack(*(const uint32_t *) member, out + rv);
-	case PROTOBUF_C_TYPE_SINT64:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		return rv + sint64_pack(*(const int64_t *) member, out + rv);
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		return rv + uint64_pack(*(const uint64_t *) member, out + rv);
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_32BIT;
-		return rv + fixed32_pack(*(const uint32_t *) member, out + rv);
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_64BIT;
-		return rv + fixed64_pack(*(const uint64_t *) member, out + rv);
-	case PROTOBUF_C_TYPE_BOOL:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		return rv + boolean_pack(*(const protobuf_c_boolean *) member, out + rv);
-	case PROTOBUF_C_TYPE_STRING:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
-		return rv + string_pack(*(char *const *) member, out + rv);
-	case PROTOBUF_C_TYPE_BYTES:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
-		return rv + binary_data_pack((const ProtobufCBinaryData *) member, out + rv);
-	case PROTOBUF_C_TYPE_MESSAGE:
-		out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
-		return rv + prefixed_message_pack(*(ProtobufCMessage * const *) member, out + rv);
-	}
-	PROTOBUF_C__ASSERT_NOT_REACHED();
-	return 0;
-}
-
-/**
- * Pack an optional field and return the number of bytes written.
- *
- * \param field
- *      Field descriptor.
- * \param has
- *      Whether the field is set.
- * \param member
- *      The field member.
- * \param[out] out
- *      Packed value.
- * \return
- *      Number of bytes written to `out`.
- */
-static size_t
-optional_field_pack(const ProtobufCFieldDescriptor *field,
-		    const protobuf_c_boolean *has,
-		    const void *member, uint8_t *out)
-{
-	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
-	    field->type == PROTOBUF_C_TYPE_STRING)
-	{
-		const void *ptr = *(const void * const *) member;
-		if (ptr == NULL || ptr == field->default_value)
-			return 0;
-	} else {
-		if (!*has)
-			return 0;
-	}
-	return required_field_pack(field, member, out);
-}
-
-/**
- * Given a field type, return the in-memory size.
- *
- * \todo Implement as a table lookup.
- *
- * \param type
- *      Field type.
- * \return
- *      Size of the field.
- */
-static inline size_t
-sizeof_elt_in_repeated_array(ProtobufCType type)
-{
-	switch (type) {
-	case PROTOBUF_C_TYPE_SINT32:
-	case PROTOBUF_C_TYPE_INT32:
-	case PROTOBUF_C_TYPE_UINT32:
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-	case PROTOBUF_C_TYPE_ENUM:
-		return 4;
-	case PROTOBUF_C_TYPE_SINT64:
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64:
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-		return 8;
-	case PROTOBUF_C_TYPE_BOOL:
-		return sizeof(protobuf_c_boolean);
-	case PROTOBUF_C_TYPE_STRING:
-	case PROTOBUF_C_TYPE_MESSAGE:
-		return sizeof(void *);
-	case PROTOBUF_C_TYPE_BYTES:
-		return sizeof(ProtobufCBinaryData);
-	}
-	PROTOBUF_C__ASSERT_NOT_REACHED();
-	return 0;
-}
-
-/**
- * Pack an array of 32-bit quantities.
- *
- * \param[out] out
- *      Destination.
- * \param[in] in
- *      Source.
- * \param[in] n
- *      Number of elements in the source array.
- */
-static void
-copy_to_little_endian_32(void *out, const void *in, const unsigned n)
-{
-#if !defined(WORDS_BIGENDIAN)
-	memcpy(out, in, n * 4);
-#else
-	unsigned i;
-	const uint32_t *ini = in;
-	for (i = 0; i < n; i++)
-		fixed32_pack(ini[i], (uint32_t *) out + i);
-#endif
-}
-
-/**
- * Pack an array of 64-bit quantities.
- *
- * \param[out] out
- *      Destination.
- * \param[in] in
- *      Source.
- * \param[in] n
- *      Number of elements in the source array.
- */
-static void
-copy_to_little_endian_64(void *out, const void *in, const unsigned n)
-{
-#if !defined(WORDS_BIGENDIAN)
-	memcpy(out, in, n * 8);
-#else
-	unsigned i;
-	const uint64_t *ini = in;
-	for (i = 0; i < n; i++)
-		fixed64_pack(ini[i], (uint64_t *) out + i);
-#endif
-}
-
-/**
- * Get the minimum number of bytes required to pack a field value of a
- * particular type.
- *
- * \param type
- *      Field type.
- * \return
- *      Number of bytes.
- */
-static unsigned
-get_type_min_size(ProtobufCType type)
-{
-	if (type == PROTOBUF_C_TYPE_SFIXED32 ||
-	    type == PROTOBUF_C_TYPE_FIXED32 ||
-	    type == PROTOBUF_C_TYPE_FLOAT)
-	{
-		return 4;
-	}
-	if (type == PROTOBUF_C_TYPE_SFIXED64 ||
-	    type == PROTOBUF_C_TYPE_FIXED64 ||
-	    type == PROTOBUF_C_TYPE_DOUBLE)
-	{
-		return 8;
-	}
-	return 1;
-}
-
-/**
- * Packs the elements of a repeated field and returns the serialised field and
- * its length.
- *
- * \param field
- *      Field descriptor.
- * \param count
- *      Number of elements in the repeated field array.
- * \param member
- *      Pointer to the elements for this repeated field.
- * \param[out] out
- *      Serialised representation of the repeated field.
- * \return
- *      Number of bytes serialised to `out`.
- */
-static size_t
-repeated_field_pack(const ProtobufCFieldDescriptor *field,
-		    size_t count, const void *member, uint8_t *out)
-{
-	void *array = *(void * const *) member;
-	unsigned i;
-
-	if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) {
-		unsigned header_len;
-		unsigned len_start;
-		unsigned min_length;
-		unsigned payload_len;
-		unsigned length_size_min;
-		unsigned actual_length_size;
-		uint8_t *payload_at;
-
-		if (count == 0)
-			return 0;
-		header_len = tag_pack(field->id, out);
-		out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
-		len_start = header_len;
-		min_length = get_type_min_size(field->type) * count;
-		length_size_min = uint32_size(min_length);
-		header_len += length_size_min;
-		payload_at = out + header_len;
-
-		switch (field->type) {
-		case PROTOBUF_C_TYPE_SFIXED32:
-		case PROTOBUF_C_TYPE_FIXED32:
-		case PROTOBUF_C_TYPE_FLOAT:
-			copy_to_little_endian_32(payload_at, array, count);
-			payload_at += count * 4;
-			break;
-		case PROTOBUF_C_TYPE_SFIXED64:
-		case PROTOBUF_C_TYPE_FIXED64:
-		case PROTOBUF_C_TYPE_DOUBLE:
-			copy_to_little_endian_64(payload_at, array, count);
-			payload_at += count * 8;
-			break;
-		case PROTOBUF_C_TYPE_INT32: {
-			const int32_t *arr = (const int32_t *) array;
-			for (i = 0; i < count; i++)
-				payload_at += int32_pack(arr[i], payload_at);
-			break;
-		}
-		case PROTOBUF_C_TYPE_SINT32: {
-			const int32_t *arr = (const int32_t *) array;
-			for (i = 0; i < count; i++)
-				payload_at += sint32_pack(arr[i], payload_at);
-			break;
-		}
-		case PROTOBUF_C_TYPE_SINT64: {
-			const int64_t *arr = (const int64_t *) array;
-			for (i = 0; i < count; i++)
-				payload_at += sint64_pack(arr[i], payload_at);
-			break;
-		}
-		case PROTOBUF_C_TYPE_ENUM:
-		case PROTOBUF_C_TYPE_UINT32: {
-			const uint32_t *arr = (const uint32_t *) array;
-			for (i = 0; i < count; i++)
-				payload_at += uint32_pack(arr[i], payload_at);
-			break;
-		}
-		case PROTOBUF_C_TYPE_INT64:
-		case PROTOBUF_C_TYPE_UINT64: {
-			const uint64_t *arr = (const uint64_t *) array;
-			for (i = 0; i < count; i++)
-				payload_at += uint64_pack(arr[i], payload_at);
-			break;
-		}
-		case PROTOBUF_C_TYPE_BOOL: {
-			const protobuf_c_boolean *arr = (const protobuf_c_boolean *) array;
-			for (i = 0; i < count; i++)
-				payload_at += boolean_pack(arr[i], payload_at);
-			break;
-		}
-		default:
-			PROTOBUF_C__ASSERT_NOT_REACHED();
-		}
-
-		payload_len = payload_at - (out + header_len);
-		actual_length_size = uint32_size(payload_len);
-		if (length_size_min != actual_length_size) {
-			assert(actual_length_size == length_size_min + 1);
-			memmove(out + header_len + 1, out + header_len,
-				payload_len);
-			header_len++;
-		}
-		uint32_pack(payload_len, out + len_start);
-		return header_len + payload_len;
-	} else {
-		/* not "packed" cased */
-		/* CONSIDER: optimize this case a bit (by putting the loop inside the switch) */
-		size_t rv = 0;
-		unsigned siz = sizeof_elt_in_repeated_array(field->type);
-
-		for (i = 0; i < count; i++) {
-			rv += required_field_pack(field, array, out + rv);
-			array = (char *)array + siz;
-		}
-		return rv;
-	}
-}
-
-static size_t
-unknown_field_pack(const ProtobufCMessageUnknownField *field, uint8_t *out)
-{
-	size_t rv = tag_pack(field->tag, out);
-	out[0] |= field->wire_type;
-	memcpy(out + rv, field->data, field->len);
-	return rv + field->len;
-}
-
-/**@}*/
-
-size_t
-protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out)
-{
-	unsigned i;
-	size_t rv = 0;
-
-	ASSERT_IS_MESSAGE(message);
-	for (i = 0; i < message->descriptor->n_fields; i++) {
-		const ProtobufCFieldDescriptor *field =
-			message->descriptor->fields + i;
-		const void *member = ((const char *) message) + field->offset;
-
-		/*
-		 * It doesn't hurt to compute qmember (a pointer to the
-		 * quantifier field of the structure), but the pointer is only
-		 * valid if the field is:
-		 *  - a repeated field, or
-		 *  - an optional field that isn't a pointer type
-		 * (Meaning: not a message or a string).
-		 */
-		const void *qmember =
-			((const char *) message) + field->quantifier_offset;
-
-		if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
-			rv += required_field_pack(field, member, out + rv);
-		} else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) {
-			/*
-			 * Note that qmember is bogus for strings and messages,
-			 * but it isn't used.
-			 */
-			rv += optional_field_pack(field, qmember, member, out + rv);
-		} else {
-			rv += repeated_field_pack(field, *(const size_t *) qmember,
-				member, out + rv);
-		}
-	}
-	for (i = 0; i < message->n_unknown_fields; i++)
-		rv += unknown_field_pack(&message->unknown_fields[i], out + rv);
-	return rv;
-}
-
-/**
- * \defgroup packbuf protobuf_c_message_pack_to_buffer() implementation
- *
- * Routines mainly used by protobuf_c_message_pack_to_buffer().
- *
- * \ingroup internal
- * @{
- */
-
-/**
- * Pack a required field to a virtual buffer.
- *
- * \param field
- *      Field descriptor.
- * \param member
- *      The element to be packed.
- * \param[out] buffer
- *      Virtual buffer to append data to.
- * \return
- *      Number of bytes packed.
- */
-static size_t
-required_field_pack_to_buffer(const ProtobufCFieldDescriptor *field,
-			      const void *member, ProtobufCBuffer *buffer)
-{
-	size_t rv;
-	uint8_t scratch[MAX_UINT64_ENCODED_SIZE * 2];
-
-	rv = tag_pack(field->id, scratch);
-	switch (field->type) {
-	case PROTOBUF_C_TYPE_SINT32:
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		rv += sint32_pack(*(const int32_t *) member, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		break;
-	case PROTOBUF_C_TYPE_INT32:
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		rv += int32_pack(*(const uint32_t *) member, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		break;
-	case PROTOBUF_C_TYPE_UINT32:
-	case PROTOBUF_C_TYPE_ENUM:
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		rv += uint32_pack(*(const uint32_t *) member, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		break;
-	case PROTOBUF_C_TYPE_SINT64:
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		rv += sint64_pack(*(const int64_t *) member, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		break;
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64:
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		rv += uint64_pack(*(const uint64_t *) member, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		break;
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_32BIT;
-		rv += fixed32_pack(*(const uint32_t *) member, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		break;
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_64BIT;
-		rv += fixed64_pack(*(const uint64_t *) member, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		break;
-	case PROTOBUF_C_TYPE_BOOL:
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
-		rv += boolean_pack(*(const protobuf_c_boolean *) member, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		break;
-	case PROTOBUF_C_TYPE_STRING: {
-		const char *str = *(char *const *) member;
-		size_t sublen = str ? strlen(str) : 0;
-
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
-		rv += uint32_pack(sublen, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		buffer->append(buffer, sublen, (const uint8_t *) str);
-		rv += sublen;
-		break;
-	}
-	case PROTOBUF_C_TYPE_BYTES: {
-		const ProtobufCBinaryData *bd = ((const ProtobufCBinaryData *) member);
-		size_t sublen = bd->len;
-
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
-		rv += uint32_pack(sublen, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		buffer->append(buffer, sublen, bd->data);
-		rv += sublen;
-		break;
-	}
-	case PROTOBUF_C_TYPE_MESSAGE: {
-		uint8_t simple_buffer_scratch[256];
-		size_t sublen;
-		const ProtobufCMessage *msg = *(ProtobufCMessage * const *) member;
-		ProtobufCBufferSimple simple_buffer =
-			PROTOBUF_C_BUFFER_SIMPLE_INIT(simple_buffer_scratch);
-
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
-		if (msg == NULL)
-			sublen = 0;
-		else
-			sublen = protobuf_c_message_pack_to_buffer(msg, &simple_buffer.base);
-		rv += uint32_pack(sublen, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		buffer->append(buffer, sublen, simple_buffer.data);
-		rv += sublen;
-		PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&simple_buffer);
-		break;
-	}
-	default:
-		PROTOBUF_C__ASSERT_NOT_REACHED();
-	}
-	return rv;
-}
-
-/**
- * Pack an optional field to a buffer.
- *
- * \param field
- *      Field descriptor.
- * \param has
- *      Whether the field is set.
- * \param member
- *      The element to be packed.
- * \param[out] buffer
- *      Virtual buffer to append data to.
- * \return
- *      Number of bytes serialised to `buffer`.
- */
-static size_t
-optional_field_pack_to_buffer(const ProtobufCFieldDescriptor *field,
-			      const protobuf_c_boolean *has,
-			      const void *member, ProtobufCBuffer *buffer)
-{
-	if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
-	    field->type == PROTOBUF_C_TYPE_STRING)
-	{
-		const void *ptr = *(const void *const *) member;
-		if (ptr == NULL || ptr == field->default_value)
-			return 0;
-	} else {
-		if (!*has)
-			return 0;
-	}
-	return required_field_pack_to_buffer(field, member, buffer);
-}
-
-/**
- * Get the packed size of an array of same field type.
- *
- * \param field
- *      Field descriptor.
- * \param count
- *      Number of elements of this type.
- * \param array
- *      The elements to get the size of.
- * \return
- *      Number of bytes required.
- */
-static size_t
-get_packed_payload_length(const ProtobufCFieldDescriptor *field,
-			  unsigned count, const void *array)
-{
-	unsigned rv = 0;
-	unsigned i;
-
-	switch (field->type) {
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-		return count * 4;
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-		return count * 8;
-	case PROTOBUF_C_TYPE_INT32: {
-		const int32_t *arr = (const int32_t *) array;
-		for (i = 0; i < count; i++)
-			rv += int32_size(arr[i]);
-		break;
-	}
-	case PROTOBUF_C_TYPE_SINT32: {
-		const int32_t *arr = (const int32_t *) array;
-		for (i = 0; i < count; i++)
-			rv += sint32_size(arr[i]);
-		break;
-	}
-	case PROTOBUF_C_TYPE_ENUM:
-	case PROTOBUF_C_TYPE_UINT32: {
-		const uint32_t *arr = (const uint32_t *) array;
-		for (i = 0; i < count; i++)
-			rv += uint32_size(arr[i]);
-		break;
-	}
-	case PROTOBUF_C_TYPE_SINT64: {
-		const int64_t *arr = (const int64_t *) array;
-		for (i = 0; i < count; i++)
-			rv += sint64_size(arr[i]);
-		break;
-	}
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64: {
-		const uint64_t *arr = (const uint64_t *) array;
-		for (i = 0; i < count; i++)
-			rv += uint64_size(arr[i]);
-		break;
-	}
-	case PROTOBUF_C_TYPE_BOOL:
-		return count;
-	default:
-		PROTOBUF_C__ASSERT_NOT_REACHED();
-	}
-	return rv;
-}
-
-/**
- * Pack an array of same field type to a virtual buffer.
- *
- * \param field
- *      Field descriptor.
- * \param count
- *      Number of elements of this type.
- * \param array
- *      The elements to get the size of.
- * \param[out] buffer
- *      Virtual buffer to append data to.
- * \return
- *      Number of bytes packed.
- */
-static size_t
-pack_buffer_packed_payload(const ProtobufCFieldDescriptor *field,
-			   unsigned count, const void *array,
-			   ProtobufCBuffer *buffer)
-{
-	uint8_t scratch[16];
-	size_t rv = 0;
-	unsigned i;
-
-	switch (field->type) {
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-#if !defined(WORDS_BIGENDIAN)
-		rv = count * 4;
-		goto no_packing_needed;
-#else
-		for (i = 0; i < count; i++) {
-			unsigned len = fixed32_pack(((uint32_t *) array)[i], scratch);
-			buffer->append(buffer, len, scratch);
-			rv += len;
-		}
-		break;
-#endif
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-#if !defined(WORDS_BIGENDIAN)
-		rv = count * 8;
-		goto no_packing_needed;
-#else
-		for (i = 0; i < count; i++) {
-			unsigned len = fixed64_pack(((uint64_t *) array)[i], scratch);
-			buffer->append(buffer, len, scratch);
-			rv += len;
-		}
-		break;
-#endif
-	case PROTOBUF_C_TYPE_INT32:
-		for (i = 0; i < count; i++) {
-			unsigned len = int32_pack(((int32_t *) array)[i], scratch);
-			buffer->append(buffer, len, scratch);
-			rv += len;
-		}
-		break;
-	case PROTOBUF_C_TYPE_SINT32:
-		for (i = 0; i < count; i++) {
-			unsigned len = sint32_pack(((int32_t *) array)[i], scratch);
-			buffer->append(buffer, len, scratch);
-			rv += len;
-		}
-		break;
-	case PROTOBUF_C_TYPE_ENUM:
-	case PROTOBUF_C_TYPE_UINT32:
-		for (i = 0; i < count; i++) {
-			unsigned len = uint32_pack(((uint32_t *) array)[i], scratch);
-			buffer->append(buffer, len, scratch);
-			rv += len;
-		}
-		break;
-	case PROTOBUF_C_TYPE_SINT64:
-		for (i = 0; i < count; i++) {
-			unsigned len = sint64_pack(((int64_t *) array)[i], scratch);
-			buffer->append(buffer, len, scratch);
-			rv += len;
-		}
-		break;
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64:
-		for (i = 0; i < count; i++) {
-			unsigned len = uint64_pack(((uint64_t *) array)[i], scratch);
-			buffer->append(buffer, len, scratch);
-			rv += len;
-		}
-		break;
-	case PROTOBUF_C_TYPE_BOOL:
-		for (i = 0; i < count; i++) {
-			unsigned len = boolean_pack(((protobuf_c_boolean *) array)[i], scratch);
-			buffer->append(buffer, len, scratch);
-			rv += len;
-		}
-		return count;
-	default:
-		PROTOBUF_C__ASSERT_NOT_REACHED();
-	}
-	return rv;
-
-#if !defined(WORDS_BIGENDIAN)
-no_packing_needed:
-	buffer->append(buffer, rv, array);
-	return rv;
-#endif
-}
-
-static size_t
-repeated_field_pack_to_buffer(const ProtobufCFieldDescriptor *field,
-			      unsigned count, const void *member,
-			      ProtobufCBuffer *buffer)
-{
-	char *array = *(char * const *) member;
-
-	if (count == 0)
-		return 0;
-	if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) {
-		uint8_t scratch[MAX_UINT64_ENCODED_SIZE * 2];
-		size_t rv = tag_pack(field->id, scratch);
-		size_t payload_len = get_packed_payload_length(field, count, array);
-		size_t tmp;
-
-		scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
-		rv += uint32_pack(payload_len, scratch + rv);
-		buffer->append(buffer, rv, scratch);
-		tmp = pack_buffer_packed_payload(field, count, array, buffer);
-		assert(tmp == payload_len);
-		return rv + payload_len;
-	} else {
-		size_t siz;
-		unsigned i;
-		/* CONSIDER: optimize this case a bit (by putting the loop inside the switch) */
-		unsigned rv = 0;
-
-		siz = sizeof_elt_in_repeated_array(field->type);
-		for (i = 0; i < count; i++) {
-			rv += required_field_pack_to_buffer(field, array, buffer);
-			array = ((char*)array) + siz;
-		}
-		return rv;
-	}
-}
-
-static size_t
-unknown_field_pack_to_buffer(const ProtobufCMessageUnknownField *field,
-			     ProtobufCBuffer *buffer)
-{
-	uint8_t header[MAX_UINT64_ENCODED_SIZE];
-	size_t rv = tag_pack(field->tag, header);
-
-	header[0] |= field->wire_type;
-	buffer->append(buffer, rv, header);
-	buffer->append(buffer, field->len, field->data);
-	return rv + field->len;
-}
-
-/**@}*/
-
-size_t
-protobuf_c_message_pack_to_buffer(const ProtobufCMessage *message,
-				  ProtobufCBuffer *buffer)
-{
-	unsigned i;
-	size_t rv = 0;
-
-	ASSERT_IS_MESSAGE(message);
-	for (i = 0; i < message->descriptor->n_fields; i++) {
-		const ProtobufCFieldDescriptor *field =
-			message->descriptor->fields + i;
-		const void *member =
-			((const char *) message) + field->offset;
-		const void *qmember =
-			((const char *) message) + field->quantifier_offset;
-
-		if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
-			rv += required_field_pack_to_buffer(field, member, buffer);
-		} else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) {
-			rv += optional_field_pack_to_buffer(
-				field,
-				qmember,
-				member,
-				buffer
-			);
-		} else {
-			rv += repeated_field_pack_to_buffer(
-				field,
-				*(const size_t *) qmember,
-				member,
-				buffer
-			);
-		}
-	}
-	for (i = 0; i < message->n_unknown_fields; i++)
-		rv += unknown_field_pack_to_buffer(&message->unknown_fields[i], buffer);
-
-	return rv;
-}
-
-/**
- * \defgroup unpack unpacking implementation
- *
- * Routines mainly used by the unpacking functions.
- *
- * \ingroup internal
- * @{
- */
-
-static inline int
-int_range_lookup(unsigned n_ranges, const ProtobufCIntRange *ranges, int value)
-{
-	unsigned n;
-	unsigned start;
-
-	if (n_ranges == 0)
-		return -1;
-	start = 0;
-	n = n_ranges;
-	while (n > 1) {
-		unsigned mid = start + n / 2;
-
-		if (value < ranges[mid].start_value) {
-			n = mid - start;
-		} else if (value >= ranges[mid].start_value +
-			   (int) (ranges[mid + 1].orig_index -
-				  ranges[mid].orig_index))
-		{
-			unsigned new_start = mid + 1;
-			n = start + n - new_start;
-			start = new_start;
-		} else
-			return (value - ranges[mid].start_value) +
-			    ranges[mid].orig_index;
-	}
-	if (n > 0) {
-		unsigned start_orig_index = ranges[start].orig_index;
-		unsigned range_size =
-			ranges[start + 1].orig_index - start_orig_index;
-
-		if (ranges[start].start_value <= value &&
-		    value < (int) (ranges[start].start_value + range_size))
-		{
-			return (value - ranges[start].start_value) +
-			    start_orig_index;
-		}
-	}
-	return -1;
-}
-
-static size_t
-parse_tag_and_wiretype(size_t len,
-		       const uint8_t *data,
-		       uint32_t *tag_out,
-		       ProtobufCWireType *wiretype_out)
-{
-	unsigned max_rv = len > 5 ? 5 : len;
-	uint32_t tag = (data[0] & 0x7f) >> 3;
-	unsigned shift = 4;
-	unsigned rv;
-
-	*wiretype_out = data[0] & 7;
-	if ((data[0] & 0x80) == 0) {
-		*tag_out = tag;
-		return 1;
-	}
-	for (rv = 1; rv < max_rv; rv++) {
-		if (data[rv] & 0x80) {
-			tag |= (data[rv] & 0x7f) << shift;
-			shift += 7;
-		} else {
-			tag |= data[rv] << shift;
-			*tag_out = tag;
-			return rv + 1;
-		}
-	}
-	return 0; /* error: bad header */
-}
-
-/* sizeof(ScannedMember) must be <= (1<<BOUND_SIZEOF_SCANNED_MEMBER_LOG2) */
-#define BOUND_SIZEOF_SCANNED_MEMBER_LOG2 5
-typedef struct _ScannedMember ScannedMember;
-/** Field as it's being read. */
-struct _ScannedMember {
-	uint32_t tag;              /**< Field tag. */
-	uint8_t wire_type;         /**< Field type. */
-	uint8_t length_prefix_len; /**< Prefix length. */
-	const ProtobufCFieldDescriptor *field; /**< Field descriptor. */
-	size_t len;                /**< Field length. */
-	const uint8_t *data;       /**< Pointer to field data. */
-};
-
-static inline uint32_t
-scan_length_prefixed_data(size_t len, const uint8_t *data,
-			  size_t *prefix_len_out)
-{
-	unsigned hdr_max = len < 5 ? len : 5;
-	unsigned hdr_len;
-	uint32_t val = 0;
-	unsigned i;
-	unsigned shift = 0;
-
-	for (i = 0; i < hdr_max; i++) {
-		val |= (data[i] & 0x7f) << shift;
-		shift += 7;
-		if ((data[i] & 0x80) == 0)
-			break;
-	}
-	if (i == hdr_max) {
-		PROTOBUF_C_UNPACK_ERROR("error parsing length for length-prefixed data");
-		return 0;
-	}
-	hdr_len = i + 1;
-	*prefix_len_out = hdr_len;
-	if (hdr_len + val > len) {
-		PROTOBUF_C_UNPACK_ERROR("data too short after length-prefix of %u", val);
-		return 0;
-	}
-	return hdr_len + val;
-}
-
-static size_t
-max_b128_numbers(size_t len, const uint8_t *data)
-{
-	size_t rv = 0;
-	while (len--)
-		if ((*data++ & 0x80) == 0)
-			++rv;
-	return rv;
-}
-
-/**@}*/
-
-/**
- * Merge earlier message into a latter message.
- *
- * For numeric types and strings, if the same value appears multiple
- * times, the parser accepts the last value it sees. For embedded
- * message fields, the parser merges multiple instances of the same
- * field. That is, all singular scalar fields in the latter instance
- * replace those in the former, singular embedded messages are merged,
- * and repeated fields are concatenated.
- *
- * The earlier message should be freed after calling this function, as
- * some of its fields may have been reused and changed to their default
- * values during the merge.
- */
-static protobuf_c_boolean
-merge_messages(ProtobufCMessage *earlier_msg,
-	       ProtobufCMessage *latter_msg,
-	       ProtobufCAllocator *allocator)
-{
-	unsigned i;
-	const ProtobufCFieldDescriptor *fields =
-		earlier_msg->descriptor->fields;
-	for (i = 0; i < latter_msg->descriptor->n_fields; i++) {
-		if (fields[i].label == PROTOBUF_C_LABEL_REPEATED) {
-			size_t *n_earlier =
-				STRUCT_MEMBER_PTR(size_t, earlier_msg,
-						  fields[i].quantifier_offset);
-			uint8_t **p_earlier =
-				STRUCT_MEMBER_PTR(uint8_t *, earlier_msg,
-						  fields[i].offset);
-			size_t *n_latter =
-				STRUCT_MEMBER_PTR(size_t, latter_msg,
-						  fields[i].quantifier_offset);
-			uint8_t **p_latter =
-				STRUCT_MEMBER_PTR(uint8_t *, latter_msg,
-						  fields[i].offset);
-
-			if (*n_earlier > 0) {
-				if (*n_latter > 0) {
-					/* Concatenate the repeated field */
-					size_t el_size =
-						sizeof_elt_in_repeated_array(fields[i].type);
-					uint8_t *new_field;
-
-					new_field = do_alloc(allocator,
-						(*n_earlier + *n_latter) * el_size);
-					if (!new_field)
-						return FALSE;
-
-					memcpy(new_field, *p_earlier,
-					       *n_earlier * el_size);
-					memcpy(new_field +
-					       *n_earlier * el_size,
-					       *p_latter,
-					       *n_latter * el_size);
-
-					do_free(allocator, *p_latter);
-					do_free(allocator, *p_earlier);
-					*p_latter = new_field;
-					*n_latter = *n_earlier + *n_latter;
-				} else {
-					/* Zero copy the repeated field from the earlier message */
-					*n_latter = *n_earlier;
-					*p_latter = *p_earlier;
-				}
-				/* Make sure the field does not get double freed */
-				*n_earlier = 0;
-				*p_earlier = 0;
-			}
-		} else if (fields[i].type == PROTOBUF_C_TYPE_MESSAGE) {
-			ProtobufCMessage **em =
-				STRUCT_MEMBER_PTR(ProtobufCMessage *,
-						  earlier_msg,
-						  fields[i].offset);
-			ProtobufCMessage **lm =
-				STRUCT_MEMBER_PTR(ProtobufCMessage *,
-						  latter_msg,
-						  fields[i].offset);
-			if (*em != NULL) {
-				if (*lm != NULL) {
-					if (!merge_messages
-					    (*em, *lm, allocator))
-						return FALSE;
-				} else {
-					/* Zero copy the optional message */
-					assert(fields[i].label ==
-					       PROTOBUF_C_LABEL_OPTIONAL);
-					*lm = *em;
-					*em = NULL;
-				}
-			}
-		} else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL) {
-			size_t el_size = 0;
-			protobuf_c_boolean need_to_merge = FALSE;
-			void *earlier_elem =
-				STRUCT_MEMBER_P(earlier_msg, fields[i].offset);
-			void *latter_elem =
-				STRUCT_MEMBER_P(latter_msg, fields[i].offset);
-			const void *def_val = fields[i].default_value;
-
-			switch (fields[i].type) {
-			case PROTOBUF_C_TYPE_BYTES: {
-				uint8_t *e_data =
-					((ProtobufCBinaryData *) earlier_elem)->data;
-				uint8_t *l_data =
-					((ProtobufCBinaryData *) latter_elem)->data;
-				const ProtobufCBinaryData *d_bd =
-					(ProtobufCBinaryData *) def_val;
-
-				el_size = sizeof(ProtobufCBinaryData);
-				need_to_merge =
-					(e_data != NULL &&
-					 (d_bd != NULL &&
-					  e_data != d_bd->data)) &&
-					(l_data == NULL ||
-					 (d_bd != NULL &&
-					  l_data == d_bd->data));
-				break;
-			}
-			case PROTOBUF_C_TYPE_STRING: {
-				char *e_str = *(char **) earlier_elem;
-				char *l_str = *(char **) latter_elem;
-				const char *d_str = def_val;
-
-				el_size = sizeof(char *);
-				need_to_merge = e_str != d_str && l_str == d_str;
-				break;
-			}
-			default: {
-				el_size = sizeof_elt_in_repeated_array(fields[i].type);
-
-				need_to_merge =
-					STRUCT_MEMBER(protobuf_c_boolean,
-						      earlier_msg,
-						      fields[i].quantifier_offset) &&
-					!STRUCT_MEMBER(protobuf_c_boolean,
-						       latter_msg,
-						       fields[i].quantifier_offset);
-				break;
-			}
-			}
-
-			if (need_to_merge) {
-				memcpy(latter_elem, earlier_elem, el_size);
-				/*
-				 * Reset the element from the old message to 0
-				 * to make sure earlier message deallocation
-				 * doesn't corrupt zero-copied data in the new
-				 * message, earlier message will be freed after
-				 * this function is called anyway
-				 */
-				memset(earlier_elem, 0, el_size);
-
-				if (fields[i].quantifier_offset != 0) {
-					/* Set the has field, if applicable */
-					STRUCT_MEMBER(protobuf_c_boolean,
-						      latter_msg,
-						      fields[i].
-						      quantifier_offset) = TRUE;
-					STRUCT_MEMBER(protobuf_c_boolean,
-						      earlier_msg,
-						      fields[i].
-						      quantifier_offset) = FALSE;
-				}
-			}
-		}
-	}
-	return TRUE;
-}
-
-/**
- * Count packed elements.
- *
- * Given a raw slab of packed-repeated values, determine the number of
- * elements. This function detects certain kinds of errors but not
- * others; the remaining error checking is done by
- * parse_packed_repeated_member().
- */
-static protobuf_c_boolean
-count_packed_elements(ProtobufCType type,
-		      size_t len, const uint8_t *data, size_t *count_out)
-{
-	switch (type) {
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-		if (len % 4 != 0) {
-			PROTOBUF_C_UNPACK_ERROR("length must be a multiple of 4 for fixed-length 32-bit types");
-			return FALSE;
-		}
-		*count_out = len / 4;
-		return TRUE;
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-		if (len % 8 != 0) {
-			PROTOBUF_C_UNPACK_ERROR("length must be a multiple of 8 for fixed-length 64-bit types");
-			return FALSE;
-		}
-		*count_out = len / 8;
-		return TRUE;
-	case PROTOBUF_C_TYPE_INT32:
-	case PROTOBUF_C_TYPE_SINT32:
-	case PROTOBUF_C_TYPE_ENUM:
-	case PROTOBUF_C_TYPE_UINT32:
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_SINT64:
-	case PROTOBUF_C_TYPE_UINT64:
-		*count_out = max_b128_numbers(len, data);
-		return TRUE;
-	case PROTOBUF_C_TYPE_BOOL:
-		*count_out = len;
-		return TRUE;
-	case PROTOBUF_C_TYPE_STRING:
-	case PROTOBUF_C_TYPE_BYTES:
-	case PROTOBUF_C_TYPE_MESSAGE:
-	default:
-		PROTOBUF_C_UNPACK_ERROR("bad protobuf-c type %u for packed-repeated", type);
-		return FALSE;
-	}
-}
-
-static inline uint32_t
-parse_uint32(unsigned len, const uint8_t *data)
-{
-	uint32_t rv = data[0] & 0x7f;
-	if (len > 1) {
-		rv |= ((uint32_t) (data[1] & 0x7f) << 7);
-		if (len > 2) {
-			rv |= ((uint32_t) (data[2] & 0x7f) << 14);
-			if (len > 3) {
-				rv |= ((uint32_t) (data[3] & 0x7f) << 21);
-				if (len > 4)
-					rv |= ((uint32_t) (data[4]) << 28);
-			}
-		}
-	}
-	return rv;
-}
-
-static inline uint32_t
-parse_int32(unsigned len, const uint8_t *data)
-{
-	return parse_uint32(len, data);
-}
-
-static inline int32_t
-unzigzag32(uint32_t v)
-{
-	if (v & 1)
-		return -(v >> 1) - 1;
-	else
-		return v >> 1;
-}
-
-static inline uint32_t
-parse_fixed_uint32(const uint8_t *data)
-{
-#if !defined(WORDS_BIGENDIAN)
-	uint32_t t;
-	memcpy(&t, data, 4);
-	return t;
-#else
-	return data[0] |
-		((uint32_t) (data[1]) << 8) |
-		((uint32_t) (data[2]) << 16) |
-		((uint32_t) (data[3]) << 24);
-#endif
-}
-
-static uint64_t
-parse_uint64(unsigned len, const uint8_t *data)
-{
-	unsigned shift, i;
-	uint64_t rv;
-
-	if (len < 5)
-		return parse_uint32(len, data);
-	rv = ((uint64_t) (data[0] & 0x7f)) |
-		((uint64_t) (data[1] & 0x7f) << 7) |
-		((uint64_t) (data[2] & 0x7f) << 14) |
-		((uint64_t) (data[3] & 0x7f) << 21);
-	shift = 28;
-	for (i = 4; i < len; i++) {
-		rv |= (((uint64_t) (data[i] & 0x7f)) << shift);
-		shift += 7;
-	}
-	return rv;
-}
-
-static inline int64_t
-unzigzag64(uint64_t v)
-{
-	if (v & 1)
-		return -(v >> 1) - 1;
-	else
-		return v >> 1;
-}
-
-static inline uint64_t
-parse_fixed_uint64(const uint8_t *data)
-{
-#if !defined(WORDS_BIGENDIAN)
-	uint64_t t;
-	memcpy(&t, data, 8);
-	return t;
-#else
-	return (uint64_t) parse_fixed_uint32(data) |
-		(((uint64_t) parse_fixed_uint32(data + 4)) << 32);
-#endif
-}
-
-static protobuf_c_boolean
-parse_boolean(unsigned len, const uint8_t *data)
-{
-	unsigned i;
-	for (i = 0; i < len; i++)
-		if (data[i] & 0x7f)
-			return TRUE;
-	return FALSE;
-}
-
-static protobuf_c_boolean
-parse_required_member(ScannedMember *scanned_member,
-		      void *member,
-		      ProtobufCAllocator *allocator,
-		      protobuf_c_boolean maybe_clear)
-{
-	unsigned len = scanned_member->len;
-	const uint8_t *data = scanned_member->data;
-	ProtobufCWireType wire_type = scanned_member->wire_type;
-
-	switch (scanned_member->field->type) {
-	case PROTOBUF_C_TYPE_INT32:
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
-			return FALSE;
-		*(uint32_t *) member = parse_int32(len, data);
-		return TRUE;
-	case PROTOBUF_C_TYPE_UINT32:
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
-			return FALSE;
-		*(uint32_t *) member = parse_uint32(len, data);
-		return TRUE;
-	case PROTOBUF_C_TYPE_SINT32:
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
-			return FALSE;
-		*(int32_t *) member = unzigzag32(parse_uint32(len, data));
-		return TRUE;
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT)
-			return FALSE;
-		*(uint32_t *) member = parse_fixed_uint32(data);
-		return TRUE;
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64:
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
-			return FALSE;
-		*(uint64_t *) member = parse_uint64(len, data);
-		return TRUE;
-	case PROTOBUF_C_TYPE_SINT64:
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
-			return FALSE;
-		*(int64_t *) member = unzigzag64(parse_uint64(len, data));
-		return TRUE;
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_64BIT)
-			return FALSE;
-		*(uint64_t *) member = parse_fixed_uint64(data);
-		return TRUE;
-	case PROTOBUF_C_TYPE_BOOL:
-		*(protobuf_c_boolean *) member = parse_boolean(len, data);
-		return TRUE;
-	case PROTOBUF_C_TYPE_ENUM:
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
-			return FALSE;
-		*(uint32_t *) member = parse_uint32(len, data);
-		return TRUE;
-	case PROTOBUF_C_TYPE_STRING: {
-		char **pstr = member;
-		unsigned pref_len = scanned_member->length_prefix_len;
-
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED)
-			return FALSE;
-
-		if (maybe_clear && *pstr != NULL) {
-			const char *def = scanned_member->field->default_value;
-			if (*pstr != NULL && *pstr != def)
-				do_free(allocator, *pstr);
-		}
-		*pstr = do_alloc(allocator, len - pref_len + 1);
-		if (*pstr == NULL)
-			return FALSE;
-		memcpy(*pstr, data + pref_len, len - pref_len);
-		(*pstr)[len - pref_len] = 0;
-		return TRUE;
-	}
-	case PROTOBUF_C_TYPE_BYTES: {
-		ProtobufCBinaryData *bd = member;
-		const ProtobufCBinaryData *def_bd;
-		unsigned pref_len = scanned_member->length_prefix_len;
-
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED)
-			return FALSE;
-
-		def_bd = scanned_member->field->default_value;
-		if (maybe_clear &&
-		    bd->data != NULL &&
-		    (def_bd == NULL || bd->data != def_bd->data))
-		{
-			do_free(allocator, bd->data);
-		}
-		if (len - pref_len > 0) {
-			bd->data = do_alloc(allocator, len - pref_len);
-			if (bd->data == NULL)
-				return FALSE;
-			memcpy(bd->data, data + pref_len, len - pref_len);
-		} else {
-			bd->data = NULL;
-		}
-		bd->len = len - pref_len;
-		return TRUE;
-	}
-	case PROTOBUF_C_TYPE_MESSAGE: {
-		ProtobufCMessage **pmessage = member;
-		ProtobufCMessage *subm;
-		const ProtobufCMessage *def_mess;
-		protobuf_c_boolean merge_successful = TRUE;
-		unsigned pref_len = scanned_member->length_prefix_len;
-
-		if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED)
-			return FALSE;
-
-		def_mess = scanned_member->field->default_value;
-		subm = protobuf_c_message_unpack(scanned_member->field->descriptor,
-						 allocator,
-						 len - pref_len,
-						 data + pref_len);
-
-		if (maybe_clear &&
-		    *pmessage != NULL &&
-		    *pmessage != def_mess)
-		{
-			if (subm != NULL)
-				merge_successful = merge_messages(*pmessage, subm, allocator);
-			/* Delete the previous message */
-			protobuf_c_message_free_unpacked(*pmessage, allocator);
-		}
-		*pmessage = subm;
-		if (subm == NULL || !merge_successful)
-			return FALSE;
-		return TRUE;
-	}
-	}
-	return FALSE;
-}
-
-static protobuf_c_boolean
-parse_optional_member(ScannedMember *scanned_member,
-		      void *member,
-		      ProtobufCMessage *message,
-		      ProtobufCAllocator *allocator)
-{
-	if (!parse_required_member(scanned_member, member, allocator, TRUE))
-		return FALSE;
-	if (scanned_member->field->quantifier_offset != 0)
-		STRUCT_MEMBER(protobuf_c_boolean,
-			      message,
-			      scanned_member->field->quantifier_offset) = TRUE;
-	return TRUE;
-}
-
-static protobuf_c_boolean
-parse_repeated_member(ScannedMember *scanned_member,
-		      void *member,
-		      ProtobufCMessage *message,
-		      ProtobufCAllocator *allocator)
-{
-	const ProtobufCFieldDescriptor *field = scanned_member->field;
-	size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset);
-	size_t siz = sizeof_elt_in_repeated_array(field->type);
-	char *array = *(char **) member;
-
-	if (!parse_required_member(scanned_member, array + siz * (*p_n),
-				   allocator, FALSE))
-	{
-		return FALSE;
-	}
-	*p_n += 1;
-	return TRUE;
-}
-
-static unsigned
-scan_varint(unsigned len, const uint8_t *data)
-{
-	unsigned i;
-	if (len > 10)
-		len = 10;
-	for (i = 0; i < len; i++)
-		if ((data[i] & 0x80) == 0)
-			break;
-	if (i == len)
-		return 0;
-	return i + 1;
-}
-
-static protobuf_c_boolean
-parse_packed_repeated_member(ScannedMember *scanned_member,
-			     void *member,
-			     ProtobufCMessage *message)
-{
-	const ProtobufCFieldDescriptor *field = scanned_member->field;
-	size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset);
-	size_t siz = sizeof_elt_in_repeated_array(field->type);
-	void *array = *(char **) member + siz * (*p_n);
-	const uint8_t *at = scanned_member->data + scanned_member->length_prefix_len;
-	size_t rem = scanned_member->len - scanned_member->length_prefix_len;
-	size_t count = 0;
-	unsigned i;
-
-	switch (field->type) {
-	case PROTOBUF_C_TYPE_SFIXED32:
-	case PROTOBUF_C_TYPE_FIXED32:
-	case PROTOBUF_C_TYPE_FLOAT:
-		count = (scanned_member->len - scanned_member->length_prefix_len) / 4;
-#if !defined(WORDS_BIGENDIAN)
-		goto no_unpacking_needed;
-#else
-		for (i = 0; i < count; i++) {
-			((uint32_t *) array)[i] = parse_fixed_uint32(at);
-			at += 4;
-		}
-		break;
-#endif
-	case PROTOBUF_C_TYPE_SFIXED64:
-	case PROTOBUF_C_TYPE_FIXED64:
-	case PROTOBUF_C_TYPE_DOUBLE:
-		count = (scanned_member->len - scanned_member->length_prefix_len) / 8;
-#if !defined(WORDS_BIGENDIAN)
-		goto no_unpacking_needed;
-#else
-		for (i = 0; i < count; i++) {
-			((uint64_t *) array)[i] = parse_fixed_uint64(at);
-			at += 8;
-		}
-		break;
-#endif
-	case PROTOBUF_C_TYPE_INT32:
-		while (rem > 0) {
-			unsigned s = scan_varint(rem, at);
-			if (s == 0) {
-				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int32 value");
-				return FALSE;
-			}
-			((int32_t *) array)[count++] = parse_int32(s, at);
-			at += s;
-			rem -= s;
-		}
-		break;
-	case PROTOBUF_C_TYPE_SINT32:
-		while (rem > 0) {
-			unsigned s = scan_varint(rem, at);
-			if (s == 0) {
-				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint32 value");
-				return FALSE;
-			}
-			((int32_t *) array)[count++] = unzigzag32(parse_uint32(s, at));
-			at += s;
-			rem -= s;
-		}
-		break;
-	case PROTOBUF_C_TYPE_ENUM:
-	case PROTOBUF_C_TYPE_UINT32:
-		while (rem > 0) {
-			unsigned s = scan_varint(rem, at);
-			if (s == 0) {
-				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated enum or uint32 value");
-				return FALSE;
-			}
-			((uint32_t *) array)[count++] = parse_uint32(s, at);
-			at += s;
-			rem -= s;
-		}
-		break;
-
-	case PROTOBUF_C_TYPE_SINT64:
-		while (rem > 0) {
-			unsigned s = scan_varint(rem, at);
-			if (s == 0) {
-				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint64 value");
-				return FALSE;
-			}
-			((int64_t *) array)[count++] = unzigzag64(parse_uint64(s, at));
-			at += s;
-			rem -= s;
-		}
-		break;
-	case PROTOBUF_C_TYPE_INT64:
-	case PROTOBUF_C_TYPE_UINT64:
-		while (rem > 0) {
-			unsigned s = scan_varint(rem, at);
-			if (s == 0) {
-				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int64/uint64 value");
-				return FALSE;
-			}
-			((int64_t *) array)[count++] = parse_uint64(s, at);
-			at += s;
-			rem -= s;
-		}
-		break;
-	case PROTOBUF_C_TYPE_BOOL:
-		count = rem;
-		for (i = 0; i < count; i++) {
-			if (at[i] > 1) {
-				PROTOBUF_C_UNPACK_ERROR("bad packed-repeated boolean value");
-				return FALSE;
-			}
-			((protobuf_c_boolean *) array)[i] = at[i];
-		}
-		break;
-	default:
-		PROTOBUF_C__ASSERT_NOT_REACHED();
-	}
-	*p_n += count;
-	return TRUE;
-
-#if !defined(WORDS_BIGENDIAN)
-no_unpacking_needed:
-	memcpy(array, at, count * siz);
-	*p_n += count;
-	return TRUE;
-#endif
-}
-
-static protobuf_c_boolean
-is_packable_type(ProtobufCType type)
-{
-	return
-		type != PROTOBUF_C_TYPE_STRING &&
-		type != PROTOBUF_C_TYPE_BYTES &&
-		type != PROTOBUF_C_TYPE_MESSAGE;
-}
-
-static protobuf_c_boolean
-parse_member(ScannedMember *scanned_member,
-	     ProtobufCMessage *message,
-	     ProtobufCAllocator *allocator)
-{
-	const ProtobufCFieldDescriptor *field = scanned_member->field;
-	void *member;
-
-	if (field == NULL) {
-		ProtobufCMessageUnknownField *ufield =
-			message->unknown_fields +
-			(message->n_unknown_fields++);
-		ufield->tag = scanned_member->tag;
-		ufield->wire_type = scanned_member->wire_type;
-		ufield->len = scanned_member->len;
-		ufield->data = do_alloc(allocator, scanned_member->len);
-		if (ufield->data == NULL)
-			return FALSE;
-		memcpy(ufield->data, scanned_member->data, ufield->len);
-		return TRUE;
-	}
-	member = (char *) message + field->offset;
-	switch (field->label) {
-	case PROTOBUF_C_LABEL_REQUIRED:
-		return parse_required_member(scanned_member, member,
-					     allocator, TRUE);
-	case PROTOBUF_C_LABEL_OPTIONAL:
-		return parse_optional_member(scanned_member, member,
-					     message, allocator);
-	case PROTOBUF_C_LABEL_REPEATED:
-		if (scanned_member->wire_type ==
-		    PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED &&
-		    (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) ||
-		     is_packable_type(field->type)))
-		{
-			return parse_packed_repeated_member(scanned_member,
-							    member, message);
-		} else {
-			return parse_repeated_member(scanned_member,
-						     member, message,
-						     allocator);
-		}
-	}
-	PROTOBUF_C__ASSERT_NOT_REACHED();
-	return 0;
-}
-
-/**
- * Initialise messages generated by old code.
- *
- * This function is used if desc->message_init == NULL (which occurs
- * for old code, and which would be useful to support allocating
- * descriptors dynamically).
- */
-static void
-message_init_generic(const ProtobufCMessageDescriptor *desc,
-		     ProtobufCMessage *message)
-{
-	unsigned i;
-
-	memset(message, 0, desc->sizeof_message);
-	message->descriptor = desc;
-	for (i = 0; i < desc->n_fields; i++) {
-		if (desc->fields[i].default_value != NULL &&
-		    desc->fields[i].label != PROTOBUF_C_LABEL_REPEATED)
-		{
-			void *field =
-				STRUCT_MEMBER_P(message, desc->fields[i].offset);
-			const void *dv = desc->fields[i].default_value;
-
-			switch (desc->fields[i].type) {
-			case PROTOBUF_C_TYPE_INT32:
-			case PROTOBUF_C_TYPE_SINT32:
-			case PROTOBUF_C_TYPE_SFIXED32:
-			case PROTOBUF_C_TYPE_UINT32:
-			case PROTOBUF_C_TYPE_FIXED32:
-			case PROTOBUF_C_TYPE_FLOAT:
-			case PROTOBUF_C_TYPE_ENUM:
-				memcpy(field, dv, 4);
-				break;
-			case PROTOBUF_C_TYPE_INT64:
-			case PROTOBUF_C_TYPE_SINT64:
-			case PROTOBUF_C_TYPE_SFIXED64:
-			case PROTOBUF_C_TYPE_UINT64:
-			case PROTOBUF_C_TYPE_FIXED64:
-			case PROTOBUF_C_TYPE_DOUBLE:
-				memcpy(field, dv, 8);
-				break;
-			case PROTOBUF_C_TYPE_BOOL:
-				memcpy(field, dv, sizeof(protobuf_c_boolean));
-				break;
-			case PROTOBUF_C_TYPE_BYTES:
-				memcpy(field, dv, sizeof(ProtobufCBinaryData));
-				break;
-
-			case PROTOBUF_C_TYPE_STRING:
-			case PROTOBUF_C_TYPE_MESSAGE:
-				/*
-				 * The next line essentially implements a cast
-				 * from const, which is totally unavoidable.
-				 */
-				*(const void **) field = dv;
-				break;
-			}
-		}
-	}
-}
-
-/**@}*/
-
-/*
- * ScannedMember slabs (an unpacking implementation detail). Before doing real
- * unpacking, we first scan through the elements to see how many there are (for
- * repeated fields), and which field to use (for non-repeated fields given
- * twice).
- *
- * In order to avoid allocations for small messages, we keep a stack-allocated
- * slab of ScannedMembers of size FIRST_SCANNED_MEMBER_SLAB_SIZE (16). After we
- * fill that up, we allocate each slab twice as large as the previous one.
- */
-#define FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2 4
-
-/*
- * The number of slabs, including the stack-allocated ones; choose the number so
- * that we would overflow if we needed a slab larger than provided.
- */
-#define MAX_SCANNED_MEMBER_SLAB			\
-  (sizeof(unsigned int)*8 - 1			\
-   - BOUND_SIZEOF_SCANNED_MEMBER_LOG2		\
-   - FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2)
-
-#define REQUIRED_FIELD_BITMAP_SET(index)	\
-	(required_fields_bitmap[(index)/8] |= (1<<((index)%8)))
-
-#define REQUIRED_FIELD_BITMAP_IS_SET(index)	\
-	(required_fields_bitmap[(index)/8] & (1<<((index)%8)))
-
-ProtobufCMessage *
-protobuf_c_message_unpack(const ProtobufCMessageDescriptor *desc,
-			  ProtobufCAllocator *allocator,
-			  size_t len, const uint8_t *data)
-{
-	ProtobufCMessage *rv;
-	size_t rem = len;
-	const uint8_t *at = data;
-	const ProtobufCFieldDescriptor *last_field = desc->fields + 0;
-	ScannedMember first_member_slab[1 <<
-					FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2];
-
-	/*
-	 * scanned_member_slabs[i] is an array of arrays of ScannedMember.
-	 * The first slab (scanned_member_slabs[0] is just a pointer to
-	 * first_member_slab), above. All subsequent slabs will be allocated
-	 * using the allocator.
-	 */
-	ScannedMember *scanned_member_slabs[MAX_SCANNED_MEMBER_SLAB + 1];
-	unsigned which_slab = 0; /* the slab we are currently populating */
-	unsigned in_slab_index = 0; /* number of members in the slab */
-	size_t n_unknown = 0;
-	unsigned f;
-	unsigned j;
-	unsigned i_slab;
-	unsigned last_field_index = 0;
-	unsigned required_fields_bitmap_len;
-	unsigned char required_fields_bitmap_stack[16];
-	unsigned char *required_fields_bitmap = required_fields_bitmap_stack;
-	protobuf_c_boolean required_fields_bitmap_alloced = FALSE;
-
-	ASSERT_IS_MESSAGE_DESCRIPTOR(desc);
-
-	if (allocator == NULL)
-		allocator = &protobuf_c__allocator;
-
-	rv = do_alloc(allocator, desc->sizeof_message);
-	if (!rv)
-		return (NULL);
-	scanned_member_slabs[0] = first_member_slab;
-
-	required_fields_bitmap_len = (desc->n_fields + 7) / 8;
-	if (required_fields_bitmap_len > sizeof(required_fields_bitmap_stack)) {
-		required_fields_bitmap = do_alloc(allocator, required_fields_bitmap_len);
-		if (!required_fields_bitmap) {
-			do_free(allocator, rv);
-			return (NULL);
-		}
-		required_fields_bitmap_alloced = TRUE;
-	}
-	memset(required_fields_bitmap, 0, required_fields_bitmap_len);
-
-	/*
-	 * Generated code always defines "message_init". However, we provide a
-	 * fallback for (1) users of old protobuf-c generated-code that do not
-	 * provide the function, and (2) descriptors constructed from some other
-	 * source (most likely, direct construction from the .proto file).
-	 */
-	if (desc->message_init != NULL)
-		protobuf_c_message_init(desc, rv);
-	else
-		message_init_generic(desc, rv);
-
-	while (rem > 0) {
-		uint32_t tag;
-		ProtobufCWireType wire_type;
-		size_t used = parse_tag_and_wiretype(rem, at, &tag, &wire_type);
-		const ProtobufCFieldDescriptor *field;
-		ScannedMember tmp;
-
-		memset(&tmp, 0, sizeof(ScannedMember));
-
-		if (used == 0) {
-			PROTOBUF_C_UNPACK_ERROR("error parsing tag/wiretype at offset %u",
-						(unsigned) (at - data));
-			goto error_cleanup_during_scan;
-		}
-		/*
-                 * \todo Consider optimizing for field[1].id == tag, if field[1]
-                 * exists!
-                 */
-		if (last_field == NULL || last_field->id != tag) {
-			/* lookup field */
-			int field_index =
-			    int_range_lookup(desc->n_field_ranges,
-					     desc->field_ranges,
-					     tag);
-			if (field_index < 0) {
-				field = NULL;
-				n_unknown++;
-			} else {
-				field = desc->fields + field_index;
-				last_field = field;
-				last_field_index = field_index;
-			}
-		} else {
-			field = last_field;
-		}
-
-		if (field != NULL && field->label == PROTOBUF_C_LABEL_REQUIRED)
-			REQUIRED_FIELD_BITMAP_SET(last_field_index);
-
-		at += used;
-		rem -= used;
-		tmp.tag = tag;
-		tmp.wire_type = wire_type;
-		tmp.field = field;
-		tmp.data = at;
-		tmp.length_prefix_len = 0;
-
-		switch (wire_type) {
-		case PROTOBUF_C_WIRE_TYPE_VARINT: {
-			unsigned max_len = rem < 10 ? rem : 10;
-			unsigned i;
-
-			for (i = 0; i < max_len; i++)
-				if ((at[i] & 0x80) == 0)
-					break;
-			if (i == max_len) {
-				PROTOBUF_C_UNPACK_ERROR("unterminated varint at offset %u",
-							(unsigned) (at - data));
-				goto error_cleanup_during_scan;
-			}
-			tmp.len = i + 1;
-			break;
-		}
-		case PROTOBUF_C_WIRE_TYPE_64BIT:
-			if (rem < 8) {
-				PROTOBUF_C_UNPACK_ERROR("too short after 64bit wiretype at offset %u",
-							(unsigned) (at - data));
-				goto error_cleanup_during_scan;
-			}
-			tmp.len = 8;
-			break;
-		case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED: {
-			size_t pref_len;
-
-			tmp.len = scan_length_prefixed_data(rem, at, &pref_len);
-			if (tmp.len == 0) {
-				/* NOTE: scan_length_prefixed_data calls UNPACK_ERROR */
-				goto error_cleanup_during_scan;
-			}
-			tmp.length_prefix_len = pref_len;
-			break;
-		}
-		case PROTOBUF_C_WIRE_TYPE_32BIT:
-			if (rem < 4) {
-				PROTOBUF_C_UNPACK_ERROR("too short after 32bit wiretype at offset %u",
-					      (unsigned) (at - data));
-				goto error_cleanup_during_scan;
-			}
-			tmp.len = 4;
-			break;
-		default:
-			PROTOBUF_C_UNPACK_ERROR("unsupported tag %u at offset %u",
-						wire_type, (unsigned) (at - data));
-			goto error_cleanup_during_scan;
-		}
-
-		if (in_slab_index == (1U <<
-			(which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2)))
-		{
-			size_t size;
-
-			in_slab_index = 0;
-			if (which_slab == MAX_SCANNED_MEMBER_SLAB) {
-				PROTOBUF_C_UNPACK_ERROR("too many fields");
-				goto error_cleanup_during_scan;
-			}
-			which_slab++;
-			size = sizeof(ScannedMember)
-				<< (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2);
-			scanned_member_slabs[which_slab] = do_alloc(allocator, size);
-			if (scanned_member_slabs[which_slab] == NULL)
-				goto error_cleanup_during_scan;
-		}
-		scanned_member_slabs[which_slab][in_slab_index++] = tmp;
-
-		if (field != NULL && field->label == PROTOBUF_C_LABEL_REPEATED) {
-			size_t *n = STRUCT_MEMBER_PTR(size_t, rv,
-						      field->quantifier_offset);
-			if (wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED &&
-			    (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) ||
-			     is_packable_type(field->type)))
-			{
-				size_t count;
-				if (!count_packed_elements(field->type,
-							   tmp.len -
-							   tmp.length_prefix_len,
-							   tmp.data +
-							   tmp.length_prefix_len,
-							   &count))
-				{
-					PROTOBUF_C_UNPACK_ERROR("counting packed elements");
-					goto error_cleanup_during_scan;
-				}
-				*n += count;
-			} else {
-				*n += 1;
-			}
-		}
-
-		at += tmp.len;
-		rem -= tmp.len;
-	}
-
-	/* allocate space for repeated fields, also check that all required fields have been set */
-	for (f = 0; f < desc->n_fields; f++) {
-		const ProtobufCFieldDescriptor *field = desc->fields + f;
-		if (field->label == PROTOBUF_C_LABEL_REPEATED) {
-			size_t siz =
-			    sizeof_elt_in_repeated_array(field->type);
-			size_t *n_ptr =
-			    STRUCT_MEMBER_PTR(size_t, rv,
-					      field->quantifier_offset);
-			if (*n_ptr != 0) {
-				unsigned n = *n_ptr;
-				void *a;
-				*n_ptr = 0;
-				assert(rv->descriptor != NULL);
-#define CLEAR_REMAINING_N_PTRS()                                              \
-              for(f++;f < desc->n_fields; f++)                                \
-                {                                                             \
-                  field = desc->fields + f;                                   \
-                  if (field->label == PROTOBUF_C_LABEL_REPEATED)              \
-                    STRUCT_MEMBER (size_t, rv, field->quantifier_offset) = 0; \
-                }
-				a = do_alloc(allocator, siz * n);
-				if (!a) {
-					CLEAR_REMAINING_N_PTRS();
-					goto error_cleanup;
-				}
-				STRUCT_MEMBER(void *, rv, field->offset) = a;
-			}
-		} else if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
-			if (field->default_value == NULL &&
-			    !REQUIRED_FIELD_BITMAP_IS_SET(f))
-			{
-				CLEAR_REMAINING_N_PTRS();
-				PROTOBUF_C_UNPACK_ERROR("message '%s': missing required field '%s'",
-							desc->name, field->name);
-				goto error_cleanup;
-			}
-		}
-	}
-#undef CLEAR_REMAINING_N_PTRS
-
-	/* allocate space for unknown fields */
-	if (n_unknown) {
-		rv->unknown_fields = do_alloc(allocator,
-					      n_unknown * sizeof(ProtobufCMessageUnknownField));
-		if (rv->unknown_fields == NULL)
-			goto error_cleanup;
-	}
-
-	/* do real parsing */
-	for (i_slab = 0; i_slab <= which_slab; i_slab++) {
-		unsigned max = (i_slab == which_slab) ?
-			in_slab_index : (1U << (i_slab + 4));
-		ScannedMember *slab = scanned_member_slabs[i_slab];
-		unsigned j;
-
-		for (j = 0; j < max; j++) {
-			if (!parse_member(slab + j, rv, allocator)) {
-				PROTOBUF_C_UNPACK_ERROR("error parsing member %s of %s",
-							slab->field ? slab->field->name : "*unknown-field*",
-					desc->name);
-				goto error_cleanup;
-			}
-		}
-	}
-
-	/* cleanup */
-	for (j = 1; j <= which_slab; j++)
-		do_free(allocator, scanned_member_slabs[j]);
-	if (required_fields_bitmap_alloced)
-		do_free(allocator, required_fields_bitmap);
-	return rv;
-
-error_cleanup:
-	protobuf_c_message_free_unpacked(rv, allocator);
-	for (j = 1; j <= which_slab; j++)
-		do_free(allocator, scanned_member_slabs[j]);
-	if (required_fields_bitmap_alloced)
-		do_free(allocator, required_fields_bitmap);
-	return NULL;
-
-error_cleanup_during_scan:
-	do_free(allocator, rv);
-	for (j = 1; j <= which_slab; j++)
-		do_free(allocator, scanned_member_slabs[j]);
-	if (required_fields_bitmap_alloced)
-		do_free(allocator, required_fields_bitmap);
-	return NULL;
-}
-
-void
-protobuf_c_message_free_unpacked(ProtobufCMessage *message,
-				 ProtobufCAllocator *allocator)
-{
-	const ProtobufCMessageDescriptor *desc = message->descriptor;
-	unsigned f;
-
-	ASSERT_IS_MESSAGE(message);
-	if (allocator == NULL)
-		allocator = &protobuf_c__allocator;
-	message->descriptor = NULL;
-	for (f = 0; f < desc->n_fields; f++) {
-		if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED) {
-			size_t n = STRUCT_MEMBER(size_t,
-						 message,
-						 desc->fields[f].quantifier_offset);
-			void *arr = STRUCT_MEMBER(void *,
-						  message,
-						  desc->fields[f].offset);
-
-			if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) {
-				unsigned i;
-				for (i = 0; i < n; i++)
-					do_free(allocator, ((char **) arr)[i]);
-			} else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) {
-				unsigned i;
-				for (i = 0; i < n; i++)
-					do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data);
-			} else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) {
-				unsigned i;
-				for (i = 0; i < n; i++)
-					protobuf_c_message_free_unpacked(
-						((ProtobufCMessage **) arr)[i],
-						allocator
-					);
-			}
-			if (arr != NULL)
-				do_free(allocator, arr);
-		} else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) {
-			char *str = STRUCT_MEMBER(char *, message,
-						  desc->fields[f].offset);
-
-			if (str && str != desc->fields[f].default_value)
-				do_free(allocator, str);
-		} else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) {
-			void *data = STRUCT_MEMBER(ProtobufCBinaryData, message,
-						   desc->fields[f].offset).data;
-			const ProtobufCBinaryData *default_bd;
-
-			default_bd = desc->fields[f].default_value;
-			if (data != NULL &&
-			    (default_bd == NULL ||
-			     default_bd->data != data))
-			{
-				do_free(allocator, data);
-			}
-		} else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) {
-			ProtobufCMessage *sm;
-
-			sm = STRUCT_MEMBER(ProtobufCMessage *, message,
-					   desc->fields[f].offset);
-			if (sm && sm != desc->fields[f].default_value)
-				protobuf_c_message_free_unpacked(sm, allocator);
-		}
-	}
-
-	for (f = 0; f < message->n_unknown_fields; f++)
-		do_free(allocator, message->unknown_fields[f].data);
-	if (message->unknown_fields != NULL)
-		do_free(allocator, message->unknown_fields);
-
-	do_free(allocator, message);
-}
-
-void
-protobuf_c_message_init(const ProtobufCMessageDescriptor * descriptor,
-			void *message)
-{
-	descriptor->message_init((ProtobufCMessage *) (message));
-}
-
-protobuf_c_boolean
-protobuf_c_message_check(const ProtobufCMessage *message)
-{
-	unsigned i;
-
-	if (!message ||
-	    !message->descriptor ||
-	    message->descriptor->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC)
-	{
-		return FALSE;
-	}
-
-	for (i = 0; i < message->descriptor->n_fields; i++) {
-		const ProtobufCFieldDescriptor *f = message->descriptor->fields + i;
-		ProtobufCType type = f->type;
-		ProtobufCLabel label = f->label;
-		void *field = STRUCT_MEMBER_P (message, f->offset);
-
-		if (label == PROTOBUF_C_LABEL_REPEATED) {
-			size_t *quantity = STRUCT_MEMBER_P (message, f->quantifier_offset);
-
-			if (*quantity > 0 && *(void **) field == NULL) {
-				return FALSE;
-			}
-
-			if (type == PROTOBUF_C_TYPE_MESSAGE) {
-				ProtobufCMessage **submessage = *(ProtobufCMessage ***) field;
-				unsigned j;
-				for (j = 0; j < *quantity; j++) {
-					if (!protobuf_c_message_check(submessage[j]))
-						return FALSE;
-				}
-			} else if (type == PROTOBUF_C_TYPE_STRING) {
-				char **string = *(char ***) field;
-				unsigned j;
-				for (j = 0; j < *quantity; j++) {
-					if (!string[j])
-						return FALSE;
-				}
-			} else if (type == PROTOBUF_C_TYPE_BYTES) {
-				ProtobufCBinaryData *bd = *(ProtobufCBinaryData **) field;
-				unsigned j;
-				for (j = 0; j < *quantity; j++) {
-					if (bd[j].len > 0 && bd[j].data == NULL)
-						return FALSE;
-				}
-			}
-
-		} else { /* PROTOBUF_C_LABEL_REQUIRED or PROTOBUF_C_LABEL_OPTIONAL */
-
-			if (type == PROTOBUF_C_TYPE_MESSAGE) {
-				ProtobufCMessage *submessage = *(ProtobufCMessage **) field;
-				if (label == PROTOBUF_C_LABEL_REQUIRED || submessage != NULL) {
-					if (!protobuf_c_message_check(submessage))
-						return FALSE;
-				}
-			} else if (type == PROTOBUF_C_TYPE_STRING) {
-				char *string = *(char **) field;
-				if (label == PROTOBUF_C_LABEL_REQUIRED && string == NULL)
-					return FALSE;
-			} else if (type == PROTOBUF_C_TYPE_BYTES) {
-				protobuf_c_boolean *has = STRUCT_MEMBER_P (message, f->quantifier_offset);
-				ProtobufCBinaryData *bd = field;
-				if (label == PROTOBUF_C_LABEL_REQUIRED || *has == TRUE) {
-					if (bd->len > 0 && bd->data == NULL)
-						return FALSE;
-				}
-			}
-		}
-	}
-
-	return TRUE;
-}
-
-/* === services === */
-
-typedef void (*GenericHandler) (void *service,
-				const ProtobufCMessage *input,
-				ProtobufCClosure closure,
-				void *closure_data);
-void
-protobuf_c_service_invoke_internal(ProtobufCService *service,
-				   unsigned method_index,
-				   const ProtobufCMessage *input,
-				   ProtobufCClosure closure,
-				   void *closure_data)
-{
-	GenericHandler *handlers;
-	GenericHandler handler;
-
-	/*
-	 * Verify that method_index is within range. If this fails, you are
-	 * likely invoking a newly added method on an old service. (Although
-	 * other memory corruption bugs can cause this assertion too.)
-	 */
-	assert(method_index < service->descriptor->n_methods);
-
-	/*
-	 * Get the array of virtual methods (which are enumerated by the
-	 * generated code).
-	 */
-	handlers = (GenericHandler *) (service + 1);
-
-	/*
-	 * Get our method and invoke it.
-	 * \todo Seems like handler == NULL is a situation that needs handling.
-	 */
-	handler = handlers[method_index];
-	(*handler)(service, input, closure, closure_data);
-}
-
-void
-protobuf_c_service_generated_init(ProtobufCService *service,
-				  const ProtobufCServiceDescriptor *descriptor,
-				  ProtobufCServiceDestroy destroy)
-{
-	ASSERT_IS_SERVICE_DESCRIPTOR(descriptor);
-	service->descriptor = descriptor;
-	service->destroy = destroy;
-	service->invoke = protobuf_c_service_invoke_internal;
-	memset(service + 1, 0, descriptor->n_methods * sizeof(GenericHandler));
-}
-
-void protobuf_c_service_destroy(ProtobufCService *service)
-{
-	service->destroy(service);
-}
-
-/* --- querying the descriptors --- */
-
-const ProtobufCEnumValue *
-protobuf_c_enum_descriptor_get_value_by_name(const ProtobufCEnumDescriptor *desc,
-					     const char *name)
-{
-	unsigned start = 0;
-	unsigned count = desc->n_value_names;
-
-	while (count > 1) {
-		unsigned mid = start + count / 2;
-		int rv = strcmp(desc->values_by_name[mid].name, name);
-		if (rv == 0)
-			return desc->values + desc->values_by_name[mid].index;
-		else if (rv < 0) {
-			count = start + count - (mid + 1);
-			start = mid + 1;
-		} else
-			count = mid - start;
-	}
-	if (count == 0)
-		return NULL;
-	if (strcmp(desc->values_by_name[start].name, name) == 0)
-		return desc->values + desc->values_by_name[start].index;
-	return NULL;
-}
-
-const ProtobufCEnumValue *
-protobuf_c_enum_descriptor_get_value(const ProtobufCEnumDescriptor *desc,
-				     int value)
-{
-	int rv = int_range_lookup(desc->n_value_ranges, desc->value_ranges, value);
-	if (rv < 0)
-		return NULL;
-	return desc->values + rv;
-}
-
-const ProtobufCFieldDescriptor *
-protobuf_c_message_descriptor_get_field_by_name(const ProtobufCMessageDescriptor *desc,
-						const char *name)
-{
-	unsigned start = 0;
-	unsigned count = desc->n_fields;
-	const ProtobufCFieldDescriptor *field;
-
-	while (count > 1) {
-		unsigned mid = start + count / 2;
-		int rv;
-		field = desc->fields + desc->fields_sorted_by_name[mid];
-		rv = strcmp(field->name, name);
-		if (rv == 0)
-			return field;
-		else if (rv < 0) {
-			count = start + count - (mid + 1);
-			start = mid + 1;
-		} else
-			count = mid - start;
-	}
-	if (count == 0)
-		return NULL;
-	field = desc->fields + desc->fields_sorted_by_name[start];
-	if (strcmp(field->name, name) == 0)
-		return field;
-	return NULL;
-}
-
-const ProtobufCFieldDescriptor *
-protobuf_c_message_descriptor_get_field(const ProtobufCMessageDescriptor *desc,
-					unsigned value)
-{
-	int rv = int_range_lookup(desc->n_field_ranges,desc->field_ranges, value);
-	if (rv < 0)
-		return NULL;
-	return desc->fields + rv;
-}
-
-const ProtobufCMethodDescriptor *
-protobuf_c_service_descriptor_get_method_by_name(const ProtobufCServiceDescriptor *desc,
-						 const char *name)
-{
-	unsigned start = 0;
-	unsigned count = desc->n_methods;
-
-	while (count > 1) {
-		unsigned mid = start + count / 2;
-		unsigned mid_index = desc->method_indices_by_name[mid];
-		const char *mid_name = desc->methods[mid_index].name;
-		int rv = strcmp(mid_name, name);
-
-		if (rv == 0)
-			return desc->methods + desc->method_indices_by_name[mid];
-		if (rv < 0) {
-			count = start + count - (mid + 1);
-			start = mid + 1;
-		} else {
-			count = mid - start;
-		}
-	}
-	if (count == 0)
-		return NULL;
-	if (strcmp(desc->methods[desc->method_indices_by_name[start]].name, name) == 0)
-		return desc->methods + desc->method_indices_by_name[start];
-	return NULL;
-}
--- a/libpurple/protocols/gg/lib/protobuf-c.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1078 +0,0 @@
-/*
- * Copyright (c) 2008-2014, Dave Benson and the protobuf-c authors.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*! \file
- * \mainpage Introduction
- *
- * This is [protobuf-c], a C implementation of [Protocol Buffers].
- *
- * This file defines the public API for the `libprotobuf-c` support library.
- * This API includes interfaces that can be used directly by client code as well
- * as the interfaces used by the code generated by the `protoc-c` compiler.
- *
- * The `libprotobuf-c` support library performs the actual serialization and
- * deserialization of Protocol Buffers messages. It interacts with structures,
- * definitions, and metadata generated by the `protoc-c` compiler from .proto
- * files.
- *
- * \authors Dave Benson and the `protobuf-c` authors.
- *
- * \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license.
- *
- * [protobuf-c]:       https://github.com/protobuf-c/protobuf-c
- * [Protocol Buffers]: https://developers.google.com/protocol-buffers/
- * [BSD-2-Clause]:     http://opensource.org/licenses/BSD-2-Clause
- *
- * \page gencode Generated Code
- *
- * For each enum, we generate a C enum. For each message, we generate a C
- * structure which can be cast to a `ProtobufCMessage`.
- *
- * For each enum and message, we generate a descriptor object that allows us to
- * implement a kind of reflection on the structures.
- *
- * First, some naming conventions:
- *
- * - The name of the type for enums and messages and services is camel case
- *   (meaning WordsAreCrammedTogether) except that double underscores are used
- *   to delimit scopes. For example, the following `.proto` file:
- *
-~~~{.proto}
-        package foo.bar;
-        message BazBah {
-            optional int32 val = 1;
-        }
-~~~
- *
- * would generate a C type `Foo__Bar__BazBah`.
- *
- * - Identifiers for functions and globals are all lowercase, with camel case
- *   words separated by single underscores. For example, one of the function
- *   prototypes generated by `protoc-c` for the above example:
- *
-~~~{.c}
-Foo__Bar__BazBah *
-       foo__bar__baz_bah__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-~~~
- *
- * - Identifiers for enum values contain an uppercase prefix which embeds the
- *   package name and the enum type name.
- *
- * - A double underscore is used to separate further components of identifier
- *   names.
- *
- * For example, in the name of the unpack function above, the package name
- * `foo.bar` has become `foo__bar`, the message name BazBah has become
- * `baz_bah`, and the method name is `unpack`. These are all joined with double
- * underscores to form the C identifier `foo__bar__baz_bah__unpack`.
- *
- * We also generate descriptor objects for messages and enums. These are
- * declared in the `.pb-c.h` files:
- *
-~~~{.c}
-extern const ProtobufCMessageDescriptor foo__bar__baz_bah__descriptor;
-~~~
- *
- * The message structures all begin with `ProtobufCMessageDescriptor *` which is
- * sufficient to allow them to be cast to `ProtobufCMessage`.
- *
- * For each message defined in a `.proto` file, we generate a number of
- * functions. Each function name contains a prefix based on the package name and
- * message name in order to make it a unique C identifier.
- *
- * - `unpack()`. Unpacks data for a particular message format. Note that the
- *   `allocator` parameter is usually `NULL` to indicate that the system's
- *   `malloc()` and `free()` functions should be used for dynamically allocating
- *   memory.
- *
-~~~{.c}
-Foo__Bar__BazBah *
-       foo__bar__baz_bah__unpack
-                     (ProtobufCAllocator  *allocator,
-                      size_t               len,
-                      const uint8_t       *data);
-~~~
- *
- * - `free_unpacked()`. Frees a message object obtained with the `unpack()`
- *   method.
- *
-~~~{.c}
-void   foo__bar__baz_bah__free_unpacked
-                     (Foo__Bar__BazBah *message,
-                      ProtobufCAllocator *allocator);
-~~~
- *
- * - `get_packed_size()`. Calculates the length in bytes of the serialized
- *   representation of the message object.
- *
-~~~{.c}
-size_t foo__bar__baz_bah__get_packed_size
-                     (const Foo__Bar__BazBah   *message);
-~~~
- *
- * - `pack()`. Pack a message object into a preallocated buffer. Assumes that
- *   the buffer is large enough. (Use `get_packed_size()` first.)
- *
-~~~{.c}
-size_t foo__bar__baz_bah__pack
-                     (const Foo__Bar__BazBah   *message,
-                      uint8_t             *out);
-~~~
- *
- * - `pack_to_buffer()`. Packs a message into a "virtual buffer". This is an
- *   object which defines an "append bytes" callback to consume data as it is
- *   serialized.
- *
-~~~{.c}
-size_t foo__bar__baz_bah__pack_to_buffer
-                     (const Foo__Bar__BazBah   *message,
-                      ProtobufCBuffer     *buffer);
-~~~
- *
- * \page pack Packing and unpacking messages
- *
- * To pack a message, first compute the packed size of the message with
- * protobuf_c_message_get_packed_size(), then allocate a buffer of at least
- * that size, then call protobuf_c_message_pack().
- *
- * Alternatively, a message can be serialized without calculating the final size
- * first. Use the protobuf_c_message_pack_to_buffer() function and provide a
- * ProtobufCBuffer object which implements an "append" method that consumes
- * data.
- *
- * To unpack a message, call the protobuf_c_message_unpack() function. The
- * result can be cast to an object of the type that matches the descriptor for
- * the message.
- *
- * The result of unpacking a message should be freed with
- * protobuf_c_message_free_unpacked().
- */
-
-#ifndef PROTOBUF_C_H
-#define PROTOBUF_C_H
-
-#include <assert.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-# define PROTOBUF_C__BEGIN_DECLS	extern "C" {
-# define PROTOBUF_C__END_DECLS		}
-#else
-# define PROTOBUF_C__BEGIN_DECLS
-# define PROTOBUF_C__END_DECLS
-#endif
-
-PROTOBUF_C__BEGIN_DECLS
-
-#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB)
-# ifdef PROTOBUF_C_EXPORT
-#  define PROTOBUF_C__API __declspec(dllexport)
-# else
-#  define PROTOBUF_C__API __declspec(dllimport)
-# endif
-#else
-# define PROTOBUF_C__API
-#endif
-
-#if !defined(PROTOBUF_C__NO_DEPRECATED) && \
-	((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-# define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__))
-#else
-# define PROTOBUF_C__DEPRECATED
-#endif
-
-#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE
- #define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \
-  , _##enum_name##_IS_INT_SIZE = INT_MAX
-#endif
-
-#define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC    0x14159bc3
-#define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC    0x28aaeef9
-#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC       0x114315af
-
-/**
- * \defgroup api Public API
- *
- * This is the public API for `libprotobuf-c`. These interfaces are stable and
- * subject to Semantic Versioning guarantees.
- *
- * @{
- */
-
-/**
- * Values for the `flags` word in `ProtobufCFieldDescriptor`.
- */
-typedef enum {
-	/** Set if the field is repeated and marked with the `packed` option. */
-	PROTOBUF_C_FIELD_FLAG_PACKED		= (1 << 0),
-
-	/** Set if the field is marked with the `deprecated` option. */
-	PROTOBUF_C_FIELD_FLAG_DEPRECATED	= (1 << 1),
-} ProtobufCFieldFlag;
-
-/**
- * Message field rules.
- *
- * \see [Defining A Message Type] in the Protocol Buffers documentation.
- *
- * [Defining A Message Type]:
- *      https://developers.google.com/protocol-buffers/docs/proto#simple
- */
-typedef enum {
-	/** A well-formed message must have exactly one of this field. */
-	PROTOBUF_C_LABEL_REQUIRED,
-
-	/**
-	 * A well-formed message can have zero or one of this field (but not
-	 * more than one).
-	 */
-	PROTOBUF_C_LABEL_OPTIONAL,
-
-	/**
-	 * This field can be repeated any number of times (including zero) in a
-	 * well-formed message. The order of the repeated values will be
-	 * preserved.
-	 */
-	PROTOBUF_C_LABEL_REPEATED,
-} ProtobufCLabel;
-
-/**
- * Field value types.
- *
- * \see [Scalar Value Types] in the Protocol Buffers documentation.
- *
- * [Scalar Value Types]:
- *      https://developers.google.com/protocol-buffers/docs/proto#scalar
- */
-typedef enum {
-	PROTOBUF_C_TYPE_INT32,      /**< int32 */
-	PROTOBUF_C_TYPE_SINT32,     /**< signed int32 */
-	PROTOBUF_C_TYPE_SFIXED32,   /**< signed int32 (4 bytes) */
-	PROTOBUF_C_TYPE_INT64,      /**< int64 */
-	PROTOBUF_C_TYPE_SINT64,     /**< signed int64 */
-	PROTOBUF_C_TYPE_SFIXED64,   /**< signed int64 (8 bytes) */
-	PROTOBUF_C_TYPE_UINT32,     /**< unsigned int32 */
-	PROTOBUF_C_TYPE_FIXED32,    /**< unsigned int32 (4 bytes) */
-	PROTOBUF_C_TYPE_UINT64,     /**< unsigned int64 */
-	PROTOBUF_C_TYPE_FIXED64,    /**< unsigned int64 (8 bytes) */
-	PROTOBUF_C_TYPE_FLOAT,      /**< float */
-	PROTOBUF_C_TYPE_DOUBLE,     /**< double */
-	PROTOBUF_C_TYPE_BOOL,       /**< boolean */
-	PROTOBUF_C_TYPE_ENUM,       /**< enumerated type */
-	PROTOBUF_C_TYPE_STRING,     /**< UTF-8 or ASCII string */
-	PROTOBUF_C_TYPE_BYTES,      /**< arbitrary byte sequence */
-	PROTOBUF_C_TYPE_MESSAGE,    /**< nested message */
-} ProtobufCType;
-
-/**
- * Field wire types.
- *
- * \see [Message Structure] in the Protocol Buffers documentation.
- *
- * [Message Structure]:
- *      https://developers.google.com/protocol-buffers/docs/encoding#structure
- */
-typedef enum {
-	PROTOBUF_C_WIRE_TYPE_VARINT = 0,
-	PROTOBUF_C_WIRE_TYPE_64BIT = 1,
-	PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED = 2,
-	/* "Start group" and "end group" wire types are unsupported. */
-	PROTOBUF_C_WIRE_TYPE_32BIT = 5,
-} ProtobufCWireType;
-
-struct ProtobufCAllocator;
-struct ProtobufCBinaryData;
-struct ProtobufCBuffer;
-struct ProtobufCBufferSimple;
-struct ProtobufCEnumDescriptor;
-struct ProtobufCEnumValue;
-struct ProtobufCEnumValueIndex;
-struct ProtobufCFieldDescriptor;
-struct ProtobufCIntRange;
-struct ProtobufCMessage;
-struct ProtobufCMessageDescriptor;
-struct ProtobufCMessageUnknownField;
-struct ProtobufCMethodDescriptor;
-struct ProtobufCService;
-struct ProtobufCServiceDescriptor;
-
-typedef struct ProtobufCAllocator ProtobufCAllocator;
-typedef struct ProtobufCBinaryData ProtobufCBinaryData;
-typedef struct ProtobufCBuffer ProtobufCBuffer;
-typedef struct ProtobufCBufferSimple ProtobufCBufferSimple;
-typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor;
-typedef struct ProtobufCEnumValue ProtobufCEnumValue;
-typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex;
-typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor;
-typedef struct ProtobufCIntRange ProtobufCIntRange;
-typedef struct ProtobufCMessage ProtobufCMessage;
-typedef struct ProtobufCMessageDescriptor ProtobufCMessageDescriptor;
-typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField;
-typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor;
-typedef struct ProtobufCService ProtobufCService;
-typedef struct ProtobufCServiceDescriptor ProtobufCServiceDescriptor;
-
-/** Boolean type. */
-typedef int protobuf_c_boolean;
-
-typedef void (*ProtobufCClosure)(const ProtobufCMessage *, void *closure_data);
-typedef void (*ProtobufCMessageInit)(ProtobufCMessage *);
-typedef void (*ProtobufCServiceDestroy)(ProtobufCService *);
-
-/**
- * Structure for defining a custom memory allocator.
- */
-struct ProtobufCAllocator {
-	/** Function to allocate memory. */
-	void		*(*alloc)(void *allocator_data, size_t size);
-
-	/** Function to free memory. */
-	void		(*free)(void *allocator_data, void *pointer);
-
-	/** Opaque pointer passed to `alloc` and `free` functions. */
-	void		*allocator_data;
-};
-
-/**
- * Structure for the protobuf `bytes` scalar type.
- *
- * The data contained in a `ProtobufCBinaryData` is an arbitrary sequence of
- * bytes. It may contain embedded `NUL` characters and is not required to be
- * `NUL`-terminated.
- */
-struct ProtobufCBinaryData {
-	size_t	len;        /**< Number of bytes in the `data` field. */
-	uint8_t	*data;      /**< Data bytes. */
-};
-
-/**
- * Structure for defining a virtual append-only buffer. Used by
- * protobuf_c_message_pack_to_buffer() to abstract the consumption of serialized
- * bytes.
- *
- * `ProtobufCBuffer` "subclasses" may be defined on the stack. For example, to
- * write to a `FILE` object:
- *
-~~~{.c}
-typedef struct {
-        ProtobufCBuffer base;
-        FILE *fp;
-} BufferAppendToFile;
-
-static void
-my_buffer_file_append(ProtobufCBuffer *buffer,
-                      size_t len,
-                      const uint8_t *data)
-{
-        BufferAppendToFile *file_buf = (BufferAppendToFile *) buffer;
-        fwrite(data, len, 1, file_buf->fp); // XXX: No error handling!
-}
-~~~
- *
- * To use this new type of ProtobufCBuffer, it could be called as follows:
- *
-~~~{.c}
-...
-BufferAppendToFile tmp = {0};
-tmp.base.append = my_buffer_file_append;
-tmp.fp = fp;
-protobuf_c_message_pack_to_buffer(&message, &tmp);
-...
-~~~
- */
-struct ProtobufCBuffer {
-	/** Append function. Consumes the `len` bytes stored at `data`. */
-	void		(*append)(ProtobufCBuffer *buffer,
-				  size_t len,
-				  const uint8_t *data);
-};
-
-/**
- * Simple buffer "subclass" of `ProtobufCBuffer`.
- *
- * A `ProtobufCBufferSimple` object is declared on the stack and uses a
- * scratch buffer provided by the user for the initial allocation. It performs
- * exponential resizing, using dynamically allocated memory. A
- * `ProtobufCBufferSimple` object can be created and used as follows:
- *
-~~~{.c}
-uint8_t pad[128];
-ProtobufCBufferSimple simple = PROTOBUF_C_BUFFER_SIMPLE_INIT(pad);
-ProtobufCBuffer *buffer = (ProtobufCBuffer *) &simple;
-~~~
- *
- * `buffer` can now be used with `protobuf_c_message_pack_to_buffer()`. Once a
- * message has been serialized to a `ProtobufCBufferSimple` object, the
- * serialized data bytes can be accessed from the `.data` field.
- *
- * To free the memory allocated by a `ProtobufCBufferSimple` object, if any,
- * call PROTOBUF_C_BUFFER_SIMPLE_CLEAR() on the object, for example:
- *
-~~~{.c}
-PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&simple);
-~~~
- *
- * \see PROTOBUF_C_BUFFER_SIMPLE_INIT
- * \see PROTOBUF_C_BUFFER_SIMPLE_CLEAR
- */
-struct ProtobufCBufferSimple {
-	/** "Base class". */
-	ProtobufCBuffer		base;
-	/** Number of bytes allocated in `data`. */
-	size_t			alloced;
-	/** Number of bytes currently stored in `data`. */
-	size_t			len;
-	/** Data bytes. */
-	uint8_t			*data;
-	/** Whether `data` must be freed. */
-	protobuf_c_boolean	must_free_data;
-	/** Allocator to use. May be NULL to indicate the system allocator. */
-	ProtobufCAllocator	*allocator;
-};
-
-/**
- * Describes an enumeration as a whole, with all of its values.
- */
-struct ProtobufCEnumDescriptor {
-	/** Magic value checked to ensure that the API is used correctly. */
-	uint32_t			magic;
-
-	/** The qualified name (e.g., "namespace.Type"). */
-	const char			*name;
-	/** The unqualified name as given in the .proto file (e.g., "Type"). */
-	const char			*short_name;
-	/** Identifier used in generated C code. */
-	const char			*c_name;
-	/** The dot-separated namespace. */
-	const char			*package_name;
-
-	/** Number elements in `values`. */
-	unsigned			n_values;
-	/** Array of distinct values, sorted by numeric value. */
-	const ProtobufCEnumValue	*values;
-
-	/** Number of elements in `values_by_name`. */
-	unsigned			n_value_names;
-	/** Array of named values, including aliases, sorted by name. */
-	const ProtobufCEnumValueIndex	*values_by_name;
-
-	/** Number of elements in `value_ranges`. */
-	unsigned			n_value_ranges;
-	/** Value ranges, for faster lookups by numeric value. */
-	const ProtobufCIntRange		*value_ranges;
-
-	/** Reserved for future use. */
-	void				*reserved1;
-	/** Reserved for future use. */
-	void				*reserved2;
-	/** Reserved for future use. */
-	void				*reserved3;
-	/** Reserved for future use. */
-	void				*reserved4;
-};
-
-/**
- * Represents a single value of an enumeration.
- */
-struct ProtobufCEnumValue {
-	/** The string identifying this value in the .proto file. */
-	const char	*name;
-
-	/** The string identifying this value in generated C code. */
-	const char	*c_name;
-
-	/** The numeric value assigned in the .proto file. */
-	int		value;
-};
-
-/**
- * Used by `ProtobufCEnumDescriptor` to look up enum values.
- */
-struct ProtobufCEnumValueIndex {
-	/** Name of the enum value. */
-	const char      *name;
-	/** Index into values[] array. */
-	unsigned        index;
-};
-
-/**
- * Describes a single field in a message.
- */
-struct ProtobufCFieldDescriptor {
-	/** Name of the field as given in the .proto file. */
-	const char		*name;
-
-	/** Tag value of the field as given in the .proto file. */
-	uint32_t		id;
-
-	/** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */
-	ProtobufCLabel		label;
-
-	/** The type of the field. */
-	ProtobufCType		type;
-
-	/**
-	 * The offset in bytes of the message's C structure's quantifier field
-	 * (the `has_MEMBER` field for optional members or the `n_MEMBER` field
-	 * for repeated members.
-	 */
-	unsigned		quantifier_offset;
-
-	/**
-	 * The offset in bytes into the message's C structure for the member
-	 * itself.
-	 */
-	unsigned		offset;
-
-	/**
-	 * A type-specific descriptor.
-	 *
-	 * If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the
-	 * corresponding `ProtobufCEnumDescriptor`.
-	 *
-	 * If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to
-	 * the corresponding `ProtobufCMessageDescriptor`.
-	 *
-	 * Otherwise this field is NULL.
-	 */
-	const void		*descriptor; /* for MESSAGE and ENUM types */
-
-	/** The default value for this field, if defined. May be NULL. */
-	const void		*default_value;
-
-	/**
-	 * A flag word. Zero or more of the bits defined in the
-	 * `ProtobufCFieldFlag` enum may be set.
-	 */
-	uint32_t		flags;
-
-	/** Reserved for future use. */
-	unsigned		reserved_flags;
-	/** Reserved for future use. */
-	void			*reserved2;
-	/** Reserved for future use. */
-	void			*reserved3;
-};
-
-/**
- * Helper structure for optimizing int => index lookups in the case
- * where the keys are mostly consecutive values, as they presumably are for
- * enums and fields.
- *
- * The data structures requires that the values in the original array are
- * sorted.
- */
-struct ProtobufCIntRange {
-	int             start_value;
-	unsigned        orig_index;
-	/*
-	 * NOTE: the number of values in the range can be inferred by looking
-	 * at the next element's orig_index. A dummy element is added to make
-	 * this simple.
-	 */
-};
-
-/**
- * An instance of a message.
- *
- * `ProtobufCMessage` is a light-weight "base class" for all messages.
- *
- * In particular, `ProtobufCMessage` doesn't have any allocation policy
- * associated with it. That's because it's common to create `ProtobufCMessage`
- * objects on the stack. In fact, that's what we recommend for sending messages.
- * If the object is allocated from the stack, you can't really have a memory
- * leak.
- *
- * This means that calls to functions like protobuf_c_message_unpack() which
- * return a `ProtobufCMessage` must be paired with a call to a free function,
- * like protobuf_c_message_free_unpacked().
- */
-struct ProtobufCMessage {
-	/** The descriptor for this message type. */
-	const ProtobufCMessageDescriptor	*descriptor;
-	/** The number of elements in `unknown_fields`. */
-	unsigned				n_unknown_fields;
-	/** The fields that weren't recognized by the parser. */
-	ProtobufCMessageUnknownField		*unknown_fields;
-};
-
-/**
- * Describes a message.
- */
-struct ProtobufCMessageDescriptor {
-	/** Magic value checked to ensure that the API is used correctly. */
-	uint32_t			magic;
-
-	/** The qualified name (e.g., "namespace.Type"). */
-	const char			*name;
-	/** The unqualified name as given in the .proto file (e.g., "Type"). */
-	const char			*short_name;
-	/** Identifier used in generated C code. */
-	const char			*c_name;
-	/** The dot-separated namespace. */
-	const char			*package_name;
-
-	/**
-	 * Size in bytes of the C structure representing an instance of this
-	 * type of message.
-	 */
-	size_t				sizeof_message;
-
-	/** Number of elements in `fields`. */
-	unsigned			n_fields;
-	/** Field descriptors, sorted by tag number. */
-	const ProtobufCFieldDescriptor	*fields;
-	/** Used for looking up fields by name. */
-	const unsigned			*fields_sorted_by_name;
-
-	/** Number of elements in `field_ranges`. */
-	unsigned			n_field_ranges;
-	/** Used for looking up fields by id. */
-	const ProtobufCIntRange		*field_ranges;
-
-	/** Message initialisation function. */
-	ProtobufCMessageInit		message_init;
-
-	/** Reserved for future use. */
-	void				*reserved1;
-	/** Reserved for future use. */
-	void				*reserved2;
-	/** Reserved for future use. */
-	void				*reserved3;
-};
-
-/**
- * An unknown message field.
- */
-struct ProtobufCMessageUnknownField {
-	/** The tag number. */
-	uint32_t		tag;
-	/** The wire type of the field. */
-	ProtobufCWireType	wire_type;
-	/** Number of bytes in `data`. */
-	size_t			len;
-	/** Field data. */
-	uint8_t			*data;
-};
-
-/**
- * Method descriptor.
- */
-struct ProtobufCMethodDescriptor {
-	/** Method name. */
-	const char				*name;
-	/** Input message descriptor. */
-	const ProtobufCMessageDescriptor	*input;
-	/** Output message descriptor. */
-	const ProtobufCMessageDescriptor	*output;
-};
-
-/**
- * Service.
- */
-struct ProtobufCService {
-	/** Service descriptor. */
-	const ProtobufCServiceDescriptor *descriptor;
-	/** Function to invoke the service. */
-	void (*invoke)(ProtobufCService *service,
-		       unsigned method_index,
-		       const ProtobufCMessage *input,
-		       ProtobufCClosure closure,
-		       void *closure_data);
-	/** Function to destroy the service. */
-	void (*destroy)(ProtobufCService *service);
-};
-
-/**
- * Service descriptor.
- */
-struct ProtobufCServiceDescriptor {
-	/** Magic value checked to ensure that the API is used correctly. */
-	uint32_t			magic;
-
-	/** Service name. */
-	const char			*name;
-	/** Short version of service name. */
-	const char			*short_name;
-	/** C identifier for the service name. */
-	const char			*c_name;
-	/** Package name. */
-	const char			*package;
-	/** Number of elements in `methods`. */
-	unsigned			n_methods;
-	/** Method descriptors, in the order defined in the .proto file. */
-	const ProtobufCMethodDescriptor	*methods;
-	/** Sort index of methods. */
-	const unsigned			*method_indices_by_name;
-};
-
-/**
- * Get the version of the protobuf-c library. Note that this is the version of
- * the library linked against, not the version of the headers compiled against.
- *
- * \return A string containing the version number of protobuf-c.
- */
-PROTOBUF_C__API
-const char *
-protobuf_c_version(void);
-
-/**
- * Get the version of the protobuf-c library. Note that this is the version of
- * the library linked against, not the version of the headers compiled against.
- *
- * \return A 32 bit unsigned integer containing the version number of
- *      protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH.
- */
-PROTOBUF_C__API
-uint32_t
-protobuf_c_version_number(void);
-
-/**
- * The version of the protobuf-c headers, represented as a string using the same
- * format as protobuf_c_version().
- */
-#define PROTOBUF_C_VERSION		"1.0.2"
-
-/**
- * The version of the protobuf-c headers, represented as an integer using the
- * same format as protobuf_c_version_number().
- */
-#define PROTOBUF_C_VERSION_NUMBER	1000002
-
-/**
- * The minimum protoc-c version which works with the current version of the
- * protobuf-c headers.
- */
-#define PROTOBUF_C_MIN_COMPILER_VERSION	1000000
-
-/**
- * Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by name.
- *
- * \param desc
- *      The `ProtobufCEnumDescriptor` object.
- * \param name
- *      The `name` field from the corresponding `ProtobufCEnumValue` object to
- *      match.
- * \return
- *      A `ProtobufCEnumValue` object.
- * \retval NULL
- *      If not found.
- */
-PROTOBUF_C__API
-const ProtobufCEnumValue *
-protobuf_c_enum_descriptor_get_value_by_name(
-	const ProtobufCEnumDescriptor *desc,
-	const char *name);
-
-/**
- * Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by numeric
- * value.
- *
- * \param desc
- *      The `ProtobufCEnumDescriptor` object.
- * \param value
- *      The `value` field from the corresponding `ProtobufCEnumValue` object to
- *      match.
- *
- * \return
- *      A `ProtobufCEnumValue` object.
- * \retval NULL
- *      If not found.
- */
-PROTOBUF_C__API
-const ProtobufCEnumValue *
-protobuf_c_enum_descriptor_get_value(
-	const ProtobufCEnumDescriptor *desc,
-	int value);
-
-/**
- * Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by
- * the name of the field.
- *
- * \param desc
- *      The `ProtobufCMessageDescriptor` object.
- * \param name
- *      The name of the field.
- * \return
- *      A `ProtobufCFieldDescriptor` object.
- * \retval NULL
- *      If not found.
- */
-PROTOBUF_C__API
-const ProtobufCFieldDescriptor *
-protobuf_c_message_descriptor_get_field_by_name(
-	const ProtobufCMessageDescriptor *desc,
-	const char *name);
-
-/**
- * Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by
- * the tag value of the field.
- *
- * \param desc
- *      The `ProtobufCMessageDescriptor` object.
- * \param value
- *      The tag value of the field.
- * \return
- *      A `ProtobufCFieldDescriptor` object.
- * \retval NULL
- *      If not found.
- */
-PROTOBUF_C__API
-const ProtobufCFieldDescriptor *
-protobuf_c_message_descriptor_get_field(
-	const ProtobufCMessageDescriptor *desc,
-	unsigned value);
-
-/**
- * Determine the number of bytes required to store the serialised message.
- *
- * \param message
- *      The message object to serialise.
- * \return
- *      Number of bytes.
- */
-PROTOBUF_C__API
-size_t
-protobuf_c_message_get_packed_size(const ProtobufCMessage *message);
-
-/**
- * Serialise a message from its in-memory representation.
- *
- * This function stores the serialised bytes of the message in a pre-allocated
- * buffer.
- *
- * \param message
- *      The message object to serialise.
- * \param[out] out
- *      Buffer to store the bytes of the serialised message. This buffer must
- *      have enough space to store the packed message. Use
- *      protobuf_c_message_get_packed_size() to determine the number of bytes
- *      required.
- * \return
- *      Number of bytes stored in `out`.
- */
-PROTOBUF_C__API
-size_t
-protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out);
-
-/**
- * Serialise a message from its in-memory representation to a virtual buffer.
- *
- * This function calls the `append` method of a `ProtobufCBuffer` object to
- * consume the bytes generated by the serialiser.
- *
- * \param message
- *      The message object to serialise.
- * \param buffer
- *      The virtual buffer object.
- * \return
- *      Number of bytes passed to the virtual buffer.
- */
-PROTOBUF_C__API
-size_t
-protobuf_c_message_pack_to_buffer(
-	const ProtobufCMessage *message,
-	ProtobufCBuffer *buffer);
-
-/**
- * Unpack a serialised message into an in-memory representation.
- *
- * \param descriptor
- *      The message descriptor.
- * \param allocator
- *      `ProtobufCAllocator` to use for memory allocation. May be NULL to
- *      specify the default allocator.
- * \param len
- *      Length in bytes of the serialised message.
- * \param data
- *      Pointer to the serialised message.
- * \return
- *      An unpacked message object.
- * \retval NULL
- *      If an error occurred during unpacking.
- */
-PROTOBUF_C__API
-ProtobufCMessage *
-protobuf_c_message_unpack(
-	const ProtobufCMessageDescriptor *descriptor,
-	ProtobufCAllocator *allocator,
-	size_t len,
-	const uint8_t *data);
-
-/**
- * Free an unpacked message object.
- *
- * This function should be used to deallocate the memory used by a call to
- * protobuf_c_message_unpack().
- *
- * \param message
- *      The message object to free.
- * \param allocator
- *      `ProtobufCAllocator` to use for memory deallocation. May be NULL to
- *      specify the default allocator.
- */
-PROTOBUF_C__API
-void
-protobuf_c_message_free_unpacked(
-	ProtobufCMessage *message,
-	ProtobufCAllocator *allocator);
-
-/**
- * Check the validity of a message object.
- *
- * Makes sure all required fields (`PROTOBUF_C_LABEL_REQUIRED`) are present.
- * Recursively checks nested messages.
- *
- * \retval TRUE
- *      Message is valid.
- * \retval FALSE
- *      Message is invalid.
- */
-PROTOBUF_C__API
-protobuf_c_boolean
-protobuf_c_message_check(const ProtobufCMessage *);
-
-/** Message initialiser. */
-#define PROTOBUF_C_MESSAGE_INIT(descriptor) { descriptor, 0, NULL }
-
-/**
- * Initialise a message object from a message descriptor.
- *
- * \param descriptor
- *      Message descriptor.
- * \param message
- *      Allocated block of memory of size `descriptor->sizeof_message`.
- */
-PROTOBUF_C__API
-void
-protobuf_c_message_init(
-	const ProtobufCMessageDescriptor *descriptor,
-	void *message);
-
-/**
- * Free a service.
- *
- * \param service
- *      The service object to free.
- */
-PROTOBUF_C__API
-void
-protobuf_c_service_destroy(ProtobufCService *service);
-
-/**
- * Look up a `ProtobufCMethodDescriptor` by name.
- *
- * \param desc
- *      Service descriptor.
- * \param name
- *      Name of the method.
- *
- * \return
- *      A `ProtobufCMethodDescriptor` object.
- * \retval NULL
- *      If not found.
- */
-PROTOBUF_C__API
-const ProtobufCMethodDescriptor *
-protobuf_c_service_descriptor_get_method_by_name(
-	const ProtobufCServiceDescriptor *desc,
-	const char *name);
-
-/**
- * Initialise a `ProtobufCBufferSimple` object.
- */
-#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes)                   \
-{                                                                       \
-	{ protobuf_c_buffer_simple_append },                            \
-	sizeof(array_of_bytes),                                         \
-	0,                                                              \
-	(array_of_bytes),                                               \
-	0,                                                              \
-	NULL                                                            \
-}
-
-/**
- * Clear a `ProtobufCBufferSimple` object, freeing any allocated memory.
- */
-#define PROTOBUF_C_BUFFER_SIMPLE_CLEAR(simp_buf)                        \
-do {                                                                    \
-	if ((simp_buf)->must_free_data) {                               \
-		if ((simp_buf)->allocator != NULL)                      \
-			(simp_buf)->allocator->free(                    \
-				(simp_buf)->allocator,                  \
-				(simp_buf)->data);			\
-		else                                                    \
-			free((simp_buf)->data);                         \
-	}                                                               \
-} while (0)
-
-/**
- * The `append` method for `ProtobufCBufferSimple`.
- *
- * \param buffer
- *      The buffer object to append to. Must actually be a
- *      `ProtobufCBufferSimple` object.
- * \param len
- *      Number of bytes in `data`.
- * \param data
- *      Data to append.
- */
-PROTOBUF_C__API
-void
-protobuf_c_buffer_simple_append(
-	ProtobufCBuffer *buffer,
-	size_t len,
-	const unsigned char *data);
-
-PROTOBUF_C__API
-void
-protobuf_c_service_generated_init(
-	ProtobufCService *service,
-	const ProtobufCServiceDescriptor *descriptor,
-	ProtobufCServiceDestroy destroy);
-
-PROTOBUF_C__API
-void
-protobuf_c_service_invoke_internal(
-	ProtobufCService *service,
-	unsigned method_index,
-	const ProtobufCMessage *input,
-	ProtobufCClosure closure,
-	void *closure_data);
-
-/**@}*/
-
-PROTOBUF_C__END_DECLS
-
-#endif /* PROTOBUF_C_H */
--- a/libpurple/protocols/gg/lib/protobuf.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2012 Tomek Wasilczyk <www.wasilczyk.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file protobuf.c
- *
- * \brief Funkcje pomocnicze do obsługi formatu protocol buffers
- */
-
-#include "protobuf.h"
-
-#define GG_PROTOBUFF_UIN_MAXLEN 15
-struct _gg_protobuf_uin_buff
-{
-	char data[GG_PROTOBUFF_UIN_MAXLEN + 1 + 2];
-};
-
-void gg_protobuf_expected(struct gg_session *gs, const char *field_name,
-	uint32_t value, uint32_t expected)
-{
-	if (value == expected) {
-		return;
-	}
-	gg_debug_session(gs, GG_DEBUG_WARNING, "// gg_packet: field %s was "
-		"expected to be %#x, but its value was %#x\n",
-		field_name, expected, value);
-}
-
-int gg_protobuf_valid_chknull(struct gg_session *gs, const char *msg_name,
-	int isNull)
-{
-	if (isNull) {
-		gg_debug_session(gs, GG_DEBUG_ERROR, "// gg_protobuf: couldn't "
-			"unpack %s message\n", msg_name);
-	}
-	return !isNull;
-}
-
-int gg_protobuf_valid_chkunknown(struct gg_session *gs, const char *msg_name,
-	ProtobufCMessage *base)
-{
-	if (base->n_unknown_fields > 0) {
-		gg_debug_session(gs, GG_DEBUG_WARNING, "// gg_protobuf: message"
-		" %s had %d unknown field(s)\n",
-		msg_name, base->n_unknown_fields);
-	}
-	return 1;
-}
-
-int gg_protobuf_send_ex(struct gg_session *gs, struct gg_event *ge, int type,
-	void *msg, gg_protobuf_size_cb_t size_cb,
-	gg_protobuf_pack_cb_t pack_cb)
-{
-	void *buffer;
-	size_t len;
-	int succ = 1;
-	enum gg_failure_t failure;
-
-	len = size_cb(msg);
-	buffer = malloc(len);
-	if (buffer == NULL) {
-		gg_debug_session(gs, GG_DEBUG_ERROR, "// gg_protobuf_send: out "
-			"of memory - tried to allocate %" GG_SIZE_FMT
-			" bytes for %#x packet\n", len, type);
-		succ = 0;
-		failure = GG_FAILURE_INTERNAL;
-	} else {
-		pack_cb(msg, buffer);
-		succ = (-1 != gg_send_packet(gs, type, buffer, len, NULL));
-		free(buffer);
-		buffer = NULL;
-		if (!succ) {
-			failure = GG_FAILURE_WRITING;
-			gg_debug_session(gs, GG_DEBUG_ERROR,
-				"// gg_protobuf_send: sending packet %#x "
-				"failed. (errno=%d, %s)\n", type, errno,
-				strerror(errno));
-		}
-	}
-
-	if (!succ) {
-		gg_connection_failure(gs, ge, failure);
-	}
-
-	return succ;
-}
-
-void gg_protobuf_set_uin(ProtobufCBinaryData *dst, uin_t uin, gg_protobuf_uin_buff_t *buff)
-{
-	char *uin_str;
-	int uin_len;
-	static gg_protobuf_uin_buff_t static_buffer;
-
-	if (buff == NULL) {
-		buff = &static_buffer;
-	}
-
-	uin_str = buff->data + 2;
-	uin_len = snprintf(uin_str, GG_PROTOBUFF_UIN_MAXLEN + 1, "%u", uin);
-
-	buff->data[0] = 0x01; /* magic: 0x00 lub 0x01 */
-	buff->data[1] = uin_len;
-
-	dst->len = uin_len + 2;
-	dst->data = (uint8_t*)&buff->data;
-}
-
-uin_t gg_protobuf_get_uin(ProtobufCBinaryData uin_data)
-{
-	uint8_t magic;
-	size_t uin_len;
-	const char *uin_str;
-	uin_t uin;
-
-	magic = (uin_data.len > 0) ? uin_data.data[0] : 0;
-	uin_len = (uin_data.len > 1) ? uin_data.data[1] : 0;
-
-	if (uin_data.len != uin_len + 2 || uin_len > 10) {
-		gg_debug(GG_DEBUG_ERROR, "// gg_protobuf_get_uin: "
-			"invalid length\n");
-		return 0;
-	}
-	if (magic != 0) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_protobuf_get_uin: "
-			"unexpected magic value=%#x\n", magic);
-	}
-
-	uin_str = (char*)(uin_data.data + 2);
-	uin = gg_str_to_uin(uin_str, uin_len);
-
-	if (uin == 0) {
-		gg_debug(GG_DEBUG_ERROR, "// gg_protobuf_get_uin: "
-			"invalid uin\n");
-	}
-	return uin;
-}
--- a/libpurple/protocols/gg/lib/protobuf.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2012 Tomek Wasilczyk <www.wasilczyk.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_PROTOBUF_H
-#define LIBGADU_PROTOBUF_H
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-
-#include "config.h"
-#ifdef GG_CONFIG_HAVE_PROTOBUF_C
-#include <protobuf-c/protobuf-c.h>
-#else
-#include "protobuf-c.h"
-#endif
-
-#include "internal.h"
-#include "fileio.h"
-
-typedef size_t (*gg_protobuf_size_cb_t)(const void *message);
-typedef size_t (*gg_protobuf_pack_cb_t)(const void *message, uint8_t *out);
-
-typedef struct _gg_protobuf_uin_buff gg_protobuf_uin_buff_t;
-
-/* Ostatni warunek (msg != NULL) jest tylko po to, żeby uciszyć analizę
- * statyczną (zawiera się w pierwszym). */
-#define GG_PROTOBUF_VALID(gs, name, msg) \
-	(gg_protobuf_valid_chknull(gs, name, msg == NULL) && \
-	gg_protobuf_valid_chkunknown(gs, name, &msg->base) && \
-	msg != NULL)
-
-#define GG_PROTOBUF_SEND(gs, ge, packet_type, msg_type, msg) \
-	gg_protobuf_send_ex(gs, ge, packet_type, &msg, \
-		(gg_protobuf_size_cb_t) msg_type ## __get_packed_size, \
-		(gg_protobuf_pack_cb_t) msg_type ## __pack)
-
-void gg_protobuf_expected(struct gg_session *gs, const char *field_name,
-	uint32_t value, uint32_t expected);
-
-int gg_protobuf_valid_chknull(struct gg_session *gs, const char *msg_name,
-	int isNull);
-int gg_protobuf_valid_chkunknown(struct gg_session *gs, const char *msg_name,
-	ProtobufCMessage *base);
-
-int gg_protobuf_send_ex(struct gg_session *gs, struct gg_event *ge, int type,
-	void *msg, gg_protobuf_size_cb_t size_cb,
-	gg_protobuf_pack_cb_t pack_cb);
-
-void gg_protobuf_set_uin(ProtobufCBinaryData *dst, uin_t uin, gg_protobuf_uin_buff_t *buff);
-uin_t gg_protobuf_get_uin(ProtobufCBinaryData uin_data);
-
-#endif /* LIBGADU_PROTOBUF_H */
--- a/libpurple/protocols/gg/lib/protocol.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,411 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2009-2010 Jakub Zawadzki <darkjames@darkjames.ath.cx>
- *                          Bartłomiej Zimoń <uzi18@o2.pl>
- *                          Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_PROTOCOL_H
-#define LIBGADU_PROTOCOL_H
-
-#include "libgadu.h"
-
-#ifdef _WIN32
-#pragma pack(push, 1)
-#endif
-
-#define GG_LOGIN80BETA 0x0029
-
-#define GG_LOGIN80 0x0031
-
-#define GG_LOGIN105 0x0083
-
-#undef GG_FEATURE_STATUS80BETA
-#undef GG_FEATURE_MSG80
-#undef GG_FEATURE_STATUS80
-#define GG_FEATURE_STATUS80BETA		0x01
-#define GG_FEATURE_MSG80		0x02
-#define GG_FEATURE_STATUS80		0x05
-
-#define GG_DEFAULT_HOST_WHITE_LIST { "gadu-gadu.pl", "gg.pl", NULL }
-
-#define GG8_LANG	"pl"
-#define GG8_VERSION	"Gadu-Gadu Client Build "
-
-#define GG11_VERSION	"GG-Phoenix/"
-#define GG11_TARGET	" (BUILD;WINNT_x86-msvc;rv:11.0,pl;release;standard) (OS;Windows;Windows NT 6.1)"
-
-struct gg_login80 {
-	uint32_t uin;			/* mój numerek */
-	uint8_t language[2];		/* język: GG8_LANG */
-	uint8_t hash_type;		/* rodzaj hashowania hasła */
-	uint8_t hash[64];		/* hash hasła dopełniony zerami */
-	uint32_t status;		/* status na dzień dobry */
-	uint32_t flags;			/* flagi (przeznaczenie nieznane) */
-	uint32_t features;		/* opcje protokołu (GG8_FEATURES) */
-	uint32_t local_ip;		/* mój adres ip */
-	uint16_t local_port;		/* port, na którym słucham */
-	uint32_t external_ip;		/* zewnętrzny adres ip (???) */
-	uint16_t external_port;		/* zewnętrzny port (???) */
-	uint8_t image_size;		/* maksymalny rozmiar grafiki w KiB */
-	uint8_t dunno2;			/* 0x64 */
-} GG_PACKED;
-
-#define GG_LOGIN_HASH_TYPE_INVALID 0x0016
-
-#define GG_LOGIN80_OK 0x0035
-
-#define GG_LOGIN110_OK 0x009d
-
-/**
- * Logowanie powiodło się (pakiet \c GG_LOGIN80_OK)
- */
-struct gg_login80_ok {
-	uint32_t unknown1;		/* 0x00000001 */
-} GG_PACKED;
-
-/**
- * Logowanie nie powiodło się (pakiet \c GG_LOGIN80_FAILED)
- */
-#define GG_LOGIN80_FAILED 0x0043
-
-struct gg_login80_failed {
-	uint32_t unknown1;		/* 0x00000001 */
-} GG_PACKED;
-
-#define GG_NEW_STATUS80BETA 0x0028
-
-#define GG_NEW_STATUS80 0x0038
-
-/**
- * Zmiana stanu (pakiet \c GG_NEW_STATUS80)
- */
-struct gg_new_status80 {
-	uint32_t status;			/**< Nowy status */
-	uint32_t flags;				/**< flagi (nieznane przeznaczenie) */
-	uint32_t description_size;		/**< rozmiar opisu */
-} GG_PACKED;
-
-#define GG_NEW_STATUS105 0x0063
-
-#define GG_STATUS80BETA 0x002a
-#define GG_NOTIFY_REPLY80BETA 0x002b
-
-#define GG_STATUS80 0x0036
-#define GG_NOTIFY_REPLY80 0x0037
-
-struct gg_notify_reply80 {
-	uint32_t uin;		/* numerek plus flagi w najstarszym bajcie */
-	uint32_t status;	/* status danej osoby */
-	uint32_t features;	/* opcje protokołu */
-	uint32_t remote_ip;	/* adres IP bezpośrednich połączeń */
-	uint16_t remote_port;	/* port bezpośrednich połączeń */
-	uint8_t image_size;	/* maksymalny rozmiar obrazków w KB */
-	uint8_t unknown1;	/* 0x00 */
-	uint32_t flags;		/* flagi połączenia */
-	uint32_t descr_len;	/* rozmiar opisu */
-} GG_PACKED;
-
-#define GG_SEND_MSG80 0x002d
-
-struct gg_send_msg80 {
-	uint32_t recipient;
-	uint32_t seq;
-	uint32_t msgclass;
-	uint32_t offset_plain;
-	uint32_t offset_attr;
-} GG_PACKED;
-
-#define GG_RECV_MSG80 0x002e
-
-struct gg_recv_msg80 {
-	uint32_t sender;
-	uint32_t seq;
-	uint32_t time;
-	uint32_t msgclass;
-	uint32_t offset_plain;
-	uint32_t offset_attr;
-} GG_PACKED;
-
-#define GG_DISCONNECT_ACK 0x000d
-
-#define GG_RECV_MSG_ACK 0x0046
-
-struct gg_recv_msg_ack {
-	uint32_t seq;
-} GG_PACKED;
-
-#define GG_USER_DATA 0x0044
-
-struct gg_user_data {
-	uint32_t type;
-	uint32_t user_count;
-} GG_PACKED;
-
-struct gg_user_data_user {
-	uint32_t uin;
-	uint32_t attr_count;
-} GG_PACKED;
-
-#define GG_TYPING_NOTIFICATION 0x0059
-
-struct gg_typing_notification {
-	uint16_t length;
-	uint32_t uin;
-} GG_PACKED;
-
-#define GG_XML_ACTION 0x002c
-
-#define GG_RECV_OWN_MSG 0x005a
-
-#define GG_MULTILOGON_INFO 0x005b
-
-struct gg_multilogon_info {
-	uint32_t count;
-} GG_PACKED;
-
-struct gg_multilogon_info_item {
-	uint32_t addr;
-	uint32_t flags;
-	uint32_t features;
-	uint32_t logon_time;
-	gg_multilogon_id_t conn_id;
-	uint32_t unknown1;
-	uint32_t name_size;
-} GG_PACKED;
-
-#define GG_MULTILOGON_DISCONNECT 0x0062
-
-struct gg_multilogon_disconnect {
-	gg_multilogon_id_t conn_id;
-} GG_PACKED;
-
-#define GG_MSG_CALLBACK 0x02	/**< Żądanie zwrotnego połączenia bezpośredniego */
-
-#define GG_MSG_OPTION_CONFERENCE 0x01
-#define GG_MSG_OPTION_ATTRIBUTES 0x02
-#define GG_MSG_OPTION_IMAGE_REQUEST 0x04
-#define GG_MSG_OPTION_IMAGE_REPLY 0x05
-#define GG_MSG_OPTION_IMAGE_REPLY_MORE 0x06
-
-#define GG_DCC7_ABORT 0x0025
-
-struct gg_dcc7_abort {
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-	uint32_t uin_from;		/* numer nadawcy */
-	uint32_t uin_to;		/* numer odbiorcy */
-} GG_PACKED;
-
-#define GG_DCC7_ABORTED 0x0025
-
-struct gg_dcc7_aborted {
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-} GG_PACKED;
-
-#define GG_DCC7_VOICE_RETRIES 0x11	/* 17 powtorzen */
-
-#define GG_DCC7_RESERVED1		0xdeadc0de
-#define GG_DCC7_RESERVED2		0xdeadbeaf
-
-struct gg_dcc7_voice_auth {
-	uint8_t type;			/* 0x00 -> wysylanie ID
-					 * 0x01 -> potwierdzenie ID
-					 */
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-	uint32_t reserved1;		/* GG_DCC7_RESERVED1 */
-	uint32_t reserved2;		/* GG_DCC7_RESERVED2 */
-} GG_PACKED;
-
-/* Wyciszony mikrofon. Ten pakiet jest wysylany co 1s (jesli chcemy podtrzymac
- * polaczenie).
- */
-struct gg_dcc7_voice_nodata {
-	uint8_t type;			/* 0x02 */
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-	uint32_t reserved1;		/* GG_DCC7_RESERVED1 */
-	uint32_t reserved2;		/* GG_DCC7_RESERVED2 */
-} GG_PACKED;
-
-struct gg_dcc7_voice_data {
-	uint8_t type;			/* 0x03 */
-	uint32_t did;			/* XXX: co ile zwieksza sie u nas id pakietu [uzywac 0x28] */
-	uint32_t len;			/* rozmiar strukturki - 1 (sizeof(type)) */
-	uint32_t packet_id;		/* numerek pakietu */
-	uint32_t datalen;		/* rozmiar danych */
-	/* char data[]; */		/* ramki: albo gsm, albo speex, albo melp, albo inne. */
-} GG_PACKED;
-
-struct gg_dcc7_voice_init {
-	uint8_t type;			/* 0x04 */
-	uint32_t id;			/* nr kroku [0x1 - 0x5] */
-	uint32_t protocol;		/* XXX: wersja protokolu (0x29, 0x2a, 0x2b) */
-	uint32_t len;			/* rozmiar sizeof(protocol)+sizeof(len)+
-					 * sizeof(data) = 0x08 + sizeof(data) */
-	/* char data[]; */		/* reszta danych */
-} GG_PACKED;
-
-struct gg_dcc7_voice_init_confirm {
-	uint8_t type;			/* 0x05 */
-	uint32_t id;			/* id tego co potwierdzamy [0x1 - 0x5] */
-} GG_PACKED;
-
-#define GG_DCC7_RELAY_TYPE_SERVER 0x01	/* adres serwera, na który spytać o proxy */
-#define GG_DCC7_RELAY_TYPE_PROXY 0x08	/* adresy proxy, na które sie łączyć */
-
-#define GG_DCC7_RELAY_DUNNO1 0x02
-
-#define GG_DCC7_RELAY_REQUEST 0x0a
-
-struct gg_dcc7_relay_req {
-	uint32_t magic;			/* 0x0a */
-	uint32_t len;			/* długość całego pakietu */
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-	uint16_t type;			/* typ zapytania */
-	uint16_t dunno1;		/* 0x02 */
-} GG_PACKED;
-
-#define GG_DCC7_RELAY_REPLY_RCOUNT 0x02
-
-#define GG_DCC7_RELAY_REPLY 0x0b
-
-struct gg_dcc7_relay_reply {
-	uint32_t magic;			/* 0x0b */
-	uint32_t len;			/* długość całego pakietu */
-	uint32_t rcount;		/* ilość serwerów */
-} GG_PACKED;
-
-struct gg_dcc7_relay_reply_server {
-	uint32_t addr;		/* adres ip serwera */
-	uint16_t port;		/* port serwera */
-	uint8_t family;		/* rodzina adresów (na końcu?!) AF_INET=2 */
-} GG_PACKED;
-
-#define GG_DCC7_WELCOME_SERVER 0xc0debabe
-
-struct gg_dcc7_welcome_server {
-	uint32_t magic;			/* 0xc0debabe */
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-} GG_PACKED;
-
-struct gg_dcc7_welcome_p2p {
-	gg_dcc7_id_t id;		/* identyfikator połączenia */
-} GG_PACKED;
-
-#define GG_TIMEOUT_DISCONNECT 5	/**< Maksymalny czas oczekiwania na rozłączenie */
-
-#define GG_USERLIST100_VERSION 0x5c
-
-struct gg_userlist100_version {
-	uint32_t version;		/* numer wersji listy kontaktów */
-} GG_PACKED;
-
-#define GG_USERLIST100_REQUEST 0x0040
-
-struct gg_userlist100_request {
-	uint8_t type;			/* rodzaj żądania */
-	uint32_t version;		/* numer ostatniej znanej wersji listy kontaktów bądź 0 */
-	uint8_t format_type;		/* rodzaj żądanego typu formatu listy kontaktów */
-	uint8_t unknown1;		/* 0x01 */
-	/* char request[]; */
-} GG_PACKED;
-
-#define GG_USERLIST100_REPLY 0x41
-
-struct gg_userlist100_reply {
-	uint8_t type;			/* rodzaj odpowiedzi */
-	uint32_t version;		/* numer wersji listy kontaktów aktualnie przechowywanej przez serwer */
-	uint8_t format_type;		/* rodzaj przesyłanego typu formatu listy kontaktów */
-	uint8_t unknown1;		/* 0x01 */
-	/* char reply[]; */
-} GG_PACKED;
-
-struct gg_chat_create {
-	uint32_t seq;
-	uint32_t dummy;
-} GG_PACKED;
-
-struct gg_chat_invite {
-	uint64_t id;
-	uint32_t seq;
-	uint32_t participants_count;
-	/* struct {
-		uint32_t uin;
-		uint32_t dummy; (0x1e)
-	} participants[]; */
-} GG_PACKED;
-
-struct gg_chat_leave {
-	uint64_t id;
-	uint32_t seq;
-} GG_PACKED;
-
-struct gg_chat_created {
-	uint64_t id;
-	uint32_t seq;
-} GG_PACKED;
-
-struct gg_chat_invite_ack {
-	uint64_t id;
-	uint32_t seq;
-	uint32_t unknown1; /* 0x00 */
-	uint32_t unknown2; /* 0x10 */
-} GG_PACKED;
-
-struct gg_chat_left {
-	uint64_t id;
-	uint32_t uin;
-} GG_PACKED;
-
-#define GG_ADD_NOTIFY105 0x007b
-#define GG_REMOVE_NOTIFY105 0x007c
-#define GG_EVENT110 0x0084
-#define GG_IMTOKEN 0x008c
-#define GG_ACCESS_INFO 0x008f
-#define GG_NOTIFY105_FIRST 0x0077
-#define GG_NOTIFY105_LAST 0x0078
-#define GG_NOTIFY105_LIST_EMPTY 0x0079
-#define GG_PONG110 0x00a1
-#define GG_OPTIONS 0x009b
-
-#define GG_SEND_MSG110 0x007d
-#define GG_RECV_MSG110 0x007e
-#define GG_RECV_OWN_MSG110 0x0082
-#define GG_ACK110 0x0086
-#define GG_SEND_MSG_ACK110 0x0087
-
-#define GG_CHAT_INFO 0x0093
-#define GG_CHAT_INFO_UPDATE 0x009e
-#define GG_CHAT_CREATED 0x0045
-#define GG_CHAT_INVITE_ACK 0x0047
-#define GG_CHAT_RECV_MSG 0x0088
-#define GG_CHAT_RECV_OWN_MSG 0x008e
-#define GG_CHAT_CREATE 0x0047
-#define GG_CHAT_INVITE 0x0090
-#define GG_CHAT_LEAVE 0x0052
-#define GG_CHAT_LEFT 0x0066
-#define GG_CHAT_SEND_MSG 0x008d
-
-#define GG_UIN_INFO 0x007a
-#define GG_TRANSFER_INFO 0x00a0
-#define GG_MAGIC_NOTIFICATION 0x009f
-
-#ifdef _WIN32
-#pragma pack(pop)
-#endif
-
-#endif /* LIBGADU_PROTOCOL_H */
--- a/libpurple/protocols/gg/lib/pubdir.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,888 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2001-2006 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Dawid Jarosz <dawjar@poczta.onet.pl>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file pubdir.c
- *
- * \brief Obsługa katalogu publicznego
- */
-
-#include "network.h"
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libgadu.h"
-
-/**
- * Rejestruje nowego użytkownika.
- *
- * Wymaga wcześniejszego pobrania tokenu za pomocą \c gg_token().
- *
- * \param email Adres e-mail
- * \param password Hasło
- * \param tokenid Identyfikator tokenu
- * \param tokenval Zawartość tokenu
- * \param async Flaga połączenia asynchronicznego
- *
- * \return Struktura \c gg_http lub \c NULL w przypadku błędu
- *
- * \ingroup register
- */
-struct gg_http *gg_register3(const char *email, const char *password,
-	const char *tokenid, const char *tokenval, int async)
-{
-	struct gg_http *h;
-	char *__pwd, *__email, *__tokenid, *__tokenval, *form, *query;
-
-	if (!email || !password || !tokenid || !tokenval) {
-		gg_debug(GG_DEBUG_MISC, "=> register, NULL parameter\n");
-		errno = EFAULT;
-		return NULL;
-	}
-
-	__pwd = gg_urlencode(password);
-	__email = gg_urlencode(email);
-	__tokenid = gg_urlencode(tokenid);
-	__tokenval = gg_urlencode(tokenval);
-
-	if (!__pwd || !__email || !__tokenid || !__tokenval) {
-		gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form fields\n");
-		free(__pwd);
-		free(__email);
-		free(__tokenid);
-		free(__tokenval);
-		return NULL;
-	}
-
-	form = gg_saprintf("pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u",
-			__pwd, __email, __tokenid, __tokenval,
-			gg_http_hash("ss", email, password));
-
-	free(__pwd);
-	free(__email);
-	free(__tokenid);
-	free(__tokenval);
-
-	if (!form) {
-		gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form query\n");
-		return NULL;
-	}
-
-	gg_debug(GG_DEBUG_MISC, "=> register, %s\n", form);
-
-	query = gg_saprintf(
-		"Host: " GG_REGISTER_HOST "\r\n"
-		"Content-Type: application/x-www-form-urlencoded\r\n"
-		"User-Agent: " GG_HTTP_USERAGENT "\r\n"
-		"Content-Length: %d\r\n"
-		"Pragma: no-cache\r\n"
-		"\r\n"
-		"%s",
-		(int) strlen(form), form);
-
-	free(form);
-
-	if (!query) {
-		gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for query\n");
-		return NULL;
-	}
-
-	if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async,
-		"POST", "/appsvc/fmregister3.asp", query)))
-	{
-		gg_debug(GG_DEBUG_MISC, "=> register, gg_http_connect() failed mysteriously\n");
-		free(query);
-		return NULL;
-	}
-
-	h->type = GG_SESSION_REGISTER;
-
-	free(query);
-
-	h->callback = gg_pubdir_watch_fd;
-	h->destroy = gg_pubdir_free;
-
-	if (!async)
-		gg_pubdir_watch_fd(h);
-
-	return h;
-}
-
-#ifdef DOXYGEN
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Operacja będzie zakończona, gdy pole \c state będzie równe \c GG_STATE_DONE.
- * Jeśli wystąpi błąd, \c state będzie równe \c GG_STATE_ERROR, a kod błędu
- * znajdzie się w polu \c error.
- *
- * \note W rzeczywistości funkcja jest makrem rozwijanym do
- * \c gg_pubdir_watch_fd().
- *
- * \param h Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup register
- */
-int gg_register_watch_fd(struct gg_httpd *h)
-{
-	return gg_pubdir_watch_fd(h);
-}
-
-/**
- * Zwalnia zasoby po operacji.
- *
- * \note W rzeczywistości funkcja jest makrem rozwijanym do \c gg_pubdir_free().
- *
- * \param h Struktura połączenia
- *
- * \ingroup register
- */
-void gg_register_free(struct gg_http *h)
-{
-	return gg_pubdir_free(h);
-}
-
-#endif /* DOXYGEN */
-
-/**
- * Usuwa użytkownika.
- *
- * Wymaga wcześniejszego pobrania tokenu za pomocą \c gg_token().
- *
- * \param uin Numer Gadu-Gadu
- * \param password Hasło
- * \param tokenid Identyfikator tokenu
- * \param tokenval Zawartość tokenu
- * \param async Flaga połączenia asynchronicznego
- *
- * \return Struktura \c gg_http lub \c NULL w przypadku błędu
- *
- * \ingroup unregister
- */
-struct gg_http *gg_unregister3(uin_t uin, const char *password, const char *tokenid, const char *tokenval, int async)
-{
-	struct gg_http *h;
-	char *__fmpwd, *__pwd, *__tokenid, *__tokenval, *form, *query;
-
-	if (!password || !tokenid || !tokenval) {
-		gg_debug(GG_DEBUG_MISC, "=> unregister, NULL parameter\n");
-		errno = EFAULT;
-		return NULL;
-	}
-
-	__pwd = gg_saprintf("%d", rand());
-	__fmpwd = gg_urlencode(password);
-	__tokenid = gg_urlencode(tokenid);
-	__tokenval = gg_urlencode(tokenval);
-
-	if (!__fmpwd || !__pwd || !__tokenid || !__tokenval) {
-		gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form fields\n");
-		free(__pwd);
-		free(__fmpwd);
-		free(__tokenid);
-		free(__tokenval);
-		return NULL;
-	}
-
-	form = gg_saprintf("fmnumber=%d&fmpwd=%s&delete=1&pwd=%s&"
-		"email=deletedaccount@gadu-gadu.pl&tokenid=%s&tokenval=%s&"
-		"code=%u", uin, __fmpwd, __pwd, __tokenid, __tokenval,
-		gg_http_hash("ss", "deletedaccount@gadu-gadu.pl", __pwd));
-
-	free(__fmpwd);
-	free(__pwd);
-	free(__tokenid);
-	free(__tokenval);
-
-	if (!form) {
-		gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form query\n");
-		return NULL;
-	}
-
-	gg_debug(GG_DEBUG_MISC, "=> unregister, %s\n", form);
-
-	query = gg_saprintf(
-		"Host: " GG_REGISTER_HOST "\r\n"
-		"Content-Type: application/x-www-form-urlencoded\r\n"
-		"User-Agent: " GG_HTTP_USERAGENT "\r\n"
-		"Content-Length: %d\r\n"
-		"Pragma: no-cache\r\n"
-		"\r\n"
-		"%s",
-		(int) strlen(form), form);
-
-	free(form);
-
-	if (!query) {
-		gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for query\n");
-		return NULL;
-	}
-
-	if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async,
-		"POST", "/appsvc/fmregister3.asp", query)))
-	{
-		gg_debug(GG_DEBUG_MISC, "=> unregister, gg_http_connect() failed mysteriously\n");
-		free(query);
-		return NULL;
-	}
-
-	h->type = GG_SESSION_UNREGISTER;
-
-	free(query);
-
-	h->callback = gg_pubdir_watch_fd;
-	h->destroy = gg_pubdir_free;
-
-	if (!async)
-		gg_pubdir_watch_fd(h);
-
-	return h;
-}
-
-#ifdef DOXYGEN
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Operacja będzie zakończona, gdy pole \c state będzie równe \c GG_STATE_DONE.
- * Jeśli wystąpi błąd, \c state będzie równe \c GG_STATE_ERROR, a kod błędu
- * znajdzie się w polu \c error.
- *
- * \note W rzeczywistości funkcja jest makrem rozwijanym do
- * \c gg_pubdir_watch_fd().
- *
- * \param h Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup unregister
- */
-int gg_unregister_watch_fd(struct gg_httpd *h)
-{
-	return gg_pubdir_watch_fd(h);
-}
-
-/**
- * Zwalnia zasoby po operacji.
- *
- * \note W rzeczywistości funkcja jest makrem rozwijanym do \c gg_pubdir_free().
- *
- * \param h Struktura połączenia
- *
- * \ingroup unregister
- */
-void gg_unregister_free(struct gg_http *h)
-{
-	return gg_pubdir_free(h);
-}
-
-#endif /* DOXYGEN */
-
-/**
- * Zmienia hasło użytkownika.
- *
- * Wymaga wcześniejszego pobrania tokenu za pomocą \c gg_token().
- *
- * \param uin Numer Gadu-Gadu
- * \param email Adres e-mail
- * \param passwd Obecne hasło
- * \param newpasswd Nowe hasło
- * \param tokenid Identyfikator tokenu
- * \param tokenval Zawartość tokenu
- * \param async Flaga połączenia asynchronicznego
- *
- * \return Struktura \c gg_http lub \c NULL w przypadku błędu
- *
- * \ingroup passwd
- */
-struct gg_http *gg_change_passwd4(uin_t uin, const char *email,
-	const char *passwd, const char *newpasswd, const char *tokenid,
-	const char *tokenval, int async)
-{
-	struct gg_http *h;
-	char *form, *query, *__email, *__fmpwd, *__pwd, *__tokenid, *__tokenval;
-
-	if (!uin || !email || !passwd || !newpasswd || !tokenid || !tokenval) {
-		gg_debug(GG_DEBUG_MISC, "=> change, NULL parameter\n");
-		errno = EFAULT;
-		return NULL;
-	}
-
-	__fmpwd = gg_urlencode(passwd);
-	__pwd = gg_urlencode(newpasswd);
-	__email = gg_urlencode(email);
-	__tokenid = gg_urlencode(tokenid);
-	__tokenval = gg_urlencode(tokenval);
-
-	if (!__fmpwd || !__pwd || !__email || !__tokenid || !__tokenval) {
-		gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n");
-		free(__fmpwd);
-		free(__pwd);
-		free(__email);
-		free(__tokenid);
-		free(__tokenval);
-		return NULL;
-	}
-
-	if (!(form = gg_saprintf("fmnumber=%d&fmpwd=%s&pwd=%s&email=%s&"
-		"tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __email,
-		__tokenid, __tokenval, gg_http_hash("ss", email, newpasswd))))
-	{
-		gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n");
-		free(__fmpwd);
-		free(__pwd);
-		free(__email);
-		free(__tokenid);
-		free(__tokenval);
-
-		return NULL;
-	}
-
-	free(__fmpwd);
-	free(__pwd);
-	free(__email);
-	free(__tokenid);
-	free(__tokenval);
-
-	gg_debug(GG_DEBUG_MISC, "=> change, %s\n", form);
-
-	query = gg_saprintf(
-		"Host: " GG_REGISTER_HOST "\r\n"
-		"Content-Type: application/x-www-form-urlencoded\r\n"
-		"User-Agent: " GG_HTTP_USERAGENT "\r\n"
-		"Content-Length: %d\r\n"
-		"Pragma: no-cache\r\n"
-		"\r\n"
-		"%s",
-		(int) strlen(form), form);
-
-	free(form);
-
-	if (!query) {
-		gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for query\n");
-		return NULL;
-	}
-
-	if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async,
-		"POST", "/appsvc/fmregister3.asp", query)))
-	{
-		gg_debug(GG_DEBUG_MISC, "=> change, gg_http_connect() failed mysteriously\n");
-		free(query);
-		return NULL;
-	}
-
-	h->type = GG_SESSION_PASSWD;
-
-	free(query);
-
-	h->callback = gg_pubdir_watch_fd;
-	h->destroy = gg_pubdir_free;
-
-	if (!async)
-		gg_pubdir_watch_fd(h);
-
-	return h;
-}
-
-#ifdef DOXYGEN
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Operacja będzie zakończona, gdy pole \c state będzie równe \c GG_STATE_DONE.
- * Jeśli wystąpi błąd, \c state będzie równe \c GG_STATE_ERROR, a kod błędu
- * znajdzie się w polu \c error.
- *
- * \note W rzeczywistości funkcja jest makrem rozwijanym do
- * \c gg_pubdir_watch_fd().
- *
- * \param h Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup passwd
- */
-int gg_change_passwd_watch_fd(struct gg_httpd *h)
-{
-	return gg_pubdir_watch_fd(h);
-}
-
-/**
- * Zwalnia zasoby po operacji.
- *
- * \note W rzeczywistości funkcja jest makrem rozwijanym do \c gg_pubdir_free().
- *
- * \param h Struktura połączenia
- *
- * \ingroup passwd
- */
-void gg_change_passwd_free(struct gg_http *h)
-{
-	return gg_pubdir_free(h);
-}
-
-#endif /* DOXYGEN */
-
-/**
- * Wysyła hasło użytkownika na e-mail.
- *
- * Wymaga wcześniejszego pobrania tokenu za pomocą \c gg_token().
- *
- * \param uin Numer Gadu-Gadu
- * \param email Adres e-mail (podany przy rejestracji)
- * \param tokenid Identyfikator tokenu
- * \param tokenval Zawartość tokenu
- * \param async Flaga połączenia asynchronicznego
- *
- * \return Struktura \c gg_http lub \c NULL w przypadku błędu
- *
- * \ingroup remind
- */
-struct gg_http *gg_remind_passwd3(uin_t uin, const char *email, const char *tokenid, const char *tokenval, int async)
-{
-	struct gg_http *h;
-	char *form, *query, *__tokenid, *__tokenval, *__email;
-
-	if (!tokenid || !tokenval || !email) {
-		gg_debug(GG_DEBUG_MISC, "=> remind, NULL parameter\n");
-		errno = EFAULT;
-		return NULL;
-	}
-
-	__tokenid = gg_urlencode(tokenid);
-	__tokenval = gg_urlencode(tokenval);
-	__email = gg_urlencode(email);
-
-	if (!__tokenid || !__tokenval || !__email) {
-		gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n");
-		free(__tokenid);
-		free(__tokenval);
-		free(__email);
-		return NULL;
-	}
-
-	if (!(form = gg_saprintf("userid=%d&code=%u&tokenid=%s&tokenval=%s&"
-		"email=%s", uin, gg_http_hash("u", uin), __tokenid, __tokenval,
-		__email)))
-	{
-		gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n");
-		free(__tokenid);
-		free(__tokenval);
-		free(__email);
-		return NULL;
-	}
-
-	free(__tokenid);
-	free(__tokenval);
-	free(__email);
-
-	gg_debug(GG_DEBUG_MISC, "=> remind, %s\n", form);
-
-	query = gg_saprintf(
-		"Host: " GG_REMIND_HOST "\r\n"
-		"Content-Type: application/x-www-form-urlencoded\r\n"
-		"User-Agent: " GG_HTTP_USERAGENT "\r\n"
-		"Content-Length: %d\r\n"
-		"Pragma: no-cache\r\n"
-		"\r\n"
-		"%s",
-		(int) strlen(form), form);
-
-	free(form);
-
-	if (!query) {
-		gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for query\n");
-		return NULL;
-	}
-
-	if (!(h = gg_http_connect(GG_REMIND_HOST, GG_REMIND_PORT, async, "POST", "/appsvc/fmsendpwd3.asp", query))) {
-		gg_debug(GG_DEBUG_MISC, "=> remind, gg_http_connect() failed mysteriously\n");
-		free(query);
-		return NULL;
-	}
-
-	h->type = GG_SESSION_REMIND;
-
-	free(query);
-
-	h->callback = gg_pubdir_watch_fd;
-	h->destroy = gg_pubdir_free;
-
-	if (!async)
-		gg_pubdir_watch_fd(h);
-
-	return h;
-}
-
-#ifdef DOXYGEN
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Operacja będzie zakończona, gdy pole \c state będzie równe \c GG_STATE_DONE.
- * Jeśli wystąpi błąd, \c state będzie równe \c GG_STATE_ERROR, a kod błędu
- * znajdzie się w polu \c error.
- *
- * \note W rzeczywistości funkcja jest makrem rozwijanym do
- * \c gg_pubdir_watch_fd().
- *
- * \param h Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup remind
- */
-int gg_remind_watch_fd(struct gg_httpd *h)
-{
-	return gg_pubdir_watch_fd(h);
-}
-
-/**
- * Zwalnia zasoby po operacji.
- *
- * \note W rzeczywistości funkcja jest makrem rozwijanym do \c gg_pubdir_free().
- *
- * \param h Struktura połączenia
- *
- * \ingroup remind
- */
-void gg_remind_free(struct gg_http *h)
-{
-	return gg_pubdir_free(h);
-}
-
-#endif /* DOXYGEN */
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Operacja będzie zakończona, gdy pole \c state będzie równe \c GG_STATE_DONE.
- * Jeśli wystąpi błąd, \c state będzie równe \c GG_STATE_ERROR, a kod błędu
- * znajdzie się w polu \c error.
- *
- * \param h Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_pubdir_watch_fd(struct gg_http *h)
-{
-	struct gg_pubdir *p;
-	char *tmp;
-
-	if (!h) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (h->state == GG_STATE_ERROR) {
-		gg_debug(GG_DEBUG_MISC, "=> pubdir, watch_fd issued on failed session\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (h->state != GG_STATE_PARSING) {
-		if (gg_http_watch_fd(h) == -1) {
-			gg_debug(GG_DEBUG_MISC, "=> pubdir, http failure\n");
-			errno = EINVAL;
-			return -1;
-		}
-	}
-
-	if (h->state != GG_STATE_PARSING)
-		return 0;
-
-	h->state = GG_STATE_DONE;
-
-	if (!(h->data = p = malloc(sizeof(struct gg_pubdir)))) {
-		gg_debug(GG_DEBUG_MISC, "=> pubdir, not enough memory for results\n");
-		return -1;
-	}
-
-	p->success = 0;
-	p->uin = 0;
-
-	gg_debug(GG_DEBUG_MISC, "=> pubdir, let's parse \"%s\"\n", h->body);
-
-	if ((tmp = strstr(h->body, "Tokens okregisterreply_packet.reg.dwUserId="))) {
-		p->success = 1;
-		p->uin = strtol(tmp + sizeof("Tokens okregisterreply_packet.reg.dwUserId=") - 1, NULL, 0);
-		p->error = GG_PUBDIR_ERROR_NONE;
-		gg_debug(GG_DEBUG_MISC, "=> pubdir, success (okregisterreply, uin=%d)\n", p->uin);
-	} else if ((tmp = strstr(h->body, "success")) || (tmp = strstr(h->body, "results"))) {
-		p->success = 1;
-		if (tmp[7] == ':')
-			p->uin = strtol(tmp + 8, NULL, 0);
-		p->error = GG_PUBDIR_ERROR_NONE;
-		gg_debug(GG_DEBUG_MISC, "=> pubdir, success (uin=%d)\n", p->uin);
-	} else if (strncmp(h->body, "error1", 6) == 0 || strncmp(h->body, "error3", 6) == 0) {
-		p->error = GG_PUBDIR_ERROR_NEW_PASSWORD;
-		gg_debug(GG_DEBUG_MISC, "=> pubdir, invalid new password\n");
-	} else if (strncmp(h->body, "not authenticated", 17) == 0) {
-		p->error = GG_PUBDIR_ERROR_OLD_PASSWORD;
-		gg_debug(GG_DEBUG_MISC, "=> pubdir, invalid old password\n");
-	} else if (strncmp(h->body, "bad_tokenval", 12) == 0) {
-		p->error = GG_PUBDIR_ERROR_TOKEN;
-		gg_debug(GG_DEBUG_MISC, "=> pubdir, invalid token\n");
-	} else {
-		p->error = GG_PUBDIR_ERROR_OTHER;
-		gg_debug(GG_DEBUG_MISC, "=> pubdir, unknown error\n");
-	}
-
-	return 0;
-}
-
-/**
- * Zwalnia zasoby po operacji na katalogu publicznym.
- *
- * \param h Struktura połączenia
- */
-void gg_pubdir_free(struct gg_http *h)
-{
-	if (!h)
-		return;
-
-	free(h->data);
-	gg_http_free(h);
-}
-
-/**
- * Pobiera token do autoryzacji operacji na katalogu publicznym.
- *
- * Token jest niezbędny do tworzenia nowego i usuwania użytkownika,
- * zmiany hasła itd.
- *
- * \param async Flaga połączenia asynchronicznego
- *
- * \return Struktura \c gg_http lub \c NULL w przypadku błędu
- *
- * \ingroup token
- */
-struct gg_http *gg_token(int async)
-{
-	struct gg_http *h;
-	const char *query;
-
-	query = "Host: " GG_REGISTER_HOST "\r\n"
-		"Content-Type: application/x-www-form-urlencoded\r\n"
-		"User-Agent: " GG_HTTP_USERAGENT "\r\n"
-		"Content-Length: 0\r\n"
-		"Pragma: no-cache\r\n"
-		"\r\n";
-
-	if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/regtoken.asp", query))) {
-		gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
-		return NULL;
-	}
-
-	h->type = GG_SESSION_TOKEN;
-
-	h->callback = gg_token_watch_fd;
-	h->destroy = gg_token_free;
-
-	if (!async)
-		gg_token_watch_fd(h);
-
-	return h;
-}
-
-/**
- * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
- *
- * Operacja będzie zakończona, gdy pole \c state będzie równe \c GG_STATE_DONE.
- * Jeśli wystąpi błąd, \c state będzie równe \c GG_STATE_ERROR, a kod błędu
- * znajdzie się w polu \c error.
- *
- * \param h Struktura połączenia
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup token
- */
-int gg_token_watch_fd(struct gg_http *h)
-{
-	if (!h) {
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (h->state == GG_STATE_ERROR) {
-		gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (h->state != GG_STATE_PARSING) {
-		if (gg_http_watch_fd(h) == -1) {
-			gg_debug(GG_DEBUG_MISC, "=> token, http failure\n");
-			errno = EINVAL;
-			return -1;
-		}
-	}
-
-	if (h->state != GG_STATE_PARSING)
-		return 0;
-
-	/* jeśli h->data jest puste, to ściągaliśmy tokenid i url do niego,
-	 * ale jeśli coś tam jest, to znaczy, że mamy drugi etap polegający
-	 * na pobieraniu tokenu. */
-	if (!h->data) {
-		int width, height, length;
-		char *url = NULL, *tokenid = NULL, *path, *headers;
-		const char *host;
-		struct gg_http *h2;
-		struct gg_token *t;
-		size_t results_len;
-
-		gg_debug(GG_DEBUG_MISC, "=> token body \"%s\"\n", h->body);
-
-		results_len = h->body ? strlen(h->body) : 0;
-
-		if (h->body && (!(url = malloc(results_len)) || !(tokenid = malloc(results_len)))) {
-			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for results\n");
-			free(url);
-			return -1;
-		}
-
-		if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) {
-			gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n");
-			free(url);
-			free(tokenid);
-			errno = EINVAL;
-			return -1;
-		}
-
-		/* dostaliśmy tokenid i wszystkie niezbędne informacje,
-		 * więc pobierzmy obrazek z tokenem */
-
-		if (strncmp(url, "http://", 7)) {
-			path = gg_saprintf("%s?tokenid=%s", url, tokenid);
-			host = GG_REGISTER_HOST;
-		} else {
-			char *slash = strchr(url + 7, '/');
-
-			if (slash) {
-				path = gg_saprintf("%s?tokenid=%s", slash, tokenid);
-				*slash = 0;
-				host = url + 7;
-			} else {
-				gg_debug(GG_DEBUG_MISC, "=> token, url parsing failed\n");
-				free(url);
-				free(tokenid);
-				errno = EINVAL;
-				return -1;
-			}
-		}
-
-		if (!path) {
-			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
-			free(url);
-			free(tokenid);
-			return -1;
-		}
-
-		if (!(headers = gg_saprintf("Host: %s\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n", host))) {
-			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
-			free(path);
-			free(url);
-			free(tokenid);
-			return -1;
-		}
-
-		if (!(h2 = gg_http_connect(host, GG_REGISTER_PORT, h->async, "GET", path, headers))) {
-			gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
-			free(headers);
-			free(url);
-			free(path);
-			free(tokenid);
-			return -1;
-		}
-
-		free(headers);
-		free(path);
-		free(url);
-
-		gg_http_free_fields(h);
-
-		memcpy(h, h2, sizeof(struct gg_http));
-		free(h2);
-
-		h->type = GG_SESSION_TOKEN;
-
-		h->callback = gg_token_watch_fd;
-		h->destroy = gg_token_free;
-
-		if (!h->async)
-			gg_token_watch_fd(h);
-
-		if (!(h->data = t = malloc(sizeof(struct gg_token)))) {
-			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token data\n");
-			free(tokenid);
-			return -1;
-		}
-
-		t->width = width;
-		t->height = height;
-		t->length = length;
-		t->tokenid = tokenid;
-	} else {
-		/* obrazek mamy w h->body */
-		h->state = GG_STATE_DONE;
-	}
-
-	return 0;
-}
-
-/**
- * Zwalnia zasoby po operacji pobierania tokenu.
- *
- * \param h Struktura połączenia
- *
- * \ingroup token
- */
-void gg_token_free(struct gg_http *h)
-{
-	struct gg_token *t;
-
-	if (!h)
-		return;
-
-	if ((t = h->data))
-		free(t->tokenid);
-
-	free(h->data);
-	gg_http_free(h);
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
--- a/libpurple/protocols/gg/lib/pubdir50.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,555 +0,0 @@
-/*
- *  (C) Copyright 2003 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file pubdir50.c
- *
- * \brief Obsługa katalogu publicznego od wersji Gadu-Gadu 5.x
- *
- * \todo Zoptymalizować konwersję CP1250<->UTF8. Obecnie robiona jest
- * testowa konwersja, żeby poznać długość tekstu wynikowego.
- */
-
-#include "network.h"
-#include "strman.h"
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "libgadu.h"
-#include "internal.h"
-#include "encoding.h"
-
-/**
- * Tworzy nowe zapytanie katalogu publicznego.
- *
- * \param type Rodzaj zapytania
- *
- * \return Zmienna \c gg_pubdir50_t lub \c NULL w przypadku błędu.
- *
- * \ingroup pubdir50
- */
-gg_pubdir50_t gg_pubdir50_new(int type)
-{
-	gg_pubdir50_t res = malloc(sizeof(struct gg_pubdir50_s));
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_new(%d);\n", type);
-
-	if (!res) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_new() out of memory\n");
-		return NULL;
-	}
-
-	memset(res, 0, sizeof(struct gg_pubdir50_s));
-
-	res->type = type;
-
-	return res;
-}
-
-/**
- * \internal Dodaje lub zastępuje pole zapytania lub odpowiedzi katalogu
- * publicznego.
- *
- * \param req Zapytanie lub odpowiedź
- * \param num Numer wyniku odpowiedzi (0 dla zapytania)
- * \param field Nazwa pola
- * \param value Wartość pola
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_pubdir50_add_n(gg_pubdir50_t req, int num, const char *field, const char *value)
-{
-	struct gg_pubdir50_entry *tmp = NULL, *entry;
-	char *dupfield, *dupvalue;
-	int i;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_add_n(%p, %d, \"%s\", \"%s\");\n", req, num, field, value);
-
-	if (!(dupvalue = strdup(value))) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_add_n() out of memory\n");
-		return -1;
-	}
-
-	for (i = 0; i < req->entries_count; i++) {
-		if (req->entries[i].num != num || strcmp(req->entries[i].field, field))
-			continue;
-
-		free(req->entries[i].value);
-		req->entries[i].value = dupvalue;
-
-		return 0;
-	}
-
-	if (!(dupfield = strdup(field))) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_add_n() out of memory\n");
-		free(dupvalue);
-		return -1;
-	}
-
-	if (!(tmp = realloc(req->entries, sizeof(struct gg_pubdir50_entry) * (req->entries_count + 1)))) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_add_n() out of memory\n");
-		free(dupfield);
-		free(dupvalue);
-		return -1;
-	}
-
-	req->entries = tmp;
-
-	entry = &req->entries[req->entries_count];
-	entry->num = num;
-	entry->field = dupfield;
-	entry->value = dupvalue;
-
-	req->entries_count++;
-
-	return 0;
-}
-
-/**
- * Dodaje pole zapytania.
- *
- * \param req Zapytanie
- * \param field Nazwa pola
- * \param value Wartość pola
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup pubdir50
- */
-int gg_pubdir50_add(gg_pubdir50_t req, const char *field, const char *value)
-{
-	return gg_pubdir50_add_n(req, 0, field, value);
-}
-
-/**
- * Ustawia numer sekwencyjny zapytania.
- *
- * \param req Zapytanie
- * \param seq Numer sekwencyjny
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- *
- * \ingroup pubdir50
- */
-int gg_pubdir50_seq_set(gg_pubdir50_t req, uint32_t seq)
-{
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_seq_set(%p, %d);\n", req, seq);
-
-	if (!req) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_seq_set() invalid arguments\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	req->seq = seq;
-
-	return 0;
-}
-
-/**
- * Zwalnia zasoby po zapytaniu lub odpowiedzi katalogu publicznego.
- *
- * \param s Zapytanie lub odpowiedź
- *
- * \ingroup pubdir50
- */
-void gg_pubdir50_free(gg_pubdir50_t s)
-{
-	int i;
-
-	if (!s)
-		return;
-
-	for (i = 0; i < s->entries_count; i++) {
-		free(s->entries[i].field);
-		free(s->entries[i].value);
-	}
-
-	free(s->entries);
-	free(s);
-}
-
-/**
- * Wysyła zapytanie katalogu publicznego do serwera.
- *
- * \param sess Struktura sesji
- * \param req Zapytanie
- *
- * \return Numer sekwencyjny zapytania lub 0 w przypadku błędu
- *
- * \ingroup pubdir50
- */
-uint32_t gg_pubdir50(struct gg_session *sess, gg_pubdir50_t req)
-{
-	int i, size = 5;
-	uint32_t res;
-	char *buf, *p;
-	struct gg_pubdir50_request *r;
-
-	gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_pubdir50(%p, %p);\n", sess, req);
-
-	if (!sess || !req) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_pubdir50() invalid arguments\n");
-		errno = EFAULT;
-		return 0;
-	}
-
-	if (sess->state != GG_STATE_CONNECTED) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_pubdir50() not connected\n");
-		errno = ENOTCONN;
-		return 0;
-	}
-
-	for (i = 0; i < req->entries_count; i++) {
-		/* wyszukiwanie bierze tylko pierwszy wpis */
-		if (req->entries[i].num)
-			continue;
-
-		if (sess->encoding == GG_ENCODING_CP1250) {
-			size += strlen(req->entries[i].field) + 1;
-			size += strlen(req->entries[i].value) + 1;
-		} else {
-			char *tmp;
-
-			/* XXX \todo zoptymalizować */
-			tmp = gg_encoding_convert(req->entries[i].field, sess->encoding, GG_ENCODING_CP1250, -1, -1);
-
-			if (tmp == NULL)
-				return -1;
-
-			size += strlen(tmp) + 1;
-
-			free(tmp);
-
-			/* XXX \todo zoptymalizować */
-			tmp = gg_encoding_convert(req->entries[i].value, sess->encoding, GG_ENCODING_CP1250, -1, -1);
-
-			if (tmp == NULL)
-				return -1;
-
-			size += strlen(tmp) + 1;
-
-			free(tmp);
-		}
-	}
-
-	if (!(buf = malloc(size))) {
-		gg_debug_session(sess, GG_DEBUG_MISC, "// gg_pubdir50() out of memory (%d bytes)\n", size);
-		return 0;
-	}
-
-	if (!req->seq)
-		req->seq = time(NULL);
-
-	res = req->seq;
-
-	r = (struct gg_pubdir50_request*) buf;
-	r->type = req->type;
-	r->seq = gg_fix32(req->seq);
-
-	for (i = 0, p = buf + 5; i < req->entries_count; i++) {
-		if (req->entries[i].num)
-			continue;
-
-		if (sess->encoding == GG_ENCODING_CP1250) {
-			strcpy(p, req->entries[i].field);
-			p += strlen(p) + 1;
-
-			strcpy(p, req->entries[i].value);
-			p += strlen(p) + 1;
-		} else {
-			char *tmp;
-
-			/* XXX \todo zoptymalizować */
-			tmp = gg_encoding_convert(req->entries[i].field, sess->encoding, GG_ENCODING_CP1250, -1, -1);
-
-			if (tmp == NULL) {
-				free(buf);
-				return -1;
-			}
-
-			strcpy(p, tmp);
-			p += strlen(tmp) + 1;
-			free(tmp);
-
-			/* XXX \todo zoptymalizować */
-			tmp = gg_encoding_convert(req->entries[i].value, sess->encoding, GG_ENCODING_CP1250, -1, -1);
-
-
-			if (tmp == NULL) {
-				free(buf);
-				return -1;
-			}
-
-			strcpy(p, tmp);
-			p += strlen(tmp) + 1;
-			free(tmp);
-		}
-	}
-
-	if (gg_send_packet(sess, GG_PUBDIR50_REQUEST, buf, size, NULL, 0) == -1)
-		res = 0;
-
-	free(buf);
-
-	return res;
-}
-
-/*
- * \internal Analizuje przychodzący pakiet odpowiedzi i zapisuje wynik
- * w strukturze \c gg_event.
- *
- * \param sess Struktura sesji
- * \param e Struktura zdarzenia
- * \param packet Pakiet odpowiedzi
- * \param length Długość pakietu odpowiedzi
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_pubdir50_handle_reply_sess(struct gg_session *sess, struct gg_event *e, const char *packet, int length)
-{
-	const char *end = packet + length, *p;
-	const struct gg_pubdir50_reply *r = (const struct gg_pubdir50_reply*) packet;
-	gg_pubdir50_t res;
-	int num = 0;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_handle_reply_sess(%p, %p, %p, %d);\n", sess, e, packet, length);
-
-	if (!sess || !e || !packet) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() invalid arguments\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	if (length < 5) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() packet too short\n");
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (!(res = gg_pubdir50_new(r->type))) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() unable to allocate reply\n");
-		return -1;
-	}
-
-	e->event.pubdir50 = res;
-
-	res->seq = gg_fix32(r->seq);
-
-	switch (res->type) {
-		case GG_PUBDIR50_READ:
-			e->type = GG_EVENT_PUBDIR50_READ;
-			break;
-
-		case GG_PUBDIR50_WRITE:
-			e->type = GG_EVENT_PUBDIR50_WRITE;
-			break;
-
-		default:
-			e->type = GG_EVENT_PUBDIR50_SEARCH_REPLY;
-			break;
-	}
-
-	/* brak wyników? */
-	if (length == 5)
-		return 0;
-
-	/* pomiń początek odpowiedzi */
-	p = packet + 5;
-
-	while (p < end) {
-		const char *field, *value;
-
-		field = p;
-
-		/* sprawdź, czy nie mamy podziału na kolejne pole */
-		if (!*field) {
-			num++;
-			field++;
-		}
-
-		value = NULL;
-
-		for (p = field; p < end; p++) {
-			/* jeśli mamy koniec tekstu... */
-			if (!*p) {
-				/* ...i jeszcze nie mieliśmy wartości pola to
-				 * wiemy, że po tym zerze jest wartość... */
-				if (!value)
-					value = p + 1;
-				else
-					/* ...w przeciwym wypadku koniec
-					 * wartości i możemy wychodzić
-					 * grzecznie z pętli */
-					break;
-			}
-		}
-
-		/* sprawdźmy, czy pole nie wychodzi poza pakiet, żeby nie
-		 * mieć segfaultów, jeśli serwer przestanie zakańczać pakietów
-		 * przez \0 */
-
-		if (p == end) {
-			gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() premature end of packet\n");
-			goto failure;
-		}
-
-		p++;
-
-		/* jeśli dostaliśmy namier na następne wyniki, to znaczy że
-		 * mamy koniec wyników i nie jest to kolejna osoba. */
-		if (!strcasecmp(field, "nextstart")) {
-			res->next = value ? atoi(value) : 0;
-			num--;
-		} else {
-			if (sess->encoding == GG_ENCODING_CP1250) {
-				if (gg_pubdir50_add_n(res, num, field, value) == -1)
-					goto failure;
-			} else {
-				char *tmp;
-
-				tmp = gg_encoding_convert(value, GG_ENCODING_CP1250, sess->encoding, -1, -1);
-
-				if (tmp == NULL)
-					goto failure;
-
-				if (gg_pubdir50_add_n(res, num, field, tmp) == -1) {
-					free(tmp);
-					goto failure;
-				}
-
-				free(tmp);
-			}
-		}
-	}
-
-	res->count = num + 1;
-
-	return 0;
-
-failure:
-	gg_pubdir50_free(res);
-	return -1;
-}
-
-/**
- * Pobiera pole z odpowiedzi katalogu publicznego.
- *
- * \param res Odpowiedź
- * \param num Numer wyniku odpowiedzi
- * \param field Nazwa pola (wielkość liter nie ma znaczenia)
- *
- * \return Wartość pola lub \c NULL jeśli nie znaleziono
- *
- * \ingroup pubdir50
- */
-const char *gg_pubdir50_get(gg_pubdir50_t res, int num, const char *field)
-{
-	char *value = NULL;
-	int i;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_get(%p, %d, \"%s\");\n", res, num, field);
-
-	if (!res || num < 0 || !field) {
-		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_get() invalid arguments\n");
-		errno = EINVAL;
-		return NULL;
-	}
-
-	for (i = 0; i < res->entries_count; i++) {
-		if (res->entries[i].num == num && !strcasecmp(res->entries[i].field, field)) {
-			value = res->entries[i].value;
-			break;
-		}
-	}
-
-	return value;
-}
-
-/**
- * Zwraca liczbę wyników odpowiedzi.
- *
- * \param res Odpowiedź
- *
- * \return Liczba wyników lub -1 w przypadku błędu
- *
- * \ingroup pubdir50
- */
-int gg_pubdir50_count(gg_pubdir50_t res)
-{
-	return (!res) ? -1 : res->count;
-}
-
-/**
- * Zwraca rodzaj zapytania lub odpowiedzi.
- *
- * \param res Zapytanie lub odpowiedź
- *
- * \return Rodzaj lub -1 w przypadku błędu
- *
- * \ingroup pubdir50
- */
-int gg_pubdir50_type(gg_pubdir50_t res)
-{
-	return (!res) ? -1 : res->type;
-}
-
-/**
- * Zwraca numer, od którego należy rozpocząc kolejne wyszukiwanie.
- *
- * Dłuższe odpowiedzi katalogu publicznego są wysyłane przez serwer
- * w mniejszych paczkach. Po otrzymaniu odpowiedzi, jeśli numer kolejnego
- * wyszukiwania jest większy od zera, dalsze wyniki można otrzymać przez
- * wywołanie kolejnego zapytania z określonym numerem początkowym.
- *
- * \param res Odpowiedź
- *
- * \return Numer lub -1 w przypadku błędu
- *
- * \ingroup pubdir50
- */
-uin_t gg_pubdir50_next(gg_pubdir50_t res)
-{
-	return (!res) ? (unsigned) -1 : res->next;
-}
-
-/**
- * Zwraca numer sekwencyjny zapytania lub odpowiedzi.
- *
- * \param res Zapytanie lub odpowiedź
- *
- * \return Numer sekwencyjny lub -1 w przypadku błędu
- *
- * \ingroup pubdir50
- */
-uint32_t gg_pubdir50_seq(gg_pubdir50_t res)
-{
-	return (!res) ? (unsigned) -1 : res->seq;
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
--- a/libpurple/protocols/gg/lib/resolver.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1132 +0,0 @@
-/*
- *  (C) Copyright 2001-2009 Wojtek Kaniewski <wojtekka@irc.pl>
- *                          Robert J. Woźny <speedy@ziew.org>
- *                          Arkadiusz Miśkiewicz <arekm@pld-linux.org>
- *                          Tomasz Chiliński <chilek@chilan.com>
- *                          Adam Wysocki <gophi@ekg.chmurka.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file resolver.c
- *
- * \brief Funkcje rozwiązywania nazw
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "strman.h"
-#include "network.h"
-#include "config.h"
-#include "libgadu.h"
-#include "resolver.h"
-#include "session.h"
-
-#ifdef GG_CONFIG_HAVE_FORK
-#include <sys/wait.h>
-#include <signal.h>
-#endif
-
-/** Sposób rozwiązywania nazw serwerów */
-static gg_resolver_t gg_global_resolver_type = GG_RESOLVER_DEFAULT;
-
-/** Funkcja rozpoczynająca rozwiązywanie nazwy */
-static int (*gg_global_resolver_start)(int *fd, void **private_data, const char *hostname);
-
-/** Funkcja zwalniająca zasoby po rozwiązaniu nazwy */
-static void (*gg_global_resolver_cleanup)(void **private_data, int force);
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-
-#include <pthread.h>
-
-/**
- * \internal Funkcja pomocnicza zwalniająca zasoby po rozwiązywaniu nazwy
- * w wątku.
- *
- * \note Funkcja nie powinna być statyczna, ponieważ zostanie potraktowana
- * jako inline i kompilator może "zoptymalizować" jej wywołanie w funkcji
- * pthread_cleanup_pop().
- *
- * \param data Wskaźnik na wskaźnik bufora zaalokowanego w wątku
- */
-void gg_resolver_cleaner(void *data)
-{
-	void **buf_ptr = (void **) data;
-
-	if (buf_ptr != NULL) {
-		free(*buf_ptr);
-		*buf_ptr = NULL;
-	}
-}
-
-#endif /* GG_CONFIG_HAVE_PTHREAD */
-
-/**
- * \internal Odpowiednik \c gethostbyname zapewniający współbieżność.
- *
- * Jeśli dany system dostarcza \c gethostbyname_r, używa się tej wersji, jeśli
- * nie, to zwykłej \c gethostbyname. Wynikiem jest tablica adresów zakończona
- * wartością INADDR_NONE, którą należy zwolnić po użyciu.
- *
- * \param hostname Nazwa serwera
- * \param result Wskaźnik na wskaźnik z tablicą adresów zakończoną INADDR_NONE
- * \param count Wskaźnik na zmienną, do ktorej zapisze się liczbę wyników
- * \param pthread Flaga blokowania unicestwiania wątku podczas alokacji pamięci
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_gethostbyname_real(const char *hostname, struct in_addr **result, unsigned int *count, int pthread)
-{
-#ifdef GG_CONFIG_HAVE_GETHOSTBYNAME_R
-	char *buf = NULL;
-	char *new_buf = NULL;
-	struct hostent he;
-	struct hostent *he_ptr = NULL;
-	size_t buf_len = 1024;
-	int res = -1;
-	int h_errnop;
-	int ret = 0;
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	int old_state;
-#endif
-
-	if (result == NULL) {
-		errno = EINVAL;
-		return -1;
-	}
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	pthread_cleanup_push(gg_resolver_cleaner, &buf);
-
-	if (pthread)
-		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
-	buf = malloc(buf_len);
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	if (pthread)
-		pthread_setcancelstate(old_state, NULL);
-#endif
-
-	if (buf != NULL) {
-		while (1) {
-#ifndef sun
-			ret = gethostbyname_r(hostname, &he, buf, buf_len, &he_ptr, &h_errnop);
-			if (ret != ERANGE)
-				break;
-#else
-			he_ptr = gethostbyname_r(hostname, &he, buf, buf_len, &h_errnop);
-			if (he_ptr != NULL || errno != ERANGE)
-				break;
-#endif
-
-			buf_len *= 2;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-			if (pthread)
-				pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
-			new_buf = realloc(buf, buf_len);
-
-			if (new_buf != NULL)
-				buf = new_buf;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-			if (pthread)
-				pthread_setcancelstate(old_state, NULL);
-#endif
-
-			if (new_buf == NULL) {
-				ret = ENOMEM;
-				break;
-			}
-		}
-
-		if (ret == 0 && he_ptr != NULL && he_ptr->h_addr_list[0] != NULL) {
-			int i;
-
-			/* Policz liczbę adresów */
-
-			for (i = 0; he_ptr->h_addr_list[i] != NULL; i++);
-
-			/* Zaalokuj */
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-			if (pthread)
-				pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
-			*result = malloc((i + 1) * sizeof(struct in_addr));
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-			if (pthread)
-				pthread_setcancelstate(old_state, NULL);
-#endif
-
-			if (*result != NULL) {
-				/* Kopiuj */
-
-				for (i = 0; he_ptr->h_addr_list[i] != NULL; i++)
-					memcpy(&((*result)[i]), he_ptr->h_addr_list[i], sizeof(struct in_addr));
-
-				(*result)[i].s_addr = INADDR_NONE;
-
-				*count = i;
-
-				res = 0;
-			} else
-				res = -1;
-		}
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-		if (pthread)
-			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
-		free(buf);
-		buf = NULL;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-		if (pthread)
-			pthread_setcancelstate(old_state, NULL);
-#endif
-	}
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	pthread_cleanup_pop(0);
-#endif
-
-	return res;
-#else /* GG_CONFIG_HAVE_GETHOSTBYNAME_R */
-	struct hostent *he;
-	int i;
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	int old_state;
-#endif
-
-	if (result == NULL || count == NULL) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	he = gethostbyname(hostname);
-
-	if (he == NULL || he->h_addr_list[0] == NULL)
-		return -1;
-
-	/* Policz liczbę adresów */
-
-	for (i = 0; he->h_addr_list[i] != NULL; i++);
-
-	/* Zaalokuj */
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	if (pthread)
-		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
-	*result = malloc((i + 1) * sizeof(struct in_addr));
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	if (pthread)
-		pthread_setcancelstate(old_state, NULL);
-#endif
-
-	if (*result == NULL)
-		return -1;
-
-	/* Kopiuj */
-
-	for (i = 0; he->h_addr_list[i] != NULL; i++)
-		memcpy(&((*result)[i]), he->h_addr_list[i], sizeof(struct in_addr));
-
-	(*result)[i].s_addr = INADDR_NONE;
-
-	*count = i;
-
-	return 0;
-#endif /* GG_CONFIG_HAVE_GETHOSTBYNAME_R */
-}
-
-/**
- * \internal Rozwiązuje nazwę i zapisuje wynik do podanego gniazda.
- *
- * \note Użycie logowania w tej funkcji może mieć negatywny wpływ na
- * aplikacje jednowątkowe korzystające.
- *
- * \param fd Deskryptor gniazda
- * \param hostname Nazwa serwera
- * \param pthread Flaga blokowania unicestwiania wątku podczas alokacji pamięci
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_resolver_run(int fd, const char *hostname, int pthread)
-{
-	struct in_addr addr_ip[2], *addr_list = NULL;
-	unsigned int addr_count;
-	int res = 0;
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	int old_state;
-#endif
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	pthread_cleanup_push(gg_resolver_cleaner, &addr_list);
-#endif
-
-	if ((addr_ip[0].s_addr = inet_addr(hostname)) == INADDR_NONE) {
-		if (gg_gethostbyname_real(hostname, &addr_list, &addr_count, pthread) == -1) {
-#ifdef GG_CONFIG_HAVE_PTHREAD
-			if (pthread)
-				pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
-			free(addr_list);
-			addr_list = NULL;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-			if (pthread)
-				pthread_setcancelstate(old_state, NULL);
-#endif
-
-			addr_count = 0;
-			/* addr_ip[0] już zawiera INADDR_NONE */
-		}
-	} else {
-		addr_ip[1].s_addr = INADDR_NONE;
-		addr_count = 1;
-	}
-
-	if (send(fd, addr_list != NULL ? addr_list : addr_ip,
-		(addr_count + 1) * sizeof(struct in_addr), 0) !=
-		(int)((addr_count + 1) * sizeof(struct in_addr)))
-	{
-		res = -1;
-	}
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	if (pthread)
-		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
-	free(addr_list);
-	addr_list = NULL;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-	if (pthread)
-		pthread_setcancelstate(old_state, NULL);
-
-	pthread_cleanup_pop(0);
-#endif
-
-	return res;
-}
-
-/**
- * \internal Odpowiednik \c gethostbyname zapewniający współbieżność.
- *
- * Jeśli dany system dostarcza \c gethostbyname_r, używa się tej wersji, jeśli
- * nie, to zwykłej \c gethostbyname. Funkcja służy do zachowania zgodności
- * ABI i służy do pobierania tylko pierwszego adresu -- pozostałe mogą
- * zostać zignorowane przez aplikację.
- *
- * \param hostname Nazwa serwera
- *
- * \return Zaalokowana struktura \c in_addr lub NULL w przypadku błędu.
- */
-struct in_addr *gg_gethostbyname(const char *hostname)
-{
-	struct in_addr *result;
-	unsigned int count;
-
-	if (gg_gethostbyname_real(hostname, &result, &count, 0) == -1)
-		return NULL;
-
-	return result;
-}
-
-#ifdef GG_CONFIG_HAVE_FORK
-
-/**
- * \internal Struktura przekazywana do wątku rozwiązującego nazwę.
- */
-struct gg_resolver_fork_data {
-	int pid;		/*< Identyfikator procesu */
-};
-
-/**
- * \internal Rozwiązuje nazwę serwera w osobnym procesie.
- *
- * Połączenia asynchroniczne nie mogą blokować procesu w trakcie rozwiązywania
- * nazwy serwera. W tym celu tworzona jest para gniazd, nowy proces i dopiero
- * w nim przeprowadzane jest rozwiązywanie nazwy. Deskryptor gniazda do odczytu
- * zapisuje się w strukturze sieci i czeka na dane w postaci struktury
- * \c in_addr. Jeśli nie znaleziono nazwy, zwracana jest \c INADDR_NONE.
- *
- * \param fd Wskaźnik na zmienną, gdzie zostanie umieszczony deskryptor gniazda
- * \param priv_data Wskaźnik na zmienną, gdzie zostanie umieszczony wskaźnik
- *                  do numeru procesu potomnego rozwiązującego nazwę
- * \param hostname Nazwa serwera do rozwiązania
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_resolver_fork_start(int *fd, void **priv_data, const char *hostname)
-{
-	struct gg_resolver_fork_data *data = NULL;
-	int pipes[2], new_errno;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_resolver_fork_start(%p, %p, \"%s\");\n", fd, priv_data, hostname);
-
-	if (fd == NULL || priv_data == NULL || hostname == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_fork_start() invalid arguments\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	data = malloc(sizeof(struct gg_resolver_fork_data));
-
-	if (data == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_fork_start() out of memory for resolver data\n");
-		return -1;
-	}
-
-	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pipes) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_fork_start() unable "
-			"to create pipes (errno=%d, %s)\n",
-			errno, strerror(errno));
-		free(data);
-		return -1;
-	}
-
-	data->pid = fork();
-
-	if (data->pid == -1) {
-		new_errno = errno;
-		goto cleanup;
-	}
-
-	if (data->pid == 0) {
-		int status;
-
-		close(pipes[0]);
-
-		status = (gg_resolver_run(pipes[1], hostname, 0) == -1) ? 1 : 0;
-
-#ifdef HAVE__EXIT
-		_exit(status);
-#else
-		exit(status);
-#endif
-	}
-
-	close(pipes[1]);
-
-	gg_debug(GG_DEBUG_MISC, "// gg_resolver_fork_start() %p\n", data);
-
-	*fd = pipes[0];
-	*priv_data = data;
-
-	return 0;
-
-cleanup:
-	free(data);
-	close(pipes[0]);
-	close(pipes[1]);
-
-	errno = new_errno;
-
-	return -1;
-}
-
-/**
- * \internal Usuwanie zasobów po procesie rozwiązywaniu nazwy.
- *
- * Funkcja wywoływana po zakończeniu rozwiązanywania nazwy lub przy zwalnianiu
- * zasobów sesji podczas rozwiązywania nazwy.
- *
- * \param priv_data Wskaźnik na zmienną przechowującą wskaźnik do prywatnych
- *                  danych
- * \param force Flaga usuwania zasobów przed zakończeniem działania
- */
-static void gg_resolver_fork_cleanup(void **priv_data, int force)
-{
-	struct gg_resolver_fork_data *data;
-
-	if (priv_data == NULL || *priv_data == NULL)
-		return;
-
-	data = (struct gg_resolver_fork_data*) *priv_data;
-	*priv_data = NULL;
-
-	if (force)
-		kill(data->pid, SIGKILL);
-
-	/* we don't care about child's exit status, just want to clean it up */
-	(void)waitpid(data->pid, NULL, WNOHANG);
-
-	free(data);
-}
-
-#endif /* GG_CONFIG_HAVE_FORK */
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-
-/**
- * \internal Struktura przekazywana do wątku rozwiązującego nazwę.
- */
-struct gg_resolver_pthread_data {
-	pthread_t thread;	/*< Identyfikator wątku */
-	char *hostname;		/*< Nazwa serwera */
-	int wfd;		/*< Deskryptor do zapisu */
-};
-
-/**
- * \internal Usuwanie zasobów po wątku rozwiązywaniu nazwy.
- *
- * Funkcja wywoływana po zakończeniu rozwiązanywania nazwy lub przy zwalnianiu
- * zasobów sesji podczas rozwiązywania nazwy.
- *
- * \param priv_data Wskaźnik na zmienną przechowującą wskaźnik do prywatnych
- *                  danych
- * \param force Flaga usuwania zasobów przed zakończeniem działania
- */
-static void gg_resolver_pthread_cleanup(void **priv_data, int force)
-{
-	struct gg_resolver_pthread_data *data;
-
-	if (priv_data == NULL || *priv_data == NULL)
-		return;
-
-	data = (struct gg_resolver_pthread_data *) *priv_data;
-	*priv_data = NULL;
-
-	if (force)
-		pthread_cancel(data->thread);
-
-	pthread_join(data->thread, NULL);
-
-	close(data->wfd);
-	free(data->hostname);
-	free(data);
-}
-
-/**
- * \internal Wątek rozwiązujący nazwę.
- *
- * \param arg Wskaźnik na strukturę \c gg_resolver_pthread_data
- */
-static void *gg_resolver_pthread_thread(void *arg)
-{
-	struct gg_resolver_pthread_data *data = arg;
-
-	if (gg_resolver_run(data->wfd, data->hostname, 1) == -1)
-		pthread_exit((void*) -1);
-	else
-		pthread_exit(NULL);
-
-	return NULL;	/* żeby kompilator nie marudził */
-}
-
-/**
- * \internal Rozwiązuje nazwę serwera w osobnym wątku.
- *
- * Funkcja działa analogicznie do \c gg_resolver_fork_start(), z tą różnicą,
- * że działa na wątkach, nie procesach. Jest dostępna wyłącznie gdy podczas
- * kompilacji włączono odpowiednią opcję.
- *
- * \param fd Wskaźnik na zmienną, gdzie zostanie umieszczony deskryptor gniazda
- * \param priv_data Wskaźnik na zmienną, gdzie zostanie umieszczony wskaźnik
- *                  do prywatnych danych wątku rozwiązującego nazwę
- * \param hostname Nazwa serwera do rozwiązania
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_resolver_pthread_start(int *fd, void **priv_data, const char *hostname)
-{
-	struct gg_resolver_pthread_data *data = NULL;
-	int pipes[2], new_errno;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_resolver_pthread_start(%p, %p, \"%s\");\n", fd, priv_data, hostname);
-
-	if (fd == NULL || priv_data == NULL || hostname == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() invalid arguments\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	data = malloc(sizeof(struct gg_resolver_pthread_data));
-
-	if (data == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() out of memory for resolver data\n");
-		return -1;
-	}
-
-	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pipes) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() unable "
-			"to create pipes (errno=%d, %s)\n",
-			errno, strerror(errno));
-		free(data);
-		return -1;
-	}
-
-	data->hostname = strdup(hostname);
-
-	if (data->hostname == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() out of memory\n");
-		new_errno = errno;
-		goto cleanup;
-	}
-
-	data->wfd = pipes[1];
-
-	if (pthread_create(&data->thread, NULL, gg_resolver_pthread_thread, data)) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() unable to create thread\n");
-		new_errno = errno;
-		goto cleanup;
-	}
-
-	gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() %p\n", data);
-
-	*fd = pipes[0];
-	*priv_data = data;
-
-	return 0;
-
-cleanup:
-	if (data != NULL)
-		free(data->hostname);
-
-	free(data);
-
-	close(pipes[0]);
-	close(pipes[1]);
-
-	errno = new_errno;
-
-	return -1;
-}
-
-#endif /* GG_CONFIG_HAVE_PTHREAD */
-
-#ifdef _WIN32
-
-/**
- * \internal Struktura przekazywana do wątku rozwiązującego nazwę.
- */
-struct gg_resolver_win32_data {
-	HANDLE thread;		/*< Uchwyt wątku */
-	CRITICAL_SECTION mutex;	/*< Semafor wątku */
-	char *hostname;		/*< Nazwa serwera */
-	int wfd;		/*< Deskryptor do zapisu */
-	int orphan;		/*< Wątek powinien sam po sobie posprzątać */
-	int finished;		/*< Wątek już skończył pracę */
-};
-
-/**
- * \internal Wątek rozwiązujący nazwę.
- *
- * \param arg Wskaźnik na strukturę \c gg_resolver_win32_data
- */
-static DWORD WINAPI gg_resolver_win32_thread(void *arg)
-{
-	struct gg_resolver_win32_data *data = arg;
-	int result, is_orphan;
-
-	result = gg_resolver_run(data->wfd, data->hostname, 0);
-
-	EnterCriticalSection(&data->mutex);
-	is_orphan = data->orphan;
-	data->finished = 1;
-	LeaveCriticalSection(&data->mutex);
-
-	if (is_orphan) {
-		CloseHandle(data->thread);
-		DeleteCriticalSection(&data->mutex);
-		close(data->wfd);
-		free(data->hostname);
-		free(data);
-	}
-
-	ExitThread(result);
-	return 0; /* żeby kompilator nie marudził */
-}
-
-/**
- * \internal Rozwiązuje nazwę serwera w osobnym wątku.
- *
- * Funkcja działa analogicznie do \c gg_resolver_pthread_start(), z tą różnicą,
- * że działa na wątkach Win32. Jest dostępna wyłącznie przy kompilacji dla
- * systemu Windows.
- *
- * \param fd Wskaźnik na zmienną, gdzie zostanie umieszczony deskryptor gniazda
- * \param priv_data Wskaźnik na zmienną, gdzie zostanie umieszczony wskaźnik
- *                  do prywatnych danych wątku rozwiązującego nazwę
- * \param hostname Nazwa serwera do rozwiązania
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_resolver_win32_start(int *fd, void **priv_data, const char *hostname)
-{
-	struct gg_resolver_win32_data *data = NULL;
-	int pipes[2], new_errno;
-	CRITICAL_SECTION *mutex = NULL;
-
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_resolver_win32_start(%p, %p, \"%s\");\n", fd, priv_data, hostname);
-
-	if (fd == NULL || priv_data == NULL || hostname == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_win32_start() invalid arguments\n");
-		errno = EFAULT;
-		return -1;
-	}
-
-	data = malloc(sizeof(struct gg_resolver_win32_data));
-
-	if (data == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_win32_start() out of memory for resolver data\n");
-		return -1;
-	}
-
-	data->orphan = 0;
-	data->finished = 0;
-
-	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pipes) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_win32_start() unable to "
-			"create pipes (errno=%d, %s)\n",
-			errno, strerror(errno));
-		free(data);
-		return -1;
-	}
-
-	data->hostname = strdup(hostname);
-
-	if (data->hostname == NULL) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_win32_start() out of memory\n");
-		new_errno = errno;
-		goto cleanup;
-	}
-
-	data->wfd = pipes[1];
-
-	mutex = &data->mutex;
-	InitializeCriticalSection(mutex);
-
-	data->thread = CreateThread(NULL, 0, gg_resolver_win32_thread, data, 0, NULL);
-	if (!data->thread) {
-		gg_debug(GG_DEBUG_MISC, "// gg_resolver_win32_start() unable to create thread\n");
-		new_errno = errno;
-		goto cleanup;
-	}
-
-	gg_debug(GG_DEBUG_MISC, "// gg_resolver_win32_start() %p\n", data);
-
-	*fd = pipes[0];
-	*priv_data = data;
-
-	return 0;
-
-cleanup:
-	if (data) {
-		free(data->hostname);
-		free(data);
-	}
-
-	close(pipes[0]);
-	close(pipes[1]);
-
-	if (mutex)
-		DeleteCriticalSection(mutex);
-
-	errno = new_errno;
-
-	return -1;
-}
-
-/**
- * \internal Usuwanie zasobów po wątku rozwiązywaniu nazwy.
- *
- * Funkcja wywoływana po zakończeniu rozwiązanywania nazwy lub przy zwalnianiu
- * zasobów sesji podczas rozwiązywania nazwy.
- *
- * \param priv_data Wskaźnik na zmienną przechowującą wskaźnik do prywatnych
- *                  danych
- * \param force Flaga usuwania zasobów przed zakończeniem działania
- */
-static void gg_resolver_win32_cleanup(void **priv_data, int force)
-{
-	struct gg_resolver_win32_data *data;
-
-	if (priv_data == NULL || *priv_data == NULL)
-		return;
-
-	data = (struct gg_resolver_win32_data *) *priv_data;
-	*priv_data = NULL;
-
-	if (WaitForSingleObject(data->thread, 0) == WAIT_TIMEOUT) {
-		int finished;
-		/* We cannot call TerminateThread here - it doesn't
-		 * release critical section locks (see MSDN docs).
-		 * if (force) TerminateThread(data->thread, 0);
-		 */
-		EnterCriticalSection(&data->mutex);
-		finished = data->finished;
-		if (!finished)
-			data->orphan = 1;
-		LeaveCriticalSection(&data->mutex);
-		if (!finished)
-			return;
-	}
-
-	CloseHandle(data->thread);
-	DeleteCriticalSection(&data->mutex);
-	close(data->wfd);
-	free(data->hostname);
-	free(data);
-}
-
-#endif /* _WIN32 */
-
-/**
- * Ustawia sposób rozwiązywania nazw w sesji.
- *
- * \param gs Struktura sesji
- * \param type Sposób rozwiązywania nazw (patrz \ref build-resolver)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_session_set_resolver(struct gg_session *gs, gg_resolver_t type)
-{
-	GG_SESSION_CHECK(gs, -1);
-
-	if (type == GG_RESOLVER_DEFAULT) {
-		if (gg_global_resolver_type != GG_RESOLVER_DEFAULT) {
-			gs->resolver_type = gg_global_resolver_type;
-			gs->resolver_start = gg_global_resolver_start;
-			gs->resolver_cleanup = gg_global_resolver_cleanup;
-			return 0;
-		}
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-		type = GG_RESOLVER_PTHREAD;
-#elif defined(_WIN32)
-		type = GG_RESOLVER_WIN32;
-#elif defined(GG_CONFIG_HAVE_FORK)
-		type = GG_RESOLVER_FORK;
-#endif
-	}
-
-	switch (type) {
-#ifdef GG_CONFIG_HAVE_FORK
-		case GG_RESOLVER_FORK:
-			gs->resolver_type = type;
-			gs->resolver_start = gg_resolver_fork_start;
-			gs->resolver_cleanup = gg_resolver_fork_cleanup;
-			return 0;
-#endif
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-		case GG_RESOLVER_PTHREAD:
-			gs->resolver_type = type;
-			gs->resolver_start = gg_resolver_pthread_start;
-			gs->resolver_cleanup = gg_resolver_pthread_cleanup;
-			return 0;
-#endif
-
-#ifdef _WIN32
-		case GG_RESOLVER_WIN32:
-			gs->resolver_type = type;
-			gs->resolver_start = gg_resolver_win32_start;
-			gs->resolver_cleanup = gg_resolver_win32_cleanup;
-			return 0;
-#endif
-
-		default:
-			errno = EINVAL;
-			return -1;
-	}
-}
-
-/**
- * Zwraca sposób rozwiązywania nazw w sesji.
- *
- * \param gs Struktura sesji
- *
- * \return Sposób rozwiązywania nazw
- */
-gg_resolver_t gg_session_get_resolver(struct gg_session *gs)
-{
-	GG_SESSION_CHECK(gs, (gg_resolver_t) -1);
-
-	return gs->resolver_type;
-}
-
-/**
- * Ustawia własny sposób rozwiązywania nazw w sesji.
- *
- * \param gs Struktura sesji
- * \param resolver_start Funkcja rozpoczynająca rozwiązywanie nazwy
- * \param resolver_cleanup Funkcja zwalniająca zasoby
- *
- * Parametry funkcji rozpoczynającej rozwiązywanie nazwy wyglądają następująco:
- *  - \c "int *fd" &mdash; wskaźnik na zmienną, gdzie zostanie umieszczony deskryptor gniazda
- *  - \c "void **priv_data" &mdash; wskaźnik na zmienną, gdzie można umieścić
- *    wskaźnik do prywatnych danych na potrzeby rozwiązywania nazwy
- *  - \c "const char *name" &mdash; nazwa serwera do rozwiązania
- *
- * Parametry funkcji zwalniającej zasoby wyglądają następująco:
- *  - \c "void **priv_data" &mdash; wskaźnik na zmienną przechowującą wskaźnik
- *    do prywatnych danych, należy go ustawić na \c NULL po zakończeniu
- *  - \c "int force" &mdash; flaga mówiąca o tym, że zasoby są zwalniane przed
- *    zakończeniem rozwiązywania nazwy, np. z powodu zamknięcia sesji.
- *
- * Własny kod rozwiązywania nazwy powinien stworzyć potok, parę gniazd lub
- * inny deskryptor pozwalający na co najmniej odbiór danych i przekazać go
- * w parametrze \c fd. Na platformie Windows możliwe jest przekazanie jedynie
- * deskryptora gniazda. Po zakończeniu rozwiązywania nazwy powinien wysłać
- * otrzymany adres IP w postaci sieciowej (big-endian) do deskryptora. Jeśli
- * rozwiązywanie nazwy się nie powiedzie, należy wysłać \c INADDR_NONE.
- * Następnie zostanie wywołana funkcja zwalniająca zasoby z parametrem
- * \c force równym \c 0. Gdyby sesja została zakończona przed rozwiązaniem
- * nazwy, np. za pomocą funkcji \c gg_logoff(), funkcja zwalniająca zasoby
- * zostanie wywołana z parametrem \c force równym \c 1.
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_session_set_custom_resolver(struct gg_session *gs,
-	int (*resolver_start)(int*, void**, const char*),
-	void (*resolver_cleanup)(void**, int))
-{
-	GG_SESSION_CHECK(gs, -1);
-
-	if (resolver_start == NULL || resolver_cleanup == NULL) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	gs->resolver_type = GG_RESOLVER_CUSTOM;
-	gs->resolver_start = resolver_start;
-	gs->resolver_cleanup = resolver_cleanup;
-
-	return 0;
-}
-
-/**
- * Ustawia sposób rozwiązywania nazw połączenia HTTP.
- *
- * \param gh Struktura połączenia
- * \param type Sposób rozwiązywania nazw (patrz \ref build-resolver)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_http_set_resolver(struct gg_http *gh, gg_resolver_t type)
-{
-	if (gh == NULL) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (type == GG_RESOLVER_DEFAULT) {
-		if (gg_global_resolver_type != GG_RESOLVER_DEFAULT) {
-			gh->resolver_type = gg_global_resolver_type;
-			gh->resolver_start = gg_global_resolver_start;
-			gh->resolver_cleanup = gg_global_resolver_cleanup;
-			return 0;
-		}
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-		type = GG_RESOLVER_PTHREAD;
-#elif defined(_WIN32)
-		type = GG_RESOLVER_WIN32;
-#elif defined(GG_CONFIG_HAVE_FORK)
-		type = GG_RESOLVER_FORK;
-#endif
-	}
-
-	switch (type) {
-#ifdef GG_CONFIG_HAVE_FORK
-		case GG_RESOLVER_FORK:
-			gh->resolver_type = type;
-			gh->resolver_start = gg_resolver_fork_start;
-			gh->resolver_cleanup = gg_resolver_fork_cleanup;
-			return 0;
-#endif
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-		case GG_RESOLVER_PTHREAD:
-			gh->resolver_type = type;
-			gh->resolver_start = gg_resolver_pthread_start;
-			gh->resolver_cleanup = gg_resolver_pthread_cleanup;
-			return 0;
-#endif
-
-#ifdef _WIN32
-		case GG_RESOLVER_WIN32:
-			gh->resolver_type = type;
-			gh->resolver_start = gg_resolver_win32_start;
-			gh->resolver_cleanup = gg_resolver_win32_cleanup;
-			return 0;
-#endif
-
-		default:
-			errno = EINVAL;
-			return -1;
-	}
-}
-
-/**
- * Zwraca sposób rozwiązywania nazw połączenia HTTP.
- *
- * \param gh Struktura połączenia
- *
- * \return Sposób rozwiązywania nazw
- */
-gg_resolver_t gg_http_get_resolver(struct gg_http *gh)
-{
-	if (gh == NULL) {
-		errno = EINVAL;
-		return GG_RESOLVER_INVALID;
-	}
-
-	return gh->resolver_type;
-}
-
-/**
- * Ustawia własny sposób rozwiązywania nazw połączenia HTTP.
- *
- * \param gh Struktura sesji
- * \param resolver_start Funkcja rozpoczynająca rozwiązywanie nazwy
- * \param resolver_cleanup Funkcja zwalniająca zasoby
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_http_set_custom_resolver(struct gg_http *gh,
-	int (*resolver_start)(int*, void**, const char*),
-	void (*resolver_cleanup)(void**, int))
-{
-	if (gh == NULL || resolver_start == NULL || resolver_cleanup == NULL) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	gh->resolver_type = GG_RESOLVER_CUSTOM;
-	gh->resolver_start = resolver_start;
-	gh->resolver_cleanup = resolver_cleanup;
-
-	return 0;
-}
-
-/**
- * Ustawia sposób rozwiązywania nazw globalnie dla biblioteki.
- *
- * \param type Sposób rozwiązywania nazw (patrz \ref build-resolver)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_global_set_resolver(gg_resolver_t type)
-{
-	switch (type) {
-		case GG_RESOLVER_DEFAULT:
-			gg_global_resolver_type = type;
-			gg_global_resolver_start = NULL;
-			gg_global_resolver_cleanup = NULL;
-			return 0;
-
-#ifdef GG_CONFIG_HAVE_FORK
-		case GG_RESOLVER_FORK:
-			gg_global_resolver_type = type;
-			gg_global_resolver_start = gg_resolver_fork_start;
-			gg_global_resolver_cleanup = gg_resolver_fork_cleanup;
-			return 0;
-#endif
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-		case GG_RESOLVER_PTHREAD:
-			gg_global_resolver_type = type;
-			gg_global_resolver_start = gg_resolver_pthread_start;
-			gg_global_resolver_cleanup = gg_resolver_pthread_cleanup;
-			return 0;
-#endif
-
-#ifdef _WIN32
-		case GG_RESOLVER_WIN32:
-			gg_global_resolver_type = type;
-			gg_global_resolver_start = gg_resolver_win32_start;
-			gg_global_resolver_cleanup = gg_resolver_win32_cleanup;
-			return 0;
-#endif
-
-		default:
-			errno = EINVAL;
-			return -1;
-	}
-}
-
-/**
- * Zwraca sposób rozwiązywania nazw globalnie dla biblioteki.
- *
- * \return Sposób rozwiązywania nazw
- */
-gg_resolver_t gg_global_get_resolver(void)
-{
-	return gg_global_resolver_type;
-}
-
-/**
- * Ustawia własny sposób rozwiązywania nazw globalnie dla biblioteki.
- *
- * \param resolver_start Funkcja rozpoczynająca rozwiązywanie nazwy
- * \param resolver_cleanup Funkcja zwalniająca zasoby
- *
- * Patrz \ref gg_session_set_custom_resolver.
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_global_set_custom_resolver(
-	int (*resolver_start)(int*, void**, const char*),
-	void (*resolver_cleanup)(void**, int))
-{
-	if (resolver_start == NULL || resolver_cleanup == NULL) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	gg_global_resolver_type = GG_RESOLVER_CUSTOM;
-	gg_global_resolver_start = resolver_start;
-	gg_global_resolver_cleanup = resolver_cleanup;
-
-	return 0;
-}
-
-/**
- * Odczytuje dane z procesu/wątku rozwiązywania nazw.
- *
- * \param fd Deskryptor
- * \param buf Wskaźnik na bufor
- * \param len Długość bufora
- *
- * \return Patrz recv() i read().
- */
-int gg_resolver_recv(int fd, void *buf, size_t len)
-{
-#ifndef _WIN32
-	return read(fd, buf, len);
-#else
-	return recv(fd, buf, len, 0);
-#endif
-}
--- a/libpurple/protocols/gg/lib/resolver.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- *  (C) Copyright 2008 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_RESOLVER_H
-#define LIBGADU_RESOLVER_H
-
-#include "network.h"
-
-int gg_gethostbyname_real(const char *hostname, struct in_addr **result, unsigned int *count, int pthread);
-int gg_resolver_recv(int fd, void *buf, size_t len);
-void gg_resolver_cleaner(void *data);
-
-#endif /* LIBGADU_RESOLVER_H */
--- a/libpurple/protocols/gg/lib/session.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- *  (C) Copyright 2008-2010 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_SESSION_H
-#define LIBGADU_SESSION_H
-
-#ifdef GG_CONFIG_HAVE_GNUTLS
-#  include <gnutls/gnutls.h>
-#endif
-
-#define GG_SESSION_CHECK(gs, result) \
-	do { \
-		if ((gs) == NULL) { \
-			errno = EINVAL; \
-			return (result); \
-		} \
-	} while (0)
-
-#define GG_SESSION_CHECK_CONNECTED(gs, result) \
-	do { \
-		GG_SESSION_CHECK(gs, result); \
-		\
-		if (!GG_SESSION_IS_CONNECTED(gs)) { \
-			errno = ENOTCONN; \
-			return (result); \
-		} \
-	} while (0)
-
-#define GG_SESSION_IS_IDLE(gs) ((gs)->state == GG_STATE_IDLE)
-#define GG_SESSION_IS_CONNECTING(gs) ((gs)->state != GG_STATE_IDLE && (gs)->state != GG_STATE_CONNECTED)
-#define GG_SESSION_IS_CONNECTED(gs) ((gs)->state == GG_STATE_CONNECTED)
-
-#ifdef GG_CONFIG_HAVE_GNUTLS
-
-typedef struct {
-	gnutls_session_t session;
-	gnutls_certificate_credentials_t xcred;
-} gg_session_gnutls_t;
-
-#define GG_SESSION_GNUTLS(gs) ((gg_session_gnutls_t*) (gs)->ssl)->session
-
-#endif /* GG_CONFIG_HAVE_GNUTLS */
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-
-#define GG_SESSION_OPENSSL(gs) ((SSL*) (gs)->ssl)
-
-#endif /* GG_CONFIG_HAVE_OPENSSL */
-
-int gg_session_handle_packet(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge);
-
-#endif /* LIBGADU_SESSION_H */
--- a/libpurple/protocols/gg/lib/sha1.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,382 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2007 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- *  Public domain SHA-1 implementation by Steve Reid <steve@edmweb.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file sha1.c
- *
- * \brief Funkcje wyznaczania skrótu SHA1
- */
-
-#include <errno.h>
-#include <string.h>
-
-#include "libgadu.h"
-#include "internal.h"
-#include "fileio.h"
-#include "config.h"
-
-/** \cond ignore */
-
-#ifdef GG_CONFIG_HAVE_OPENSSL
-
-#include <openssl/sha.h>
-
-#elif defined(GG_CONFIG_HAVE_GNUTLS)
-
-#include <gnutls/gnutls.h>
-#include <gnutls/crypto.h>
-
-#define SHA_CTX gnutls_hash_hd_t
-#define SHA1_Init(ctx) (gnutls_hash_init((ctx), GNUTLS_DIG_SHA1) == 0 ? 1 : 0)
-#define SHA1_Update(ctx, ptr, len) (gnutls_hash(*(ctx), (ptr), (len)) == 0 ? 1 : 0)
-#define SHA1_Final(digest, ctx) (gnutls_hash_deinit(*(ctx), (digest)), 1)
-
-#else
-
-/*
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-
-Modified by Wojtek Kaniewski <wojtekka@toxygen.net> for compatibility
-with libgadu and OpenSSL API.
-
-Test Vectors (from FIPS PUB 180-1)
-"abc"
-  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
-"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
-  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
-A million repetitions of "a"
-  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-*/
-
-/* #define LITTLE_ENDIAN * This should be #define'd if true. */
-/* #define SHA1HANDSOFF * Copies data before messing with it. */
-
-typedef struct {
-    uint32_t state[5];
-    uint32_t count[2];
-    unsigned char buffer[64];
-} SHA_CTX;
-
-static void SHA1_Transform(uint32_t state[5], const unsigned char buffer[64]);
-static int SHA1_Init(SHA_CTX* context);
-static int SHA1_Update(SHA_CTX* context, const unsigned char* data, unsigned int len);
-static int SHA1_Final(unsigned char digest[20], SHA_CTX* context);
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#ifndef GG_CONFIG_BIGENDIAN
-#define blk0(i) (block.l[i] = (rol(block.l[i], 24) & 0xFF00FF00) \
-    |(rol(block.l[i], 8) & 0x00FF00FF))
-#else
-#define blk0(i) block.l[i]
-#endif
-#define blk(i) (block.l[i&15] = rol(block.l[(i+13)&15]^block.l[(i+8)&15] \
-    ^block.l[(i+2)&15]^block.l[i&15], 1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-/* style:comma:start-ignore */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-/* style:comma:end-ignore */
-
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-static void SHA1_Transform(uint32_t state[5], const unsigned char buffer[64])
-{
-uint32_t a, b, c, d, e;
-typedef union {
-    unsigned char c[64];
-    uint32_t l[16];
-} CHAR64LONG16;
-    CHAR64LONG16 block;
-    memcpy(&block, buffer, sizeof(block));
-    /* Copy context->state[] to working vars */
-    a = state[0];
-    b = state[1];
-    c = state[2];
-    d = state[3];
-    e = state[4];
-    /* 4 rounds of 20 operations each. Loop unrolled. */
-    /* style:comma:start-ignore */
-    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
-    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
-    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
-    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
-    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
-    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
-    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
-    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
-    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
-    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
-    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
-    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
-    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
-    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
-    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
-    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-    /* style:comma:end-ignore */
-    /* Add the working vars back into context.state[] */
-    state[0] += a;
-    state[1] += b;
-    state[2] += c;
-    state[3] += d;
-    state[4] += e;
-    /* Wipe variables */
-    memset(&a, 0, sizeof(a));
-    memset(&b, 0, sizeof(b));
-    memset(&c, 0, sizeof(c));
-    memset(&d, 0, sizeof(d));
-    memset(&e, 0, sizeof(e));
-}
-
-
-/* SHA1_Init - Initialize new context */
-
-static int SHA1_Init(SHA_CTX* context)
-{
-    /* SHA1 initialization constants */
-    context->state[0] = 0x67452301;
-    context->state[1] = 0xEFCDAB89;
-    context->state[2] = 0x98BADCFE;
-    context->state[3] = 0x10325476;
-    context->state[4] = 0xC3D2E1F0;
-    context->count[0] = context->count[1] = 0;
-
-    return 1;
-}
-
-
-/* Run your data through this. */
-
-static int SHA1_Update(SHA_CTX* context, const unsigned char* data, unsigned int len)
-{
-unsigned int i, j;
-
-    j = (context->count[0] >> 3) & 63;
-    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
-    context->count[1] += (len >> 29);
-    if ((j + len) > 63) {
-        memcpy(&context->buffer[j], data, (i = 64-j));
-        SHA1_Transform(context->state, context->buffer);
-        for ( ; i + 63 < len; i += 64) {
-            SHA1_Transform(context->state, &data[i]);
-        }
-        j = 0;
-    }
-    else i = 0;
-    memcpy(&context->buffer[j], &data[i], len - i);
-
-    return 1;
-}
-
-
-/* Add padding and return the message digest. */
-
-static int SHA1_Final(unsigned char digest[20], SHA_CTX* context)
-{
-uint32_t i;
-unsigned char finalcount[8];
-
-    for (i = 0; i < 8; i++) {
-        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
-         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
-    }
-    SHA1_Update(context, (const unsigned char *)"\200", 1);
-    while ((context->count[0] & 504) != 448) {
-        SHA1_Update(context, (const unsigned char *)"\0", 1);
-    }
-    SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1_Transform() */
-    for (i = 0; i < 20; i++) {
-        digest[i] = (unsigned char)
-         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
-    }
-    /* Wipe variables */
-    memset(context->buffer, 0, 64);
-    memset(context->state, 0, 20);
-    memset(context->count, 0, 8);
-    memset(&finalcount, 0, 8);
-#ifdef SHA1HANDSOFF  /* make SHA1_Transform overwrite it's own static vars */
-    SHA1_Transform(context->state, context->buffer);
-#endif
-
-    return 1;
-}
-
-#endif /* GG_CONFIG_HAVE_OPENSSL */
-
-/** \endcond */
-
-/** \cond internal */
-
-/**
- * \internal Liczy skrót SHA1 z ziarna i hasła.
- *
- * \param password Hasło
- * \param seed Ziarno
- * \param result Bufor na wynik funkcji skrótu (20 bajtów)
- *
- * \return 0 lub -1
- */
-int gg_login_hash_sha1_2(const char *password, uint32_t seed, uint8_t *result)
-{
-	SHA_CTX ctx;
-
-	if (!SHA1_Init(&ctx))
-		return -1;
-
-	if (!SHA1_Update(&ctx, (const unsigned char*) password, strlen(password)))
-		goto fail;
-
-	seed = gg_fix32(seed);
-	if (!SHA1_Update(&ctx, (uint8_t*) &seed, 4))
-		goto fail;
-
-	if (!SHA1_Final(result, &ctx))
-		return -1;
-
-	return 0;
-
-fail:
-	/* Zwolnij zasoby. Tylko GnuTLS przyjęłoby NULL zamiast result, więc przekaż result. */
-	(void)SHA1_Final(result, &ctx);
-	return -1;
-}
-
-/**
- * \internal Liczy skrót SHA1 z fragmentu pliku.
- *
- * \param fd Deskryptor pliku
- * \param ctx Kontekst SHA-1
- * \param pos Położenie fragmentu pliku
- * \param len Długość fragmentu pliku
- *
- * \return 0 lub -1
- */
-static int gg_file_hash_sha1_part(int fd, SHA_CTX *ctx, off_t pos, size_t len)
-{
-	unsigned char buf[4096];
-	size_t chunk_len;
-	int res = 0;
-
-	while (len > 0) {
-		if (lseek(fd, pos, SEEK_SET) == (off_t) -1) {
-			res = -1;
-			break;
-		}
-
-		chunk_len = len;
-
-		if (chunk_len > sizeof(buf))
-			chunk_len = sizeof(buf);
-
-		res = read(fd, buf, chunk_len);
-
-		if (res == -1 && errno != EINTR)
-			break;
-
-		if (res == 0)
-			break;
-
-		if (res != -1) {
-			if (!SHA1_Update(ctx, buf, res)) {
-				res = -1;
-				break;
-			}
-
-			pos += res;
-			len -= res;
-		}
-	}
-
-	return res;
-}
-
-/**
- * \internal Liczy skrót SHA1 z pliku.
- *
- * Dla plików poniżej 10MB liczony jest skrót z całego pliku, dla plików
- * powyżej 10MB liczy się 9 jednomegabajtowych fragmentów.
- *
- * \param fd Deskryptor pliku
- * \param result Bufor na wynik funkcji skrótu (20 bajtów)
- *
- * \return 0 lub -1
- */
-int gg_file_hash_sha1(int fd, uint8_t *result)
-{
-	SHA_CTX ctx;
-	off_t pos, len;
-	int res;
-	const size_t part_len = 1048576;
-
-	if ((pos = lseek(fd, 0, SEEK_CUR)) == (off_t) -1)
-		return -1;
-
-	if ((len = lseek(fd, 0, SEEK_END)) == (off_t) -1)
-		return -1;
-
-	if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
-		return -1;
-
-	if (!SHA1_Init(&ctx))
-		return -1;
-
-	if (len <= (off_t)part_len * 10) {
-		res = gg_file_hash_sha1_part(fd, &ctx, 0, len);
-	} else {
-		unsigned int i;
-
-		for (i = 0; i < 9; i++) {
-			off_t part_pos = (len - part_len) / 9 * i;
-
-			res = gg_file_hash_sha1_part(fd, &ctx, part_pos, part_len);
-
-			if (res == -1)
-				break;
-		}
-	}
-
-	if (!SHA1_Final(result, &ctx))
-		return -1;
-
-	if (res == -1)
-		return -1;
-
-	if (lseek(fd, pos, SEEK_SET) == (off_t) -1)
-		return -1;
-
-	return 0;
-}
-
-/** \endcond */
--- a/libpurple/protocols/gg/lib/strman.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2011 Bartosz Brachaczek <b.brachaczek@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file strman.h
- *
- * \brief Makra zapewniające kompatybilność API do obsługi operacji na stringach na różnych systemach
- */
-
-#ifndef LIBGADU_STRMAN_H
-#define LIBGADU_STRMAN_H
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#ifndef _MSC_VER
-#  include <strings.h>
-#else
-#  define snprintf(str, size, format, ...) _snprintf_s(str, size, _TRUNCATE, format, __VA_ARGS__)
-#  define vsnprintf(str, size, format, ap) vsnprintf_s(str, size, _TRUNCATE, format, ap)
-#  define strdup _strdup
-#  define strcasecmp _stricmp
-#  define strncasecmp _strnicmp
-#endif
-
-#endif /* LIBGADU_STRMAN_H */
--- a/libpurple/protocols/gg/lib/tvbuff.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,607 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2012 Tomek Wasilczyk <www.wasilczyk.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file tvbuff.c
- *
- * \brief Bufor wspierający obsługę pakietów typu Type-Value(s)
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "tvbuff.h"
-
-#include "internal.h"
-
-struct gg_tvbuff
-{
-	const char *buffer;
-	size_t length;
-	size_t offset;
-	int valid;
-};
-
-/**
- * \internal Tworzy nową instancję bufora.
- *
- * \param buffer Bufor źródłowy; nie może być modyfikowany (w szczególności
- *        zwalniany) przez cały okres korzystania z jego opakowanej wersji.
- * \param length Długość bufora źródłowego.
- *
- * \return Zaalokowane opakowanie bufora - musi być zwolnione przez free lub
- *         gg_tvbuff_close.
- */
-gg_tvbuff_t *gg_tvbuff_new(const char *buffer, size_t length)
-{
-	gg_tvbuff_t *tvb;
-
-	tvb = malloc(sizeof(gg_tvbuff_t));
-	if (tvb == NULL)
-		return NULL;
-	memset(tvb, 0, sizeof(gg_tvbuff_t));
-
-	if (buffer == NULL && length > 0) {
-		gg_debug(GG_DEBUG_ERROR, "// gg_tvbuff_new() "
-			"invalid arguments\n");
-		tvb->valid = 0;
-		return tvb;
-	}
-
-	tvb->buffer = buffer;
-	tvb->length = length;
-	tvb->offset = 0;
-	tvb->valid = 1;
-
-	return tvb;
-}
-
-/**
- * \internal Zwalnia opakowanie bufora. Przed zwolnieniem sprawdza, czy
- * przeczytano go do końca.
- *
- * \param tvb Bufor.
- *
- * \return Wartość różna od 0, jeżeli bufor tuż przed zwolnieniem był oznaczony
- *         jako prawidłowy
- */
-int gg_tvbuff_close(gg_tvbuff_t *tvb)
-{
-	int valid;
-
-	gg_tvbuff_expected_eob(tvb);
-	valid = gg_tvbuff_is_valid(tvb);
-	free(tvb);
-
-	return valid;
-}
-
-/**
- * \internal Sprawdza, czy wszystkie odczyty z bufora były prawidłowe.
- *
- * \param tvb Bufor.
- *
- * \return Wartość różna od 0, jeżeli wszystkie odczyty były prawidłowe.
- */
-int gg_tvbuff_is_valid(const gg_tvbuff_t *tvb)
-{
-	if (tvb == NULL)
-		return 0;
-	return tvb->valid;
-}
-
-/**
- * \internal Zwraca pozostałą do odczytania liczbę bajtów w buforze.
- *
- * \param tvb Bufor.
- *
- * \return Pozostała liczba bajtów do odczytania.
- */
-size_t gg_tvbuff_get_remaining(const gg_tvbuff_t *tvb)
-{
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	return tvb->length - tvb->offset;
-}
-
-/**
- * \internal Sprawdza, czy w buforze pozostała określona liczba bajtów do
- * odczytania. Jeżeli nie została - oznacza bufor jako nieprawidłowy.
- *
- * \param tvb    Bufor.
- * \param length Ilość bajtów do odczytania.
- *
- * \return Wartość różna od 0, jeżeli można odczytać podaną liczbę bajtów.
- */
-int gg_tvbuff_have_remaining(gg_tvbuff_t *tvb, size_t length)
-{
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	if (gg_tvbuff_get_remaining(tvb) >= length)
-		return 1;
-
-	gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_have_remaining() failed "
-		"(%" GG_SIZE_FMT " < %" GG_SIZE_FMT ")\n",
-		gg_tvbuff_get_remaining(tvb), length);
-	tvb->valid = 0;
-	return 0;
-}
-
-/**
- * \internal Pomija określoną liczbę bajtów w buforze. Jeżeli w wyniku ich
- * pominięcia wyjdzie poza zakres, oznacza bufor jako nieprawidłowy.
- *
- * \param tvb    Bufor
- * \param amount Liczba bajtów do pominięcia
- */
-void gg_tvbuff_skip(gg_tvbuff_t *tvb, size_t amount)
-{
-	if (!gg_tvbuff_is_valid(tvb))
-		return;
-
-	if (tvb->offset + amount > tvb->length) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_skip() failed\n");
-		tvb->valid = 0;
-		return;
-	}
-
-	tvb->offset += amount;
-}
-
-/**
- * \internal Cofa się o określoną liczbę bajtów w buforze. Jeżeli cofnie przed
- * pierwszy znak, oznacza bufor jako nieprawidłowy.
- *
- * \param tvb    Bufor
- * \param amount Liczba bajtów do cofnięcia
- */
-void gg_tvbuff_rewind(gg_tvbuff_t *tvb, size_t amount)
-{
-	if (!gg_tvbuff_is_valid(tvb))
-		return;
-
-	if (tvb->offset < amount) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_rewind() failed\n");
-		tvb->valid = 0;
-		return;
-	}
-
-	tvb->offset -= amount;
-}
-
-/**
- * \internal Sprawdza, czy pod aktualną pozycją w buforze występuje podana
- * wartość. Jeżeli tak, przesuwa aktualną pozycję do przodu.
- *
- * \param tvb   Bufor.
- * \param value Wartość do sprawdzenia
- *
- * \return Wartość różna od 0, jeżeli znaleziono podaną wartość.
- */
-int gg_tvbuff_match(gg_tvbuff_t *tvb, uint8_t value)
-{
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	if (!gg_tvbuff_have_remaining(tvb, 1)) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_match() failed\n");
-		return 0;
-	}
-
-	if (tvb->buffer[tvb->offset] != value)
-		return 0;
-
-	tvb->offset++;
-	return 1;
-}
-
-/**
- * \internal Odczytuje z bufora liczbę 8-bitową.
- *
- * \param tvb Bufor
- *
- * \return Odczytana liczba
- */
-uint8_t gg_tvbuff_read_uint8(gg_tvbuff_t *tvb)
-{
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	if (!gg_tvbuff_have_remaining(tvb, 1)) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_uint8() "
-			"failed at %" GG_SIZE_FMT "\n", tvb->offset);
-		return 0;
-	}
-
-	return tvb->buffer[tvb->offset++];
-}
-
-/**
- * \internal Odczytuje z bufora liczbę 32-bitową.
- *
- * \param tvb Bufor
- *
- * \return Odczytana liczba
- */
-uint32_t gg_tvbuff_read_uint32(gg_tvbuff_t *tvb)
-{
-	uint32_t val;
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	if (!gg_tvbuff_have_remaining(tvb, 4)) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_uint32() "
-			"failed at %" GG_SIZE_FMT "\n", tvb->offset);
-		return 0;
-	}
-
-	memcpy(&val, tvb->buffer + tvb->offset, 4);
-	tvb->offset += 4;
-
-	return gg_fix32(val);
-}
-
-/**
- * \internal Odczytuje z bufora liczbę 64-bitową.
- *
- * \param tvb Bufor
- *
- * \return Odczytana liczba
- */
-uint64_t gg_tvbuff_read_uint64(gg_tvbuff_t *tvb)
-{
-	uint64_t val;
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	if (!gg_tvbuff_have_remaining(tvb, 8)) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_uint64() "
-			"failed at %" GG_SIZE_FMT "\n", tvb->offset);
-		return 0;
-	}
-
-	memcpy(&val, tvb->buffer + tvb->offset, 8);
-	tvb->offset += 8;
-
-	return gg_fix64(val);
-}
-
-/**
- * \internal Odczytuje z bufora skompresowaną liczbę całkowitą.
- * Liczba taka może być zapisana w buforze na 1-9 bajtach, w zależności
- * od jej wartości.
- *
- * Skompresowana liczba jest zapisywana od najmłodszego bajtu do najstarszego
- * niezerowego. W każdym bajcie zapisuje się bit sterujący (równy 0, jeżeli jest
- * to ostatni bajt do przeczytania, lub 1 w p.p.) oraz 7 kolejnych bitów z
- * kompresowanej liczby.
- *
- * Przykładowo, liczby mniejsze od 128 (1000.0000b) są zapisywane dokładnie tak,
- * jak uint8_t; a np. 12345 (0011.0000.0011.1001b) zostanie zapisana jako 0x60B9
- * (0110.0000.1011.1001b).
- *
- * \param tvb Bufor.
- *
- * \return Odczytana liczba.
- */
-uint64_t gg_tvbuff_read_packed_uint(gg_tvbuff_t *tvb)
-{
-	uint64_t val = 0;
-	int i, val_len = 0;
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	while (gg_tvbuff_have_remaining(tvb, 1)) {
-		val_len++;
-		if (!(gg_tvbuff_read_uint8(tvb) & 0x80))
-			break;
-	}
-
-	if (!gg_tvbuff_is_valid(tvb)) {
-		gg_debug(GG_DEBUG_WARNING,
-			"// gg_tvbuff_read_packed_uint() failed\n");
-		return 0;
-	}
-
-	if (val_len > 9) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_packed_uint() "
-			"packed uint size too big: %d\n", val_len);
-		tvb->valid = 0;
-		return 0;
-	}
-
-	for (i = 1; i <= val_len; i++) {
-		uint64_t old_val = val;
-		val <<= 7;
-		if (old_val != (val >> 7)) {
-			gg_debug(GG_DEBUG_WARNING,
-				"// gg_tvbuff_read_packed_uint() overflow\n");
-			tvb->valid = 0;
-			return 0;
-		}
-		val |= (uint8_t)(tvb->buffer[tvb->offset - i] & ~0x80);
-	}
-
-	return val;
-}
-
-/**
- * \internal Odczytuje z bufora podciąg bez kopiowania danych.
- *
- * \param tvb    Bufor źródłowy
- * \param length Ilość bajtów do odczytania
- *
- * \return Wskaźnik na początek odczytanych danych, lub NULL w przypadku
- *         niepowodzenia
- */
-const char *gg_tvbuff_read_buff(gg_tvbuff_t *tvb, size_t length)
-{
-	const char *buff;
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return NULL;
-
-	if (!gg_tvbuff_have_remaining(tvb, length)) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_get_buff() "
-			"failed at %" GG_SIZE_FMT ":%" GG_SIZE_FMT "\n",
-			tvb->offset, length);
-		return NULL;
-	}
-
-	buff = tvb->buffer + tvb->offset;
-	tvb->offset += length;
-	return buff;
-}
-
-/**
- * \internal Odczytuje z bufora podciąg kopiując go do nowego obszaru pamięci.
- *
- * \param tvb    Bufor źródłowy
- * \param buffer Bufor docelowy
- * \param length Ilość bajtów do odczytania
- */
-void gg_tvbuff_read_buff_cpy(gg_tvbuff_t *tvb, char *buffer, size_t length)
-{
-	if (!gg_tvbuff_is_valid(tvb))
-		return;
-
-	if (!gg_tvbuff_have_remaining(tvb, length)) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_buff() "
-			"failed at %" GG_SIZE_FMT ":%" GG_SIZE_FMT "\n",
-			tvb->offset, length);
-		return;
-	}
-
-	if (buffer == NULL && length > 0) {
-		gg_debug(GG_DEBUG_ERROR, "// gg_tvbuff_new() "
-			"invalid arguments\n");
-		tvb->valid = 0;
-		return;
-	}
-
-	memcpy(buffer, tvb->buffer + tvb->offset, length);
-	tvb->offset += length;
-}
-
-/**
- * \internal Odczytuje z bufora ciąg tekstowy (mogący zawierać dowolne znaki,
- * również \0) bez kopiowania danych.
- *
- * \param tvb    Bufor źródłowy
- * \param length Zmienna, do której zostanie zapisana długość odczytanego ciągu
- *
- * \return Wskaźnik na początek odczytanych danych, lub NULL w przypadku
- *         niepowodzenia
- */
-const char *gg_tvbuff_read_str(gg_tvbuff_t *tvb, size_t *length)
-{
-	size_t offset;
-	uint32_t str_len;
-	const char *str;
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return NULL;
-
-	offset = tvb->offset;
-	str_len = gg_tvbuff_read_packed_uint(tvb);
-	if (!gg_tvbuff_is_valid(tvb) ||
-		!gg_tvbuff_have_remaining(tvb, str_len))
-	{
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_str() failed at "
-			"%" GG_SIZE_FMT ":%d\n", offset, str_len);
-		return NULL;
-	}
-
-	str = gg_tvbuff_read_buff(tvb, str_len);
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return NULL;
-
-	if (length != NULL)
-		*length = str_len;
-	if (str_len == 0)
-		return NULL;
-	return str;
-}
-
-/**
- * \internal Odczytuje z bufora ciąg tekstowy (mogący zawierać dowolne znaki,
- * również \0) kopiując go do nowego obszaru pamięci. Zwrócony ciąg będzie
- * zawsze zakończony znakiem \0.
- *
- * \param tvb Bufor źródłowy
- * \param dst Zmienna, do której zostanie zapisany wskaźnik na odczytany ciąg.
- *            Po użyciu, blok ten powinien zostać zwolniony za pomocą \c free()
- *
- * \return Wskaźnik na początek odczytanych danych, lub NULL w przypadku
- *         niepowodzenia
- */
-void gg_tvbuff_read_str_dup(gg_tvbuff_t *tvb, char **dst)
-{
-	size_t offset;
-	uint32_t str_len;
-	char *str;
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return;
-
-	offset = tvb->offset;
-	str_len = gg_tvbuff_read_packed_uint(tvb);
-	if (!gg_tvbuff_is_valid(tvb) ||
-		!gg_tvbuff_have_remaining(tvb, str_len))
-	{
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_str_dup() failed "
-			"at %" GG_SIZE_FMT ":%d\n", offset, str_len);
-		return;
-	}
-
-	str = malloc(str_len + 1);
-	if (str == NULL) {
-		gg_debug(GG_DEBUG_ERROR, "// gg_tvbuff_read_str_dup() "
-			"not enough free memory: %d + 1\n", str_len);
-		tvb->valid = 0;
-		return;
-	}
-
-	gg_tvbuff_read_buff_cpy(tvb, str, str_len);
-	str[str_len] = '\0';
-
-	if (*dst != NULL) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_str_dup() "
-			"destination already filled, freeing it...\n");
-		free(*dst);
-	}
-	*dst = str;
-}
-
-/**
- * \internal Odczytuje z bufora identyfikator użytkownika.
- *
- * \param tvb Bufor
- *
- * \return Identyfikator użytkownika, lub 0 w przypadku niepowodzenia
- */
-uin_t gg_tvbuff_read_uin(gg_tvbuff_t *tvb)
-{
-	uin_t uin = 0;
-	uint32_t uin_len, full_len;
-	uint8_t uin_type;
-	const char *raw;
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	full_len = gg_tvbuff_read_packed_uint(tvb);
-	uin_type = gg_tvbuff_read_uint8(tvb);
-	uin_len = gg_tvbuff_read_uint8(tvb);
-
-	if (!gg_tvbuff_is_valid(tvb))
-		return 0;
-
-	if (full_len != uin_len + 2 ||
-		uin_type != 0 ||
-		uin_len > 10)
-	{
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_uin() failed (1)\n");
-		tvb->valid = 0;
-		return 0;
-	}
-
-	raw = gg_tvbuff_read_buff(tvb, uin_len);
-	if (raw)
-		uin = gg_str_to_uin(raw, uin_len);
-
-	if (uin == 0) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_read_uin() failed (2)\n");
-		tvb->valid = 0;
-		return 0;
-	}
-
-	return uin;
-}
-
-/**
- * \internal Odczytuje z bufora liczbę 8-bitową i porównuje z podaną. Jeżeli te
- * się różnią, zostaje wygenerowane ostrzeżenie.
- *
- * \param tvb   Bufor
- * \param value Oczekiwana wartość
- */
-void gg_tvbuff_expected_uint8(gg_tvbuff_t *tvb, uint8_t value)
-{
-	uint8_t got;
-	size_t offset;
-
-	offset = tvb->offset;
-	got = gg_tvbuff_read_uint8(tvb);
-	if (!gg_tvbuff_is_valid(tvb))
-		return;
-
-	if (got != value)
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_expected_uint8() "
-			"expected %#02x, but %#02x found at %" GG_SIZE_FMT "\n",
-			value, got, offset);
-}
-
-/**
- * \internal Odczytuje z bufora liczbę 32-bitową i porównuje z podaną. Jeżeli te
- * się różnią, zostaje wygenerowane ostrzeżenie.
- *
- * \param tvb   Bufor
- * \param value Oczekiwana wartość
- */
-void gg_tvbuff_expected_uint32(gg_tvbuff_t *tvb, uint32_t value)
-{
-	uint32_t got;
-	size_t offset;
-
-	offset = tvb->offset;
-	got = gg_tvbuff_read_uint32(tvb);
-	if (!gg_tvbuff_is_valid(tvb))
-		return;
-
-	if (got != value)
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_expected_uint32() "
-			"expected %#08x, but %#08x found at %" GG_SIZE_FMT "\n",
-			value, got, offset);
-}
-
-/**
- * \internal Oczekuje końca bufora. Jeżeli w buforze są jeszcze dane do
- * przeczytania, generuje ostrzeżenie.
- *
- * \param tvb Bufor.
- */
-void gg_tvbuff_expected_eob(const gg_tvbuff_t *tvb)
-{
-	if (!gg_tvbuff_is_valid(tvb))
-		return;
-
-	if (gg_tvbuff_get_remaining(tvb) != 0)
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuff_expected_eob() "
-			"unexpected %" GG_SIZE_FMT " bytes, first=%#02x\n",
-			gg_tvbuff_get_remaining(tvb),
-			tvb->buffer[tvb->offset]);
-}
--- a/libpurple/protocols/gg/lib/tvbuff.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2012 Tomek Wasilczyk <www.wasilczyk.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_TVBUFF_H
-#define LIBGADU_TVBUFF_H
-
-#include "libgadu.h"
-
-typedef struct gg_tvbuff gg_tvbuff_t;
-
-gg_tvbuff_t * gg_tvbuff_new(const char *buffer, size_t length);
-int gg_tvbuff_close(gg_tvbuff_t *tvb);
-
-int gg_tvbuff_is_valid(const gg_tvbuff_t *tvb);
-
-size_t gg_tvbuff_get_remaining(const gg_tvbuff_t *tvb);
-
-int gg_tvbuff_have_remaining(gg_tvbuff_t *tvb, size_t length);
-
-void gg_tvbuff_skip(gg_tvbuff_t *tvb, size_t amount);
-void gg_tvbuff_rewind(gg_tvbuff_t *tvb, size_t amount);
-
-int gg_tvbuff_match(gg_tvbuff_t *tvb, uint8_t value);
-
-uint8_t gg_tvbuff_read_uint8(gg_tvbuff_t *tvb);
-uint32_t gg_tvbuff_read_uint32(gg_tvbuff_t *tvb);
-uint64_t gg_tvbuff_read_uint64(gg_tvbuff_t *tvb);
-
-uint64_t gg_tvbuff_read_packed_uint(gg_tvbuff_t *tvb);
-
-const char * gg_tvbuff_read_buff(gg_tvbuff_t *tvb, size_t length);
-void gg_tvbuff_read_buff_cpy(gg_tvbuff_t *tvb, char *buffer, size_t length);
-const char * gg_tvbuff_read_str(gg_tvbuff_t *tvb, size_t *length);
-void gg_tvbuff_read_str_dup(gg_tvbuff_t *tvb, char **dst);
-
-uin_t gg_tvbuff_read_uin(gg_tvbuff_t *tvb);
-
-void gg_tvbuff_expected_uint8(gg_tvbuff_t *tvb, uint8_t value);
-void gg_tvbuff_expected_uint32(gg_tvbuff_t *tvb, uint32_t value);
-void gg_tvbuff_expected_eob(const gg_tvbuff_t *tvb);
-
-#endif /* LIBGADU_TVBUFF_H */
--- a/libpurple/protocols/gg/lib/tvbuilder.c	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,426 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2012 Tomek Wasilczyk <www.wasilczyk.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-/**
- * \file tvbuilder.c
- *
- * \brief Bufor wspierający budowanie pakietów typu Type-Value(s)
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "tvbuilder.h"
-
-#include "internal.h"
-#include "fileio.h"
-
-#include <errno.h>
-
-struct gg_tvbuilder
-{
-	char *buffer;
-	size_t length;
-	size_t alloc_length;
-	int valid;
-
-	struct gg_session *gs;
-	struct gg_event *ge;
-};
-
-static char *gg_tvbuilder_extend(gg_tvbuilder_t *tvb, size_t length);
-
-/**
- * \internal Tworzy nową instancję bufora.
- *
- * \param gs Struktura sesji
- * \param ge Struktura zdarzenia
- *
- * \return Zaalokowany bufor - musi być zwolniony przez gg_tvbuilder_free,
- *         gg_tvbuilder_fail lub gg_tvbuilder_send.
- */
-gg_tvbuilder_t *gg_tvbuilder_new(struct gg_session *gs, struct gg_event *ge)
-{
-	gg_tvbuilder_t *tvb;
-
-	tvb = malloc(sizeof(gg_tvbuilder_t));
-	if (tvb == NULL)
-		return NULL;
-	memset(tvb, 0, sizeof(gg_tvbuilder_t));
-
-	if (gs == NULL) {
-		gg_debug(GG_DEBUG_ERROR, "// gg_tvbuilder_new() "
-			"invalid arguments\n");
-		tvb->valid = 0;
-		return tvb;
-	}
-
-	tvb->buffer = NULL;
-	tvb->length = 0;
-	tvb->alloc_length = 0;
-	tvb->valid = 1;
-
-	tvb->gs = gs;
-	tvb->ge = ge;
-
-	return tvb;
-}
-
-/**
- * \internal Zwalnia bufor.
- *
- * \param tvb Bufor
- */
-void gg_tvbuilder_free(gg_tvbuilder_t *tvb)
-{
-	if (tvb == NULL)
-		return;
-
-	free(tvb->buffer);
-	free(tvb);
-}
-
-/**
- * \internal Zwalnia bufor i generuje błąd połączenia.
- *
- * \param tvb     Bufor
- * \param failure Powód błędu
- */
-void gg_tvbuilder_fail(gg_tvbuilder_t *tvb, enum gg_failure_t failure)
-{
-	int errno_copy;
-
-	if (tvb == NULL) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuilder_fail() "
-			"NULL tvbuilder\n");
-		return;
-	}
-
-	errno_copy = errno;
-	close(tvb->gs->fd);
-	tvb->gs->fd = -1;
-	errno = errno_copy;
-
-	if (tvb->ge) {
-		tvb->ge->type = GG_EVENT_CONN_FAILED;
-		tvb->ge->event.failure = failure;
-	}
-	tvb->gs->state = GG_STATE_IDLE;
-
-	gg_tvbuilder_free(tvb);
-}
-
-/**
- * \internal Próbuje wysłać zawartość bufora i go zwalnia.
- *
- * \param tvb  Bufor
- * \param type Typ pakietu
- *
- * \return 1 jeśli się powiodło, 0 w p.p.
- */
-int gg_tvbuilder_send(gg_tvbuilder_t *tvb, int type)
-{
-	int ret;
-	enum gg_failure_t failure;
-
-	if (tvb == NULL) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuilder_send() "
-			"NULL tvbuilder\n");
-		return 0;
-	}
-
-	if (!gg_tvbuilder_is_valid(tvb)) {
-		gg_debug_session(tvb->gs, GG_DEBUG_ERROR, "// gg_tvbuilder_send() "
-			"invalid buffer\n");
-		ret = -1;
-		failure = GG_FAILURE_INTERNAL;
-	} else {
-		const char *buffer = (tvb->length > 0) ? tvb->buffer : "";
-		ret = gg_send_packet(tvb->gs, type, buffer, tvb->length, NULL);
-		if (ret == -1) {
-			failure = GG_FAILURE_WRITING;
-			gg_debug_session(tvb->gs, GG_DEBUG_ERROR,
-				"// gg_tvbuilder_send() "
-				"sending packet %#x failed. (errno=%d, %s)\n",
-				type, errno, strerror(errno));
-		}
-	}
-
-	if (ret == -1) {
-		gg_tvbuilder_fail(tvb, failure);
-		return 0;
-	}
-
-	gg_tvbuilder_free(tvb);
-	return 1;
-}
-
-/**
- * \internal Sprawdza, czy wszystkie zapisy do  bufora były prawidłowe.
- *
- * \param tvb Builder.
- *
- * \return Wartość różna od 0, jeżeli wszystkie zapisy były prawidłowe.
- */
-int gg_tvbuilder_is_valid(const gg_tvbuilder_t *tvb)
-{
-	if (tvb == NULL)
-		return 0;
-	return tvb->valid;
-}
-
-/**
- * \internal Sprawdza rozmiar bufora.
- *
- * \param tvb Bufor
- *
- * \return Rozmiar bufora
- */
-size_t gg_tvbuilder_get_size(const gg_tvbuilder_t *tvb)
-{
-	if (!gg_tvbuilder_is_valid(tvb))
-		return 0;
-
-	return tvb->length;
-}
-
-/**
- * \internal Określa oczekiwaną liczbę bajtów, o którą zostanie rozszerzony
- * bufor.
- *
- * Funkcja powoduje jedynie wzrost wydajności poprzez zmniejszenie ilości
- * realokacji.
- *
- * \param tvb    Builder.
- * \param length Oczekiwana liczba bajtów.
- */
-void gg_tvbuilder_expected_size(gg_tvbuilder_t *tvb, size_t length)
-{
-	size_t length_new;
-	char *buff_new;
-
-	if (!gg_tvbuilder_is_valid(tvb) || length == 0)
-		return;
-
-	length_new = tvb->length + length;
-
-	if (length_new <= tvb->alloc_length)
-		return;
-
-	if (tvb->alloc_length > 0) {
-		gg_debug(GG_DEBUG_MISC, "// gg_tvbuilder_expected_size(%p, %"
-			GG_SIZE_FMT ") realloc from %" GG_SIZE_FMT " to %"
-			GG_SIZE_FMT "\n",
-			tvb, length, tvb->alloc_length, length_new);
-	}
-
-	buff_new = realloc(tvb->buffer, length_new);
-	if (buff_new != NULL) {
-		tvb->buffer = buff_new;
-		tvb->alloc_length = length_new;
-		return;
-	}
-
-	gg_debug(GG_DEBUG_ERROR, "// gg_tvbuilder_expected_size(%p, %"
-		GG_SIZE_FMT ") out of memory (new length: %" GG_SIZE_FMT
-		")\n", tvb, length, length_new);
-	free(tvb->buffer);
-	tvb->buffer = NULL;
-	tvb->length = 0;
-	tvb->alloc_length = 0;
-	tvb->valid = 0;
-}
-
-/**
- * \internal Poszerza bufor o podaną liczbę bajtów.
- *
- * \param tvb    Bufor
- * \param length Liczba bajtów do dodania
- *
- * \return Początek nowo dodanego bloku bufora
- */
-static char * gg_tvbuilder_extend(gg_tvbuilder_t *tvb, size_t length)
-{
-	size_t length_old;
-
-	gg_tvbuilder_expected_size(tvb, length);
-	if (!gg_tvbuilder_is_valid(tvb))
-		return NULL;
-
-	length_old = tvb->length;
-	tvb->length += length;
-
-	return tvb->buffer + length_old;
-}
-
-/**
- * \internal Skraca bufor o podaną liczbę bajtów
- *
- * \param tvb Bufor
- * \param length Ilość bajtów do skrócenia
- */
-void gg_tvbuilder_strip(gg_tvbuilder_t *tvb, size_t length)
-{
-	if (!gg_tvbuilder_is_valid(tvb))
-		return;
-
-	if (length > tvb->length) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuilder_strip() "
-			"out of range\n");
-		tvb->valid = 0;
-		return;
-	}
-
-	tvb->length = length;
-}
-
-/**
- * \internal Zapisuje do bufora liczbę 8-bitową.
- *
- * \param tvb   Bufor
- * \param value Wartość do zapisania
- */
-void gg_tvbuilder_write_uint8(gg_tvbuilder_t *tvb, uint8_t value)
-{
-	gg_tvbuilder_write_buff(tvb, (const char *)&value, 1);
-}
-
-/**
- * \internal Zapisuje do bufora liczbę 32-bitową.
- *
- * \param tvb   Bufor
- * \param value Wartość do zapisania
- */
-void gg_tvbuilder_write_uint32(gg_tvbuilder_t *tvb, uint32_t value)
-{
-	value = gg_fix32(value);
-	gg_tvbuilder_write_buff(tvb, (const char *)&value, 4);
-}
-
-/**
- * \internal Zapisuje do bufora liczbę 64-bitową.
- *
- * \param tvb   Bufor
- * \param value Wartość do zapisania
- */
-void gg_tvbuilder_write_uint64(gg_tvbuilder_t *tvb, uint64_t value)
-{
-	value = gg_fix64(value);
-	gg_tvbuilder_write_buff(tvb, (const char *)&value, 8);
-}
-
-/**
- * \internal Zapisuje do bufora liczbę 1-9 bajtową.
- *
- * \param tvb   Bufor
- * \param value Wartość do zapisania
- *
- * \see gg_tvbuff_read_packed_uint
- */
-void gg_tvbuilder_write_packed_uint(gg_tvbuilder_t *tvb, uint64_t value)
-{
-	uint8_t buff[9];
-	uint64_t val_curr;
-	int i, val_len = 0;
-
-	if (!gg_tvbuilder_is_valid(tvb))
-		return;
-
-	val_curr = value;
-	while (val_curr > 0) {
-		val_curr >>= 7;
-		val_len++;
-	}
-	if (val_len == 0)
-		val_len = 1;
-
-	if (val_len > 9) {
-		gg_debug(GG_DEBUG_WARNING, "// gg_tvbuilder_write_packed_uint() "
-			"int size too big (%d): %" PRIu64 "\n", val_len, value);
-		tvb->valid = 0;
-		return;
-	}
-
-	val_curr = value;
-	for (i = 0; i < val_len; i++) {
-		uint8_t raw = val_curr & 0x7F;
-		val_curr >>= 7;
-		if (i + 1 < val_len)
-			raw |= 0x80;
-		buff[i] = raw;
-	}
-
-	gg_tvbuilder_write_buff(tvb, (const char*)buff, val_len);
-}
-
-/**
- * \internal Zapisuje do bufora zawartość innego bufora.
- *
- * \param tvb    Bufor docelowy
- * \param buffer Bufor źródłowy
- * \param length Ilość danych do skopiowania
- */
-void gg_tvbuilder_write_buff(gg_tvbuilder_t *tvb, const char *buffer,
-	size_t length)
-{
-	char *buff = gg_tvbuilder_extend(tvb, length);
-	if (!buff)
-		return;
-
-	memcpy(buff, buffer, length);
-}
-
-/**
- * \internal Zapisuje do bufora ciąg tekstowy (mogący zawierać znaki \0).
- *
- * \param tvb    Bufor docelowy
- * \param buffer Bufor źródłowy
- * \param length Długość tekstu, lub -1, jeżeli ma zostać wyliczona
- *               automatycznie (do pierwszego znaku \0)
- */
-void gg_tvbuilder_write_str(gg_tvbuilder_t *tvb, const char *buffer,
-	ssize_t length)
-{
-	if (!gg_tvbuilder_is_valid(tvb))
-		return;
-
-	if (length == -1)
-		length = strlen(buffer);
-
-	gg_tvbuilder_write_packed_uint(tvb, length);
-	gg_tvbuilder_write_buff(tvb, buffer, length);
-}
-
-/**
- * \internal Zapisuje do bufora identyfikator użytkownika.
- *
- * \param tvb          Bufor
- * \param uin          Identyfikator użytkownika
- */
-void gg_tvbuilder_write_uin(gg_tvbuilder_t *tvb, uin_t uin)
-{
-	char uin_str[16];
-	int uin_len;
-
-	uin_len = snprintf(uin_str, sizeof(uin_str), "%u", uin);
-
-	gg_tvbuilder_write_uint8(tvb, 0x00);
-	gg_tvbuilder_write_str(tvb, uin_str, uin_len);
-}
--- a/libpurple/protocols/gg/lib/tvbuilder.h	Wed Sep 28 09:32:19 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/* $Id$ */
-
-/*
- *  (C) Copyright 2012 Tomek Wasilczyk <www.wasilczyk.pl>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License Version
- *  2.1 as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-
-#ifndef LIBGADU_TVBUILDER_H
-#define LIBGADU_TVBUILDER_H
-
-#include "libgadu.h"
-
-typedef struct gg_tvbuilder gg_tvbuilder_t;
-
-gg_tvbuilder_t * gg_tvbuilder_new(struct gg_session *gs, struct gg_event *ge);
-void gg_tvbuilder_free(gg_tvbuilder_t *tvb);
-void gg_tvbuilder_fail(gg_tvbuilder_t *tvb, enum gg_failure_t failure);
-int gg_tvbuilder_send(gg_tvbuilder_t *tvb, int type);
-
-int gg_tvbuilder_is_valid(const gg_tvbuilder_t *tvb);
-
-size_t gg_tvbuilder_get_size(const gg_tvbuilder_t *tvb);
-void gg_tvbuilder_expected_size(gg_tvbuilder_t *tvb, size_t length);
-void gg_tvbuilder_strip(gg_tvbuilder_t *tvb, size_t length);
-
-void gg_tvbuilder_write_uint8(gg_tvbuilder_t *tvb, uint8_t value);
-void gg_tvbuilder_write_uint32(gg_tvbuilder_t *tvb, uint32_t value);
-void gg_tvbuilder_write_uint64(gg_tvbuilder_t *tvb, uint64_t value);
-
-void gg_tvbuilder_write_packed_uint(gg_tvbuilder_t *tvb, uint64_t value);
-
-void gg_tvbuilder_write_buff(gg_tvbuilder_t *tvb, const char *buffer, size_t length);
-void gg_tvbuilder_write_str(gg_tvbuilder_t *tvb, const char *buffer, ssize_t length);
-
-void gg_tvbuilder_write_uin(gg_tvbuilder_t *tvb, uin_t uin);
-
-#endif /* LIBGADU_TVBUILDER_H */

mercurial